Skip to content

Commit 227220c

Browse files
committed
feat(cargo): Set rustc-check-cfg for all config options
This squashes lint warnings for config options which are not currently enabled. See https://doc.rust-lang.org/cargo/reference/build-scripts.html\#rustc-check-cfg Signed-off-by: Hayden Ball <[email protected]>
1 parent 8952b44 commit 227220c

File tree

6 files changed

+78
-22
lines changed

6 files changed

+78
-22
lines changed

CMakeLists.txt

+12
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,17 @@ DT_AUGMENTS = \"${DT_AUGMENTS}\"
152152
${config_paths}
153153
")
154154

155+
add_custom_command(
156+
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/rust-kconfig-bool-options.json
157+
COMMAND
158+
${CMAKE_COMMAND} -E
159+
env ${COMMON_KCONFIG_ENV_SETTINGS}
160+
${RUST_MODULE_DIR}/scripts/kconfig-bool-options.py ${KCONFIG_ROOT} ${DOTCONFIG} > ${CMAKE_CURRENT_BINARY_DIR}/rust-kconfig-bool-options.json
161+
DEPENDS ${DOTCONFIG}
162+
COMMENT "Finding valid kconfig boolean options"
163+
WORKING_DIRECTORY ${APPLICATION_SOURCE_DIR}
164+
)
165+
155166
# The block of environment variables below could theoretically be captured in a variable, but this
156167
# seems "challenging" in CMake (to be polite), as many of these contain spaces, and the quoting
157168
# rules in CMake are inconsistent, at best.
@@ -161,6 +172,7 @@ ${config_paths}
161172
add_custom_command(
162173
OUTPUT ${DUMMY_FILE}
163174
BYPRODUCTS ${RUST_LIBRARY} ${WRAPPER_FILE}
175+
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/rust-kconfig-bool-options.json
164176
USES_TERMINAL
165177
COMMAND
166178
${CMAKE_COMMAND} -E

samples/bench/src/lib.rs

-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
#![no_std]
5-
// Cargo tries to detect configs that have typos in them. Unfortunately, the Zephyr Kconfig system
6-
// uses a large number of Kconfigs and there is no easy way to know which ones might conceivably be
7-
// valid. This prevents a warning about each cfg that is used.
8-
#![allow(unexpected_cfgs)]
95

106
extern crate alloc;
117

samples/philosophers/src/lib.rs

-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
#![no_std]
5-
// Cargo tries to detect configs that have typos in them. Unfortunately, the Zephyr Kconfig system
6-
// uses a large number of Kconfigs and there is no easy way to know which ones might conceivably be
7-
// valid. This prevents a warning about each cfg that is used.
8-
#![allow(unexpected_cfgs)]
95

106
extern crate alloc;
117

samples/work-philosophers/src/lib.rs

-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
#![no_std]
5-
// Cargo tries to detect configs that have typos in them. Unfortunately, the Zephyr Kconfig system
6-
// uses a large number of Kconfigs and there is no easy way to know which ones might conceivably be
7-
// valid. This prevents a warning about each cfg that is used.
8-
#![allow(unexpected_cfgs)]
95

106
extern crate alloc;
117

scripts/kconfig-bool-options.py

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env python3
2+
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
import os
6+
import sys
7+
import argparse
8+
import json
9+
10+
from itertools import chain
11+
12+
sys.path.insert(0, str(os.path.join(os.environ["ZEPHYR_BASE"], "scripts", "kconfig")))
13+
from kconfiglib import Kconfig, _T_BOOL, _T_CHOICE
14+
15+
16+
def main():
17+
args = parse_args()
18+
19+
kconf = Kconfig(args.kconfig_file)
20+
kconf.load_config(args.dotconfig)
21+
22+
options = {}
23+
24+
for sym in chain(kconf.unique_defined_syms, kconf.unique_choices):
25+
if not sym.name:
26+
continue
27+
28+
if "-" in sym.name:
29+
# Rust does not allow hyphens in cfg options.
30+
continue
31+
32+
if sym.type in [_T_BOOL, _T_CHOICE]:
33+
options[f"CONFIG_{sym.name}"] = sym.str_value
34+
35+
print(json.dumps(options))
36+
37+
38+
def parse_args():
39+
parser = argparse.ArgumentParser(allow_abbrev=False)
40+
41+
parser.add_argument("kconfig_file", help="Top-level Kconfig file")
42+
parser.add_argument("dotconfig", help="Path to dotconfig file")
43+
44+
return parser.parse_args()
45+
46+
47+
if __name__ == "__main__":
48+
main()

zephyr-build/src/lib.rs

+18-10
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// This builds a program that is run on the compilation host before the code is compiled. It can
1212
// output configuration settings that affect the compilation.
1313

14+
use std::collections::BTreeMap;
1415
use std::env;
1516
use std::fs::File;
1617
use std::io::{BufRead, BufReader, Write};
@@ -27,19 +28,26 @@ mod devicetree;
2728
/// Export boolean Kconfig entries. This must happen in any crate that wishes to access the
2829
/// configuration settings.
2930
pub fn export_bool_kconfig() {
30-
let dotconfig = env::var("DOTCONFIG").expect("DOTCONFIG must be set by wrapper");
31+
let build_dir = env::var("BUILD_DIR").expect("BUILD_DIR must be set by wrapper");
3132

32-
// Ensure the build script is rerun when the dotconfig changes.
33-
println!("cargo:rerun-if-env-changed=DOTCONFIG");
34-
println!("cargo-rerun-if-changed={}", dotconfig);
33+
let bool_options_path = Path::new(&build_dir)
34+
.join("rust-kconfig-bool-options.json")
35+
.to_str()
36+
.unwrap()
37+
.to_string();
3538

36-
let config_y = Regex::new(r"^(CONFIG_.*)=y$").unwrap();
39+
// Ensure the build script is rerun when kconfig bool options change.
40+
println!("cargo:rerun-if-changed={}", bool_options_path);
3741

38-
let file = File::open(&dotconfig).expect("Unable to open dotconfig");
39-
for line in BufReader::new(file).lines() {
40-
let line = line.expect("reading line from dotconfig");
41-
if let Some(caps) = config_y.captures(&line) {
42-
println!("cargo:rustc-cfg={}", &caps[1]);
42+
let bool_options = File::open(&bool_options_path).expect("Unable to open bool options");
43+
let bool_options: BTreeMap<String, String> =
44+
serde_yaml_ng::from_reader(bool_options).expect("Unable to parse bool options");
45+
46+
for (key, value) in bool_options.iter() {
47+
println!("cargo:rustc-check-cfg=cfg({})", key);
48+
49+
if value == "y" {
50+
println!("cargo:rustc-cfg={}", key);
4351
}
4452
}
4553
}

0 commit comments

Comments
 (0)