Don't fail if multiple --targets are passed with same value

Currently rustc will fail if --target is present more than once on command line:

  error: Option 'target' given more than once

That's irrespective what those --targets where pointing to.

Would it be possible to change behavior so rustc fails only if it was passed more than one different value for --target? The idea first appeared in Build fails if target is passed within`RUSTFLAGS` · Issue #11452 · rust-lang/cargo · GitHub but the bottom line is: as rust gains adoption and popularity more and more build tools are starting to support it. As a packager I would love to reuse as much logic between them as possible but sometimes it results in overlapping build flags. It would be good if rustc was more lenient in case there is no actual conflict.

Why are you passing the target in RUSTFLAGS rather than as cargo argument? Cargo knows when it needs to build for the host rather than the target. Cargo also has an unstable feature to allow multiple --target arguments. This feature is meant to build for multiple targets at once, but I would expect it to allow passing the same target multiple times too.

See this comment: Build fails if target is passed within`RUSTFLAGS` · Issue #11452 · rust-lang/cargo · GitHub for explanation of how --target ended in RUSTFLAGS.

Why is the suggestion given there about CARGO_BUILD_TARGET not sufficient?

For the same reason I can't pass --target on cargo command line if --target is already present in RUSTFLAGS -- it will result in --target being added twice to rustc invocation.

The idea is to have one common RUSTFLAGS for both meson and cargo that includes --target (for meson) and not to end up in failure.

Then don't pass --target in RUSTFLAGS. RUSTFLAGS is meant to be passed verbatim to rustc, however the build system needs to be the one deciding if --target is passed to the compiler or not as host dependencies must not get it. You did get the same kind of breakage in a C project if you used clang and then specified the target in CFLAGS if the build system needs to build things for the host. (Except if the build system ignores CFLAGS entirely when compiling for the host, just like cargo if you passed --target or CARGO_BUILD_TARGET to cargo. In that case I did expect the build system to have a way to specify the target independent of CFLAGS too though.)

I do know how to make it build with either cargo or meson. I merely ask if it would be feasible to change rustc behavior in a way that would make automation simpler and easier. If not feel free to reject the request.

Skimming meson's docs it looks like you should be passing this argument in the cross-configuration, not an environment variable:

If you need extra compiler arguments to be used during cross compilation you can set them with [langname]_args = [args]

https://mesonbuild.com/Cross-compilation.html#properties

and

Prefixing the option with build. only affects the build machine configuration, while leaving it unprefixed only affects the host machine configuration.

https://mesonbuild.com/Builtin-options.html#specifying-options-per-machine

The only mention of RUSTFLAGS I can find says:

It is recommended that you do not use these. They are provided purely to for backwards compatibility with other build systems. There are many caveats to their use, especially when rebuilding the project. It is highly recommended that you use the command line arguments instead.

https://mesonbuild.com/Reference-tables.html#compiler-and-linker-flag-environment-variables


So overall something like -Drust_args="['--target=...']" (EDIT: Meson's "host" and Cargo's "host" are the opposite :man_facepalming:)