-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Feature request: compile build.rs scripts in release mode even when doing a debug build #2424
Comments
I've certainly wanted this in the past as well. The tricky parts I can think of are:
|
On Tue, Mar 01, 2016 at 10:46:06AM -0800, Alex Crichton wrote:
Yeah, I think the main reason I'd not yet opened an issue requesting I could also imagine this not being something that one configures, but |
The story for lalrpop is kind of interesting here. It's fairly expensive to compile, particularly in release mode (~minutes). For small grammars, total build script time is dominated by compiling lalrpop-snap, in which case you'd probably want a release build, but for larger grammars, the situation inverts and you really need an optimized version of lalrpop. |
I'd rather not have this. In the scenario where I have
I'd like for |
My proposal was that release would be the default. You would use debug if you knew you wanted to debug the build.rs script (which would presumably not be the common case). But the point is this is a decision that only the end-user is really in a position to make, not any particular dependency. |
I'd much rather always have release mode. Sure, the first compile is slow, but after that it doesn't change, so who cares? In general I feel like the first time I compile anything in cargo (or virtually any build system) it is slow, because it has to run off and grab a bunch of deps. |
@nikomatsakis Ok yeah, I agree with this. Running build scripts in release sounds like a good default. |
There's a few concerns I'd have about having a default release for build dependencies:
|
Considering cross-compilation with cargo, isn't already a thing that build dependencies are compiled in a very different way than crate ones? Having this scenario in mind, the fact that build script are compiled in release mode with the triplet target of the host is a default that make more sense than being similar to the crate compilation profile. In case a crate is used for both dependencies, for a cross-compilation use case, you would have to compile it twice anyway so it doesn't seems crazy. |
I contend that this is the wrong default -- I think the number of That said, it may be that the right fix here is to stop using This also makes using LALRPOP, syntex, and other similar preprocessors
My assumption was that the "build-dependencies" are distinct from the (Feels a lot like workspaces. :) |
Yeah this may indeed be a different class of dependencies (preprocessors), but those also sound a lot like plugins... When you're compiling for the host target (e.g. you didn't pass |
Is this surprising? I guess you're saying that adding something more "first class" than |
Hm yeah I guess they're different enough to warrant different systems. Seems plausible as becoming a thing! |
Is the idea of a
I would love to not rebuild all the host build dependencies when using other profiles. |
@jdub that's plausible, yeah! The only question would be what to do for a crate which needs to be compiled by the host profile and the target profile. My guess would be the target takes precedent, but in general doesn't matter too too much. |
This commit includes two significant changes: 1. Patterns are bundled in their plain TeX form, and serialized at build time; this is preliminary to user-chosen normalization. 2. Patterns are generated by applying a binary serialization strategy directly to pattern and exception *tries*. Change 1 entails a significant increase in the time of first-build, partly owing to the limitation that `build.rs` cannot be compiled in release mode for debug builds. (Refer to [cargo #2424](rust-lang/cargo#2424).) The alternative to build-time serialization would be to package patterns in every normalization form, and then either bundle them as a whole, or isolate each as an optional data-only dependency. The former would unacceptably inflate package size (to roughly 40MB, as of writing); the latter I perceive as a misuse of Cargo crates. Change 2 offers modest improvements in deserialization times, at the expense of size: - Deserializing the interned trie is about ~20–25% faster than deserializing sequential JSON data and building the trie at runtime. - The interned data is approximately 25% larger. This may improve in the future, e.g. by compressing shared prefixes or suffixes.
I should like to offer another example: the hyphenation crate normalizes a corpus of UTF-8 text at build time, an operation that takes an order of magnitude longer in debug mode. This was cause of some perplexity upon first encounter. Dependencies notwithstanding, for small libraries such as |
For another example, see rust-phf/rust-phf#104 , which provides an example where PHF's perfect hash generation takes 685 seconds when compiled for debug, or ~16.8 seconds when compiled for release. |
FWIW we don't really need any more examples of where this is helpful, it's clear that there's a well-motivated use case. What we need now is a solution! |
There are also cases where Some way to turn the optimization level down a bit would greatly speed up the build. I've also found that |
Possibly related to rust-lang/rfcs#2282. |
Any update on this? :) |
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.
I believe RFC 2822 solves this feature request and this can be closed as a dupe of rust-lang/rust#48683. |
Indeed! |
Right now,
cargo build
compiles build.rs in debug mode, whilecargo build --release
compiles build.rs in release mode. However build.rs scripts can potentially be very computationally intensive, and I would like the option to run my build.rs script in release mode even when doing a debug compile of the rest of my crate.As a motivating example, nikomatsakis/lalrpop is a parser generator that does source generation during the custom build step. Just the build.rs step takes 6m30s when compiling in debug, and 33s when compiling in release for a complex grammar.
The text was updated successfully, but these errors were encountered: