What changed, and why it matters
This commit is a build-system improvement for the BitBox02 hardware wallet firmware. It creates a script that automatically generates local Cargo (Rust build tool) configuration files so that Rust code compiles correctly for the ARM microcontroller inside the device. It does not change any wallet logic, cryptography, or user-facing behavior. There is no indication this is a security fix or vulnerability patch.
No security action required. Treat as normal build-system maintenance. Reviewers may verify that the generated config.local.toml is gitignored and that CI still produces reproducible firmware hashes.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change introduces scripts/bootstrap-cargo-config, which writes .cargo/config.local.toml containing target-specific CFLAGS and BINDGEN_EXTRA_CLANG_ARGS for thumbv7em-none-eabi and thumbv8m.main-none-eabihf. The generated file is included from .cargo/config.toml and src/rust/.cargo/config.toml. CMake is updated to pass CFLAGS_${RUST_TARGET_ARCH} instead of generic CFLAGS, and the three sys build.rs files (bitbox-lvgl-sys, bitbox-securechip-sys, bitbox02-sys) stop hardcoding ARM sysroot/target flags and instead rely on the Cargo-provided environment variables. This is a build hygiene/refactoring change.
Changed components
Build system (Makefile, CMake, Cargo config)Rust sys crates: bitbox-lvgl-sys, bitbox-securechip-sys, bitbox02-sysInspect captured patch +277 / −139
diff --git a/.cargo/config.toml b/.cargo/config.toml
new file mode 100644
index 0000000..59688e5
--- /dev/null
+++ b/.cargo/config.toml
@@ -0,0 +1,2 @@
+# Include host-specific Cargo settings generated by scripts/bootstrap-cargo-config.
+include = [{ path = "config.local.toml", optional = true }]
diff --git a/.github/workflows/ci-common.yml b/.github/workflows/ci-common.yml
index 8663c95..1721ab0 100644
--- a/.github/workflows/ci-common.yml
+++ b/.github/workflows/ci-common.yml
@@ -297,7 +297,7 @@ jobs:
run: cargo install --path tools/prost-build-proto --locked
- name: Build ${{ matrix.target }}
- run: make -j$(($(nproc)+1)) ${{ matrix.target }}
+ run: make -j$(($(sysctl -n hw.ncpu)+1)) ${{ matrix.target }}
- name: Print hashes
run: sha256sum build*/bin/*
@@ -326,6 +326,7 @@ jobs:
- name: Build ${{ matrix.target }}
run: |
+ make bootstrap
(mkdir -p build; cd build; cmake -DDOC_GRAPHS=NO ..)
make -j$(($(nproc)+1)) docs
diff --git a/.gitignore b/.gitignore
index 12c5daa..929c6fb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@
/releases/temp/
.vagrant/
# LSP caches and local configs
+.cargo/config.local.toml
.clangd
.cquery
.ccls
diff --git a/AGENTS.md b/AGENTS.md
index 7c5e5a5..0c5d656 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -27,6 +27,11 @@ for the current scope.
Run regular Unix commands such as `git`, `rg`, `grep`, `ls`, `find`, `sed`, and `cat` directly on
the host.
+Before running Rust workspace commands directly, run `./scripts/bootstrap-cargo-config` once in the
+environment where Cargo will run. It writes `.cargo/config.local.toml` with the bindgen and `cc`
+crate target settings for the local ARM sysroot. The generated file is included by Cargo config
+files. Re-run it after changing ARM toolchains or sysroots.
+
Cargo commands for the Rust workspace, such as `cargo test`, `cargo check`, and `cargo clippy`, may
also be run directly on the host by passing `--manifest-path src/rust/Cargo.toml`.
@@ -78,7 +83,8 @@ bindings (`cbindgen`, protobuf) when interfaces change. When changing protobuf i
Place new C specs in `test/unit-test` and add doubles to `test/hardware-fakes` when hardware
behavior is mocked; follow the `test_<feature>.c` naming pattern and update CMake lists. Rust crates
use standard `tests/` modules or `#[cfg(test)]` blocks. Before opening a PR, run both `make
-run-unit-tests` and `cargo test --manifest-path src/rust/Cargo.toml --all-features -- --test-threads 1`,
+run-unit-tests` and
+`cargo test --manifest-path src/rust/Cargo.toml --all-features -- --test-threads 1`,
and refresh `make coverage` for cryptography or security-sensitive areas.
- in Rust unit tests, prefer .unwrap() over .expect().
diff --git a/BUILD.md b/BUILD.md
index 56c2810..2b38d6d 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -141,9 +141,13 @@ Run the following commands to enter the container and build the firmware:
```sh
make dockerdev
+make bootstrap
make firmware
```
+`make bootstrap` must be run before compiling firmware. It initializes submodules and writes the
+local Cargo configuration needed for the firmware ARM targets.
+
> [!TIP]
> If you have multiple cores you can speed up compilation by passing `-j<N>`, for example `-j8`.
diff --git a/Makefile b/Makefile
index 7a32c7c..252e778 100644
--- a/Makefile
+++ b/Makefile
@@ -9,24 +9,29 @@ SANITIZE ?= ON
bootstrap:
git submodule update --init --recursive
+ ./scripts/bootstrap-cargo-config
build/Makefile:
+ ./scripts/bootstrap-cargo-config
mkdir -p build
cd build && cmake -DCMAKE_TOOLCHAIN_FILE=arm.cmake ..
$(MAKE) -C py/bitbox02
build-debug/Makefile:
+ ./scripts/bootstrap-cargo-config
mkdir -p build-debug
cd build-debug && cmake -DCMAKE_TOOLCHAIN_FILE=arm.cmake -DCMAKE_BUILD_TYPE=DEBUG ..
$(MAKE) -C py/bitbox02
build-build/Makefile:
+ ./scripts/bootstrap-cargo-config
mkdir -p build-build
cd build-build && cmake .. -DCOVERAGE=ON -DSANITIZE_ADDRESS=$(SANITIZE) -DSANITIZE_UNDEFINED=$(SANITIZE)
$(MAKE) -C py/bitbox02
# ubsan/asan not supported with simulators and rust unit tests
build-build-noasan/Makefile:
+ ./scripts/bootstrap-cargo-config
mkdir -p build-build-noasan
cd build-build-noasan && cmake .. -DCOVERAGE=OFF -DSANITIZE_ADDRESS=OFF -DSANITIZE_UNDEFINED=OFF
$(MAKE) -C py/bitbox02
@@ -111,6 +116,7 @@ run-unit-tests: | build-build
# `mock_sd()` and `mock_memory()`. Using mutexes instead leads to mutex
# poisoning and very messy output in case of a unit test failure.
run-rust-unit-tests:
+ ./scripts/bootstrap-cargo-config
cargo test --manifest-path src/rust/Cargo.toml --all-features -- --test-threads 1
run-rust-clippy: | build-build-noasan
${MAKE} -C build-build-noasan rust-clippy
diff --git a/scripts/bootstrap-cargo-config b/scripts/bootstrap-cargo-config
new file mode 100755
index 0000000..c022774
--- /dev/null
+++ b/scripts/bootstrap-cargo-config
@@ -0,0 +1,125 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+usage() {
+ cat <<EOF
+Usage: $0 [--sysroot <path>]
+
+Generates .cargo/config.local.toml with bindgen and cc crate arguments for
+the firmware ARM targets. Run this in the environment where cargo will run.
+EOF
+}
+
+script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+repo_root="$(cd "${script_dir}/.." && pwd)"
+config_dir="${repo_root}/.cargo"
+config_local="${config_dir}/config.local.toml"
+
+sysroot=""
+
+while (($# > 0)); do
+ case "$1" in
+ --sysroot)
+ if (($# < 2)); then
+ echo "error: --sysroot requires a path" >&2
+ exit 1
+ fi
+ sysroot="$2"
+ shift 2
+ ;;
+ --sysroot=*)
+ sysroot="${1#--sysroot=}"
+ shift
+ ;;
+ -h | --help)
+ usage
+ exit 0
+ ;;
+ *)
+ echo "error: unknown argument: $1" >&2
+ usage >&2
+ exit 1
+ ;;
+ esac
+done
+
+if [[ -z "${sysroot}" ]]; then
+ if ! command -v arm-none-eabi-gcc >/dev/null 2>&1; then
+ echo "warning: arm-none-eabi-gcc not found; writing config without an ARM sysroot" >&2
+ else
+ sysroot="$(arm-none-eabi-gcc -print-sysroot)"
+ if [[ -z "${sysroot}" ]]; then
+ echo "warning: arm-none-eabi-gcc returned an empty sysroot; writing config without an ARM sysroot" >&2
+ fi
+ fi
+fi
+
+if [[ -n "${sysroot}" ]] && resolved_sysroot="$(readlink -f -- "${sysroot}" 2>/dev/null)"; then
+ sysroot="${resolved_sysroot}"
+fi
+
+toml_escape() {
+ local value="$1"
+ value="${value//\\/\\\\}"
+ value="${value//\"/\\\"}"
+ printf '%s' "${value}"
+}
+
+bindgen_args_for_target() {
+ local target="$1"
+ local args="--target=${target} -fshort-enums"
+
+ if [[ -n "${sysroot}" ]]; then
+ args="${args} --sysroot=${sysroot}"
+ fi
+
+ printf '%s' "${args}"
+}
+
+write_bindgen_env() {
+ local target="$1"
+ local args
+ args="$(bindgen_args_for_target "${target}")"
+
+ printf '"%s" = "%s"\n' \
+ "$(toml_escape "BINDGEN_EXTRA_CLANG_ARGS_${target}")" \
+ "$(toml_escape "${args}")"
+}
+
+write_cc_env() {
+ local target="$1"
+ local args="-fshort-enums -mthumb"
+
+ if [[ -n "${sysroot}" ]]; then
+ args="${args} --sysroot=${sysroot}"
+ fi
+
+ if [[ "${target}" == thumbv7* ]]; then
+ args="${args} -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16"
+ fi
+
+ printf '"%s" = "%s"\n' \
+ "$(toml_escape "CFLAGS_${target}")" \
+ "$(toml_escape "${args}")"
+}
+
+mkdir -p "${config_dir}"
+
+tmp="${config_local}.tmp"
+trap 'rm -f "${tmp}"' EXIT
+
+{
+ echo "# Generated by scripts/bootstrap-cargo-config."
+ echo "# Host-specific bindgen and cc configuration. Re-run after changing ARM toolchains."
+ echo
+ echo "[env]"
+ write_cc_env "thumbv7em-none-eabi"
+ write_cc_env "thumbv8m.main-none-eabihf"
+ write_bindgen_env "thumbv7em-none-eabi"
+ write_bindgen_env "thumbv8m.main-none-eabihf"
+} >"${tmp}"
+
+mv "${tmp}" "${config_local}"
+trap - EXIT
+
+echo "Wrote ${config_local}"
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index deb4e45..8626a98 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -224,6 +224,11 @@ if(CMAKE_CROSSCOMPILING)
else()
set(RUST_TARGET_ARCH_DIR .)
endif()
+if(CMAKE_CROSSCOMPILING)
+ set(CARGO_CC_FLAGS_ENV "CFLAGS_${RUST_TARGET_ARCH}=${CARGO_C_FLAGS} --sysroot=${CMAKE_SYSROOT}")
+else()
+ set(CARGO_CC_FLAGS_ENV "CFLAGS=${CARGO_C_FLAGS}")
+endif()
set(RUST_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/rust)
set(LIBBITBOX02_RUST_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/rust/bitbox02-rust-c)
@@ -251,7 +256,6 @@ if(NOT CMAKE_CROSSCOMPILING)
add_custom_target(rust-clippy
COMMAND
${CMAKE_COMMAND} -E env
- CMAKE_SYSROOT=${CMAKE_SYSROOT}
CMAKE_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
${CARGO} clippy
$<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-v>
@@ -346,10 +350,9 @@ foreach(type ${RUST_LIBS})
OUTPUT ${lib} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/lib${type}_rust_c.a dummy
COMMAND
${CMAKE_COMMAND} -E env
- CMAKE_SYSROOT=${CMAKE_SYSROOT}
CMAKE_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
RUSTFLAGS=${RUSTFLAGS}
- CFLAGS=${CARGO_C_FLAGS}
+ ${CARGO_CC_FLAGS_ENV}
$<$<BOOL:${SCCACHE_PROGRAM}>:RUSTC_WRAPPER=${SCCACHE_PROGRAM}>
RUSTC_BOOTSTRAP=1
MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}
@@ -400,7 +403,6 @@ endforeach()
if(CMAKE_CROSSCOMPILING)
add_custom_target(rust-docs
COMMAND
- CMAKE_SYSROOT=${CMAKE_SYSROOT}
${CMAKE_COMMAND} -E env
${CARGO} doc --document-private-items --target-dir ${CMAKE_BINARY_DIR}/docs-rust --target thumbv7em-none-eabi
COMMAND
diff --git a/src/rust/.cargo/config.toml b/src/rust/.cargo/config.toml
index 66f912f..9cb4c9a 100644
--- a/src/rust/.cargo/config.toml
+++ b/src/rust/.cargo/config.toml
@@ -1,3 +1,5 @@
+include = [{ path = "../../../.cargo/config.local.toml", optional = true }]
+
[source.crates-io]
replace-with = "vendored-sources"
diff --git a/src/rust/bitbox-lvgl-sys/build.rs b/src/rust/bitbox-lvgl-sys/build.rs
index e515c7c..28ce69b 100644
--- a/src/rust/bitbox-lvgl-sys/build.rs
+++ b/src/rust/bitbox-lvgl-sys/build.rs
@@ -237,6 +237,7 @@ fn main() -> Result<(), &'static str> {
}
return Err("failed to execute `bindgen --version`");
}
+ emit_bindgen_env_rerun_if_changed();
let cflags = [
format!("-I{}", lvgl_dir.display()),
@@ -271,3 +272,9 @@ fn main() -> Result<(), &'static str> {
fonts.compile("lvgl_fonts");
run_bindgen(&wrapper, &out_path, &cflags)
}
+
+fn emit_bindgen_env_rerun_if_changed() {
+ let target = env::var("TARGET").expect("TARGET not set");
+ println!("cargo::rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS");
+ println!("cargo::rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS_{target}");
+}
diff --git a/src/rust/bitbox-securechip-sys/build.rs b/src/rust/bitbox-securechip-sys/build.rs
index cd77f2c..dcac2a6 100644
--- a/src/rust/bitbox-securechip-sys/build.rs
+++ b/src/rust/bitbox-securechip-sys/build.rs
@@ -100,6 +100,7 @@ type BuildResult<T> = Result<T, String>;
pub fn main() -> BuildResult<()> {
ensure_command_exists("bindgen")?;
+ emit_bindgen_env_rerun_if_changed();
let manifest_dir =
PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"));
@@ -122,28 +123,16 @@ pub fn main() -> BuildResult<()> {
emit_rerun_if_changed(external_dir.join("optiga-trust-m/config"));
emit_rerun_if_changed(&optiga_include_dir);
- let target = env::var("TARGET").expect("TARGET not set");
- let cross_compiling = target == "thumbv7em-none-eabi";
- let arm_sysroot = env::var("CMAKE_SYSROOT").unwrap_or("/usr/local/arm-none-eabi".to_string());
- let arm_sysroot = format!("--sysroot={arm_sysroot}");
-
- let mut extra_flags = if cross_compiling {
- vec![
- // Generate bindings for the firmware target ABI, not the host ABI.
- "--target=thumbv7em-none-eabi",
- &arm_sysroot,
- // The firmware C code is compiled with arm-none-eabi-gcc, which uses
- // -fshort-enums by default. Bindgen must match those enum sizes.
- "-fshort-enums",
- ]
- } else {
- vec![]
- };
+ let mut definitions = vec![
+ // Expose the U2F counter declarations guarded by APP_U2F in atecc.h/optiga.h.
+ "-DAPP_U2F=1",
+ "-DOPTIGA_LIB_EXTERNAL=\"optiga_config.h\"",
+ ];
if let Ok(rustflags) = std::env::var("CARGO_ENCODED_RUSTFLAGS") {
for flag in rustflags.split('\x1f') {
if flag == "-Dwarnings" {
- extra_flags.push("-Werror");
+ definitions.push("-Werror");
}
}
}
@@ -151,78 +140,71 @@ pub fn main() -> BuildResult<()> {
let out_path = out_dir.join("bindings.rs");
let out_path = out_path.into_os_string().into_string().unwrap();
- let mut definitions = vec![
- // Expose the U2F counter declarations guarded by APP_U2F in atecc.h/optiga.h.
- "-DAPP_U2F=1",
- "-DOPTIGA_LIB_EXTERNAL=\"optiga_config.h\"",
- ];
- definitions.extend(&extra_flags);
+ let mut bindgen = Command::new("bindgen");
+ bindgen
+ .args(["--output", &out_path])
+ .arg("--use-core")
+ .arg("--with-derive-default")
+ .args(
+ ALLOWLIST_FNS
+ .iter()
+ .flat_map(|item| ["--allowlist-function", item]),
+ )
+ .args(
+ ALLOWLIST_TYPES
+ .iter()
+ .flat_map(|item| ["--allowlist-type", item]),
+ )
+ .args(
+ ALLOWLIST_VARS
+ .iter()
+ .flat_map(|item| ["--allowlist-var", item]),
+ )
+ .args(
+ RUSTIFIED_ENUMS
+ .iter()
+ .flat_map(|item| ["--rustified-enum", item]),
+ )
+ .arg(&wrapper)
+ .arg("--")
+ .args(&definitions)
+ .arg(format!("-I{}", src_dir.display()))
+ .arg(format!("-I{}", external_dir.display()))
+ .arg(format!(
+ "-I{}",
+ external_dir.join("optiga-trust-m/config").display()
+ ))
+ .arg(format!("-I{}", optiga_include_dir.display()))
+ .arg(format!(
+ "-I{}",
+ external_dir.join("optiga-trust-m/include/cmd").display()
+ ))
+ .arg(format!(
+ "-I{}",
+ external_dir.join("optiga-trust-m/include/common").display()
+ ))
+ .arg(format!(
+ "-I{}",
+ external_dir
+ .join("optiga-trust-m/include/ifx_i2c")
+ .display()
+ ))
+ .arg(format!(
+ "-I{}",
+ external_dir.join("optiga-trust-m/include/pal").display()
+ ))
+ .arg(format!(
+ "-I{}",
+ external_dir.join("optiga-trust-m/include/comms").display()
+ ))
+ .arg(format!(
+ "-I{}",
+ external_dir
+ .join("optiga-trust-m/external/mbedtls/include")
+ .display()
+ ));
- run_command(
- Command::new("bindgen")
- .args(["--output", &out_path])
- .arg("--use-core")
- .arg("--with-derive-default")
- .args(
- ALLOWLIST_FNS
- .iter()
- .flat_map(|item| ["--allowlist-function", item]),
- )
- .args(
- ALLOWLIST_TYPES
- .iter()
- .flat_map(|item| ["--allowlist-type", item]),
- )
- .args(
- ALLOWLIST_VARS
- .iter()
- .flat_map(|item| ["--allowlist-var", item]),
- )
- .args(
- RUSTIFIED_ENUMS
- .iter()
- .flat_map(|item| ["--rustified-enum", item]),
- )
- .arg(&wrapper)
- .arg("--")
- .args(&definitions)
- .arg(format!("-I{}", src_dir.display()))
- .arg(format!("-I{}", external_dir.display()))
- .arg(format!(
- "-I{}",
- external_dir.join("optiga-trust-m/config").display()
- ))
- .arg(format!("-I{}", optiga_include_dir.display()))
- .arg(format!(
- "-I{}",
- external_dir.join("optiga-trust-m/include/cmd").display()
- ))
- .arg(format!(
- "-I{}",
- external_dir.join("optiga-trust-m/include/common").display()
- ))
- .arg(format!(
- "-I{}",
- external_dir
- .join("optiga-trust-m/include/ifx_i2c")
- .display()
- ))
- .arg(format!(
- "-I{}",
- external_dir.join("optiga-trust-m/include/pal").display()
- ))
- .arg(format!(
- "-I{}",
- external_dir.join("optiga-trust-m/include/comms").display()
- ))
- .arg(format!(
- "-I{}",
- external_dir
- .join("optiga-trust-m/external/mbedtls/include")
- .display()
- )),
- "run bindgen",
- )?;
+ run_command(&mut bindgen, "run bindgen")?;
Ok(())
}
@@ -231,6 +213,12 @@ fn emit_rerun_if_changed(path: impl AsRef<std::path::Path>) {
println!("cargo::rerun-if-changed={}", path.as_ref().display());
}
+fn emit_bindgen_env_rerun_if_changed() {
+ let target = env::var("TARGET").expect("TARGET not set");
+ println!("cargo::rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS");
+ println!("cargo::rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS_{target}");
+}
+
fn ensure_command_exists(command: &str) -> BuildResult<()> {
match Command::new(command).arg("--version").output() {
Ok(_) => Ok(()),
diff --git a/src/rust/bitbox02-sys/build.rs b/src/rust/bitbox02-sys/build.rs
index c74fc68..619f7db 100644
--- a/src/rust/bitbox02-sys/build.rs
+++ b/src/rust/bitbox02-sys/build.rs
@@ -328,33 +328,19 @@ pub fn main() -> BuildResult<()> {
ensure_command_exists("bindgen")?;
let target = env::var("TARGET").expect("TARGET not set");
- let cross_compiling = target == "thumbv7em-none-eabi";
-
- let arm_sysroot = env::var("CMAKE_SYSROOT").unwrap_or("/usr/local/arm-none-eabi".to_string());
- let arm_sysroot = format!("--sysroot={arm_sysroot}");
-
- let mut extra_flags = if cross_compiling {
- vec![
- "-D__SAMD51J20A__",
- "--target=thumbv7em-none-eabi",
- "-mcpu=cortex-m4",
- "-mthumb",
- "-mfloat-abi=soft",
- &arm_sysroot,
- "-fshort-enums",
- ]
+ emit_bindgen_env_rerun_if_changed(&target);
+ let cross_compiling = target.starts_with("thumb");
+
+ let target_definitions = if cross_compiling {
+ vec!["-D__SAMD51J20A__"]
} else {
vec!["-DTESTING", "-D_UNIT_TEST_", "-DPRODUCT_BITBOX_MULTI=1"]
};
- // If user enables -Dwarnings for rust we also want to enable -Werror for C.
- if let Ok(rustflags) = std::env::var("CARGO_ENCODED_RUSTFLAGS") {
- for flag in rustflags.split('\x1f') {
- if flag == "-Dwarnings" {
- extra_flags.push("-Werror");
- }
- }
- }
+ // If user enables -Dwarnings for Rust we also want to enable -Werror for C.
+ let warnings_as_errors = std::env::var("CARGO_ENCODED_RUSTFLAGS")
+ .map(|rustflags| rustflags.split('\x1f').any(|flag| flag == "-Dwarnings"))
+ .unwrap_or(false);
let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR not set"));
@@ -425,28 +411,31 @@ pub fn main() -> BuildResult<()> {
// Needs to match the definitions in `CMakeList.txt' files (unit tests, hardware fakes and
// simulator)
let mut definitions = vec!["-DAPP_U2F=1"];
- definitions.extend(&extra_flags);
+ definitions.extend(target_definitions);
+ if warnings_as_errors {
+ definitions.push("-Werror");
+ }
- run_command(
- Command::new("bindgen")
- .args(["--output", &out_path])
- .arg("--use-core")
- .arg("--with-derive-default")
- .args(
- ALLOWLIST_FNS
- .iter()
- .flat_map(|s| ["--allowlist-function", s]),
- )
- .args(ALLOWLIST_TYPES.iter().flat_map(|s| ["--allowlist-type", s]))
- .args(ALLOWLIST_VARS.iter().flat_map(|s| ["--allowlist-var", s]))
- .args(RUSTIFIED_ENUMS.iter().flat_map(|s| ["--rustified-enum", s]))
- .args(OPAQUE_TYPES.iter().flat_map(|s| ["--opaque-type", s]))
- .arg("wrapper.h")
- .arg("--")
- .args(&definitions)
- .args(includes.iter().map(|s| format!("-I{s}"))),
- "run bindgen",
- )?;
+ let mut bindgen = Command::new("bindgen");
+ bindgen
+ .args(["--output", &out_path])
+ .arg("--use-core")
+ .arg("--with-derive-default")
+ .args(
+ ALLOWLIST_FNS
+ .iter()
+ .flat_map(|s| ["--allowlist-function", s]),
+ )
+ .args(ALLOWLIST_TYPES.iter().flat_map(|s| ["--allowlist-type", s]))
+ .args(ALLOWLIST_VARS.iter().flat_map(|s| ["--allowlist-var", s]))
+ .args(RUSTIFIED_ENUMS.iter().flat_map(|s| ["--rustified-enum", s]))
+ .args(OPAQUE_TYPES.iter().flat_map(|s| ["--opaque-type", s]))
+ .arg("wrapper.h")
+ .arg("--")
+ .args(&definitions)
+ .args(includes.iter().map(|s| format!("-I{s}")));
+
+ run_command(&mut bindgen, "run bindgen")?;
let excludes = if let Ok(libtype) = env::var("LIB_TYPE") {
match libtype.as_str() {
@@ -492,6 +481,11 @@ fn emit_rerun_if_changed(path: &str) {
println!("cargo::rerun-if-changed={path}");
}
+fn emit_bindgen_env_rerun_if_changed(target: &str) {
+ println!("cargo::rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS");
+ println!("cargo::rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS_{target}");
+}
+
fn emit_git_rerun_if_changed(repo_root: &Path) {
let Some(git_dir) = git_output(repo_root, &["rev-parse", "--absolute-git-dir"]) else {
return;
Why this scored 14/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.