This ensures the executor compiles with all recent nightly versions, including the stable-but-with-nightly-features-enabled xtensa rustc.
		
			
				
	
	
		
			127 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| // NOTE: this file is copy-pasted between several Embassy crates, because there is no
 | |
| // straightforward way to share this code:
 | |
| // - it cannot be placed into the root of the repo and linked from each build.rs using `#[path =
 | |
| // "../build_common.rs"]`, because `cargo publish` requires that all files published with a crate
 | |
| // reside in the crate's directory,
 | |
| // - it cannot be symlinked from `embassy-xxx/build_common.rs` to `../build_common.rs`, because
 | |
| // symlinks don't work on Windows.
 | |
| 
 | |
| use std::collections::HashSet;
 | |
| use std::env;
 | |
| 
 | |
| /// Helper for emitting cargo instruction for enabling configs (`cargo:rustc-cfg=X`) and declaring
 | |
| /// them (`cargo:rust-check-cfg=cfg(X)`).
 | |
| #[derive(Debug)]
 | |
| pub struct CfgSet {
 | |
|     enabled: HashSet<String>,
 | |
|     declared: HashSet<String>,
 | |
| }
 | |
| 
 | |
| impl CfgSet {
 | |
|     pub fn new() -> Self {
 | |
|         Self {
 | |
|             enabled: HashSet::new(),
 | |
|             declared: HashSet::new(),
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Enable a config, which can then be used in `#[cfg(...)]` for conditional compilation.
 | |
|     ///
 | |
|     /// All configs that can potentially be enabled should be unconditionally declared using
 | |
|     /// [`Self::declare()`].
 | |
|     pub fn enable(&mut self, cfg: impl AsRef<str>) {
 | |
|         if self.enabled.insert(cfg.as_ref().to_owned()) {
 | |
|             println!("cargo:rustc-cfg={}", cfg.as_ref());
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     pub fn enable_all(&mut self, cfgs: &[impl AsRef<str>]) {
 | |
|         for cfg in cfgs.iter() {
 | |
|             self.enable(cfg.as_ref());
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /// Declare a valid config for conditional compilation, without enabling it.
 | |
|     ///
 | |
|     /// This enables rustc to check that the configs in `#[cfg(...)]` attributes are valid.
 | |
|     pub fn declare(&mut self, cfg: impl AsRef<str>) {
 | |
|         if self.declared.insert(cfg.as_ref().to_owned()) {
 | |
|             println!("cargo:rustc-check-cfg=cfg({})", cfg.as_ref());
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     pub fn declare_all(&mut self, cfgs: &[impl AsRef<str>]) {
 | |
|         for cfg in cfgs.iter() {
 | |
|             self.declare(cfg.as_ref());
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     pub fn set(&mut self, cfg: impl Into<String>, enable: bool) {
 | |
|         let cfg = cfg.into();
 | |
|         if enable {
 | |
|             self.enable(cfg.clone());
 | |
|         }
 | |
|         self.declare(cfg);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// Sets configs that describe the target platform.
 | |
| pub fn set_target_cfgs(cfgs: &mut CfgSet) {
 | |
|     let target = env::var("TARGET").unwrap();
 | |
| 
 | |
|     if target.starts_with("thumbv6m-") {
 | |
|         cfgs.enable_all(&["cortex_m", "armv6m"]);
 | |
|     } else if target.starts_with("thumbv7m-") {
 | |
|         cfgs.enable_all(&["cortex_m", "armv7m"]);
 | |
|     } else if target.starts_with("thumbv7em-") {
 | |
|         cfgs.enable_all(&["cortex_m", "armv7m", "armv7em"]);
 | |
|     } else if target.starts_with("thumbv8m.base") {
 | |
|         cfgs.enable_all(&["cortex_m", "armv8m", "armv8m_base"]);
 | |
|     } else if target.starts_with("thumbv8m.main") {
 | |
|         cfgs.enable_all(&["cortex_m", "armv8m", "armv8m_main"]);
 | |
|     }
 | |
|     cfgs.declare_all(&[
 | |
|         "cortex_m",
 | |
|         "armv6m",
 | |
|         "armv7m",
 | |
|         "armv7em",
 | |
|         "armv8m",
 | |
|         "armv8m_base",
 | |
|         "armv8m_main",
 | |
|     ]);
 | |
| 
 | |
|     cfgs.set("has_fpu", target.ends_with("-eabihf"));
 | |
| }
 | |
| 
 | |
| #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 | |
| pub struct CompilerDate {
 | |
|     year: u16,
 | |
|     month: u8,
 | |
|     day: u8,
 | |
| }
 | |
| 
 | |
| impl CompilerDate {
 | |
|     fn parse(date: &str) -> Option<Self> {
 | |
|         let mut parts = date.split('-');
 | |
|         let year = parts.next()?.parse().ok()?;
 | |
|         let month = parts.next()?.parse().ok()?;
 | |
|         let day = parts.next()?.parse().ok()?;
 | |
|         Some(Self { year, month, day })
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl PartialEq<&str> for CompilerDate {
 | |
|     fn eq(&self, other: &&str) -> bool {
 | |
|         let Some(other) = Self::parse(other) else {
 | |
|             return false;
 | |
|         };
 | |
|         self.eq(&other)
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl PartialOrd<&str> for CompilerDate {
 | |
|     fn partial_cmp(&self, other: &&str) -> Option<std::cmp::Ordering> {
 | |
|         Self::parse(other).map(|other| self.cmp(&other))
 | |
|     }
 | |
| }
 |