Add backtrace functions for sandbox, including: - os_backtrace() to collect addresses into a caller-supplied buffer - os_backtrace_symbols() to convert addresses to symbol strings - os_backtrace_symbols_free() to free the symbol array The libbacktrace library (bundled with GCC) reads DWARF debug information to provide detailed symbol resolution including function names (even for static functions), source file paths, and line numbers. The sandbox backtrace implementation wraps these OS functions to implement the generic backtrace API (backtrace_init, backtrace_get_syms, etc.). Enable it for just the 'sandbox' board. Add the library for the Rust example too. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com>
109 lines
4.2 KiB
Rust
109 lines
4.2 KiB
Rust
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Build script for U-Boot Rust demo
|
|
*
|
|
* This configures linking with the U-Boot library, similar to how
|
|
* the C examples are built in examples/ulib
|
|
*
|
|
* Copyright 2025 Canonical Ltd.
|
|
* Written by Simon Glass <simon.glass@canonical.com>
|
|
*/
|
|
|
|
use std::env;
|
|
use std::path::PathBuf;
|
|
use std::process::Command;
|
|
|
|
fn main() {
|
|
// Get the U-Boot build directory from environment or use default
|
|
let uboot_build = env::var("UBOOT_BUILD")
|
|
.unwrap_or_else(|_| "/tmp/b/sandbox".to_string());
|
|
|
|
|
|
let uboot_build_path = PathBuf::from(&uboot_build);
|
|
|
|
println!("cargo:rerun-if-env-changed=UBOOT_BUILD");
|
|
println!("cargo:rerun-if-changed=build.rs");
|
|
|
|
// Add library search path
|
|
println!("cargo:rustc-link-search=native={}", uboot_build_path.display());
|
|
|
|
// Check if dynamic linking is requested
|
|
if env::var("UBOOT_DYNAMIC").is_ok() {
|
|
// Dynamic linking with libu-boot.so
|
|
println!("cargo:rustc-link-lib=dylib=u-boot");
|
|
println!("cargo:rustc-link-arg=-Wl,-rpath,{}", uboot_build_path.display());
|
|
} else {
|
|
// Static linking with libu-boot.a using whole-archive to ensure
|
|
// all symbols are included (required for U-Boot linker lists)
|
|
// Use the same linker script as the C examples for proper linker list ordering
|
|
let static_lib_path = uboot_build_path.join("libu-boot.a");
|
|
// Use absolute path to the linker script in the source tree
|
|
let current_dir = env::current_dir().expect("Failed to get current directory");
|
|
let linker_script_path = current_dir.join("../ulib/static.lds");
|
|
|
|
println!("cargo:rustc-link-arg=-Wl,-T,{}", linker_script_path.display());
|
|
println!("cargo:rustc-link-arg=-Wl,--whole-archive");
|
|
println!("cargo:rustc-link-arg={}", static_lib_path.display());
|
|
println!("cargo:rustc-link-arg=-Wl,--no-whole-archive");
|
|
println!("cargo:rustc-link-arg=-Wl,-z,noexecstack");
|
|
|
|
// Add required system libraries AFTER --no-whole-archive like the C version
|
|
println!("cargo:rustc-link-arg=-lpthread");
|
|
println!("cargo:rustc-link-arg=-ldl");
|
|
|
|
// Get SDL libraries using sdl2-config like the C version does
|
|
if let Ok(output) = Command::new("sdl2-config").arg("--libs").output() {
|
|
if output.status.success() {
|
|
let libs_str = String::from_utf8_lossy(&output.stdout);
|
|
for lib_flag in libs_str.split_whitespace() {
|
|
if lib_flag.starts_with("-l") {
|
|
println!("cargo:rustc-link-arg={}", lib_flag);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// Fallback to just SDL2 if sdl2-config is not available
|
|
println!("cargo:rustc-link-arg=-lSDL2");
|
|
}
|
|
|
|
// Link with libbacktrace for backtrace support on sandbox
|
|
println!("cargo:rustc-link-arg=-lbacktrace");
|
|
}
|
|
|
|
// For dynamic linking, link required system libraries normally
|
|
if env::var("UBOOT_DYNAMIC").is_ok() {
|
|
println!("cargo:rustc-link-lib=pthread");
|
|
println!("cargo:rustc-link-lib=dl");
|
|
println!("cargo:rustc-link-lib=rt");
|
|
}
|
|
|
|
// Optional SDL2 support (if available) - only for dynamic linking
|
|
if env::var("UBOOT_DYNAMIC").is_ok() {
|
|
if let Ok(sdl_libs) = env::var("SDL_LIBS") {
|
|
for lib in sdl_libs.split_whitespace() {
|
|
if let Some(lib_name) = lib.strip_prefix("-l") {
|
|
println!("cargo:rustc-link-lib={}", lib_name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Define symbols that may be missing (from U-Boot troubleshooting docs)
|
|
// Note: __stack_chk_guard is provided by U-Boot's common/stackprot.c
|
|
println!("cargo:rustc-link-arg=-Wl,--defsym,sandbox_sdl_sync=0");
|
|
|
|
// For static linking, we need to ensure libc is available for atexit and other functions
|
|
if env::var("UBOOT_DYNAMIC").is_err() {
|
|
println!("cargo:rustc-link-arg=-lc");
|
|
}
|
|
|
|
// Add include path for headers if needed for bindgen (future enhancement)
|
|
let uboot_include = uboot_build_path.join("include");
|
|
if uboot_include.exists() {
|
|
println!("cargo:include={}", uboot_include.display());
|
|
}
|
|
|
|
// Recompile if main source changes
|
|
println!("cargo:rerun-if-changed=src/demo.rs");
|
|
}
|