Problem
Background, but note that I already know how to work around this for me but am posting for want of a more general solution: I'm using rust on an unsupported macOS target (toolchain installed with macports) for $reasons. Due to missing system symbols like _getentropy() and _clock_gettime, the rust toolchain is built additionally linked against /opt/local/lib/libMacportsLegacySystem.B.dylib which provides these symbols that the standard library now uses since support for older macOS releases was removed.
Compiling a project with transitive dependencies that use std functionality that pulls in a reference to these symbols requires that the cargo be executed as env RUSTFLAGS='-Clink-args=-Wl,/opt/local/lib/libMacportsLegacySystem.B.dylib' cargo build and works great. No problems.
However, due to the logic that cargo uses internally to determine when and where rustflags are forwarded to rustc, this does not work if cargo is executed with an explicit --target, even when the target matches the host (e.g. x86_64-apple-darwin in this case).
I have tried the following methods:
env RUSTFLAGS='...' cargo build --target x86_64-apple-darwin
env CARGO_BUILD_RUSTFLAGS='...' cargo build --target x86_64-apple-darwin
env CARGO_TARGET_X86_64_APPLE_DARWIN_RUSTFLAGS='...' cargo build --target x86_64-apple-darwin
- Specifying
target.x86_64-apple-darwin.rustflags in a newly created .config/cargo.toml (to emphasize that there was no previous such file masking the above)
In all these cases, the provided rust flags are not passed when the linker is invoked in dependency builds (e.g. pcre2-sys fails to compile with errors about a missing _getentropy() symbol).
Debugging with env CARGO_LOG=trace reveals that the flags are picked up, and they're even used for some of the rustc invocations, but critically, they're ignored when it comes to build scripts (which is predominantly where external linker invocations will come in).
I can understand why "normal" RUSTFLAGS are not forwarded to all rustc invocations when --target is used, but I would proffer that the specific combination of CARGO_TARGET_<TRIPLE>_RUSTFLAGS with a matching --target <triple> should be forwarded the same way that RUSTFLAGS is when no --target is passed. (Note here that the project builds successfully when using RUSTFLAGS and no --target, with the correct -Clink-args being forwarded throughout.)
Note also that I am requesting that a solution be possible via the usage of environment variables only, without needing to specify any values in .cargo/config.toml so that this can be used in external build systems. (Indeed, the problem here is that I am calling cargo from a build system that determines the target and always passes --target <triple> to cargo.)
(For the record, I am not reporting this as a "I can't build on this unsupported platform" bug but rather as a "there doesn't seem to be any way to influence the linker behavior of all transitive dependencies in one go with an environment variable" issue only when building for a specific --target triple.)
cc #9743, which identified the issue but ended up being treated as a symptom of the OP's problem rather than the problem itself, and was closed accordingly.
Steps
No response
Possible Solution(s)
- Always pass
CARGO_TARGET_<TRIPLE>_RUSTFLAGS to build scripts when an explicitly provided, matching cargo build --target triple is used
- Extract at least linker-specific flags like
-Clink-args and other -Clink... flags and pass those to build scripts where currently no rustflags are forwarded
Notes
No response
Version
cargo 1.78.0
release: 1.78.0
host: x86_64-apple-darwin
libgit2: 1.7.2 (sys:0.18.2 system)
libcurl: 8.7.1 (sys:0.4.72+curl-8.6.0 system ssl:OpenSSL/3.1.5)
os: Mac OS 10.10.5 [64-bit]
Problem
Background, but note that I already know how to work around this for me but am posting for want of a more general solution: I'm using rust on an unsupported macOS target (toolchain installed with
macports) for $reasons. Due to missing system symbols like_getentropy()and_clock_gettime, the rust toolchain is built additionally linked against/opt/local/lib/libMacportsLegacySystem.B.dylibwhich provides these symbols that the standard library now uses since support for older macOS releases was removed.Compiling a project with transitive dependencies that use std functionality that pulls in a reference to these symbols requires that the cargo be executed as
env RUSTFLAGS='-Clink-args=-Wl,/opt/local/lib/libMacportsLegacySystem.B.dylib' cargo buildand works great. No problems.However, due to the logic that cargo uses internally to determine when and where rustflags are forwarded to
rustc, this does not work if cargo is executed with an explicit--target, even when the target matches the host (e.g.x86_64-apple-darwinin this case).I have tried the following methods:
env RUSTFLAGS='...' cargo build --target x86_64-apple-darwinenv CARGO_BUILD_RUSTFLAGS='...' cargo build --target x86_64-apple-darwinenv CARGO_TARGET_X86_64_APPLE_DARWIN_RUSTFLAGS='...' cargo build --target x86_64-apple-darwintarget.x86_64-apple-darwin.rustflagsin a newly created.config/cargo.toml(to emphasize that there was no previous such file masking the above)In all these cases, the provided rust flags are not passed when the linker is invoked in dependency builds (e.g.
pcre2-sysfails to compile with errors about a missing_getentropy()symbol).Debugging with
env CARGO_LOG=tracereveals that the flags are picked up, and they're even used for some of therustcinvocations, but critically, they're ignored when it comes to build scripts (which is predominantly where external linker invocations will come in).I can understand why "normal" RUSTFLAGS are not forwarded to all rustc invocations when
--targetis used, but I would proffer that the specific combination ofCARGO_TARGET_<TRIPLE>_RUSTFLAGSwith a matching--target <triple>should be forwarded the same way that RUSTFLAGS is when no--targetis passed. (Note here that the project builds successfully when usingRUSTFLAGSand no--target, with the correct-Clink-argsbeing forwarded throughout.)Note also that I am requesting that a solution be possible via the usage of environment variables only, without needing to specify any values in
.cargo/config.tomlso that this can be used in external build systems. (Indeed, the problem here is that I am callingcargofrom a build system that determines the target and always passes--target <triple>tocargo.)(For the record, I am not reporting this as a "I can't build on this unsupported platform" bug but rather as a "there doesn't seem to be any way to influence the linker behavior of all transitive dependencies in one go with an environment variable" issue only when building for a specific
--targettriple.)cc #9743, which identified the issue but ended up being treated as a symptom of the OP's problem rather than the problem itself, and was closed accordingly.
Steps
No response
Possible Solution(s)
CARGO_TARGET_<TRIPLE>_RUSTFLAGSto build scripts when an explicitly provided, matchingcargo build --target tripleis used-Clink-argsand other-Clink...flags and pass those to build scripts where currently no rustflags are forwardedNotes
No response
Version