cargo
cargo copied to clipboard
Per-target profiles?
https://github.com/rust-lang/cargo/pull/4817
This commit enables incremental compilation by default […] A
profile.dev.incremental
field is added toCargo.toml
to disable it on a per-project basis (in case of bugs).
I was hoping to use something like this:
[target.'cfg(windows)'.profile.dev]
incremental = false
to work around https://github.com/rust-lang/rust/issues/47186, but looking at src/cargo/util/toml/mod.rs
it seems that target.cfg
sections can only be combined with dependencies, not other sections like profile
.
Would it make sense to add support for this?
I made a different work-around in Servo, have mach
(the wrapper script that normally calls Cargo) set CARGO_INCREMENTAL=0
on Windows.
So there’s no pressing need to implement this as far as Servo is concerned. But maybe it could still be useful for other use cases.
In my use case , I need this feature to work around wasm32 related issue: https://github.com/rust-lang/rust/issues/47643
LTO is currently broken on armv7
, so I'd like such a feature to use fat LTO on x86_64
releases, but disable it elsewhere.
I have a use-case for this too: I'd like to minimize code size for WASM targets, which means panic=abort, lto, opt-level=s
, but for native targets I'd rather have different trade-offs.
I have my own usecase for this: our company is using VS 2015 and we encounter this issue: https://github.com/briansmith/ring/issues/1031
My workaround while waiting for the decision to update VS is to do:
[profile.release.package.ring]
opt-level = 0
debug-assertions = false
but it impacts Linux as well, and it's a pity
While waiting for an actual / true solution, I have posted a hacky workaround, that may suit some people / use-cases:
- https://users.rust-lang.org/t/how-to-modify-profile-release-only-for-a-target/48811/3?u=yandros
I eagerly need this, do we want to still do it?
Same here, specifically
[target."cfg(macos)".profile.dev]
split-debuginfo = "unpacked"
So it's only turned on for macs where it matters.
If cargo adds a config item, it really should work for everyone, even if ignored. Here the build is unhappy on Linux.
I have another wasm related use case our code runs some (in wasm) tests expressly slow if no optimizations are enabled.
In some of the more extreme cases setting opt-level=2
did lead to a speed up by a factor of over 10. But only for the wasm32 tests. For the x86_64 it's a net slow down in test speed by often around ~20%.
As a side note: This is not limited to wasm32
but appears also on android targets.
So being able to do:
[target.'cfg(any(target_arch="wasm32", target_os="android"))'.profile.dev]
opt-level = 2
[target.'cfg(any(target_arch="wasm32", target_os="android"))'.profile.test]
opt-level = 2
would be grate.
But there are some open questions:
- interactions with workspaces
- interaction with other scopes e.g. can we do
target.<...>.profile.dev.package.foo
- given that it behaves like a
profile
directive shouldn't it beprofile.dev.target.<...>
In the meantime i think you can use rustflags with the -C
command like so:
rustflags = [ "-C", "opt-level=z", "-C", "codegen-units=1" ]
That should help
I'm on the same boat. For example it would be great to change the profile according to Rust version like this:
[cfg(version("1.59")).profile.release]
strip = true
For now, writing this option will not compile for versions below 1.58.
This is definitely needed for WASM/Non-WASM build preferences.
Those who wish to make cross-platform binaries ideally need differing targets.
This is definitely needed for WASM/Non-WASM build preferences. Those who wish to make cross-platform binaries ideally need differing targets.
Agreed. I just ran into this.
It's possible to do some things in Cargo build based on "target_arch". But you can't write something like:
[target.'cfg(target_arch != "host_arch")'.dependencies]
There's no way to tell Cargo "do this differently when cross-compiling". Which is usually a situation in which things are different. So I'd suggest adding a feature for that.
I would use this to optimize for size in WASM builds and speed in native builds.
Could someone help me understand why defining a new profile that sets the needed fields is not sufficient?
Could someone help me understand why defining a new profile that sets the needed fields is not sufficient?
How might one do this with profiles?
I think most of everyone here is seeking to minify their WASM builds. How one would create a "minified" WASM build, and a regular native build, with profiles?
The reason I give this feature request a big thumbs up is because I want to strip debug/panic=abort/etc. for wasm build where the bundle size is a concern, but keep all that good information available on native builds.
This is the current solution I do.
# SURE would be great if I could only apply these settings ONLY to WASM!
# e.g. [profile.'cfg(target_arch = "wasm32")'.release]
# Unfortunately, these settings must apply to native/wasm/etc. bc https://github.com/rust-lang/cargo/issues/4897
[profile.release]
panic = "abort"
lto = true
codegen-units = 1
opt-level = 'z'
You can do this though: https://github.com/SUPERCILEX/bevy-vs-pixi/blob/aef22bab8584d8257d34c16e189f9211360a70b9/Cargo.toml#L33-L42
[profile.release]
lto = true
codegen-units = 1
strip = true
panic = "abort"
[profile.web-release]
inherits = "release"
opt-level = "s"
strip = "debuginfo"
And run cargo build --target wasm32-unknown-unknown --profile web-release
. Thanks @SUPERCILEX!
See Custom profiles for more.
Well that certainly satisfies me. Didn't know that was possible.
Custom profiles was stabilized in 1.57, 3 years after this issue was created. In general, there are a lot in rust releases and not obvious how all they can solve a specific problem in front of you.
This might become more relevant with profile rustflags (#10271), because the rustflags to set might be scpecific to the platform you're building for, e.g.:
[target.'cfg(target_arch="riscv64imac")'.profile.dev]
rustflags = ["-C", "target-feature=+relax", "-C", "link-arg=--relax-gp"]
Some things, like the link-arg
can currently be done with a custom build script, but others like target-feature
don't seem to be allowed in build scripts. Having to use a build script to set rustflags per target also seems unnecessarily complex.
One issue with this actually still exists @epage :
warning: profiles for the non root package will be ignored, specify profiles at the workspace root:
package: /Users/simbleau/git/nova/client/Cargo.toml
workspace: /Users/simbleau/git/nova/Cargo.toml
And if you apply this at a workspace-level:
[target.'cfg(target_arch="wasm32")'.profile.dev]
# TODO: Remove when WebGPU is no longer an unstable
rustflags = ["--cfg", "web_sys_unstable_apis"]
It will affect all downstream members.
OR will it? Actually, to my surprise: It doesn't!
When I tried putting this profile at the room level workspace Cargo.toml, and I had a sub member that I compile to wasm32. It appars the flags don't even apply to the sub members, which seems like a bug.
Either way, I don't think this looks good!