diff --git a/build.rs b/build.rs index 24b3e3c..bab859e 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::env; use std::fs::File; use std::io::Write; @@ -45,6 +45,32 @@ fn handle_esp8266() { fn handle_esp32() { let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + let rustflags = env::var_os("CARGO_ENCODED_RUSTFLAGS") + .unwrap() + .into_string() + .unwrap(); + + let mut features_to_disable: HashSet = HashSet::new(); + + // Users can pass -Ctarget-feature to the compiler multiple times, so we have to handle that + let target_flags = rustflags + .split(0x1f as char) + .filter(|s| s.starts_with("target-feature=")) + .map(|s| s.strip_prefix("target-feature=")) + .flatten(); + for tf in target_flags { + tf.split(",") + .map(|s| s.trim()) + .filter(|s| s.starts_with('-')) + .map(|s| s.strip_prefix('-')) + .flatten() + .map(rustc_feature_to_xchal_have) + .flatten() + .for_each(|s| { + features_to_disable.insert(s.to_owned()); + }) + } + let chip = match ( cfg!(feature = "esp32"), cfg!(feature = "esp32s2"), @@ -57,7 +83,7 @@ fn handle_esp32() { }; let isa_config = get_config(chip).expect("Unable to parse ISA config"); - inject_cfgs(&isa_config); + inject_cfgs(&isa_config, &features_to_disable); inject_cpu_cfgs(&isa_config); generate_exception_x(&out, &isa_config); generate_interrupt_level_masks(&out, &isa_config); @@ -117,10 +143,12 @@ fn generate_exception_x(out: &PathBuf, isa_config: &HashMap) { .unwrap(); } -fn inject_cfgs(isa_config: &HashMap) { +fn inject_cfgs(isa_config: &HashMap, disabled_features: &HashSet) { for (key, value) in isa_config { if key.starts_with("XCHAL_HAVE") && *value.as_integer().unwrap_or(&0) != 0 { - println!("cargo:rustc-cfg={}", key); + if !disabled_features.contains(key) { + println!("cargo:rustc-cfg={}", key); + } } } } @@ -149,3 +177,38 @@ fn inject_cpu_cfgs(isa_config: &HashMap) { } } } + +fn rustc_feature_to_xchal_have(s: &str) -> Option<&str> { + // List of rustc features taken from here: + // https://github.com/esp-rs/rust/blob/84ecb3f010525cb1b2e7d4da306099c2eaa3e6cd/compiler/rustc_codegen_ssa/src/target_features.rs#L278 + // unlikely to change + Some(match s { + "fp" => "XCHAL_HAVE_FP", + "windowed" => "XCHAL_HAVE_WINDOWED", + "bool" => "XCHAL_HAVE_BOOLEANS", + "loop" => "XCHAL_HAVE_LOOPS", + "sext" => "XCHAL_HAVE_SEXT", + "nsa" => "XCHAL_HAVE_NSA", + "mul32" => "XCHAL_HAVE_MUL32", + "mul32high" => "XCHAL_HAVE_MUL32_HIGH", + "div32" => "XCHAL_HAVE_DIV32", + "mac16" => "XCHAL_HAVE_MAC16", + "dfpaccel" => "XCHAL_HAVE_DFP", + "s32c1i" => "XCHAL_HAVE_S32C1I", + "threadptr" => "XCHAL_HAVE_THREADPTR", + "extendedl32r" => "XCHAL_HAVE_ABSOLUTE_LITERALS", + "debug" => "XCHAL_HAVE_DEBUG", + "exception" => "XCHAL_HAVE_EXCEPTIONS", + "highpriinterrupts" => "XCHAL_HAVE_HIGHPRI_INTERRUPTS", + "coprocessor" => "XCHAL_HAVE_CP", + "interrupt" => "XCHAL_HAVE_INTERRUPTS", + "rvector" => "XCHAL_HAVE_VECTOR_SELECT", + "prid" => "XCHAL_HAVE_PRID", + "regprotect" => "XCHAL_HAVE_MIMIC_CACHEATTR", + "miscsr" => return None, // XCHAL_NUM_MISC_REGS + "timerint" => return None, // XCHAL_NUM_TIMERS + "atomctl" => return None, + "memctl" => return None, + _ => return None, + }) +}