build.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. use std::collections::HashMap;
  2. use std::fmt::Write;
  3. use std::path::PathBuf;
  4. use std::{env, fs};
  5. static CONFIGS: &[(&str, usize)] = &[
  6. // BEGIN AUTOGENERATED CONFIG FEATURES
  7. // Generated by gen_config.py. DO NOT EDIT.
  8. ("IFACE_MAX_ADDR_COUNT", 2),
  9. ("IFACE_MAX_MULTICAST_GROUP_COUNT", 4),
  10. ("IFACE_MAX_SIXLOWPAN_ADDRESS_CONTEXT_COUNT", 4),
  11. ("IFACE_NEIGHBOR_CACHE_COUNT", 8),
  12. ("IFACE_MAX_ROUTE_COUNT", 2),
  13. ("FRAGMENTATION_BUFFER_SIZE", 1500),
  14. ("ASSEMBLER_MAX_SEGMENT_COUNT", 4),
  15. ("REASSEMBLY_BUFFER_SIZE", 1500),
  16. ("REASSEMBLY_BUFFER_COUNT", 1),
  17. ("IPV6_HBH_MAX_OPTIONS", 4),
  18. ("DNS_MAX_RESULT_COUNT", 1),
  19. ("DNS_MAX_SERVER_COUNT", 1),
  20. ("DNS_MAX_NAME_SIZE", 255),
  21. ("RPL_RELATIONS_BUFFER_COUNT", 16),
  22. ("RPL_PARENTS_BUFFER_COUNT", 8),
  23. // END AUTOGENERATED CONFIG FEATURES
  24. ];
  25. struct ConfigState {
  26. value: usize,
  27. seen_feature: bool,
  28. seen_env: bool,
  29. }
  30. fn main() {
  31. // only rebuild if build.rs changed. Otherwise Cargo will rebuild if any
  32. // other file changed.
  33. println!("cargo:rerun-if-changed=build.rs");
  34. // Rebuild if config envvar changed.
  35. for (name, _) in CONFIGS {
  36. println!("cargo:rerun-if-env-changed=SMOLTCP_{name}");
  37. }
  38. let mut configs = HashMap::new();
  39. for (name, default) in CONFIGS {
  40. configs.insert(
  41. *name,
  42. ConfigState {
  43. value: *default,
  44. seen_env: false,
  45. seen_feature: false,
  46. },
  47. );
  48. }
  49. for (var, value) in env::vars() {
  50. if let Some(name) = var.strip_prefix("SMOLTCP_") {
  51. let Some(cfg) = configs.get_mut(name) else {
  52. panic!("Unknown env var {name}")
  53. };
  54. let Ok(value) = value.parse::<usize>() else {
  55. panic!("Invalid value for env var {name}: {value}")
  56. };
  57. cfg.value = value;
  58. cfg.seen_env = true;
  59. }
  60. if let Some(feature) = var.strip_prefix("CARGO_FEATURE_") {
  61. if let Some(i) = feature.rfind('_') {
  62. let name = &feature[..i];
  63. let value = &feature[i + 1..];
  64. if let Some(cfg) = configs.get_mut(name) {
  65. let Ok(value) = value.parse::<usize>() else {
  66. panic!("Invalid value for feature {name}: {value}")
  67. };
  68. // envvars take priority.
  69. if !cfg.seen_env {
  70. if cfg.seen_feature {
  71. panic!(
  72. "multiple values set for feature {}: {} and {}",
  73. name, cfg.value, value
  74. );
  75. }
  76. cfg.value = value;
  77. cfg.seen_feature = true;
  78. }
  79. }
  80. }
  81. }
  82. }
  83. let mut data = String::new();
  84. for (name, cfg) in &configs {
  85. writeln!(&mut data, "pub const {}: usize = {};", name, cfg.value).unwrap();
  86. }
  87. let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
  88. let out_file = out_dir.join("config.rs").to_string_lossy().to_string();
  89. fs::write(out_file, data).unwrap();
  90. }