From 368893c9cb1b192c9e0d45440cacb271d1039c29 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20=C5=A0pa=C4=8Dek?= <patek.mail@gmail.com>
Date: Sat, 25 May 2024 21:44:37 +0200
Subject: [PATCH] Emit cargo:rustc-check-cfg instructions from build.rs

---
 build_common.rs                    | 101 +++++++++++++++++
 embassy-executor/build.rs          |  31 +-----
 embassy-hal-internal/build.rs      |  30 +----
 embassy-nrf/src/qspi.rs            |   2 +-
 embassy-stm32/Cargo.toml           |   4 +-
 embassy-stm32/build.rs             | 173 +++++++++++++++++------------
 embassy-stm32/src/adc/mod.rs       |   6 +-
 embassy-stm32/src/adc/v2.rs        |   2 +-
 embassy-stm32/src/can/bxcan/mod.rs |   4 +-
 embassy-stm32/src/cryp/mod.rs      |   4 +-
 embassy-stm32/src/dsihost.rs       |   6 +-
 embassy-stm32/src/flash/mod.rs     |   4 +-
 embassy-stm32/src/fmc.rs           |   4 +-
 embassy-stm32/src/rcc/bd.rs        |   6 +-
 embassy-stm32/src/rcc/f013.rs      |   8 +-
 embassy-stm32/src/usb/usb.rs       |   4 +-
 embassy-sync/build.rs              |  32 +-----
 embassy-sync/src/lib.rs            |   2 +-
 rust-toolchain-nightly.toml        |   2 +-
 19 files changed, 242 insertions(+), 183 deletions(-)
 create mode 100644 build_common.rs

diff --git a/build_common.rs b/build_common.rs
new file mode 100644
index 000000000..eda83f25d
--- /dev/null
+++ b/build_common.rs
@@ -0,0 +1,101 @@
+use std::collections::HashSet;
+use std::env;
+use std::ffi::OsString;
+use std::process::Command;
+
+/// 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>,
+    emit_declared: bool,
+}
+
+impl CfgSet {
+    pub fn new() -> Self {
+        Self {
+            enabled: HashSet::new(),
+            declared: HashSet::new(),
+            emit_declared: is_rustc_nightly(),
+        }
+    }
+
+    /// 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()) && self.emit_declared {
+            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);
+    }
+}
+
+fn is_rustc_nightly() -> bool {
+    let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
+
+    let output = Command::new(rustc)
+        .arg("--version")
+        .output()
+        .expect("failed to run `rustc --version`");
+
+    String::from_utf8_lossy(&output.stdout).contains("nightly")
+}
+
+/// 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"));
+}
diff --git a/embassy-executor/build.rs b/embassy-executor/build.rs
index 07f31e3fb..8af8ccaf3 100644
--- a/embassy-executor/build.rs
+++ b/embassy-executor/build.rs
@@ -3,6 +3,9 @@ use std::fmt::Write;
 use std::path::PathBuf;
 use std::{env, fs};
 
+#[path = "../build_common.rs"]
+mod common;
+
 static CONFIGS: &[(&str, usize)] = &[
     // BEGIN AUTOGENERATED CONFIG FEATURES
     // Generated by gen_config.py. DO NOT EDIT.
@@ -91,30 +94,6 @@ fn main() {
     let out_file = out_dir.join("config.rs").to_string_lossy().to_string();
     fs::write(out_file, data).unwrap();
 
-    // cortex-m targets
-    let target = env::var("TARGET").unwrap();
-
-    if target.starts_with("thumbv6m-") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv6m");
-    } else if target.starts_with("thumbv7m-") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv7m");
-    } else if target.starts_with("thumbv7em-") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv7m");
-        println!("cargo:rustc-cfg=armv7em"); // (not currently used)
-    } else if target.starts_with("thumbv8m.base") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv8m");
-        println!("cargo:rustc-cfg=armv8m_base");
-    } else if target.starts_with("thumbv8m.main") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv8m");
-        println!("cargo:rustc-cfg=armv8m_main");
-    }
-
-    if target.ends_with("-eabihf") {
-        println!("cargo:rustc-cfg=has_fpu");
-    }
+    let mut rustc_cfgs = common::CfgSet::new();
+    common::set_target_cfgs(&mut rustc_cfgs);
 }
diff --git a/embassy-hal-internal/build.rs b/embassy-hal-internal/build.rs
index 6fe82b44f..2649f5d37 100644
--- a/embassy-hal-internal/build.rs
+++ b/embassy-hal-internal/build.rs
@@ -1,29 +1,7 @@
-use std::env;
+#[path = "../build_common.rs"]
+mod common;
 
 fn main() {
-    let target = env::var("TARGET").unwrap();
-
-    if target.starts_with("thumbv6m-") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv6m");
-    } else if target.starts_with("thumbv7m-") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv7m");
-    } else if target.starts_with("thumbv7em-") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv7m");
-        println!("cargo:rustc-cfg=armv7em"); // (not currently used)
-    } else if target.starts_with("thumbv8m.base") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv8m");
-        println!("cargo:rustc-cfg=armv8m_base");
-    } else if target.starts_with("thumbv8m.main") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv8m");
-        println!("cargo:rustc-cfg=armv8m_main");
-    }
-
-    if target.ends_with("-eabihf") {
-        println!("cargo:rustc-cfg=has_fpu");
-    }
+    let mut cfgs = common::CfgSet::new();
+    common::set_target_cfgs(&mut cfgs);
 }
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs
index 060fe72cd..d40096edc 100755
--- a/embassy-nrf/src/qspi.rs
+++ b/embassy-nrf/src/qspi.rs
@@ -166,7 +166,7 @@ impl<'d, T: Instance> Qspi<'d, T> {
                 $pin.conf().write(|w| {
                     w.dir().output();
                     w.drive().h0h1();
-                    #[cfg(feature = "_nrf5340-s")]
+                    #[cfg(all(feature = "_nrf5340", feature = "_s"))]
                     w.mcusel().peripheral();
                     w
                 });
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 4f0d7356d..6a1dfec26 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -72,7 +72,7 @@ rand_core = "0.6.3"
 sdio-host = "0.5.0"
 critical-section = "1.1"
 #stm32-metapac = { version = "15" }
-stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ad633a3e266151ea4d8fad630031a075ee02ab34" }
+stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-59b1f65bd109c3ef35782e6c44062208d0ef3d0e" }
 
 vcell = "0.1.3"
 nb = "1.0.0"
@@ -97,7 +97,7 @@ proc-macro2 = "1.0.36"
 quote = "1.0.15"
 
 #stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
-stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ad633a3e266151ea4d8fad630031a075ee02ab34", default-features = false, features = ["metadata"]}
+stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-59b1f65bd109c3ef35782e6c44062208d0ef3d0e", default-features = false, features = ["metadata"] }
 
 [features]
 default = ["rt"]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 6c524ced6..c7b2ea63a 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -9,35 +9,16 @@ use proc_macro2::{Ident, TokenStream};
 use quote::{format_ident, quote};
 use stm32_metapac::metadata::ir::BitOffset;
 use stm32_metapac::metadata::{
-    MemoryRegionKind, PeripheralRccKernelClock, PeripheralRccRegister, PeripheralRegisters, StopMode, METADATA,
+    MemoryRegionKind, PeripheralRccKernelClock, PeripheralRccRegister, PeripheralRegisters, StopMode, ALL_CHIPS,
+    ALL_PERIPHERAL_VERSIONS, METADATA,
 };
 
+#[path = "../build_common.rs"]
+mod common;
+
 fn main() {
-    let target = env::var("TARGET").unwrap();
-
-    if target.starts_with("thumbv6m-") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv6m");
-    } else if target.starts_with("thumbv7m-") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv7m");
-    } else if target.starts_with("thumbv7em-") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv7m");
-        println!("cargo:rustc-cfg=armv7em"); // (not currently used)
-    } else if target.starts_with("thumbv8m.base") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv8m");
-        println!("cargo:rustc-cfg=armv8m_base");
-    } else if target.starts_with("thumbv8m.main") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv8m");
-        println!("cargo:rustc-cfg=armv8m_main");
-    }
-
-    if target.ends_with("-eabihf") {
-        println!("cargo:rustc-cfg=has_fpu");
-    }
+    let mut cfgs = common::CfgSet::new();
+    common::set_target_cfgs(&mut cfgs);
 
     let chip_name = match env::vars()
         .map(|(a, _)| a)
@@ -56,8 +37,15 @@ fn main() {
 
     for p in METADATA.peripherals {
         if let Some(r) = &p.registers {
-            println!("cargo:rustc-cfg={}", r.kind);
-            println!("cargo:rustc-cfg={}_{}", r.kind, r.version);
+            cfgs.enable(r.kind);
+            cfgs.enable(format!("{}_{}", r.kind, r.version));
+        }
+    }
+
+    for &(kind, versions) in ALL_PERIPHERAL_VERSIONS.iter() {
+        cfgs.declare(kind);
+        for &version in versions.iter() {
+            cfgs.declare(format!("{}_{}", kind, version));
         }
     }
 
@@ -67,7 +55,13 @@ fn main() {
     let mut singletons: Vec<String> = Vec::new();
     for p in METADATA.peripherals {
         if let Some(r) = &p.registers {
-            println!("cargo:rustc-cfg=peri_{}", p.name.to_ascii_lowercase());
+            if r.kind == "adccommon" || r.kind == "sai" || r.kind == "ucpd" {
+                // TODO: should we emit this for all peripherals? if so, we will need a list of all
+                // possible peripherals across all chips, so that we can declare the configs
+                // (replacing the hard-coded list of `peri_*` cfgs below)
+                cfgs.enable(format!("peri_{}", p.name.to_ascii_lowercase()));
+            }
+
             match r.kind {
                 // Generate singletons per pin, not per port
                 "gpio" => {
@@ -87,7 +81,7 @@ fn main() {
                         if pin.signal.starts_with("MCO") {
                             let name = pin.signal.replace('_', "").to_string();
                             if !singletons.contains(&name) {
-                                println!("cargo:rustc-cfg={}", name.to_ascii_lowercase());
+                                cfgs.enable(name.to_ascii_lowercase());
                                 singletons.push(name);
                             }
                         }
@@ -106,6 +100,20 @@ fn main() {
         }
     }
 
+    cfgs.declare_all(&[
+        "peri_adc1_common",
+        "peri_adc3_common",
+        "peri_adc12_common",
+        "peri_adc34_common",
+        "peri_sai1",
+        "peri_sai2",
+        "peri_sai3",
+        "peri_sai4",
+        "peri_ucpd1",
+        "peri_ucpd2",
+    ]);
+    cfgs.declare_all(&["mco", "mco1", "mco2"]);
+
     // One singleton per EXTI line
     for pin_num in 0..16 {
         singletons.push(format!("EXTI{}", pin_num));
@@ -221,7 +229,13 @@ fn main() {
     };
 
     if !time_driver_singleton.is_empty() {
-        println!("cargo:rustc-cfg=time_driver_{}", time_driver_singleton.to_lowercase());
+        cfgs.enable(format!("time_driver_{}", time_driver_singleton.to_lowercase()));
+    }
+    for tim in [
+        "tim1", "tim2", "tim3", "tim4", "tim5", "tim8", "tim9", "tim12", "tim15", "tim20", "tim21", "tim22", "tim23",
+        "tim24",
+    ] {
+        cfgs.declare(format!("time_driver_{}", tim));
     }
 
     // ========
@@ -1593,54 +1607,65 @@ fn main() {
     rustfmt(&out_file);
 
     // ========
-    // Multicore
+    // Configs for multicore and for targeting groups of chips
 
-    let mut s = chip_name.split('_');
-    let mut chip_name: String = s.next().unwrap().to_string();
-    let core_name = if let Some(c) = s.next() {
-        if !c.starts_with("CM") {
-            chip_name.push('_');
-            chip_name.push_str(c);
+    fn get_chip_cfgs(chip_name: &str) -> Vec<String> {
+        let mut cfgs = Vec::new();
+
+        // Multicore
+
+        let mut s = chip_name.split('_');
+        let mut chip_name: String = s.next().unwrap().to_string();
+        let core_name = if let Some(c) = s.next() {
+            if !c.starts_with("CM") {
+                chip_name.push('_');
+                chip_name.push_str(c);
+                None
+            } else {
+                Some(c)
+            }
+        } else {
             None
-        } else {
-            Some(c)
-        }
-    } else {
-        None
-    };
+        };
 
-    if let Some(core) = core_name {
-        println!("cargo:rustc-cfg={}_{}", &chip_name[..chip_name.len() - 2], core);
+        if let Some(core) = core_name {
+            cfgs.push(format!("{}_{}", &chip_name[..chip_name.len() - 2], core));
+        }
+
+        // Configs for targeting groups of chips
+        if &chip_name[..8] == "stm32wba" {
+            cfgs.push(chip_name[..8].to_owned()); // stm32wba
+            cfgs.push(chip_name[..10].to_owned()); // stm32wba52
+            cfgs.push(format!("package_{}", &chip_name[10..11]));
+            cfgs.push(format!("flashsize_{}", &chip_name[11..12]));
+        } else {
+            if &chip_name[..8] == "stm32h7r" || &chip_name[..8] == "stm32h7s" {
+                cfgs.push("stm32h7rs".to_owned());
+            } else {
+                cfgs.push(chip_name[..7].to_owned()); // stm32f4
+            }
+            cfgs.push(chip_name[..9].to_owned()); // stm32f429
+            cfgs.push(format!("{}x", &chip_name[..8])); // stm32f42x
+            cfgs.push(format!("{}x{}", &chip_name[..7], &chip_name[8..9])); // stm32f4x9
+            cfgs.push(format!("package_{}", &chip_name[9..10]));
+            cfgs.push(format!("flashsize_{}", &chip_name[10..11]));
+        }
+
+        // Mark the L4+ chips as they have many differences to regular L4.
+        if &chip_name[..7] == "stm32l4" {
+            if "pqrs".contains(&chip_name[7..8]) {
+                cfgs.push("stm32l4_plus".to_owned());
+            } else {
+                cfgs.push("stm32l4_nonplus".to_owned());
+            }
+        }
+
+        cfgs
     }
 
-    // =======
-    // Features for targeting groups of chips
-
-    if &chip_name[..8] == "stm32wba" {
-        println!("cargo:rustc-cfg={}", &chip_name[..8]); // stm32wba
-        println!("cargo:rustc-cfg={}", &chip_name[..10]); // stm32wba52
-        println!("cargo:rustc-cfg=package_{}", &chip_name[10..11]);
-        println!("cargo:rustc-cfg=flashsize_{}", &chip_name[11..12]);
-    } else {
-        if &chip_name[..8] == "stm32h7r" || &chip_name[..8] == "stm32h7s" {
-            println!("cargo:rustc-cfg=stm32h7rs");
-        } else {
-            println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4
-        }
-        println!("cargo:rustc-cfg={}", &chip_name[..9]); // stm32f429
-        println!("cargo:rustc-cfg={}x", &chip_name[..8]); // stm32f42x
-        println!("cargo:rustc-cfg={}x{}", &chip_name[..7], &chip_name[8..9]); // stm32f4x9
-        println!("cargo:rustc-cfg=package_{}", &chip_name[9..10]);
-        println!("cargo:rustc-cfg=flashsize_{}", &chip_name[10..11]);
-    }
-
-    // Mark the L4+ chips as they have many differences to regular L4.
-    if &chip_name[..7] == "stm32l4" {
-        if "pqrs".contains(&chip_name[7..8]) {
-            println!("cargo:rustc-cfg=stm32l4_plus");
-        } else {
-            println!("cargo:rustc-cfg=stm32l4_nonplus");
-        }
+    cfgs.enable_all(&get_chip_cfgs(&chip_name));
+    for &chip_name in ALL_CHIPS.iter() {
+        cfgs.declare_all(&get_chip_cfgs(&chip_name.to_ascii_lowercase()));
     }
 
     println!("cargo:rerun-if-changed=build.rs");
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index 040ee9c53..0c22a7dae 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -71,9 +71,9 @@ pub(crate) trait SealedAdcChannel<T> {
 /// Performs a busy-wait delay for a specified number of microseconds.
 #[allow(unused)]
 pub(crate) fn blocking_delay_us(us: u32) {
-    #[cfg(time)]
-    embassy_time::block_for(embassy_time::Duration::from_micros(us));
-    #[cfg(not(time))]
+    #[cfg(feature = "time")]
+    embassy_time::block_for(embassy_time::Duration::from_micros(us as u64));
+    #[cfg(not(feature = "time"))]
     {
         let freq = unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 as u64;
         let us = us as u64;
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index 77e8bb56f..e3175dff5 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -31,7 +31,7 @@ impl AdcChannel<ADC1> for Temperature {}
 impl super::SealedAdcChannel<ADC1> for Temperature {
     fn channel(&self) -> u8 {
         cfg_if::cfg_if! {
-            if #[cfg(any(stm32f2, stm32f40, stm32f41))] {
+            if #[cfg(any(stm32f2, stm32f40x, stm32f41x))] {
                 16
             } else {
                 18
diff --git a/embassy-stm32/src/can/bxcan/mod.rs b/embassy-stm32/src/can/bxcan/mod.rs
index 69e20e909..9f7df1e71 100644
--- a/embassy-stm32/src/can/bxcan/mod.rs
+++ b/embassy-stm32/src/can/bxcan/mod.rs
@@ -1132,8 +1132,8 @@ foreach_peripheral!(
     (can, CAN1) => {
         cfg_if::cfg_if! {
             if #[cfg(all(
-                any(stm32l4, stm32f72, stm32f73),
-                not(any(stm32l49, stm32l4a))
+                any(stm32l4, stm32f72x, stm32f73x),
+                not(any(stm32l49x, stm32l4ax))
             ))] {
                 // Most L4 devices and some F7 devices use the name "CAN1"
                 // even if there is no "CAN2" peripheral.
diff --git a/embassy-stm32/src/cryp/mod.rs b/embassy-stm32/src/cryp/mod.rs
index ad118ef6e..8d600c73c 100644
--- a/embassy-stm32/src/cryp/mod.rs
+++ b/embassy-stm32/src/cryp/mod.rs
@@ -744,7 +744,7 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Aes
             } else {
                 aad_header[0] = 0xFF;
                 aad_header[1] = 0xFE;
-                let aad_len_bytes: [u8; 4] = aad_len.to_be_bytes();
+                let aad_len_bytes: [u8; 4] = (aad_len as u32).to_be_bytes();
                 aad_header[2] = aad_len_bytes[0];
                 aad_header[3] = aad_len_bytes[1];
                 aad_header[4] = aad_len_bytes[2];
@@ -765,7 +765,7 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Aes
         block0[0] |= ((((TAG_SIZE as u8) - 2) >> 1) & 0x07) << 3;
         block0[0] |= ((15 - (iv.len() as u8)) - 1) & 0x07;
         block0[1..1 + iv.len()].copy_from_slice(iv);
-        let payload_len_bytes: [u8; 4] = payload_len.to_be_bytes();
+        let payload_len_bytes: [u8; 4] = (payload_len as u32).to_be_bytes();
         if iv.len() <= 11 {
             block0[12] = payload_len_bytes[0];
         } else if payload_len_bytes[0] > 0 {
diff --git a/embassy-stm32/src/dsihost.rs b/embassy-stm32/src/dsihost.rs
index dc58bca92..e1fb3b0b0 100644
--- a/embassy-stm32/src/dsihost.rs
+++ b/embassy-stm32/src/dsihost.rs
@@ -11,9 +11,9 @@ use crate::{peripherals, Peripheral};
 
 /// Performs a busy-wait delay for a specified number of microseconds.
 pub fn blocking_delay_ms(ms: u32) {
-    #[cfg(time)]
-    embassy_time::block_for(embassy_time::Duration::from_millis(ms));
-    #[cfg(not(time))]
+    #[cfg(feature = "time")]
+    embassy_time::block_for(embassy_time::Duration::from_millis(ms as u64));
+    #[cfg(not(feature = "time"))]
     cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 1_000 * ms);
 }
 
diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs
index 8c6ca2471..ce2d1a04c 100644
--- a/embassy-stm32/src/flash/mod.rs
+++ b/embassy-stm32/src/flash/mod.rs
@@ -96,7 +96,7 @@ pub enum FlashBank {
 #[cfg_attr(any(flash_f1, flash_f3), path = "f1f3.rs")]
 #[cfg_attr(flash_f4, path = "f4.rs")]
 #[cfg_attr(flash_f7, path = "f7.rs")]
-#[cfg_attr(any(flash_g0, flash_g4), path = "g.rs")]
+#[cfg_attr(any(flash_g0, flash_g4c2, flash_g4c3, flash_g4c4), path = "g.rs")]
 #[cfg_attr(flash_h7, path = "h7.rs")]
 #[cfg_attr(flash_h7ab, path = "h7.rs")]
 #[cfg_attr(flash_u5, path = "u5.rs")]
@@ -105,7 +105,7 @@ pub enum FlashBank {
 #[cfg_attr(
     not(any(
         flash_l0, flash_l1, flash_l4, flash_wl, flash_wb, flash_f0, flash_f1, flash_f3, flash_f4, flash_f7, flash_g0,
-        flash_g4, flash_h7, flash_h7ab, flash_u5, flash_h50, flash_u0
+        flash_g4c2, flash_g4c3, flash_g4c4, flash_h7, flash_h7ab, flash_u5, flash_h50, flash_u0
     )),
     path = "other.rs"
 )]
diff --git a/embassy-stm32/src/fmc.rs b/embassy-stm32/src/fmc.rs
index 0df64f711..82d8089f4 100644
--- a/embassy-stm32/src/fmc.rs
+++ b/embassy-stm32/src/fmc.rs
@@ -35,7 +35,7 @@ where
         // fmc v1 and v2 does not have the fmcen bit
         // fsmc v1, v2 and v3 does not have the fmcen bit
         // This is a "not" because it is expected that all future versions have this bit
-        #[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fsmc_v2x3, fsmc_v3x1, fmc_v4)))]
+        #[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fmc_v4)))]
         T::REGS.bcr1().modify(|r| r.set_fmcen(true));
         #[cfg(any(fmc_v4))]
         T::REGS.nor_psram().bcr1().modify(|r| r.set_fmcen(true));
@@ -61,7 +61,7 @@ where
         // fmc v1 and v2 does not have the fmcen bit
         // fsmc v1, v2 and v3 does not have the fmcen bit
         // This is a "not" because it is expected that all future versions have this bit
-        #[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fsmc_v2x3, fsmc_v3x1, fmc_v4)))]
+        #[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fmc_v4)))]
         T::REGS.bcr1().modify(|r| r.set_fmcen(true));
         #[cfg(any(fmc_v4))]
         T::REGS.nor_psram().bcr1().modify(|r| r.set_fmcen(true));
diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs
index f3ac4fdbe..4e9c18594 100644
--- a/embassy-stm32/src/rcc/bd.rs
+++ b/embassy-stm32/src/rcc/bd.rs
@@ -33,7 +33,7 @@ pub enum LseDrive {
 }
 
 // All families but these have the LSEDRV register
-#[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))]
+#[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f410, rcc_l1)))]
 impl From<LseDrive> for crate::pac::rcc::vals::Lsedrv {
     fn from(value: LseDrive) -> Self {
         use crate::pac::rcc::vals::Lsedrv;
@@ -186,7 +186,7 @@ impl LsConfig {
         }
         ok &= reg.lseon() == lse_en;
         ok &= reg.lsebyp() == lse_byp;
-        #[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))]
+        #[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f410, rcc_l1)))]
         if let Some(lse_drv) = lse_drv {
             ok &= reg.lsedrv() == lse_drv.into();
         }
@@ -224,7 +224,7 @@ impl LsConfig {
 
         if lse_en {
             bdcr().modify(|w| {
-                #[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))]
+                #[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f410, rcc_l1)))]
                 if let Some(lse_drv) = lse_drv {
                     w.set_lsedrv(lse_drv.into());
                 }
diff --git a/embassy-stm32/src/rcc/f013.rs b/embassy-stm32/src/rcc/f013.rs
index 1c951a22b..63dc27bdd 100644
--- a/embassy-stm32/src/rcc/f013.rs
+++ b/embassy-stm32/src/rcc/f013.rs
@@ -95,7 +95,7 @@ pub struct Config {
 
     #[cfg(all(stm32f3, not(rcc_f37)))]
     pub adc: AdcClockSource,
-    #[cfg(all(stm32f3, not(rcc_f37), adc3_common))]
+    #[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))]
     pub adc34: AdcClockSource,
 
     /// Per-peripheral kernel clock selection muxes
@@ -125,7 +125,7 @@ impl Default for Config {
 
             #[cfg(all(stm32f3, not(rcc_f37)))]
             adc: AdcClockSource::Hclk(AdcHclkPrescaler::Div1),
-            #[cfg(all(stm32f3, not(rcc_f37), adc3_common))]
+            #[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))]
             adc34: AdcClockSource::Hclk(AdcHclkPrescaler::Div1),
 
             mux: Default::default(),
@@ -339,7 +339,7 @@ pub(crate) unsafe fn init(config: Config) {
         }
     };
 
-    #[cfg(all(stm32f3, not(rcc_f37), adc3_common))]
+    #[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))]
     let adc34 = {
         #[cfg(peri_adc3_common)]
         let common = crate::pac::ADC3_COMMON;
@@ -404,7 +404,7 @@ pub(crate) unsafe fn init(config: Config) {
         hclk1: Some(hclk),
         #[cfg(all(stm32f3, not(rcc_f37)))]
         adc: Some(adc),
-        #[cfg(all(stm32f3, not(rcc_f37), adc3_common))]
+        #[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))]
         adc34: Some(adc34),
         rtc: rtc,
         hsi48: hsi48,
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs
index 81a2d2623..b6c88ac9a 100644
--- a/embassy-stm32/src/usb/usb.rs
+++ b/embassy-stm32/src/usb/usb.rs
@@ -267,9 +267,9 @@ impl<'d, T: Instance> Driver<'d, T> {
             w.set_fres(true);
         });
 
-        #[cfg(time)]
+        #[cfg(feature = "time")]
         embassy_time::block_for(embassy_time::Duration::from_millis(100));
-        #[cfg(not(time))]
+        #[cfg(not(feature = "time"))]
         cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 10);
 
         #[cfg(not(usb_v4))]
diff --git a/embassy-sync/build.rs b/embassy-sync/build.rs
index afd76dad1..2649f5d37 100644
--- a/embassy-sync/build.rs
+++ b/embassy-sync/build.rs
@@ -1,31 +1,7 @@
-use std::env;
+#[path = "../build_common.rs"]
+mod common;
 
 fn main() {
-    println!("cargo:rerun-if-changed=build.rs");
-
-    let target = env::var("TARGET").unwrap();
-
-    if target.starts_with("thumbv6m-") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv6m");
-    } else if target.starts_with("thumbv7m-") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv7m");
-    } else if target.starts_with("thumbv7em-") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv7m");
-        println!("cargo:rustc-cfg=armv7em"); // (not currently used)
-    } else if target.starts_with("thumbv8m.base") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv8m");
-        println!("cargo:rustc-cfg=armv8m_base");
-    } else if target.starts_with("thumbv8m.main") {
-        println!("cargo:rustc-cfg=cortex_m");
-        println!("cargo:rustc-cfg=armv8m");
-        println!("cargo:rustc-cfg=armv8m_main");
-    }
-
-    if target.ends_with("-eabihf") {
-        println!("cargo:rustc-cfg=has_fpu");
-    }
+    let mut cfgs = common::CfgSet::new();
+    common::set_target_cfgs(&mut cfgs);
 }
diff --git a/embassy-sync/src/lib.rs b/embassy-sync/src/lib.rs
index 1873483f9..a5eee8d02 100644
--- a/embassy-sync/src/lib.rs
+++ b/embassy-sync/src/lib.rs
@@ -1,4 +1,4 @@
-#![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)]
+#![cfg_attr(not(feature = "std"), no_std)]
 #![allow(async_fn_in_trait)]
 #![allow(clippy::new_without_default)]
 #![doc = include_str!("../README.md")]
diff --git a/rust-toolchain-nightly.toml b/rust-toolchain-nightly.toml
index ac160b995..2143c1b2d 100644
--- a/rust-toolchain-nightly.toml
+++ b/rust-toolchain-nightly.toml
@@ -1,5 +1,5 @@
 [toolchain]
-channel = "nightly-2024-04-14"
+channel = "nightly-2024-05-20"
 components = [ "rust-src", "rustfmt", "llvm-tools", "miri" ]
 targets = [
     "thumbv7em-none-eabi",