Skip to content

There is no way to set RUSTFLAGS for build scripts (or proc macros) when cross-compiling #4423

@RalfJung

Description

@RalfJung
Member

The cargo documentation environment-variables.md says

RUSTFLAGS - A space-separated list of custom flags to pass to all compiler invocations that Cargo performs. In contrast with cargo rustc, this is useful for passing a flag to all compiler instances.

This is wrong, unfortunately. The flag is not passed to all compiler instances: When cross-compiling (i.e., when --target is set), the flag is not passed to build scripts. It seems there is currently no way to pass anything to build scripts when --target is set, which clearly is a feature gap. Cargo should provide a way to set flags for build scripts even when cross-compiling.

One may be tempted to set CARGO_TARGET_<target>_RUSTFLAGS or target.<target>.rustflags, but that does not work either.

Also see #9453, #9452.

Activity

alexcrichton

alexcrichton commented on Aug 22, 2017

@alexcrichton
Member

This is currently intentional as it is the conservative choice of how to interpret RUSTFLAGS, but it's always possible to expand it!

RalfJung

RalfJung commented on Aug 22, 2017

@RalfJung
MemberAuthor

This is currently intentional as it is the conservative choice of how to interpret RUSTFLAGS, but it's always possible to expand it!

So the fact that whether RUSTFLAGS applies to build scripts or not depends on whether --target was set or not is how things ought to be? That's a really surprising side-effect of setting a target! The option should be called --target-and-ignore-rustflags-for-buildscripts, then... ;)
To make matters worse, this behavior is actually stable and hence can probably never be changed :(

Actually the code says this is just a hack:

    // We *want* to apply RUSTFLAGS only to builds for the
    // requested target architecture, and not to things like build
    // scripts and plugins, which may be for an entirely different
    // architecture. Cargo's present architecture makes it quite
    // hard to only apply flags to things that are not build
    // scripts and plugins though, so we do something more hacky
    // instead to avoid applying the same RUSTFLAGS to multiple targets
    // arches:

It seems that what we really want is two environment variables; one applied to plugins/build scripts and one applied to the "actual" code. (And maybe a third applied to both.) However, that's currently not easy to do because the function setting the flags has no idea whether this is for the host or target. Correct? That's what this comment sounds like.

Judging from trouble that xargo has wrt. plugins, I assume the problem is that when I just run cargo build, the kind is actually Kind::Host for everything? IOW, cargo build and cargo build --target $host_arch are very different. Not sure why this is, sounds like a bug to me.

One "easy" fix for this problem would be to double-down on the existing hack, and change env_args such that rather than not passing any arguments when it detects a build script in a cross-build, it just goes looking for a different environment variable, like RUSTFLAGS_HOST or so. That would be enough to solve my problem, but I'm not sure if you'd be willing to accept such a patch -- and anyway, it'd all still be a hack.
(My problem is described in japaric/xargo#162: I want a way to run cargo build --target <...> such that all compiler invocations have --cap-lint=allow set.)

The alternative I guess is to fix cargo such that kind actually reliably says whether this is a build script or part of the "real" build. Judging from the fact that nobody did this so far, I expect that to be non-trivial, and there may also be good reasons for why things are the way they are right now.

RalfJung

RalfJung commented on Aug 22, 2017

@RalfJung
MemberAuthor

Browsing through the code, I have found other code using Target::for_host to distinguish builds for plugins from builds for the target. What is the reason that env_args relies on a different signal?

alexcrichton

alexcrichton commented on Aug 23, 2017

@alexcrichton
Member

er just to be clear, none of this behavior is a bug today, it's all intentional. RUSTFLAGS is intended to only apply to the "final artifact" which when cross compiling doesn't account for build scripts and such. We left ourselves room to grow other environment variables, though, so we can certainly add some more!

RalfJung

RalfJung commented on Aug 23, 2017

@RalfJung
MemberAuthor

RUSTFLAGS is intended to only apply to the "final artifact" which when cross compiling doesn't account for build scripts and such

But that's not what happens. If I run just cargo build, RUSTFLAGS is applied to build scripts and the artifact alike.
The entire behavior in cross-compilation vs. "native" compilation mode is pretty inconsistent. Also see the xargo README which observes that

When using compiler plugins (e.g. serde_derive) the target triple must be provided even when compiling for the host platform due to the way cargo handles compiler plugins. I.e., use xargo build --target x86_64-unknown-linux-gnu instead of just xargo build. (Surprisingly, these commands are NOT the same to Cargo.)

RalfJung

RalfJung commented on Aug 23, 2017

@RalfJung
MemberAuthor

Well anyway I submitted #4428 which tries to not touch this existing logic, but is just enough to fix my problem. Some other day I'll try to distill my trouble with this logic into a separate bugreport. ;)

104 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-build-scriptsArea: build.rs scriptsA-cross-compilingArea: using --target flag for other platformsA-rustflagsArea: rustflagsC-enhancementCategory: enhancementS-needs-designStatus: Needs someone to work further on the design for the feature or fix. NOT YET accepted.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Participants

      @mbrubeck@saurik@ehuss@michaelforney@epage

      Issue actions

        There is no way to set RUSTFLAGS for build scripts (or proc macros) when cross-compiling · Issue #4423 · rust-lang/cargo