rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.34k stars 12.72k forks source link

wasm target not honoring linker set at bootstrap time (1.42.0 and maybe earlier) #70589

Open gyakovlev opened 4 years ago

gyakovlev commented 4 years ago

rust for gentoo linux (the one we ship in official repositories)

here's how we configure wasm target:

[target.wasm32-unknown-unknown]
linker = "lld"

but it still looks for rust-lld for that target by default.

cargo build --release --target=wasm32-unknown-unknown --verbose
   Compiling wasm-test v0.1.0 (/tmp/wasm-test)
     Running `rustc --crate-name wasm_test src/lib.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type cdylib --emit=dep-info,link -C opt-level=3 -C metadata=7a89689720da237e --out-dir /tmp/wasm-test/target/wasm32-unknown-unknown/release/deps --target wasm32-unknown-unknown -L dependency=/tmp/wasm-test/target/wasm32-unknown-unknown/release/deps -L dependency=/tmp/wasm-test/target/release/deps`
error: linker `rust-lld` not found
  |
  = note: No such file or directory (os error 2)

error: aborting due to previous error

error: could not compile `wasm-test`.

Caused by:
  process didn't exit successfully: `rustc --crate-name wasm_test src/lib.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type cdylib --emit=dep-info,link -C opt-level=3 -C metadata=7a89689720da237e --out-dir /tmp/wasm-test/target/wasm32-unknown-unknown/release/deps --target wasm32-unknown-unknown -L dependency=/tmp/wasm-test/target/wasm32-unknown-unknown/release/deps -L dependency=/tmp/wasm-test/target/release/deps` (exit code: 1)

not sure when it started to happen, but it was working as expected before. rustc -Z unstable-options --target=wasm32-unknown-unknown --print target-spec-json

{
  "arch": "wasm32",
  "data-layout": "e-m:e-p:32:32-i64:64-n32:64-S128",
  "default-hidden-visibility": true,
  "dll-prefix": "",
  "dll-suffix": ".wasm",
  "dynamic-linking": true,
  "emit-debug-gdb-scripts": false,
  "env": "",
  "exe-suffix": ".wasm",
  "executables": true,
  "has-elf-tls": true,
  "is-builtin": true,
  "limit-rdylib-exports": false,
  "linker": "rust-lld",
  "linker-flavor": "wasm-ld",
  "lld-flavor": "wasm",
  "llvm-target": "wasm32-unknown-unknown",
  "max-atomic-width": 64,
  "only-cdylib": true,
  "os": "unknown",
  "panic-strategy": "abort",
  "pre-link-args": {
    "gcc": [
      "-Wl,--no-threads",
      "-Wl,-z",
      "-Wl,stack-size=1048576",
      "-Wl,--stack-first",
      "-Wl,--allow-undefined",
      "-Wl,--fatal-warnings",
      "-Wl,--no-demangle",
      "-Wl,--export-dynamic",
      "--target=wasm32-unknown-unknown",
      "-nostdlib",
      "-Wl,--no-entry"
    ],
    "wasm-ld": [
      "--no-threads",
      "-z",
      "stack-size=1048576",
      "--stack-first",
      "--allow-undefined",
      "--fatal-warnings",
      "--no-demangle",
      "--export-dynamic",
      "--no-entry"
    ]
  },
  "relocation-model": "static",
  "simd-types-indirect": false,
  "singlethread": true,
  "target-c-int-width": "32",
  "target-endian": "little",
  "target-pointer-width": "32",
  "tls-model": "local-exec",
  "vendor": "unknown"
}

for some reason target spec still lists rust-lld as preferred linker

Yes, there are ways to mitigate that, like CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_LINKER=lld or RUSTFLAGS="-C linker=/usr/bin/lld

lld is system installed and provides the following files

/usr/bin/lld
/usr/bin/wasm-ld -> lld
/usr/bin/ld64.lld -> lld
/usr/bin/ld.lld -> lld
/usr/bin/lld-link -> lld

if we build using bundled llvm and lld, everything works as expected ofc.

full config.toml, happens on x86_64 as well, so powerpc being primay is irrelevant.

[llvm]
optimize = true
release-debuginfo = false
assertions = false
targets = "WebAssembly;PowerPC;AMDGPU"
experimental-targets = ""
link-shared = true
[build]
build = "powerpc64le-unknown-linux-gnu"
host = ["powerpc64le-unknown-linux-gnu"]
target = ["powerpc64le-unknown-linux-gnu","wasm32-unknown-unknown"]
cargo = "/usr/bin/cargo"
rustc = "/usr/bin/rustc"
docs = false
compiler-docs = false
submodules = false
python = "python3.6"
locked-deps = true
vendor = true
extended = true
tools = ["rustfmt","rls","analysis","src","miri","clippy","cargo",]
verbose = 2
[install]
prefix = "/usr"
libdir = "lib"
docdir = "share/doc/rust-1.42.0-r1"
mandir = "share/man"
[rust]
optimize = true
debug = false
debug-assertions = false
default-linker = "powerpc64le-unknown-linux-gnu-gcc"
parallel-compiler = true
channel = "nightly"
rpath = false
lld = false
backtrace-on-ice = true
[dist]
src-tarball = false
[target.powerpc64le-unknown-linux-gnu]
cc = "powerpc64le-unknown-linux-gnu-gcc"
cxx = "powerpc64le-unknown-linux-gnu-g++"
linker = "powerpc64le-unknown-linux-gnu-gcc"
ar = "powerpc64le-unknown-linux-gnu-ar"
llvm-config = "/usr/lib/llvm/10/bin/llvm-config"
[target.wasm32-unknown-unknown]
linker = "lld"
mati865 commented 4 years ago

Linker configured during Rust compilation is not meant to propagate to the final binary. AFAIK if you want to change default linker you should patch the spec file or use Cargo configuration file.

rjzak commented 2 years ago

I also have the linker issue when compiling for wasm32-wasi on powerpc64le-unknown-linux-gnu, where rust-lld can't be found. Forcing the use of /bin/lld from LLVM seems to work fine. But the PPC64LE port seems to not have rust-lld, whereas x86_64-unknown-linux-gnu does. Is this intentional?