Cargo cross compilation fails when build.rs exists

I am trying to cross compile a simple hello program for targets like x86/arm.
I have specified the 'linker' to link to right binary as per platform arch.

carbo build --taget $taget works fine.

Now, when I just create build.rs (even an empty file), I see failure as:
/work/rust-app6/target/release/build/rust-app6-a90ab9194b51e486/build-script-build: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /work/rust-app6/target/release/build/rust-app6-a90ab9194b51e486/build-script-build)

What is looks like is: build-script-build may be trying to link with target linker instead of native and hence the error related to glibc mismatch.

This sounds like a basic. How do I over come the same?

config.toml is:
[target.arm-unknown-linux-gnueabihf]
linker="/usr/arm-12.3-glibc-2.37/bin/arm-buildroot-linux-gnueabihf-gcc"
rustflags=["-C", "target-feature=-crt-static", "-C", "link-arg=-lgcc"]

[target.x86_64-unknown-linux-gnu]
linker="/usr/x86-10.3-glibc-2.34/bin/x86_64-aruba_buildroot-linux-gnu-gcc"
rustflags=["-C", "target-feature=-crt-static", "-C", "link-arg=-lgcc"]

The build output confirms the fact that, 'build-script-build' binary is using 'linker' from target instead of from host...
error: failed to run custom build command for rust-app6 v0.1.0 (/work/rust-app6)

Caused by:
process didn't exit successfully: CARGO=/usr/local/rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/cargo CARGO_CFG_PANIC=unwind CARGO_CFG_TARGET_ARCH=x86_64 CARGO_CFG_TARGET_ENDIAN=little CARGO_CFG_TARGET_ENV=gnu CARGO_CFG_TARGET_FAMILY=unix CARGO_CFG_TARGET_FEATURE=fxsr,sse,sse2 CARGO_CFG_TARGET_HAS_ATOMIC=16,32,64,8,ptr CARGO_CFG_TARGET_OS=linux CARGO_CFG_TARGET_POINTER_WIDTH=64 CARGO_CFG_TARGET_VENDOR=unknown CARGO_CFG_UNIX='' CARGO_ENCODED_RUSTFLAGS='-Ctarget-feature=-crt-static-Clink-arg=-lgcc' CARGO_MANIFEST_DIR=/work/rust-app6 CARGO_PKG_AUTHORS='' CARGO_PKG_DESCRIPTION='' CARGO_PKG_HOMEPAGE='' CARGO_PKG_LICENSE='' CARGO_PKG_LICENSE_FILE='' CARGO_PKG_NAME=rust-app6 CARGO_PKG_README=README CARGO_PKG_REPOSITORY='' CARGO_PKG_RUST_VERSION='' CARGO_PKG_VERSION=0.1.0 CARGO_PKG_VERSION_MAJOR=0 CARGO_PKG_VERSION_MINOR=1 CARGO_PKG_VERSION_PATCH=0 CARGO_PKG_VERSION_PRE='' DEBUG=false HOST=x86_64-unknown-linux-gnu LD_LIBRARY_PATH='/work/rust-app6/target/release/deps:/work/rust-app6/target/release:/usr/local/rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib:/usr/local/rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib' NUM_JOBS=6 OPT_LEVEL=3 OUT_DIR=/work/rust-app6/target/x86_64-unknown-linux-gnu/release/build/rust-app6-656cf34c8436d9fd/out PROFILE=release RUSTC=/usr/local/rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustc **RUSTC_LINKER=/usr/x86-10.3-glibc-2.34/bin/x86_64-aruba_buildroot-linux-gnu-gcc** RUSTDOC=/usr/local/rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/rustdoc TARGET=x86_64-unknown-linux-gnu **/work/rust-app6/target/release/build/rust-app6-a90ab9194b51e486/build-script-build** (exit status: 1)
--- stderr
/work/rust-app6/target/release/build/rust-app6-a90ab9194b51e486/build-script-build: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /work/rust-app6/target/release/build/rust-app6-a90ab9194b51e486/build-script-build)

I think it's a runtime error (the error is issued by the dynamic linker, or loader, not when the program is being produced). the build script is produced, but for some reasons it cannot run due to libc mismatch.

to verify my guess, can you try run /work/rust-app6/target/release/build/rust-app6-a90ab9194b51e486/build-script-build from the shell? you can also try ldd to see what libc it is being linked.

what's your host environment? can you build and run a simple rust program natively (not cross-compiling)?

@nerditation Thanks for the response.
Yes, 'build-script-build' is trying to link with target libc version. Isn't this script supposed to be running on the build machine (to produce/help build targets)? Expectedly, it should only link it with local libs.
Any target built binaries will only be linking with target libs and same will be provided by run time environment when run on the target.

Native compilation works fine with build.rs script.
Just to repeat, If I remove 'build.rs' cross compilation also goes through. (I'm yet to put content into build.rs, so no dependencies on content yet).

yes, that's correct. so I suggest to check the output of ldd, e,g,:

$ ldd /work/rust-app6/target/release/build/rust-app6-a90ab9194b51e486/build-script-build

it might give some clue.

also, it would be helpful if you can provide details about your host environment, e.g. what's the version of OS, linker, gcc/clang, libc, etc.

Here it goes...
libc from build-machine is 2.31, target is 2.34.

aos-dev ➜ /work/rust-app6 $ ldd /work/rust-app6/target/release/build/rust-app6-a90ab9194b51e486/build-script-build
/work/rust-app6/target/release/build/rust-app6-a90ab9194b51e486/build-script-build: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.33' not found (required by /work/rust-app6/target/release/build/rust-app6-a90ab9194b51e486/build-script-build) /work/rust-app6/target/release/build/rust-app6-a90ab9194b51e486/build-script-build: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.32' not found (required by /work/rust-app6/target/release/build/rust-app6-a90ab9194b51e486/build-script-build)
/work/rust-app6/target/release/build/rust-app6-a90ab9194b51e486/build-script-build: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /work/rust-app6/target/release/build/rust-app6-a90ab9194b51e486/build-script-build)
linux-vdso.so.1 (0x00007fff73b8c000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f87f2d7d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f87f2b8b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f87f2dfc000)

aos-dev ➜ /work/rust-app6 $ /lib/x86_64-linux-gnu/libc.so.6
GNU C Library (Ubuntu GLIBC 2.31-0ubuntu9.14) stable release version 2.31.

Clearly, its expecting libc version other than 2.31.

I think the problem is the aruba target (supposedly cross-compiled) and the host (ubuntu) are the same triplet: x86_64-unknown-linux-gnu

this is indeed a corner case. the host and the target are the same triplet but needs different version of system tools and libraries. I don't know what's the "proper" way to configure cargo in this case, generally, cross-rs is the recommended way to cross-compile rust projects, maybe you can try it out:

if I were in similar situation, I would probably just use a different host system, e.g. alpine linux, which uses musl libc instead of gnu libc, thus the triplet is x86_64-unknown-linux-musl, not x86_64-unknown-linux-gnu. there's official docker images for alpine based rust build systems. e.g.

https://hub.docker.com/layers/library/rust/alpine3.19/images/sha256-9af4ed962405e24b37240ce34a2272e40cff99b4f5150cc6a53b03f95d40e6e0

Ok. You are right. It's due to triplet being same.
Unfortunately, I can't change the host here. Rust is just an extension being added.

The other package managers like conan do handles this by providing additional env arguments where 'cross compilation' environment can be effective detected.

So, cargo should be fixed in a way that, 'linker' setting to be used only for target binaries/libs and not for locally run compiler tools/binaries.

That will be pretty useful feature.

yeah, I totally agree.

after some searching, I find out that cargo actually does support such use cases, but they are unstable (for now at least), and I've never used these features, so I suggest you do some experiment yourself. see the target-applies-to-host and host-config section in the "unstable features" chapter:

https://doc.rust-lang.org/cargo/reference/unstable.html

to be fair, I don't think tools like conan uses native toolchains the way cargo handles build scripts. many of them uses some kind of DSL (or scripting languages) for custom building steps and actions. but I'm not a C++ expert, so I might be wrong about this.

Well, as expected, this issue has been reported by many people in same case as like this.. i.e. build-arch==target-arch.
Relevant ones and supposed to be fixed by:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.