Disallow log and defmt at the same time (#3675)

This commit is contained in:
Dániel Buga 2025-06-23 14:44:21 +02:00 committed by GitHub
parent b21ae76176
commit 29ac33f2a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 147 additions and 69 deletions

View File

@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- The `log` feature has been renamed to `log-04` (#3675)
- `defmt` and `log-04` can no longer be selected at the same time (#3675)
### Fixed

View File

@ -18,11 +18,12 @@ bench = false
test = true
[dependencies]
cfg-if = "1.0.0"
defmt = { version = "1.0.1", optional = true }
document-features = "0.2.11"
esp-config = { version = "0.4.0", path = "../esp-config" }
embedded-storage = "0.3.1"
log = { version = "0.4.26", optional = true }
log-04 = { package = "log", version = "0.4.26", optional = true }
strum = { version = "0.27.1", default-features = false, features = ["derive"] }
crc = { version = "3.0.0", optional = true }
@ -38,8 +39,8 @@ default = ["validation"]
## Enable MD5 validation of the partition table.
validation = ["dep:md-5"]
## Enable support for the `log` crate
log = ["dep:log"]
## Enable support for version 0.4 of the `log` crate
log-04 = ["dep:log-04"]
## Enable support for `defmt`
defmt = ["dep:defmt"]

View File

@ -3,9 +3,25 @@ use std::env;
use esp_config::generate_config_from_yaml_definition;
use jiff::Timestamp;
#[macro_export]
macro_rules! assert_unique_features {
($($feature:literal),+ $(,)?) => {
assert!(
(0 $(+ cfg!(feature = $feature) as usize)+ ) <= 1,
"Exactly zero or one of the following features must be enabled: {}",
[$($feature),+].join(", ")
);
};
}
fn main() {
println!("cargo::rustc-check-cfg=cfg(embedded_test)");
// Log and defmt are mutually exclusive features. The main technical reason is
// that allowing both would make the exact panicking behaviour a fragile
// implementation detail.
assert_unique_features!("log-04", "defmt");
let build_time = match env::var("SOURCE_DATE_EPOCH") {
Ok(val) => Timestamp::from_microsecond(val.parse::<i64>().unwrap()).unwrap(),
Err(_) => Timestamp::now(),

View File

@ -5,10 +5,13 @@
macro_rules! assert {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::assert!($($x)*);
#[cfg(feature = "defmt")]
::defmt::assert!($($x)*);
cfg_if::cfg_if! {
if #[cfg(feature = "defmt")] {
::defmt::assert!($($x)*);
} else {
::core::assert!($($x)*);
}
}
}
};
}
@ -17,10 +20,13 @@ macro_rules! assert {
macro_rules! assert_eq {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::assert_eq!($($x)*);
#[cfg(feature = "defmt")]
::defmt::assert_eq!($($x)*);
cfg_if::cfg_if! {
if #[cfg(feature = "defmt")] {
::defmt::assert_eq!($($x)*);
} else {
::core::assert_eq!($($x)*);
}
}
}
};
}
@ -29,10 +35,13 @@ macro_rules! assert_eq {
macro_rules! assert_ne {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::assert_ne!($($x)*);
#[cfg(feature = "defmt")]
::defmt::assert_ne!($($x)*);
cfg_if::cfg_if! {
if #[cfg(feature = "defmt")] {
::defmt::assert_ne!($($x)*);
} else {
::core::assert_ne!($($x)*);
}
}
}
};
}
@ -41,10 +50,13 @@ macro_rules! assert_ne {
macro_rules! debug_assert {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::debug_assert!($($x)*);
#[cfg(feature = "defmt")]
::defmt::debug_assert!($($x)*);
cfg_if::cfg_if! {
if #[cfg(feature = "defmt")] {
::defmt::debug_assert!($($x)*);
} else {
::core::debug_assert!($($x)*);
}
}
}
};
}
@ -53,10 +65,13 @@ macro_rules! debug_assert {
macro_rules! debug_assert_eq {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::debug_assert_eq!($($x)*);
#[cfg(feature = "defmt")]
::defmt::debug_assert_eq!($($x)*);
cfg_if::cfg_if! {
if #[cfg(feature = "defmt")] {
::defmt::debug_assert_eq!($($x)*);
} else {
::core::debug_assert_eq!($($x)*);
}
}
}
};
}
@ -65,10 +80,13 @@ macro_rules! debug_assert_eq {
macro_rules! debug_assert_ne {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::debug_assert_ne!($($x)*);
#[cfg(feature = "defmt")]
::defmt::debug_assert_ne!($($x)*);
cfg_if::cfg_if! {
if #[cfg(feature = "defmt")] {
::defmt::debug_assert_ne!($($x)*);
} else {
::core::debug_assert_ne!($($x)*);
}
}
}
};
}
@ -77,10 +95,13 @@ macro_rules! debug_assert_ne {
macro_rules! todo {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::todo!($($x)*);
#[cfg(feature = "defmt")]
::defmt::todo!($($x)*);
cfg_if::cfg_if! {
if #[cfg(feature = "defmt")] {
::defmt::todo!($($x)*);
} else {
::core::todo!($($x)*);
}
}
}
};
}
@ -89,10 +110,13 @@ macro_rules! todo {
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
cfg_if::cfg_if! {
if #[cfg(feature = "defmt")] {
::defmt::unreachable!($($x)*);
} else {
::core::unreachable!($($x)*);
}
}
}
};
}
@ -101,10 +125,13 @@ macro_rules! unreachable {
macro_rules! panic {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::panic!($($x)*);
#[cfg(feature = "defmt")]
::defmt::panic!($($x)*);
cfg_if::cfg_if! {
if #[cfg(feature = "defmt")] {
::defmt::panic!($($x)*);
} else {
::core::panic!($($x)*);
}
}
}
};
}
@ -113,12 +140,15 @@ macro_rules! panic {
macro_rules! trace {
($s:literal $(, $x:expr)* $(,)?) => {
{
#[cfg(feature = "log")]
::log::trace!($s $(, $x)*);
#[cfg(feature = "defmt")]
::defmt::trace!($s $(, $x)*);
#[cfg(not(any(feature = "log", feature="defmt")))]
let _ = ($( & $x ),*);
cfg_if::cfg_if! {
if #[cfg(feature = "defmt")] {
::defmt::trace!($s $(, $x)*);
} else if #[cfg(feature = "log-04")] {
::log_04::trace!($s $(, $x)*);
} else {
let _ = ($( & $x ),*);
}
}
}
};
}
@ -127,12 +157,15 @@ macro_rules! trace {
macro_rules! debug {
($s:literal $(, $x:expr)* $(,)?) => {
{
#[cfg(feature = "log")]
::log::debug!($s $(, $x)*);
#[cfg(feature = "defmt")]
::defmt::debug!($s $(, $x)*);
#[cfg(not(any(feature = "log", feature="defmt")))]
let _ = ($( & $x ),*);
cfg_if::cfg_if! {
if #[cfg(feature = "defmt")] {
::defmt::debug!($s $(, $x)*);
} else if #[cfg(feature = "log-04")] {
::log_04::debug!($s $(, $x)*);
} else {
let _ = ($( & $x ),*);
}
}
}
};
}
@ -141,12 +174,15 @@ macro_rules! debug {
macro_rules! info {
($s:literal $(, $x:expr)* $(,)?) => {
{
#[cfg(feature = "log")]
::log::info!($s $(, $x)*);
#[cfg(feature = "defmt")]
::defmt::info!($s $(, $x)*);
#[cfg(not(any(feature = "log", feature="defmt")))]
let _ = ($( & $x ),*);
cfg_if::cfg_if! {
if #[cfg(feature = "defmt")] {
::defmt::info!($s $(, $x)*);
} else if #[cfg(feature = "log-04")] {
::log_04::info!($s $(, $x)*);
} else {
let _ = ($( & $x ),*);
}
}
}
};
}
@ -155,12 +191,15 @@ macro_rules! info {
macro_rules! warn {
($s:literal $(, $x:expr)* $(,)?) => {
{
#[cfg(feature = "log")]
::log::warn!($s $(, $x)*);
#[cfg(feature = "defmt")]
::defmt::warn!($s $(, $x)*);
#[cfg(not(any(feature = "log", feature="defmt")))]
let _ = ($( & $x ),*);
cfg_if::cfg_if! {
if #[cfg(feature = "defmt")] {
::defmt::warn!($s $(, $x)*);
} else if #[cfg(feature = "log-04")] {
::log_04::warn!($s $(, $x)*);
} else {
let _ = ($( & $x ),*);
}
}
}
};
}
@ -169,12 +208,15 @@ macro_rules! warn {
macro_rules! error {
($s:literal $(, $x:expr)* $(,)?) => {
{
#[cfg(feature = "log")]
::log::error!($s $(, $x)*);
#[cfg(feature = "defmt")]
::defmt::error!($s $(, $x)*);
#[cfg(not(any(feature = "log", feature="defmt")))]
let _ = ($( & $x ),*);
cfg_if::cfg_if! {
if #[cfg(feature = "defmt")] {
::defmt::error!($s $(, $x)*);
} else if #[cfg(feature = "log-04")] {
::log_04::error!($s $(, $x)*);
} else {
let _ = ($( & $x ),*);
}
}
}
};
}

View File

@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Removed `esp_wifi::deinit_unchecked` and `esp_wifi::EspWifiController::deinit` - you can just drop `EspWifiController` instead (#3553)
- `defmt` and `log-04` can no longer be selected at the same time (#3675)
### Fixed

View File

@ -3,6 +3,17 @@ use std::error::Error;
use esp_config::generate_config_from_yaml_definition;
use esp_metadata::{Chip, Config};
#[macro_export]
macro_rules! assert_unique_features {
($($feature:literal),+ $(,)?) => {
assert!(
(0 $(+ cfg!(feature = $feature) as usize)+ ) <= 1,
"Exactly zero or one of the following features must be enabled: {}",
[$($feature),+].join(", ")
);
};
}
fn main() -> Result<(), Box<dyn Error>> {
// Load the configuration file for the configured device:
let chip = Chip::from_cargo_feature()?;
@ -11,6 +22,11 @@ fn main() -> Result<(), Box<dyn Error>> {
// Define all necessary configuration symbols for the configured device:
config.define_symbols();
// Log and defmt are mutually exclusive features. The main technical reason is
// that allowing both would make the exact panicking behaviour a fragile
// implementation detail.
assert_unique_features!("log-04", "defmt");
assert!(
!cfg!(feature = "ble") || config.contains("bt"),
r#"