Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ ${config_paths}
WRAPPER_FILE="${WRAPPER_FILE}"
DT_AUGMENTS="${DT_AUGMENTS}"
BINARY_DIR_INCLUDE_GENERATED="${BINARY_DIR_INCLUDE_GENERATED}"
CC=${CMAKE_C_COMPILER}
cargo build
${rust_build_type_arg}

Expand Down Expand Up @@ -217,6 +218,7 @@ ${config_paths}
WRAPPER_FILE="${WRAPPER_FILE}"
DT_AUGMENTS="${DT_AUGMENTS}"
BINARY_DIR_INCLUDE_GENERATED="${BINARY_DIR_INCLUDE_GENERATED}"
CC=${CMAKE_C_COMPILER}
cargo doc
${rust_build_type_arg}

Expand Down
33 changes: 31 additions & 2 deletions zephyr-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,31 @@ fn main() -> Result<()> {
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let wrapper_path = PathBuf::from(env::var("WRAPPER_FILE").unwrap());

// Get GCC toolchain info to find stddef.h
let cc = env::var("CC").unwrap_or_default();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I don't think it is the right thing, ever to use the gcc compiler-specific header files with the clang compiler. Clang will have it's own version of these headers. Some platforms will have clang try to figure this out, but that doesn't happen everywhere, and I'm guessing you're running into that.

It's a little weird to try to figure out the clang headers, but it ends up being something like:

RESOURCE_DIR=$(${LIBCLANG_PATH}/../bin/clang --print-resource-dir)

Then the arguments to the clang invocation need to include: nostdinc (which I think must already be the case), and then -isystem $RESOURCE_DIR/include. This should get the versions of these headers that make sense with the clang compiler.

let gcc_include = if !cc.is_empty() {
let cc_path = Path::new(&cc);
let toolchain_path = cc_path.parent().and_then(|p| p.parent()).unwrap();
let target_triple = cc_path.file_name().unwrap().to_str().unwrap()
.strip_suffix("-gcc").unwrap_or("arm-zephyr-eabi");
let gcc_version = std::process::Command::new(&cc)
.arg("-dumpversion")
.output().ok()
.and_then(|o| String::from_utf8(o.stdout).ok())
.map(|v| v.trim().to_string())
.unwrap_or("12.2.0".to_string());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we defaulting to 12.2.0?

format!("{}/lib/gcc/{}/{}/include", toolchain_path.display(), target_triple, gcc_version)
} else {
String::new()
};

// Create dummy ARM headers to avoid ACLE errors
let dummy_headers = out_path.join("dummy_headers");
std::fs::create_dir_all(&dummy_headers).ok();
std::fs::write(dummy_headers.join("arm_acle.h"), "").ok();

// Bindgen everything.
let bindings = Builder::default()
let mut bindings = Builder::default()
.header(
Path::new("wrapper.h")
.canonicalize()
Expand All @@ -63,7 +86,13 @@ fn main() -> Result<()> {
.unwrap(),
)
.use_core()
.clang_arg(&target_arg);
.clang_arg(&target_arg)
.clang_arg(format!("-I{}", dummy_headers.display()));

if !gcc_include.is_empty() {
bindings = bindings.clang_arg(format!("-I{}", gcc_include));
}

let bindings = define_args(bindings, "-I", "INCLUDE_DIRS");
let bindings = define_args(bindings, "-D", "INCLUDE_DEFINES");
let bindings = bindings
Expand Down
Loading