Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bindgen passes the rust target to clang. It should pass the host target #1728

Open
ceigel opened this issue Feb 14, 2020 · 4 comments
Open
Labels

Comments

@ceigel
Copy link

ceigel commented Feb 14, 2020

I'm trying to build bindings for minimp3 (https://github.com/lieff/minimp3). I am using these bindings from an embedded project, with target "thumbv7em-none-eabihf". I call bindgen from build.rs, together with the cc invocation to compile the C library. I get a large amount of errors from clang about types being in the wrong architecture (see below). When calling bindgen with the same arguments (taken from .command_line_flags() method) the generation finishes successfully. When I force bindgen to pass the HOST env var to the clang compiler as the --target flag the generation is also successful (see build.rs). I think my solution is a hack and the default behavior of bindgen should be to pass the host target to clang.
I believe this issue is similar to issue #1555

Bindgen Invocation

bindgen --output src/bindings.rs bindgen.h --rust-target 1.33 --no-derive-default --ctypes-prefix cty --generate functions,types,vars,methods,constructors,destructors --use-core -- -Iminimp3

Build.rs usage

extern crate bindgen;
extern crate cc;
use std::env;
use std::path::PathBuf;

fn main() {
    println!("cargo:rustc-link-lib=minimp3");
    println!("cargo:rerun-if-changed=minimp3.c");
    println!("cargo:rerun-if-changed=bindgen.h");
    let mut build = cc::Build::new();
    build
        .include("minimp3")
        .define("MINIMP3_IMPLEMENTATION", None)
        .define("MINIMP3_NO_STDIO", None)
        .file("minimp3.c")
        .compile("minimp3");

    let bb = bindgen::builder()
        .header("bindgen.h")
        .ctypes_prefix("cty")
        .generate_comments(true)
        .rustfmt_bindings(true)
        .clang_arg("-Iminimp3")
        // uncomment to make it work .clang_arg(format!("--target={}", env::var("HOST").unwrap()))
        .use_core();
    eprintln!(
        "please run bindgen --output src/bindings.rs {}",
        bb.command_line_flags().join(" ")
    );

    // bindgen --output src/bindings.rs bindgen.h --rust-target 1.33 --no-derive-default --ctypes-prefix cty --generate functions,types,vars,methods,constructors,destructors --use-core -- -Iminimp3
    let bindings = bb.generate().expect("Unable to generate bindings");

    let out_path = PathBuf::from("src");
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");
}

Errors:1)
--- stdout
cargo:rustc-link-lib=minimp3
cargo:rerun-if-changed=minimp3.c
cargo:rerun-if-changed=bindgen.h
TARGET = Some("thumbv7em-none-eabihf")
OPT_LEVEL = Some("0")
HOST = Some("x86_64-apple-darwin")
CC_thumbv7em-none-eabihf = None
CC_thumbv7em_none_eabihf = None
TARGET_CC = None
CC = None
CROSS_COMPILE = None
CFLAGS_thumbv7em-none-eabihf = None
CFLAGS_thumbv7em_none_eabihf = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
DEBUG = Some("true")
CARGO_CFG_TARGET_FEATURE = None
running: "arm-none-eabi-gcc" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-g" "-fno-omit-frame-pointer" "-mthumb" "-mfloat-abi=hard" "-march=armv7e-m" "-mfpu=fpv4-sp-d16" "-I" "minimp3" "-Wall" "-Wextra" "-DMINIMP3_IMPLEMENTATION" "-DMINIMP3_NO_STDIO" "-o" "/Users/.../src/stm32f3/example-sound/minimp3-ffi/target/thumbv7em-none-eabihf/debug/build/minimp3-ffi-f769533addf55ac0/out/minimp3.o" "-c" "minimp3.c"
exit code: 0
AR_thumbv7em-none-eabihf = None
AR_thumbv7em_none_eabihf = None
TARGET_AR = None
AR = None
running: "ar" "crs" "/Users/.../src/stm32f3/example-sound/minimp3-ffi/target/thumbv7em-none-eabihf/debug/build/minimp3-ffi-f769533addf55ac0/out/libminimp3.a" "/Users/.../src/stm32f3/example-sound/minimp3-ffi/target/thumbv7em-none-eabihf/debug/build/minimp3-ffi-f769533addf55ac0/out/minimp3.o"
exit code: 0
cargo:rustc-link-lib=static=minimp3
cargo:rustc-link-search=native=/Users/.../src/stm32f3/example-sound/minimp3-ffi/target/thumbv7em-none-eabihf/debug/build/minimp3-ffi-f769533addf55ac0/out

--- stderr
please run bindgen --output src/bindings.rs bindgen.h --rust-target 1.40 --no-derive-default --ctypes-prefix cty --generate functions,types,vars,methods,constructors,destructors --use-core -- -Iminimp3
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:807:2: error: Unsupported architecture
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/machine/_types.h:34:2: error: architecture not supported
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:55:9: error: unknown type name '__int64_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:56:9: error: unknown type name '__int32_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:57:9: error: unknown type name '__int32_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:60:9: error: unknown type name '__uint32_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:61:9: error: unknown type name '__uint32_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:62:9: error: unknown type name '__uint64_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:68:9: error: unknown type name '__darwin_natural_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:70:9: error: unknown type name '__uint16_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:71:9: error: unknown type name '__int64_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:72:9: error: unknown type name '__int32_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:73:9: error: unknown type name '__uint32_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:74:9: error: unknown type name '__int32_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:75:9: error: unknown type name '__uint32_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:76:9: error: unknown type name '__uint32_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/machine/types.h:37:2: error: architecture not supported
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types/_intptr_t.h:32:9: error: unknown type name '__darwin_intptr_t'
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:807:2: error: Unsupported architecture, err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/machine/_types.h:34:2: error: architecture not supported, err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:55:9: error: unknown type name '__int64_t', err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:56:9: error: unknown type name '__int32_t', err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:57:9: error: unknown type name '__int32_t', err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:60:9: error: unknown type name '__uint32_t', err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:61:9: error: unknown type name '__uint32_t', err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:62:9: error: unknown type name '__uint64_t', err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:68:9: error: unknown type name '__darwin_natural_t', err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:70:9: error: unknown type name '__uint16_t', err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:71:9: error: unknown type name '__int64_t', err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:72:9: error: unknown type name '__int32_t', err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:73:9: error: unknown type name '__uint32_t', err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:74:9: error: unknown type name '__int32_t', err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:75:9: error: unknown type name '__uint32_t', err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/_types.h:76:9: error: unknown type name '__uint32_t', err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/machine/types.h:37:2: error: architecture not supported, err: true
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/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 bindings: ()', src/libcore/result.rs:1165:5
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace.

@emilio
Copy link
Contributor

emilio commented Feb 17, 2020

Hmmm... I'm confused. You generally want to generate the bindings for the target. Otherwise you may get wrong bindings.

It just seems like you're not passing the right include / sysroot flags to correctly find those types, so it's failing with weird errors when including host headers, which seems obviously bad.

@ceigel
Copy link
Author

ceigel commented Feb 17, 2020

I am confused as well. I'm not an expert of bindgen but I expect running from command-line or calling the library from build.rs to be identical. The default target of my project is "thumbv7em-none-eabihf". Finding documentation about passing the right way to call bindgen when building cross-compiled libraries is not easy.

@ceigel
Copy link
Author

ceigel commented Feb 17, 2020

I added "-I/usr/local/opt/gcc-arm-none-eabi-74/arm-none-eabi/include/" to the clang_arg and it also worked. Thank you @emilio for the suggestion.

bunnie added a commit to bunnie/rust-bindgen that referenced this issue Feb 21, 2020
I spent an afternoon scratching my head on this one before I ran
into rust-lang#1728.

Since the error message welcomes PRs...
@bunnie
Copy link
Contributor

bunnie commented Feb 21, 2020

I also ran into this problem, and opened a pull request #1734 to add to the list of possible problems a host v. target architecture mismatch. Took me a day of head scratching before I came across this thread, so at least a note about the issue might save other embedded developers an afternoon down the road...

fwiw, I am developing for risc-v and I was unable to get it to work by adding the sysroot includes as @ceigel did. It turns out my problem is actually even weirder than his, I am trying to build an FFI binding for a library to format data packets for a network coprocessor that's ARM architecture, from an embedded CPU that's RISC-V, being developed on an x86_64 machine.

So in this case, neither host nor target is the architectural binding I'm looking to generate. That being said, the vendor's C API for their ARM-based coprocessor is "oblivious" to all of this, and people have used it successfully from various ARM and x86 hosts and it's worked, likely because they don't do anything too arcane with respect to packing data into structs, and thus the mismatch of host v. target in the C API hasn't been a problem (afaik).

My final solution to this was to just run bindgen from the command line on the x86_64 host and commit the output as a static artifact. Ugly, but probably OK given that this is essentially what everyone has been doing when they target the C API from C.

emilio pushed a commit that referenced this issue Feb 21, 2020
I spent an afternoon scratching my head on this one before I ran
into #1728.

Since the error message welcomes PRs...
alistair23 added a commit to westerndigitalcorporation/spdm-utils that referenced this issue Nov 8, 2023
In order to avoid errors like this when cross compiling:

    error: unknown target triple 'riscv32imc-unknown-none-elf', please use -triple or -arch

we pass the host target to clang instead of the target.

See rust-lang/rust-bindgen#1728 for the
upstream issue.

Signed-off-by: Alistair Francis <[email protected]>
alistair23 added a commit to westerndigitalcorporation/spdm-utils that referenced this issue Nov 9, 2023
In order to avoid errors like this when cross compiling:

    error: unknown target triple 'riscv32imc-unknown-none-elf', please use -triple or -arch

we pass the host target to clang instead of the target.

See rust-lang/rust-bindgen#1728 for the
upstream issue.

Signed-off-by: Alistair Francis <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants