Skip to content
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

rustPlatform: increase build-speed of checkPhase for rust-packages #82342

Merged
merged 12 commits into from Jun 5, 2020

Conversation

Ma27
Copy link
Member

@Ma27 Ma27 commented Mar 11, 2020

Motivation for this change

⚠️ Caution: this is more or less an experiment and I'm not sure if that has implications on any leaf-packages since I just tested a few packages like rustup or cargo-audit with it, so this needs some review and testing before becoming mergable.

As noted later on, I consider this rather usable after several iterations of reviews and tests, however we need more extensive testing before merging this to upstream.


When running cargo test --release, the artifacts from buildPhase
will be reused here. Previously, most of the stuff had to be recompiled
without optimizations.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@cole-h
Copy link
Member

cole-h commented Mar 15, 2020

Since you note that this needs testing, I tried it on the recently-added zoxide package. (If it's useful to know: I run an "other Linux distribution", Arch, as opposed to NixOS.)

After building cargo, it proceeded to build the project, followed by tests. With this patch, they completed instantly (because there are none to run). I cannot comfortably speak for the Nix code, but the functionality works fine in this case.

running tests
Running cargo cargo test --release --target x86_64-unknown-linux-gnu --frozen --
   Compiling zoxide v0.2.1 (/build/source)
    Finished release [optimized] target(s) in 0.50s
     Running target/x86_64-unknown-linux-gnu/release/deps/zoxide-6631378e48db285a

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

EDIT: If there's anything else I can help with, let me know -- excited to see this land to reduce unnecessary compilation.

@Ma27
Copy link
Member Author

Ma27 commented Mar 16, 2020

@cole-h thanks for taking a look at this!

If there's anything else I can help with, let me know -- excited to see this land to reduce unnecessary compilation.

Well, this might be pretty time-consuming, but in case someone finds a crate (preferably something used in a NixOS-package) that breaks with this patch it would be fairly helpful (I didn't find any, but I don't consider myself an expert in the rust ecosystem though :) )

@Ma27 Ma27 marked this pull request as ready for review March 16, 2020 15:22
Copy link
Contributor

@kevincox kevincox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I tried (unsuccessfully) to do this a while ago. Looks great!

Copy link
Member

@cole-h cole-h left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I built a few packages that I use (hyperfine, alacritty, and ripgrep) with this patch applied and it was all sunshine and rainbows. No more compiling 250+ dependencies twice for a test run!

@bhipple
Copy link
Contributor

bhipple commented Mar 19, 2020

Looks like a great change in general. Build performance optimizations aside, this is also arguably superior on its own right: we're shipping optimizied binaries built against optimized libraries, but previously we were running the test suite against debug libs. This gets us closer to testing what we're deploying. The fact that it basically halves our compilations is nice too :)

That said, after trying several successfully, I think I found a package that has issues. (It builds on master, and still fails when this PR is rebased onto master.)

@GrahamcOfBorg build zcash

@Ma27 Ma27 changed the base branch from master to staging March 19, 2020 10:39
@Ma27 Ma27 force-pushed the increase-rust-build-speed branch from 67e82fb to b790f3a Compare March 19, 2020 10:39
@Ma27 Ma27 requested a review from Mic92 March 19, 2020 10:39
@Ma27
Copy link
Member Author

Ma27 commented Mar 19, 2020

Fix the build issue and also changed the base to staging as there's quite much to rebuild :)

@cole-h
Copy link
Member

cole-h commented Mar 20, 2020

While I was messing with #82982, I noticed that, when combined with this PR, ripgrep would fail to compile because of its preFixup -- it wants to cd $releaseDir/build/ripgrep-*/out, but there are multiple directories that match that glob (most likely due to the tests being compiled in release mode)!

I have no idea how this should be worked around, but it's something that should be dealt with before this merges. This worked in the past (I assume) because there was only 1 possible match in the $releaseDir due to the tests being run in debug mode.

(I guess I didn't properly test this with ripgrep earlier, because it fails similarly on 11.0.2 -- that's a failing on my part and I will try to be more careful about these kinds of assertions in the future.)

EDIT: Originally, I was thinking we could use the --target-dir flag, but this changes where it outputs to as well as where it reads from. This might require some magic.

EDIT2: Or we could just change the cps to cp -n -- the outputs should all be the same, so it shouldn't matter which one gets copied. Maybe this is another instance of something that should be changed to improve robustness.

EDIT4: The real solution (IMHO) is to use the installShellCompletion and installManPage helpers on that globbed path instead of cding to it or cping the files, e.g. installShellCompletions --zsh $releaseDir/build/ripgrep-*/out/_rg. No problems with that solution, so far.


EDIT3: Probably the most annoying side-effect of this change is rg, rg-edd1cb3b1163a7ff, and integration-3cd6ef3798b37d0e get installed to bin/ -- is there any way to reliably detect these hash-appended executables and not copy them?

@Ma27
Copy link
Member Author

Ma27 commented Mar 23, 2020

EDIT3: Probably the most annoying side-effect of this change is rg, rg-edd1cb3b1163a7ff, and integration-3cd6ef3798b37d0e get installed to bin/ -- is there any way to reliably detect these hash-appended executables and not copy them?

Not sure yet. In case I have sufficient time, I will start investigating tomorrow :)

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/speeding-up-rust-app-packaging/6384/6

@danieldk
Copy link
Contributor

I wonder if this is actually a good idea, debug doesn’t just compile with fewer optimizations, it also turns on integer overflow checks and debug assertions (which are used throughout the standard library and crates to do more expensive checks). Doing tests with release builds may miss some bugs which are captured by regular testing using debug builds.

@kevincox
Copy link
Contributor

kevincox commented Mar 24, 2020

<opinion>

In general I see nix tests as a quick check to ensure that you didn't compile things terribly wrong. In this case I think that integer overflow checks should be caught by the application developers. Debug assertions are more difficult to categorize as catching build/configuration issues but I think that in general it is worth the time savings to turn them off. The job of nix isn't to check that the code is perfect, but mostly to ensure that we built it correctly.

Copy link
Member Author

@Ma27 Ma27 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general I see nix tests as a quick check to ensure that you didn't compile things terribly wrong. In this case I think that integer overflow checks should be caught by the application developers. Debug assertions are more difficult to categorize as catching build/configuration issues but I think that in general it is worth the time savings to turn them off. The job of nix isn't to check that the code is perfect, but mostly to ensure that we built it correctly.

Agreed. See also my comment in discourse: https://discourse.nixos.org/t/speeding-up-rust-app-packaging/6384/8?u=ma27

pkgs/build-support/rust/default.nix Show resolved Hide resolved
@ofborg ofborg bot requested review from globin, symphorien and Br1ght0ne and removed request for symphorien May 30, 2020 19:07
@Ma27 Ma27 force-pushed the increase-rust-build-speed branch from c303244 to 7e8d602 Compare May 30, 2020 20:29
@Ma27
Copy link
Member Author

Ma27 commented May 30, 2020

Docs have been fixed, thanks @cole-h and @asymmetric !

I'd love to see a final review, after that I'd consider this mergable (will leave a comment, then). /cc @FRidh @vcunat

@ofborg ofborg bot requested review from symphorien and removed request for Br1ght0ne May 30, 2020 20:37
@bhipple
Copy link
Contributor

bhipple commented May 31, 2020

Sadly I don't have time for a full review/test, but I'll at least comment to say I'm morally in favor of this change.

Copy link
Member

@cole-h cole-h left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few nits, and the rest LGTM. Thanks for your work on this! Can't wait to compile packages like Alacritty only once when testing ;-)

doc/languages-frameworks/rust.section.md Show resolved Hide resolved
doc/languages-frameworks/rust.section.md Outdated Show resolved Hide resolved
@Ma27 Ma27 force-pushed the increase-rust-build-speed branch from 7e8d602 to 84e1ff8 Compare May 31, 2020 19:39
@Ma27
Copy link
Member Author

Ma27 commented May 31, 2020

@cole-h fixed :)

@ofborg ofborg bot requested review from Br1ght0ne and removed request for symphorien May 31, 2020 19:47
Co-authored-by: cole-h <cole.e.helbling@outlook.com>
Co-authored-by: asymmetric <lorenzo@mailbox.org>
@Ma27 Ma27 force-pushed the increase-rust-build-speed branch from 84e1ff8 to 59e8e7a Compare May 31, 2020 19:47
@ofborg ofborg bot requested review from symphorien and Br1ght0ne and removed request for Br1ght0ne and symphorien May 31, 2020 19:55
@Ma27
Copy link
Member Author

Ma27 commented Jun 4, 2020

@vcunat @FRidh I'd consider this PR good to go now. Is there anything else to be done from your PoV before merging this to staging?

@vcunat vcunat changed the base branch from staging-next to staging June 5, 2020 07:14
@vcunat vcunat merged commit 677e396 into NixOS:staging Jun 5, 2020
Staging automation moved this from Ready to Done Jun 5, 2020
@Ma27 Ma27 deleted the increase-rust-build-speed branch June 5, 2020 07:20
@jtojnar jtojnar mentioned this pull request Jun 22, 2020
11 tasks
@cole-h cole-h mentioned this pull request Jun 23, 2020
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Staging
  
Done
Development

Successfully merging this pull request may close these issues.

None yet