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.