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

Indicate to build scripts that the crate they are being run for is being built for the host #5755

Open
luser opened this issue Jul 20, 2018 · 7 comments
Labels
A-build-scripts Area: build.rs scripts S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted.

Comments

@luser
Copy link
Contributor

luser commented Jul 20, 2018

cargo sets a number of environment variables when running build scripts, including HOST and TARGET. When running a build script that is used by a crate that's being built for the host (because it's being used by another build script, say) it just gets HOST == TARGET. Similar to #5754, this can cause issues when a build script wants to compile C code. In a non-cross-compile, there's no useful way to communicate to the cc crate that a certain compiler and CFLAGS should be used for host compilation vs. target compilation. The canonical example is address sanitizer. For asan builds we have -fsanitize=address in CFLAGS, but we don't want to pass that when compiling objects that are linked into build scripts.

I ran into this problem while fixing the Firefox build to pass our compiler and flags to cargo so that build scripts using cc would compile their sources properly. Specifically, the libloading crate compiles a C source file on Linux. libloading is used by the clang-sys crate for runtime loading of libclang, and clang-sys is used by bindgen as part of the stylo build script, so libloading should compile its source file with the host compiler and flags. I was unable to find a workable solution so I just added some hacks to not pass the compiler and flags for our asan builds, which is not great.

Ideally cargo would set an environment variable for build scripts to indicate this scenario, like TARGET_IS_HOST or BUILDING_FOR_HOST (I don't care about the specifics of the name) then the cc crate could detect this and provide some way to set the compiler and cflags separately for this case.

@joshtriplett
Copy link
Member

I'd like to see this as well. Please consider matching the naming conventions that autoconf and meson use for this.

@luser
Copy link
Contributor Author

luser commented Jul 21, 2018

I'd like to see this as well. Please consider matching the naming conventions that autoconf and meson use for this.

Can you elaborate on this?

@joshtriplett
Copy link
Member

@luser autoconf macros commonly set things like CC_FOR_BUILD, for instance. I'm suggesting that cargo should follow existing conventions rather than inventing new ones, wherever possible.

@luser
Copy link
Contributor Author

luser commented Jul 22, 2018

Ah, OK. In the Firefox build we've never moved past autoconf 2.13 so I'm not familiar with the details of its more modern implementation. :)

@glandium
Copy link
Contributor

glandium commented Sep 6, 2018

Note that the autoconf naming conventions are very build-a-compiler-oriented in their meaning of host, target and build, where host is what you'd pass to --target, target is what the compiler that is being built would generate code for (which is biased towards a compiler that can only build for one target, i.e. gcc, not clang), and build is what we usually mean with host.

@jameshilliard
Copy link
Contributor

When running a build script that is used by a crate that's being built for the host (because it's being used by another build script, say) it just gets HOST == TARGET. Similar to #5754, this can cause issues when a build script wants to compile C code. In a non-cross-compile, there's no useful way to communicate to the cc crate that a certain compiler and CFLAGS should be used for host compilation vs. target compilation.

Maybe the host-config feature is what is needed here?

You should be able to set host artifact compilation variables(ie those that are used to compile build scripts that execute on the host system) separately from target variables passed to build scripts on stable toolchains by setting something like this in your env:

__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS="nightly"
CARGO_UNSTABLE_TARGET_APPLIES_TO_HOST="true"
CARGO_TARGET_APPLIES_TO_HOST="false"
CARGO_UNSTABLE_HOST_CONFIG="true"
CARGO_HOST_AR="host-ar"
CARGO_HOST_LINKER="host-gcc"
CARGO_HOST_RUNNER="host-runner"
CARGO_HOST_RUSTFLAGS="$(HOST_RUSTFLAGS)"

@epage epage added the S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted. label Oct 23, 2023
@RalfJung
Copy link
Member

When building with --target, cargo clearly distinguishes between two kinds of crates: those that are build for the host, and those that are built for the target. (This is true even if --target is set to the host target.) The latter have rustc invoked with --target, the former do not. This is crucial for cross-compilation situations; it is also crucial for situations like Miri or rustc bootstrap where "host" may be the same target triple as "target", but will still be a different sysroot (in case of Miri, "host" uses a sysroot that allows actual code generation and not just interpretation; in case of bootstrap, "host" uses the sysroot of the previous stage).

The problem is, build scripts are never told whether the crate they belong to is being built as a host crate or a target crate. This is an issue because some build scripts like to build "build probes" to check whether certain features are supported, and those build probes need to be built with the right flags. Specifically, if a crate C has a build script, then whenever C is used as a target crate, the build probe should use --target, but whenever it is used as a host crate, it should not set --target.

This issue would be elegantly resolved by #11244, but that's a much bigger ask. So maybe in the mean time cargo can just set some sort of environment variable to provide this information to build scripts?

@jameshilliard I don't quite follow how cost-config is useful here, how would the build script now detect whether its crate is a host crate or a target crate? Also from the description of that feature it doesn't look like Miri could make use of it, since it requires the user to change their cargo config?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-build-scripts Area: build.rs scripts S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted.
Projects
None yet
Development

No branches or pull requests

7 participants