-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Implemet dependency-specific profiles #5298
Comments
Thanks! I've been reading as much as I can find on what has been expressed around profiles. I have a few initial questions:
I have some thoughts on cleaning up the current implementation, but would love to hear if you have some ideas in mind already! |
Sure yeah I think two feature flags should work just fine! I wouldn't worry too much about For the For docs I think you're right in that a new chapter is best, we haven't documented too many unstable cargo features yet! |
So, the backwards compatibility story is interesting here! Profiles do not affect downstream crates at all, so I think we can actually break stuff here, if we really want to :-)
I'd conservatively restricted new syntax to
I think it's better to preserve metadata output. The test flag is sort-of important, because you get two artifacts for It also seems like we have 11 profiles currently: cargo/src/cargo/core/manifest.rs Lines 192 to 204 in 6817562
Profile includes test , doc , run_custom_build and check fields, which are more like "what to do" and not "what optimization flags to pass". I think a good first step here might be to try to extract these flag into a separate struct, add it as a field to Unit and try to replace branching on profile (like here) with branching on the value of this field.
EDIT: to expand a bit on the last point, I think one the problems of current profile implementation is that we make decisions in cargo, based on the current profile. I'd love to get rid of this profile-based decision making, and the above seems like a first step in that direction :) |
Excellent, that's exactly what I was thinking. It should hopefully simplify things quite a bit. There might be some tricky parts (like |
I think that this probably could generate |
Btw, is there already an issue for "separate debug/release profiles for |
@matklad I have a few questions: I'm finding the result of splitting up the existing Profile struct a little awkward, and not really gaining the benefits I hoped for. I have a new approach that I have been working on that I'm happier with, and just wanted to run it by you:
pub fn target_opts(
&mut self,
pkg: &Package,
target_kind: &TargetKind,
mode: CompileMode,
release: bool,
) -> &TargetOptions {...} Some other questions:
|
Hm, interesting. Another option is, instead of splitting profile, is to try to lift fields like
Seems nifty!
A nice start would be to use the settings from the root profile.
One option is to use |
Question: Do overrides merge settings with higher-level definitions? Or does each override start over with all settings at default? [profile.dev]
opt-level = 3
[profile.dev.overrides.image]
debug = false
[profile.dev.overrides."*"]
debug-assertions = false Does I would assume they merge ( |
Yeah, merging is the most sane behavior I think. |
I was wondering if you could give any suggestions on how to handle the ownership of the struct with all of the target settings (what I would prefer to place the struct directly in the I tried leaving the settings as a reference in the Unit and keeping a cache in the I feel like this shouldn't be so difficult, but |
It's hard to give any advice in the abstract, but I personally would have tried to keep unit as a simple key to what is compiled (package/target, architecture, special flags like test or custom build scripts), and to compute compiler flags on demand. |
Ah, that's very helpful! I've gone down this road and it's working much better. Thanks! |
@matklad I'd like to write some tests that are more precise about exactly which commands get run (and verify no extra commands are run). However, If not, do you have any ideas on a reliable way to implement that? I was thinking of something simple, along the lines of listing the commands and options (and options that should not be there), and it would just check the output from |
@ehuss I think multiple It's also to submit a PR first, and add tests later ;) |
Profile Overrides (RFC #2282 Part 1) Profile Overrides (RFC #2282 Part 1) WIP: Putting this up before I dig into writing tests, but should be mostly complete. I also have a variety of questions below. This implements the ability to override profiles for dependencies and build scripts. This includes a general rework of how profiles work internally. Closes #5298. Profile overrides are available with `profile-overrides` set in `cargo-features` in the manifest. Part 2 is to implement profiles in config files (to be in a separate PR). General overview of changes: - `Profiles` moved to `core/profiles.rs`. All profile selection is centralized there. - Removed Profile flags `test`, `doc`, `run_custom_build`, and `check`. - Removed `Profile` from `Unit` and replaced it with two enums: `CompileMode` and `ProfileFor`. This is the minimum information needed to compute profiles at a later stage. - Also removed `rustc_args`/`rustdoc_args` from `Profile` and place them in `Context`. This is currently not very elegant because it is a special case, but it works. An alternate solution I considered was to leave them in the `Profile` and add a special uber-override layer. Let me know if you think it should change. - Did some general cleanup in `generate_targets`. ## Misc Fixes - `cargo check` now honors the `--release` flag. Fixes #5218. - `cargo build --test` will set `panic` correctly for dependences. Fixes #5369. - `cargo check --tests` will no longer include bins twice (once as a normal check, once as a `--test` check). It only does `--test` check now. - Similarly, `cargo check --test name` no longer implicitly checks bins. - Examples are no longer considered a "test". (See #5397). Consequences: - `cargo test` will continue to build examples as a regular build (no change). - `cargo test --tests` will no longer build examples at all. - `cargo test --all-targets` will no longer build examples as tests, but instead build them as a regular build (now matches `cargo test` behavior). - `cargo check --all-targets` will no longer check examples twice (once as normal, once as `--test`). It now only checks it once as a normal target. ## Questions - Thumbs up/down on the general approach? - The method to detect if a package is a member of a workspace should probably be redone. I'm uncertain of the best approach. Maybe `Workspace.members` could be a set? - `Hash` and `PartialEq` are implemented manually for `Profile` only to avoid matching on the `name` field. The `name` field is only there for debug purposes. Is it worth it to keep `name`? Maybe useful for future use (like #4140)? - I'm unhappy with the `Finished` line summary that displays `[unoptimized + debuginfo]`. It doesn't actually show what was compiled. Currently it just picks the base "dev" or "release" profile. I'm not sure what a good solution is (to be accurate it would need to potentially display a list of different options). Is it ok? (See also #4140 for the wrong profile name being printed.) - Build-dependencies use different profiles based on whether or not `--release` flag is given. This means that if you want build-dependencies to always use a specific set of settings, you have to specify both `[profile.dev.build_override]` and `[profile.release.build_override]`. Is that reasonable (for now)? I've noticed some issues (like #1774, #2234, #2424) discussing having more control over how build-dependencies are handled. - `build --bench xxx` or `--benches` builds dependencies with dev profile, which may be surprising. `--release` does the correct thing. Perhaps print a warning when using `cargo build` that builds benchmark deps in dev mode? - Should it warn/error if you have an override for a package that does not exist? - Should it warn/error if you attempt to set `panic` on the `test` or `bench` profile? ## TODO - I have a long list of tests to add. - Address a few "TODO" comments left behind.
If I want to build all external crates in release mode (when building my crate in debug mode), would this require writing a profile for every external crate? Or is there a catch-all way to do this? |
@Boscop the current syntax for catch all is |
So this applies to "all crates that aren't this crate", right? |
@Boscop |
Thanks, but it doesn't seem to be working with nightly 03-06.. Any idea which nightly is the earliest to support this? (I only have a 16kb/s connection for now, that's why I'm still on the old nightly..) When I add it to |
@Boscop it won't show up in nightly until someone (manually) updates Cargo in the Rust repository. I don't know when that will happen. |
@ehuss Thanks, I updated to nightly-05-04, and I have this in my Cargo.toml: cargo-features = ["profile-overrides"]
[profile.dev.overrides."*"]
opt-level = 3 But it still complains:
But I have that key, why am I still getting the error? |
@Boscop |
Ah, thanks, I put it before |
But my application has the exact same CPU usage in debug build ( |
RFC: rust-lang/rfcs#2282
Tracking issue: rust-lang/rust#48683
cc @ehuss you wanted to work on this, so let's make this issue a point of coordination.
I'll try to write some mentoring docs later today! Cargo's current profile implementation has a certain historical linage, so the first step here might be to just clean up an existing implementation :)
The text was updated successfully, but these errors were encountered: