cargo icon indicating copy to clipboard operation
cargo copied to clipboard

Per-target profiles?

Open SimonSapin opened this issue 7 years ago • 22 comments

https://github.com/rust-lang/cargo/pull/4817

This commit enables incremental compilation by default […] A profile.dev.incremental field is added to Cargo.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?

SimonSapin avatar Jan 04 '18 16:01 SimonSapin

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.

SimonSapin avatar Jan 04 '18 16:01 SimonSapin

In my use case , I need this feature to work around wasm32 related issue: https://github.com/rust-lang/rust/issues/47643

edwin0cheng avatar Feb 02 '18 00:02 edwin0cheng

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.

jedisct1 avatar Sep 22 '19 08:09 jedisct1

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.

kornelski avatar May 28 '20 17:05 kornelski

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

Geobert avatar Sep 15 '20 15:09 Geobert

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

danielhenrymantilla avatar Sep 16 '20 11:09 danielhenrymantilla

I eagerly need this, do we want to still do it?

vertexclique avatar Nov 05 '20 11:11 vertexclique

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.

DanielJoyce avatar Apr 13 '21 18:04 DanielJoyce

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 be profile.dev.target.<...>

rustonaut avatar Jun 09 '21 18:06 rustonaut

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

dndll avatar Jun 22 '21 12:06 dndll

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.

kyoheiu avatar Aug 06 '22 06:08 kyoheiu

This is definitely needed for WASM/Non-WASM build preferences.

Those who wish to make cross-platform binaries ideally need differing targets.

simbleau avatar Aug 11 '22 00:08 simbleau

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.

John-Nagle avatar Feb 21 '23 17:02 John-Nagle

I would use this to optimize for size in WASM builds and speed in native builds.

OwenTrokeBillard avatar Aug 15 '23 21:08 OwenTrokeBillard

Could someone help me understand why defining a new profile that sets the needed fields is not sufficient?

epage avatar Oct 17 '23 20:10 epage

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'

simbleau avatar Oct 18 '23 03:10 simbleau

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"

SUPERCILEX avatar Oct 18 '23 03:10 SUPERCILEX

And run cargo build --target wasm32-unknown-unknown --profile web-release. Thanks @SUPERCILEX!

See Custom profiles for more.

weihanglo avatar Oct 18 '23 03:10 weihanglo

Well that certainly satisfies me. Didn't know that was possible.

simbleau avatar Oct 18 '23 14:10 simbleau

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.

epage avatar Oct 18 '23 15:10 epage

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.

Kritzefitz avatar Nov 10 '23 11:11 Kritzefitz

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!

simbleau avatar Dec 05 '23 03:12 simbleau