cross: cross picking up wrong target options in cargos config.toml

I’ve added a [target.target.x86_64-unknown-linux-gnu] section to my $HOME/.cargo/config.toml. If i am now using cross to compile for a different target, say cross build --target aarch64-unknown-linux-gnu, the build picks up the config for x86_64-unknown-linux-gnu.

In my case, i’ve configured

oliver@machine ~> /bin/cat ~/.cargo/config.toml
[target.x86_64-unknown-linux-gnu]
linker = "/usr/bin/clang"
rustflags = [
  "-C", "target-cpu=native",
  "-C", "link-arg=-fuse-ld=/home/oliver/.local/bin/mold"
]

And the build fails with

oliver@machine ~> cross build --target aarch64-unknown-linux-gnu --release
info: syncing channel updates for '1.56.0-x86_64-unknown-linux-gnu'
  1.56.0-x86_64-unknown-linux-gnu unchanged - rustc 1.56.0 (09c42c458 2021-10-18)
error: linker `/usr/bin/clang` not found
  |
  = note: No such file or directory (os error 2)

doesn’t work with rust 1.57.0 either. cross version 0.2.1

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 12
  • Comments: 34 (20 by maintainers)

Most upvoted comments

I’ll try to get in a fix for this. Not sure exactly what is happening but have an idea how to solve it.

Thing is, I don’t want cross to pick that file up at all. It currently contains only configuration related to my host machine and target. But when compiling with cross on x86_64 for target aarch64, it picks up the options for the x86_64 target. Also still broken with the the current master version.

Thank you so much for this issue, as this was driving me up the wall why my cross compiling was failing. I’m a little confused as to why it was happening though. I was compiling a simple program, and it would compile until I added “libc” as a dependency. The failure was:

Compiling num-integer v0.1.44
error: linker `/usr/bin/clang` not found
  |
  = note: No such file or directory (os error 2)

This would happen because my ~/.cargo/config.toml contained:

[target.x86_64-unknown-linux-gnu]
linker = "/usr/bin/clang"
rustflags = ["-C", "link-arg=--ld-path=/usr/sbin/mold"]

The confusing thing to me is that I’m targetting aarch64-linux-android. Maybe I’m misunderstanding exactly what cross does, but why does it care about the x86_64-unknown-linux-gnu target when I’m compiling for android?

Anyway, this was surprising to me here and I agree with @oliverbestmann.

We’ve got a working solution in #931 which once rebased will support both ignoring all configurations outside of CARGO_HOME (there’s no good way to ignore that right now without touching the filesystem) and including all configuration files. This is pretty close to being finished. The default behavior would be the same (to avoid breaking changes), but you can specify the desired behavior via:

[build.env]
# This can be "complete", "default", or "ignore".
cargo-config = "complete"

Trying to find the best solution right now, and sorry for the convenience. Working on a few issues but this is pretty high on my priority list.

I work around this by renaming my cargo config and renaming back when cross is finished

Sincerely, Jack

On 5 Jan 2023 at 8:24 AM +0800, Sergii Mikhtoniuk @.***>, wrote:

For users of mold here’s an ugly workaround that worked for me: Create Cross.toml file:

This avoids cross picking up custom linker from ~/.cargo/config.toml

See: https://github.com/cross-rs/cross/issues/621

[build.env] passthrough = [ “CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc”, “RUSTFLAGS”, ] Invoke cross as: RUSTFLAGS=“” cross build --target x86_64-unknown-linux-gnu --release — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

For users of mold here’s an ugly workaround that worked for me:

Create Cross.toml file:

# This avoids cross picking up custom linker from ~/.cargo/config.toml
# See: https://github.com/cross-rs/cross/issues/621

[build.env]
passthrough = [
    "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=x86_64-linux-gnu-gcc",
    "RUSTFLAGS",
]

Invoke cross as:

RUSTFLAGS="" cross build --target x86_64-unknown-linux-gnu --release

So far I only tried per project .cargo/config.toml, haven’t used a global one.

That we can very easily support (as in, skipping it). This is because the cargo subdirectory of the project won’t be used for anything else (unless it’s cargo’s home, in which case we need to mount it), and Docker has ways of preventing subdirectories from being mounted.

To do so, you mount an anonymous data volume at the resulting path, and it prevents the data in bind mount (the volume being mounted on the host) at that subdirectory from being mounted. We actually do this already in cross, for example, to prevent the binaries in cargo home from being mounted.

That should be handled automatically though from the latest main as of #869. This was not in v0.2.2 though. You can use the --verbose flag to confirm this.

It does seem that way. For now I’m just renaming the config with a script. A pity though, an env variable fix would be less cumber some. Thanks for the fast feedback, I wasn’t completely sure if that was the correct linker.