| 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. |
| ("IFACE_MAX_ADDR_COUNT", 2), |
| ("IFACE_MAX_MULTICAST_GROUP_COUNT", 4), |
| ("IFACE_MAX_SIXLOWPAN_ADDRESS_CONTEXT_COUNT", 4), |
| ("IFACE_NEIGHBOR_CACHE_COUNT", 4), |
| ("IFACE_MAX_ROUTE_COUNT", 2), |
| ("FRAGMENTATION_BUFFER_SIZE", 1500), |
| ("ASSEMBLER_MAX_SEGMENT_COUNT", 4), |
| ("REASSEMBLY_BUFFER_SIZE", 1500), |
| ("REASSEMBLY_BUFFER_COUNT", 1), |
| ("IPV6_HBH_MAX_OPTIONS", 1), |
| ("DNS_MAX_RESULT_COUNT", 1), |
| ("DNS_MAX_SERVER_COUNT", 1), |
| ("DNS_MAX_NAME_SIZE", 255), |
| ("RPL_RELATIONS_BUFFER_COUNT", 16), |
| ("RPL_PARENTS_BUFFER_COUNT", 8), |
| // END AUTOGENERATED CONFIG FEATURES |
| ]; |
| |
| struct ConfigState { |
| value: usize, |
| seen_feature: bool, |
| seen_env: bool, |
| } |
| |
| fn main() { |
| // 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=SMOLTCP_{name}"); |
| } |
| |
| let mut configs = HashMap::new(); |
| for (name, default) in CONFIGS { |
| configs.insert( |
| *name, |
| ConfigState { |
| value: *default, |
| seen_env: false, |
| seen_feature: false, |
| }, |
| ); |
| } |
| |
| for (var, value) in env::vars() { |
| if let Some(name) = var.strip_prefix("SMOLTCP_") { |
| 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 { |
| if cfg.seen_feature { |
| panic!( |
| "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(); |
| } |