This repository has been archived on 2026-08-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
donglora/vendor/semihosting/build.rs
T
swaitsandClaude Opus 4.6 3102fc747a feat: add display UI with splash screen, dashboard, and RSSI sparkline
Implement full SSD1306 OLED display support:
- Splash screen on boot (1.5s) with project name, version, board
- Dashboard showing radio state, config, counters, RSSI/SNR
- RSSI history sparkline (64-sample ring buffer, 2px-wide bars)
- DisplayOn/DisplayOff host commands routed via dedicated channel
- Pure render functions against generic DrawTarget (no hardware coupling)
- Display on/off control bypasses radio task entirely

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:42:54 -06:00

154 lines
7.3 KiB
Rust

// SPDX-License-Identifier: Apache-2.0 OR MIT
// The rustc-cfg emitted by the build script are *not* public API.
#[path = "src/gen/build.rs"]
mod generated;
#[path = "version.rs"]
mod version;
use std::env;
use self::version::{Version, rustc_version};
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=src/gen/build.rs");
let target_arch = &*env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH not set");
let version = match rustc_version() {
Some(version) => version,
None => {
if env::var_os("SEMIHOSTING_DENY_WARNINGS").is_some() {
panic!("unable to determine rustc version")
}
println!(
"cargo:warning={}: unable to determine rustc version; assuming latest stable rustc (1.{})",
env!("CARGO_PKG_NAME"),
Version::LATEST.minor
);
Version::LATEST
}
};
if version.minor >= 80 {
// Custom cfgs set by build script. Not public API.
// grep -F 'cargo:rustc-cfg=' build.rs | grep -Ev '^ *//' | sed -E 's/^.*cargo:rustc-cfg=//; s/(=\\)?".*$//' | LC_ALL=C sort -u | tr '\n' ',' | sed -E 's/,$/\n/'
println!(
"cargo:rustc-check-cfg=cfg(semihosting_no_asm,semihosting_no_duration_checked_float,semihosting_no_error_in_core,semihosting_no_strict_provenance,semihosting_target_feature)"
);
// TODO: handle multi-line target_feature_fallback
// grep -F 'target_feature_fallback("' build.rs | grep -Ev '^ *//' | sed -E 's/^.*target_feature_fallback\(//; s/",.*$/"/' | LC_ALL=C sort -u | tr '\n' ',' | sed -E 's/,$/\n/'
println!(
r#"cargo:rustc-check-cfg=cfg(semihosting_target_feature,values("mclass","thumb-mode"))"#
);
}
// Note that cfgs are `no_`*, not `has_*`. This allows treating as the latest
// stable rustc is used when the build script doesn't run. This is useful
// for non-cargo build systems that don't run the build script.
// duration_checked_float stabilized in Rust 1.66 (nightly-2022-10-25): https://github.com/rust-lang/rust/pull/102271
if !version.probe(66, 2022, 10, 24) {
println!("cargo:rustc-cfg=semihosting_no_duration_checked_float");
}
// error_in_core stabilized in Rust 1.81 (nightly-2024-06-09): https://github.com/rust-lang/rust/pull/125951
if !version.probe(81, 2024, 6, 8) {
println!("cargo:rustc-cfg=semihosting_no_error_in_core");
}
// strict_provenance/exposed_provenance APIs stabilized in Rust 1.84 (nightly-2024-10-22): https://github.com/rust-lang/rust/pull/130350
if !version.probe(84, 2024, 10, 21) {
println!("cargo:rustc-cfg=semihosting_no_strict_provenance");
}
match target_arch {
"arm" => {
let target = &*env::var("TARGET").expect("TARGET not set");
// https://github.com/rust-lang/rust/pull/123745 (includes https://github.com/rust-lang/cargo/pull/13560) merged in Rust 1.79 (nightly-2024-04-11).
if !version.probe(79, 2024, 4, 10) {
// HACK: If --target is specified, rustflags is not applied to the build
// script itself, so the build script will not be recompiled when rustflags
// is changed. That in itself is not a problem, but the old Cargo does
// not rerun the build script as well, which can be problematic.
// https://github.com/rust-lang/cargo/issues/13003
// This problem has been fixed in 1.79 so only older versions need a workaround.
println!("cargo:rerun-if-env-changed=CARGO_ENCODED_RUSTFLAGS");
println!("cargo:rerun-if-env-changed=RUSTFLAGS");
println!("cargo:rerun-if-env-changed=CARGO_BUILD_RUSTFLAGS");
let mut target_upper = target.replace(['-', '.'], "_");
target_upper.make_ascii_uppercase();
println!("cargo:rerun-if-env-changed=CARGO_TARGET_{target_upper}_RUSTFLAGS");
}
if needs_target_feature_fallback(&version) {
// See https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/build.rs for details
let mut subarch =
target.strip_prefix("arm").or_else(|| target.strip_prefix("thumb")).unwrap();
subarch = subarch.strip_prefix("eb").unwrap_or(subarch); // ignore endianness
subarch = subarch.split('-').next().unwrap(); // ignore vender/os/env
subarch = subarch.split('.').next().unwrap(); // ignore .base/.main suffix
let mut mclass = false;
match subarch {
"v6m" | "v7em" | "v7m" | "v8m" => mclass = true,
_ => {}
}
target_feature_fallback("mclass", mclass);
// All builtin targets that start with "thumb" enable thumb-mode, and
// some builtin targets that start with "arm" are also enable thumb-mode.
let thumb_mode =
target.starts_with("thumb") || generated::ARM_BUT_THUMB_MODE.contains(&target);
target_feature_fallback("thumb-mode", thumb_mode);
}
}
"loongarch32" => {
// asm! on loongarch32 stabilized in Rust 1.91 (nightly-2025-08-11): https://github.com/rust-lang/rust/pull/144402
if !version.probe(91, 2025, 8, 10) {
println!("cargo:rustc-cfg=semihosting_no_asm");
}
}
_ => {}
}
}
// HACK: Currently, it seems that the only way to handle unstable target
// features on the stable is to parse the `-C target-feature` in RUSTFLAGS.
//
// - #[cfg(target_feature = "unstable_target_feature")] doesn't work on stable.
// - CARGO_CFG_TARGET_FEATURE excludes unstable target features on stable.
//
// As mentioned in the [RFC2045], unstable target features are also passed to LLVM
// (e.g., https://godbolt.org/z/4rr7rMcfG), so this hack works properly on stable.
//
// [RFC2045]: https://rust-lang.github.io/rfcs/2045-target-feature.html#backend-compilation-options
fn needs_target_feature_fallback(version: &Version) -> bool {
if version.nightly {
// In this case, cfg(target_feature = "...") would work, so skip emitting our own fallback target_feature cfg.
false
} else {
true
}
}
fn target_feature_fallback(name: &str, mut has_target_feature: bool) {
if let Some(rustflags) = env::var_os("CARGO_ENCODED_RUSTFLAGS") {
for mut flag in rustflags.to_string_lossy().split('\x1f') {
flag = flag.strip_prefix("-C").unwrap_or(flag);
if let Some(flag) = flag.strip_prefix("target-feature=") {
for s in flag.split(',') {
// TODO: Handles cases where a specific target feature
// implicitly enables another target feature.
match (s.as_bytes().first(), s.as_bytes().get(1..)) {
(Some(b'+'), Some(f)) if f == name.as_bytes() => has_target_feature = true,
(Some(b'-'), Some(f)) if f == name.as_bytes() => has_target_feature = false,
_ => {}
}
}
}
}
}
if has_target_feature {
println!("cargo:rustc-cfg=semihosting_target_feature=\"{name}\"");
}
}