97 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use std::collections::HashMap;
 | |
| use std::fmt::Write;
 | |
| use std::path::PathBuf;
 | |
| use std::{env, fs};
 | |
| 
 | |
| static CONFIGS: &[(&str, usize)] = &[
 | |
|     // BEGIN AUTOGENERATED CONFIG FEATURES
 | |
|     // Generated by gen_config.py. DO NOT EDIT.
 | |
|     ("MAX_INTERFACE_COUNT", 4),
 | |
|     ("MAX_HANDLER_COUNT", 4),
 | |
|     // END AUTOGENERATED CONFIG FEATURES
 | |
| ];
 | |
| 
 | |
| struct ConfigState {
 | |
|     value: usize,
 | |
|     seen_feature: bool,
 | |
|     seen_env: bool,
 | |
| }
 | |
| 
 | |
| fn main() {
 | |
|     let crate_name = env::var("CARGO_PKG_NAME")
 | |
|         .unwrap()
 | |
|         .to_ascii_uppercase()
 | |
|         .replace('-', "_");
 | |
| 
 | |
|     // only rebuild if build.rs changed. Otherwise Cargo will rebuild if any
 | |
|     // other file changed.
 | |
|     println!("cargo:rerun-if-changed=build.rs");
 | |
| 
 | |
|     // Rebuild if config envvar changed.
 | |
|     for (name, _) in CONFIGS {
 | |
|         println!("cargo:rerun-if-env-changed={crate_name}_{name}");
 | |
|     }
 | |
| 
 | |
|     let mut configs = HashMap::new();
 | |
|     for (name, default) in CONFIGS {
 | |
|         configs.insert(
 | |
|             *name,
 | |
|             ConfigState {
 | |
|                 value: *default,
 | |
|                 seen_env: false,
 | |
|                 seen_feature: false,
 | |
|             },
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     let prefix = format!("{crate_name}_");
 | |
|     for (var, value) in env::vars() {
 | |
|         if let Some(name) = var.strip_prefix(&prefix) {
 | |
|             let Some(cfg) = configs.get_mut(name) else {
 | |
|                 panic!("Unknown env var {name}")
 | |
|             };
 | |
| 
 | |
|             let Ok(value) = value.parse::<usize>() else {
 | |
|                 panic!("Invalid value for env var {name}: {value}")
 | |
|             };
 | |
| 
 | |
|             cfg.value = value;
 | |
|             cfg.seen_env = true;
 | |
|         }
 | |
| 
 | |
|         if let Some(feature) = var.strip_prefix("CARGO_FEATURE_") {
 | |
|             if let Some(i) = feature.rfind('_') {
 | |
|                 let name = &feature[..i];
 | |
|                 let value = &feature[i + 1..];
 | |
|                 if let Some(cfg) = configs.get_mut(name) {
 | |
|                     let Ok(value) = value.parse::<usize>() else {
 | |
|                         panic!("Invalid value for feature {name}: {value}")
 | |
|                     };
 | |
| 
 | |
|                     // envvars take priority.
 | |
|                     if !cfg.seen_env {
 | |
|                         assert!(
 | |
|                             !cfg.seen_feature,
 | |
|                             "multiple values set for feature {}: {} and {}",
 | |
|                             name, cfg.value, value
 | |
|                         );
 | |
| 
 | |
|                         cfg.value = value;
 | |
|                         cfg.seen_feature = true;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     let mut data = String::new();
 | |
| 
 | |
|     for (name, cfg) in &configs {
 | |
|         writeln!(&mut data, "pub const {}: usize = {};", name, cfg.value).unwrap();
 | |
|     }
 | |
| 
 | |
|     let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
 | |
|     let out_file = out_dir.join("config.rs").to_string_lossy().to_string();
 | |
|     fs::write(out_file, data).unwrap();
 | |
| }
 |