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

Tracking Issue for profile-rustflags #10271

Open
4 tasks
ehuss opened this issue Jan 7, 2022 · 11 comments
Open
4 tasks

Tracking Issue for profile-rustflags #10271

ehuss opened this issue Jan 7, 2022 · 11 comments
Labels
A-profiles Area: profiles A-rustflags Area: rustflags C-tracking-issue Category: A tracking issue for something unstable. S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted. S-needs-mentor Status: Issue or feature is accepted, but needs a team member to commit to helping and reviewing. S-waiting-on-feedback Status: An implemented feature is waiting on community feedback for bugs or design concerns. Z-profile-rustflags Nightly: profile-rustflags
Projects

Comments

@ehuss
Copy link
Contributor

ehuss commented Jan 7, 2022

Summary

Original issue: #7878
Implementation: #10217
Documentation: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#profile-rustflags-option

The profile-rustflags feature allows setting RUSTFLAGS per-profile.

Unresolved Issues

  • How should things interact with rustdoc? If there is a flag that is required to correctly build a project, then cargo test may fail if they aren't passed to rustdoc. However, rustdoc doesn't accept all of rustc's flags. Adding a rustdocflags option seems to be adding more unwanted complexity, though.
  • This introduces potential backwards-compatibility hazards. For example, when Cargo adds new features or changes the way it invokes rustc, that can interfere with pre-existing flags. Is documenting this sufficient?
  • What should the behavior be with build scripts and proc-macros? Those have historically been a pain point with rustflags. Perhaps there should be a default build-override.rustflags = [].
  • Profile rustflags are not considered as part of TargetInfo, which impacts feature resolution and other things.

Future Extensions

No response

About tracking issues

Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

@bstrie
Copy link
Contributor

bstrie commented Apr 29, 2022

I see something like this as necessary for the usability of RFC 3028 (artifact dependencies): #9096 . Historically Cargo has not supported passing arbitrary flags in profile overrides because many of them made no sense to pass to a dependency (e.g. -C linker). However, with binary artifacts, now literally all rustc flags become something that users will have valid reasons to want to specify. Currently this leads to lots of pain and workarounds with trying to use binary dependencies, either by hacking things up with Cargo config files (which don't work in all cases) or build scripts (which don't support all flags) or environment variables (which are difficult to set in all circumstances).

That doesn't mean that this feature is the only way to satisfy this need, but I think anything that does satisfy this need would have to be functionally equivalent to profile-rustflags.

@Qubasa
Copy link

Qubasa commented Sep 29, 2022

cargo-features = ["per-package-target", "profile-rustflags"] don't work together.
By this I mean the target does not get applied when profile-rustflags get used.

cargo-features = ["per-package-target", "profile-rustflags"]

[package]
name = "perf_kernel"
version = "0.1.0"
authors = ["Luis Hebendanz <luis.nixos@gmail.com>"]
edition = "2021"
forced-target = "x86_64-unknown-none"

[profile.dev]
rustflags = [ "-C", "link-args=--image-base=0x200000" ]

Will fail with gcc: error: unrecognized command-line option '--image-base=0x200000' even though target defines ld.lld as linker

@MauriceKayser
Copy link

MauriceKayser commented Jan 28, 2023

I can not get this to work with a no_std crate on Windows with the current nightly. Steps to reproduce the linker issue:

  1. Create a new binary project.
  2. Cargo.toml:
    [... default content ...]
    
    [profile.release]
    panic = "abort"
  3. src/main.rs:
    #![no_main]
    #![no_std]
    
    #[panic_handler]
    fn rust_begin_unwind(_: &core::panic::PanicInfo) -> ! { loop {} }
    
    #[no_mangle]
    fn WinMainCRTStartup() -> u32 { 0 }
  4. .cargo/config.toml:
    [target.'cfg(target_env = "msvc")']
    rustflags = [ "-C", "link-args=/Debug:None /SubSystem:Windows" ]
  5. Compile with cargo build --release --target x86_64-pc-windows-msvc -Z build-std=core -> it succeeds.
  6. Delete .cargo/config.toml.
  7. Cargo.toml:
    cargo-features = [ "profile-rustflags" ]
    
    [... previous content ...]
    
    rustflags = [ "-C", "link-args=/Debug:None /SubSystem:Windows" ]
  8. Compile with cargo build --release --target x86_64-pc-windows-msvc -Z build-std=core -> it succeeds.
  9. Delete the target build artifact directory to enforce a complete recompilation.
  10. Compile with cargo build --release --target x86_64-pc-windows-msvc -Z build-std=core -> it fails:
    Compiling compiler_builtins v0.1.85
    Compiling rustc-std-workspace-core v1.99.0
    
    error: linking with `link.exe` failed: exit code: 1120
    [... linker command arguments ...]
    note: msvcrt.lib(exe_winmain.obj) : error LNK2019: unresolved external symbol WinMain referenced in function "int __cdecl __scrt_common_main_seh(void)" (?__scrt_common_main_seh@@YAHXZ)
    build_script_build-[RandomHash].exe : fatal error LNK1120: 1 unresolved externals

It seems like it tries to link the things that should be excluded via no_std, like msvcrt and WinMain.
By the way, is it possible to use something like cfg(target_env = "msvc") with profile-rustflags?

@ehuss
Copy link
Contributor Author

ehuss commented Jan 28, 2023

As mentioned in the unresolved section, profile rustflags get applied to build scripts. You can override that with:

[profile.dev.build-override]
rustflags = []

Also, I might suggest using the #[windows_subsystem] attribute instead of setting it manually.

Conditional settings are not supported in profiles, you'll need to use separate profiles.

In the future, please file a new issue if you have a question or problem. See the "About tracking issues" section above.

@MauriceKayser
Copy link

Sorry, I will read more carefully next time and create a separate issue instead. I did not realize that my example contained a build script, thanks for the hint! The #![windows_subsystem = "windows"] seems to be ignored, if applied to the example - it will look for mainCRTStartup, the console subsystem main function, instead of WinMainCRTStartup, the windows subsystem main function.

@ehuss ehuss added S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted. S-waiting-on-feedback Status: An implemented feature is waiting on community feedback for bugs or design concerns. S-needs-mentor Status: Issue or feature is accepted, but needs a team member to commit to helping and reviewing. labels Apr 25, 2023
@simbleau
Copy link

simbleau commented Dec 5, 2023

I am getting an issue where workspace rustflags don't work for sub-crates.

For example, - in the workspace Cargo.toml:

# TODO: Remove when WebGPU is no longer an unstable
[target.'cfg(target_arch="wasm32")'.profile.dev]
rustflags = ["--cfg", "web_sys_unstable_apis"]

Subcrates won't compile that depend on this:

error[E0599]: no method named `gpu` found for struct `WorkerNavigator` in the current scope
   --> /Users/simbleau/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wgpu-0.17.2/src/backend/web.rs:950:18
    |
947 | /             global
948 | |                 .unchecked_into::<web_sys::WorkerGlobalScope>()
949 | |                 .navigator()
950 | |                 .gpu()
    | |                 -^^^ method not found in `WorkerNavigator`
    | |_________________|

cargo build --verbose confirms the flags are not passed down correctly.

Related: #4897

@weihanglo
Copy link
Member

# TODO: Remove when WebGPU is no longer an unstable
[target.'cfg(target_arch="wasm32")'.profile.dev]
rustflags = ["--cfg", "web_sys_unstable_apis"]

This is not a valid key in Cargo.toml. You might get a warning like

warning: /path/to/pkg/Cargo.toml: unused manifest key: target.cfg(target_arch="wasm32").profile

@simbleau
Copy link

simbleau commented Dec 5, 2023

# TODO: Remove when WebGPU is no longer an unstable
[target.'cfg(target_arch="wasm32")'.profile.dev]
rustflags = ["--cfg", "web_sys_unstable_apis"]

This is not a valid key in Cargo.toml. You might get a warning like

warning: /path/to/pkg/Cargo.toml: unused manifest key: target.cfg(target_arch="wasm32").profile

Confused what you mean by it's not a key.

It's documented here: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#profile-rustflags-option

@intelfx
Copy link

intelfx commented Mar 20, 2024

Can we also have per-profile environment variables, for CFLAGS/CXXFLAGS? Before I make a corresponding issue, is this idea going to fly at all?

Rationale: RUSTFLAGS alone is not enough to have, for example, cross-language LTO on the release profile.

@weihanglo
Copy link
Member

Depends on how you use profile. For now we can leverage --config <alternative-config.toml> without waiting for such feature being implemented.

BTW I feel like this has been brought up, but couldn't find an issue of it.

intelfx added a commit to intelfx/bin that referenced this issue Apr 3, 2024
Wrapper for `cargo --profile=release` with a custom config, to make up
for absence of per-profile options (flags, env) in (stable) Cargo.
intelfx added a commit to intelfx/bin that referenced this issue Apr 3, 2024
Wrapper for `cargo --profile=release` with a custom config, to make up
for absence of per-profile options (flags, env) in (stable) Cargo.
intelfx added a commit to intelfx/dotfiles that referenced this issue Apr 3, 2024
Submodule bin 9be07f2..bc34b46:
  > wrappers: cargo-rel: workaround for rust-lang/cargo#10271 and co.
  > lib: bump
  > wrappers: komake: build an in-tree kernel module as an out-of-tree one
  > git/misc: git-delete-refs: tee delete commands on stderr
  > devel: unfuck.sh: cleanup
  > devel: replace unfuck-*.sh with unfuck.sh
  > misc: syncthing-curl: do not `curl -f`
intelfx added a commit to intelfx/dotfiles that referenced this issue Apr 7, 2024
Submodule bin 9be07f2..74e6e1c:
  > etc/easyrsa: add common easyrsa vars for intelfx.name PKIs
  > lib: bump
  > git/misc: git-edit: use `git add --intent-to-add` on all changed files
  > Merge branch 'master' of github.com:intelfx/bin
  > build-*-full: allow specifying SAN as a command option
  > easyrsa: init-pki: fix bogus unset when printing the new PKI status
  > easyrsa: init-pki: actually find vars.example outside of $EASYRSA_PKI
  > easyrsa: export(pkcs): only check ca.crt
  > tools: easyrsa: import easyrsa 3.1.7
  > misc: promote pkgbuild-* to misc
  > wrappers: lsblk-pt: `lsblk` with columns about partitions themselves
  > pass: get.bash: add pass(1) extension to retrieve specific fields in "key: value" format
  > util: disk-fstrim: always skip BIOS boot partitions (gdisk type EF02)
  > util: disk-fstrim: use lsblk instead of blkid
  > util: disk-fstrim: clean up variable usage in pattern contexts
  > util: disk-fstrim: clean up locals handling
  > wrappers: cargo-rel: workaround for rust-lang/cargo#10271 and co.
  > lib: bump
  > wrappers: komake: build an in-tree kernel module as an out-of-tree one
  > git/misc: git-delete-refs: tee delete commands on stderr
  > devel: unfuck.sh: cleanup
  > devel: replace unfuck-*.sh with unfuck.sh
  > misc: syncthing-curl: do not `curl -f`
@kamulos
Copy link

kamulos commented Apr 9, 2024

Depends on how you use profile. For now we can leverage --config <alternative-config.toml> without waiting for such feature being implemented.

BTW I feel like this has been brought up, but couldn't find an issue of it.

@weihanglo this sounds like a great solution, I just cant get it to work reasonably

let's say I have a default configuration that is used during development and in the dev profile. This should be a default and work without an extra command line which could be forgotten, because I want to put things like sanitizer support in there.

So this is my .cargo/config.toml:

[build]
target = "x86_64-unknown-linux-gnu"
rustflags = ["-Z", "sanitizer=address"]

[env]
BUILD_PROFILE = "debug"

Now in my build system I want to build the release build with a different configuration and the stable compiler. I create a new .cargo/config-release.toml with the following content:

[env]
BUILD_PROFILE = "release"

And use the command cargo +stable --config .cargo/config-release.toml to build it. Now it will still fall back to the .cargo/config.toml which will not work because there is no sanitizer in the stable compiler. Only once I delete the .cargo/config.toml, it will start using the config-release.toml.

How would you approach such a use case? I have a mixed C and Rust application, that needs different rustflags and environment variables for the debug and release builds.

I am really struggling with getting that right. Another really unfortunate thing with defining the rustflags in the config.toml, everytime I set the RUSTFLAGS env variable all the entries in the config.toml are silently thrown away. I just realized today, that I am setting RUSTFLAGS="${RUSTFLAGS} -D warnings" in the CI and by doing this am disabling all the flags I set in the config.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-profiles Area: profiles A-rustflags Area: rustflags C-tracking-issue Category: A tracking issue for something unstable. S-needs-design Status: Needs someone to work further on the design for the feature or fix. NOT YET accepted. S-needs-mentor Status: Issue or feature is accepted, but needs a team member to commit to helping and reviewing. S-waiting-on-feedback Status: An implemented feature is waiting on community feedback for bugs or design concerns. Z-profile-rustflags Nightly: profile-rustflags
Projects
Status: Unstable, baking
Roadmap
  
Unstable, baking
Development

No branches or pull requests

8 participants