rust-bindgen icon indicating copy to clipboard operation
rust-bindgen copied to clipboard

Cross-compiled crate appears to include host header files after 0.30

Open thenewwazoo opened this issue 7 years ago • 9 comments

When building bindings for an embedded OS, updating the dependency from 0.30 to 0.31 causes an error when Builder::generate is called. To repro (this assumes you've got arm-none-eabi tools installed):

$ git clone --recursive [email protected]:thenewwazoo/ChibiOS-rust.git && cd ChibiOS-rust
$ rustup override set nightly
$ cp -R os_ports/* ChibiOS/
$ xargo build --target thumbv7m-none-eabi --features stm32f407xg

The crate will build successfully.

Updating bindgen to 0.31 results in the following output:

<successful output snipped>
--- stderr
/usr/include/sys/cdefs.h:761:2: error: Unsupported architecture
/usr/include/machine/_types.h:34:2: error: architecture not supported
/usr/include/sys/_types.h:55:9: error: unknown type name '__int64_t'
/usr/include/sys/_types.h:56:9: error: unknown type name '__int32_t'
/usr/include/sys/_types.h:57:9: error: unknown type name '__int32_t'
/usr/include/sys/_types.h:60:9: error: unknown type name '__uint32_t'
/usr/include/sys/_types.h:61:9: error: unknown type name '__uint32_t'
/usr/include/sys/_types.h:62:9: error: unknown type name '__uint64_t'
/usr/include/sys/_types.h:68:9: error: unknown type name '__darwin_natural_t'
/usr/include/sys/_types.h:70:9: error: unknown type name '__uint16_t'
/usr/include/sys/_types.h:71:9: error: unknown type name '__int64_t'
/usr/include/sys/_types.h:72:9: error: unknown type name '__int32_t'
/usr/include/sys/_types.h:73:9: error: unknown type name '__uint32_t'
/usr/include/sys/_types.h:74:9: error: unknown type name '__int32_t'
/usr/include/sys/_types.h:75:9: error: unknown type name '__uint32_t'
/usr/include/sys/_types.h:76:9: error: unknown type name '__uint32_t'
/usr/include/machine/types.h:37:2: error: architecture not supported
/usr/include/sys/_types/_intptr_t.h:32:9: error: unknown type name '__darwin_intptr_t'
/usr/include/sys/cdefs.h:761:2: error: Unsupported architecture, err: true
/usr/include/machine/_types.h:34:2: error: architecture not supported, err: true
/usr/include/sys/_types.h:55:9: error: unknown type name '__int64_t', err: true
/usr/include/sys/_types.h:56:9: error: unknown type name '__int32_t', err: true
/usr/include/sys/_types.h:57:9: error: unknown type name '__int32_t', err: true
/usr/include/sys/_types.h:60:9: error: unknown type name '__uint32_t', err: true
/usr/include/sys/_types.h:61:9: error: unknown type name '__uint32_t', err: true
/usr/include/sys/_types.h:62:9: error: unknown type name '__uint64_t', err: true
/usr/include/sys/_types.h:68:9: error: unknown type name '__darwin_natural_t', err: true
/usr/include/sys/_types.h:70:9: error: unknown type name '__uint16_t', err: true
/usr/include/sys/_types.h:71:9: error: unknown type name '__int64_t', err: true
/usr/include/sys/_types.h:72:9: error: unknown type name '__int32_t', err: true
/usr/include/sys/_types.h:73:9: error: unknown type name '__uint32_t', err: true
/usr/include/sys/_types.h:74:9: error: unknown type name '__int32_t', err: true
/usr/include/sys/_types.h:75:9: error: unknown type name '__uint32_t', err: true
/usr/include/sys/_types.h:76:9: error: unknown type name '__uint32_t', err: true
/usr/include/machine/types.h:37:2: error: architecture not supported, err: true
/usr/include/sys/_types/_intptr_t.h:32:9: error: unknown type name '__darwin_intptr_t', err: true
thread 'main' panicked at 'unable to generate cmsis bindings: ()', libcore/result.rs:916:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

(looking at the backtrace points to where I expect the generate call)

Relevant host information:

Darwin hartwell.local 17.3.0 Darwin Kernel Version 17.3.0: Thu Nov  9 18:09:22 PST 2017; root:xnu-4570.31.3~1/RELEASE_X86_64 x86_64
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.2.1 20151202 (release) [ARM/embedded-5-branch revision 231848]
Apple LLVM version 9.0.0 (clang-900.0.39.2)
rustc 1.25.0-nightly (e6072a7b3 2018-01-13)

You can find the __bindgen.i file here

thenewwazoo avatar Jan 20 '18 06:01 thenewwazoo

I added a "successful" dump to the gist (they're named __bindgen.i (0.3?))

thenewwazoo avatar Jan 20 '18 06:01 thenewwazoo

Thanks for the bug report!

The best way to help solve it would be to create a minimal, standalone test case that reproduces system headers getting included. Unfortunately, because this has to do with includes and include paths, I don't think creduce will be of much use here.

fitzgen avatar Jan 22 '18 17:01 fitzgen

I've been experiencing similar problem.

For simple wrapper.h containing:

#include <stdint.h>

Running cargo build --target=arm-unknown-linux-gnueabi with build.rs

let bindings = bindgen::Builder::default()
    .header("wrapper.h")
    .generate()
    .expect("Unable to generate bindings");

or running the following command

$ TARGET=arm-unknown-linux-gnueabi bindgen wrapper.h

produces the same error.

/usr/include/x86_64-linux-gnu/gnu/stubs.h:7:11: fatal error: 'gnu/stubs-32.h' file not found
/usr/include/x86_64-linux-gnu/gnu/stubs.h:7:11: fatal error: 'gnu/stubs-32.h' file not found, err: true
thread 'main' panicked at 'Unable to generate bindings: ()', /checkout/src/libcore/result.rs:916:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

I had to add explicit --sysroot clang argument when I cross compile for ARM target.

.clang_arg("--sysroot=/my/path/to/arm/sysroot")

trlim avatar Feb 18 '18 15:02 trlim

I encountered the same problem where the i386 stubs-32.h was getting referenced when trying to cross-compile for armhf. I was able to get past it by modifying build_gecko.rs with something similar to @trlim's suggestion:

            let mut builder = Builder::default()
+               .clang_arg("-target")
+               .clang_arg("arm-linux-gnueabihf")
                .rustfmt_bindings(false)
                .rust_target(RustTarget::Stable_1_0);

That was on Xenial, then on Bionic it still couldn't find the proper cross-target headers, and complained about being unable to find <bits/c++config.h>, so with another hint from Stack Overflow I ended up using:

            let mut builder = Builder::default()
+               .clang_arg("-target")
+               .clang_arg("arm-linux-gnueabihf")
+               .clang_arg("-I/usr/arm-linux-gnueabihf/include/c++/7")
+               .clang_arg("-I/usr/arm-linux-gnueabihf/include/c++/7/arm-linux-gnueabihf")
                .rustfmt_bindings(false)
                .rust_target(RustTarget::Stable_1_0);

and then was able to cross-compile all the Rust code in Firefox 59.

jdonald avatar Apr 04 '18 06:04 jdonald

Hey everyone, I've added the ability to pass additional clang arguments through an environment variable, while trying trying to tackle this exact problem. If you use that to pass --sysroot /path/to/cross/dir to clang, it should fix these issues.

If anyone could try that, perhaps this bug could be closed.

jhwgh1968 avatar Mar 16 '19 03:03 jhwgh1968

With bindgen 0.55.1 I am able to cross-compile (host debian 10, target raspbian 10) for a raspberry pi zero w with:

$ cat .cargo/config 
[target.arm-unknown-linux-gnueabi]
linker = "arm-linux-gnueabi-gcc"
$ BINDGEN_EXTRA_CLANG_ARGS='--sysroot /usr/arm-linux-gnueabi' cargo build --target arm-unknown-linux-gnueabi

It would be convenient if the sysroot directory could be specified alongside the linker in a cargo config file.

mdavidsaver avatar Oct 13 '20 19:10 mdavidsaver

It would be convenient if the sysroot directory could be specified alongside the linker in a cargo config file.

Even if the crate were to read an extra parameter from .cargo/config (which is probably not supported by cargo directly, and would be working around it), I suspect it would be difficult to provide in a truly agnostic way.

There are a number of behavior changes between gcc versions and linkers. Since a lot of cross compiling involves 3rd party or vendor toolchains, I don't know that any single set of parameters would be portable.

For the case I was working on when I wrote this, I also found that I needed more than just a sysroot. Looking at how bindgen propagated arguments prior to that, I thought "extra clang args" was the best solution.

jhwgh1968 avatar Oct 14 '20 10:10 jhwgh1968

This seems to be clang version dependent: for libOSCORE (where I track this as #61), this hasn't been an issue until I installed Debian's clang-18. In particular, things start misbehaving as soon as libclang-common-18-dev is installed, no matter whether clang itself is installed. (Beware that there might be missing emitted Cargo rebuild checks -- after installing/uninstalling libclang files, be sure to cargo clean).

chrysn avatar Sep 26 '24 14:09 chrysn

For my most recent occurrence of this, setting .clang_arg("-std=c23") made all the difference; the clue came from comparing the LLVM 16 and 18 versions of its stdint.h. No clue how that is supposed to play together, or whether the issue is with LLVM, bindgen or something inbetween, but that's a workaround that fixed it for me.

chrysn avatar Sep 26 '24 15:09 chrysn