You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Debugger support in dev profile slows down builds #15931
If we make this change, what do we have to maintain compatibility on and how do we do it?
Would we provide a built-in profile for debugging? If so, new built-in profiles would be a breaking change because built-in profiles can't inherit from other profiles. So if user had a debugging profile that inherits from dev and we made debugging a built-in, their build would fail.
Options:
Allow users to inherit in any profile with some way to deal with cycles. This would allow users to mask the built-in profiles completely.
One way to avoid the masking of built-in profiles is to move all of the built-in profiles into a namespace (e.g. cargo::dev). In place of the built-in profiles would be default profiles that implicitly inherit from the same-named profile in the namespace (cargo::).
Another alternative is to use an existing reserved name. An obvious choice is debug. The challenge here is that build results for dev builds go in target/debug. A naive solution is dev goes in target/dev and debug goes in target/debug. However, if the default profile remains dev, then that would break users expecting to find final artifacts. What if we had a config field like build.target for the default profile for builds (except install / bench) and the default was dynamic, based on the edition? The first problem is users can specify multiple packages at once and there are no editions for a workspace.
Reacted by dishmaker, Ricardo Fernández Serrata and kleines Filmröllchen
We talked about this a little in today's cargo team meeting (notes). Some ideas:
Have dev and debug share the same artifact directory
Intermediate artifacts won't be thrashed
Final artifacts will be thrashed but less likely to happen
Add a new dev profile with a dev artifact directory w/ config for default profile
Breaks for people doing --profile dev
Workout a transition plan for changing the default profile, either breaking people or stretching the meaning of editions and doing it with a workspace edition
This should likely be done as an RFC due to the breakages
Have dev and debug share the same artifact directory
Add a new dev profile with a dev artifact directory w/ config for default profile
In thinking this through more, instead of these being two separate solution options, they could be steps in the process. We can split dev / debug and later move dev out of target-dir. Doing it now or later shouldn't make a difference to the decisions being made or the design. This allows us to move forward without having to figure everything out ahead of time.
My proposed plan for this:
Add a debug profile (maybe even --debug) that is a copy of dev
After sufficient time for debug to percolate out so people can migrate, change dev profile's settings
If needed and if we sign off on it, move dev out of the debugbuild-dir / target-dir
if needed, add a build.profile config field (need to figure out how to define its behavior wrt to install)
At a first glance, I'd say that profiles should be "additive", so rather than removing debuginfo, I'd make sense to me for debug to extend dev and add debuginfo to it. I assume that people using debug care exactly about debuginfo, and most other things from dev should be inherited.
Another thing to consider to help alleviate this issue is simply "make debuginfo generation faster". I wouldn't say it's exactly low-hanging fruit, but there is a lot of wasteful work being done repeatedly during each build. If we could remove or cache that, then the difference between debuginfo = 2 and debuginfo = "line-tables-only" (which I assume would be the default for the dev profile), wouldn't have to be so large.
At a first glance, I'd say that profiles should be "additive", so rather than removing debuginfo, I'd make sense to me for debug to extend dev and add debuginfo to it. I assume that people using debug care exactly about debuginfo, and most other things from dev should be inherited.
So long as the defaults can be framed as additive, rather than just different.
I think it also makes conceptually that "debugging" is a part of "development".
That still leaves whether to have them both be roots, rather than one inheriting from the other. I'm somewhat leaning towards built-in only and not also root but not fully sure.
Another thing to consider to help alleviate this issue is simply "make debuginfo generation faster". I wouldn't say it's exactly low-hanging fruit, but there is a lot of wasteful work being done repeatedly during each build. If we could remove or cache that, then the difference between debuginfo = 2 and debuginfo = "line-tables-only" (which I assume would be the default for the dev profile), wouldn't have to be so large.
How much work do you think that is, how much do you think it will improve, and what is the likelihood we get someone to do it?
Debug info isn't the only setting we expect to change but also opt-level, maybe more.
4. if needed, add a build.profile config field (need to figure out how to define its behavior wrt to install)
I was looking into this because it would offer a smoother transition for debugger-heavy users. If they could set build.profile = "debug" and old cargo ignores it (getting the debug-friendly dev profile) and new cargo respects it, then they can set and forget.
I mentioned the install problem. build.target already says it doesn't apply to install so we could say the same for build.profile. To make this even clearer, we could also offer an install.profile field which would let users easily override how their installed tools get built without affecting anything else.
The problem I ran into is that cargo bench defaults to a built-in bench profile that inherits from dev and similarly cargo test defaults to a test profile.
Before, I could say build.profile controls all compile commands and defaults to dev. How do we fit test and bench into this? A context-specific default? bench.profile and test.profile configs?
On top of that, our profile and command docs don't even talk about these profiles that let you customize compilation just for test and bench commands. The only hint is the compiler output saying
Finished `test` profile [unoptimized + debuginfo] target(s) in 0.00s
which is usually lost in the noise of actual test/bench execution.
Assuming most users debug a cargo build and not a cargo test, having it configured separately might not be too bad.
Dang, we should have asked about that in the debugging survey. I'm not personally sure about that, I might personally even debug cargo test more often than cargo run. Really depends on the project.
Another dimension to consider could be default codegen backend. I'm not sure if Cranelift even has support for emitting debuginfo, or if it intends to.
Activity
epage commentedon Sep 5, 2025
Questions for us to deal with:
epage commentedon Sep 5, 2025
Would we provide a built-in profile for debugging? If so, new built-in profiles would be a breaking change because built-in profiles can't inherit from other profiles. So if user had a
debuggingprofile that inherits fromdevand we madedebugginga built-in, their build would fail.Options:
Allow users to inherit in any profile with some way to deal with cycles. This would allow users to mask the built-in profiles completely.
One way to avoid the masking of built-in profiles is to move all of the built-in profiles into a namespace (e.g.
cargo::dev). In place of the built-in profiles would be default profiles that implicitly inherit from the same-named profile in the namespace (cargo::).Another alternative is to use an existing reserved name. An obvious choice is
debug. The challenge here is that build results fordevbuilds go intarget/debug. A naive solution isdevgoes intarget/devanddebuggoes intarget/debug. However, if the default profile remainsdev, then that would break users expecting to find final artifacts. What if we had a config field likebuild.targetfor the default profile for builds (exceptinstall/bench) and the default was dynamic, based on the edition? The first problem is users can specify multiple packages at once and there are no editions for a workspace.epage commentedon Mar 31, 2026
We talked about this a little in today's cargo team meeting (notes). Some ideas:
devanddebugshare the same artifact directorydevprofile with adevartifact directory w/ config for default profile--profile devcargo --profile debugfor simpler Makefiles #13495CC @Kobzol
Kobzol commentedon Apr 7, 2026
I had this opened in a group of tabs for the past ~6 months, but didn't have time to work on it yet 🙈 Thanks for the summary though.
epage commentedon Jun 29, 2026
In thinking this through more, instead of these being two separate solution options, they could be steps in the process. We can split
dev/debugand later movedevout oftarget-dir. Doing it now or later shouldn't make a difference to the decisions being made or the design. This allows us to move forward without having to figure everything out ahead of time.My proposed plan for this:
--debug) that is a copy ofdevdebugto percolate out so people can migrate, changedevprofile's settingsdevout of thedebugbuild-dir/target-dirbuild.profileconfig field (need to figure out how to define its behavior wrt toinstall)epage commentedon Jul 13, 2026
One question I hadn't considered before: what should be builtin vs root?
debuganddevare both rootdebugis builtin that inherits fromdevrootdevis builtin that inherits fromdebugrootI suspect the following are the only ones that might want to be shared
incrementalcodegen-unitsrpathKobzol commentedon Jul 13, 2026
At a first glance, I'd say that profiles should be "additive", so rather than removing debuginfo, I'd make sense to me for debug to extend dev and add debuginfo to it. I assume that people using debug care exactly about debuginfo, and most other things from dev should be inherited.
Another thing to consider to help alleviate this issue is simply "make debuginfo generation faster". I wouldn't say it's exactly low-hanging fruit, but there is a lot of wasteful work being done repeatedly during each build. If we could remove or cache that, then the difference between
debuginfo = 2anddebuginfo = "line-tables-only"(which I assume would be the default for thedevprofile), wouldn't have to be so large.epage commentedon Jul 13, 2026
So long as the defaults can be framed as additive, rather than just different.
I think it also makes conceptually that "debugging" is a part of "development".
That still leaves whether to have them both be roots, rather than one inheriting from the other. I'm somewhat leaning towards built-in only and not also root but not fully sure.
How much work do you think that is, how much do you think it will improve, and what is the likelihood we get someone to do it?
Debug info isn't the only setting we expect to change but also
opt-level, maybe more.epage commentedon Jul 13, 2026
I was looking into this because it would offer a smoother transition for debugger-heavy users. If they could set
build.profile = "debug"and old cargo ignores it (getting the debug-friendlydevprofile) and new cargo respects it, then they can set and forget.I mentioned the
installproblem.build.targetalready says it doesn't apply toinstallso we could say the same forbuild.profile. To make this even clearer, we could also offer aninstall.profilefield which would let users easily override how their installed tools get built without affecting anything else.The problem I ran into is that
cargo benchdefaults to a built-inbenchprofile that inherits fromdevand similarlycargo testdefaults to atestprofile.Before, I could say
build.profilecontrols all compile commands and defaults todev. How do we fittestandbenchinto this? A context-specific default?bench.profileandtest.profileconfigs?On top of that, our profile and command docs don't even talk about these profiles that let you customize compilation just for
testandbenchcommands. The only hint is the compiler output sayingwhich is usually lost in the noise of actual test/bench execution.
epage commentedon Jul 13, 2026
Sounds like
testandbenchprofiles didn't get much rationalization. The most I found is:https://github.com/rust-lang/rfcs/blob/master/text/2678-named-custom-cargo-profiles.md#unresolved-questions asked
#6988 replied with
epage commentedon Jul 14, 2026
A user can do
profile.test.inherits = "debug".The main issue is discoverability.
Assuming most users debug a
cargo buildand not acargo test, having it configured separately might not be too bad.Kobzol commentedon Jul 14, 2026
Dang, we should have asked about that in the debugging survey. I'm not personally sure about that, I might personally even debug
cargo testmore often thancargo run. Really depends on the project.docs(ref): Improve handing of built-in profiles (rust-lang#17213)
feat(profile): Add built-in profile debug (#17214)
feat(config): Add build.profile, install.profile (rust-lang#17215)
perf(compile)!: Switch dev profile to debug=lines-and-tables-only
bstrie commentedon Oct 2, 2026
Another dimension to consider could be default codegen backend. I'm not sure if Cranelift even has support for emitting debuginfo, or if it intends to.
bjorn3 commentedon Oct 2, 2026
cg_clif fully supports line debuginfo. Anything beyond that is currently rather limited, but I would love to have debuginfo parity with cg_llvm.