Skip to content

stdenv: Move all stdenv lookups out of mkDerivation #431756

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

YorikSar
Copy link
Contributor

@YorikSar YorikSar commented Aug 7, 2025

All lookups and expressions that don't depend on derivation attrs are moved to the outer let block. Saves over 10% lookups for eval on x86_64-linux, along with 53MiB memory (over 1%).
For some reason lists concats go 14% up, but defaultConfigurePlatformsFlags optimisation removes ~7% of them.

Overall time is down ~3%.

Things done


Add a 👍 reaction to pull requests you find important.

All lookups and expressions that don't depend on derivation attrs are
moved to the outer let block. Saves over 10% lookups for eval on
x86_64-linux, along with 53MiB memory (over 1%).

For some reason lists concats go 14% up, but
defaultConfigurePlatformsFlags optimisation removes ~7% of them.

Overall time is down ~3%.
@nixpkgs-ci nixpkgs-ci bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux. 6.topic: stdenv Standard environment labels Aug 7, 2025
@philiptaron
Copy link
Contributor

philiptaron commented Aug 11, 2025

I still have this on my list to review, but I won't be able to be at a computer until a little later this week. These sorts of PRs need careful attention…Although I have a strong belief that you have not introduced any regressions with this change.

Copy link
Contributor

@philiptaron philiptaron left a comment

Choose a reason for hiding this comment

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

Requesting changes only for the defaultConfigurePlatformsFlags searching and the system hoisting. Everything else is me puzzling over how this whole thing came to be.

extraNativeBuildInputs
extraBuildInputs
extraSandboxProfile
__extraImpureHostDeps
Copy link
Contributor

Choose a reason for hiding this comment

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

__extraImpureHostDeps dates to fa9c81f694680. In the Darwin stdenv, it's set to commonImpureHostDeps: 49a5791bc4f20. The Darwin stdenv appears to be the only user.

# Target is not included by default because most programs don't care.
# Including it then would cause needless mass rebuilds.
#
# TODO(@Ericson2314): Make [ "build" "host" ] always the default / resolve #87909
Copy link
Contributor

Choose a reason for hiding this comment

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

Currently a draft; needs substantial work to integrate into the current world.

Comment on lines +206 to +211
defaultConfigurePlatforms =
optionals (hostPlatform != buildPlatform || config.configurePlatformsByDefault)
[
"build"
"host"
];
Copy link
Contributor

Choose a reason for hiding this comment

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

As I read it, defaultConfigurePlatforms is either [] or it is [ "build" "host" ].

#
# TODO(@Ericson2314): Make [ "build" "host" ] always the default / resolve #87909
defaultConfigurePlatforms =
optionals (hostPlatform != buildPlatform || config.configurePlatformsByDefault)
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's extract hostPlatform != buildPlatform || config.configurePlatformsByDefault to useDefaultConfigurePlatforms.

Comment on lines +215 to +218
defaultConfigurePlatformsFlags =
optional (elem "build" defaultConfigurePlatforms) buildPlatformConfigureFlag
++ optional (elem "host" defaultConfigurePlatforms) hostPlatformConfigureFlag
++ optional (elem "target" defaultConfigurePlatforms) targetPlatformConfigureFlag;
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see a way for the target condition to be true, since (as I read it) defaultConfigurePlatforms will only contain "host" or "build" but never "target".

I think this simplifies to:

Suggested change
defaultConfigurePlatformsFlags =
optional (elem "build" defaultConfigurePlatforms) buildPlatformConfigureFlag
++ optional (elem "host" defaultConfigurePlatforms) hostPlatformConfigureFlag
++ optional (elem "target" defaultConfigurePlatforms) targetPlatformConfigureFlag;
defaultConfigurePlatformsFlags = if useDefaultConfigurePlatforms then [ buildPlatformConfigureFlag hostPlatformConfigureFlag ] else [ ];

The code is copied and modified from a context where configurePlatforms might include "target" but in this context it's quite a bit simpler.

@@ -521,9 +577,9 @@ let
# indeed more finely than Nix knows or cares about. The `system`
# attribute of `buildPlatform` matches Nix's degree of specificity.
# exactly.
inherit (stdenv.buildPlatform) system;
inherit system;
Copy link
Contributor

Choose a reason for hiding this comment

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

Prefer to revert this change.


userHook = config.stdenv.userHook or null;
inherit userHook;
Copy link
Contributor

Choose a reason for hiding this comment

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

As per previous comment, I support removing this functionality.

@@ -544,9 +600,14 @@ let
# This parameter is sometimes a string, sometimes null, and sometimes a list, yuck
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't true anymore, based on the usage of ++ below. That would cause an eval failure.

Comment on lines 387 to +390
# TODO(@oxij, @Ericson2314): This is here to keep the old semantics, remove when
# no package has `doCheck = true`.
doCheck' = doCheck && stdenv.buildPlatform.canExecute stdenv.hostPlatform;
doInstallCheck' = doInstallCheck && stdenv.buildPlatform.canExecute stdenv.hostPlatform;
doCheck' = doCheck && canExecuteHostOnBuild;
doInstallCheck' = doInstallCheck && canExecuteHostOnBuild;
Copy link
Contributor

Choose a reason for hiding this comment

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

++ optional (elem "build" configurePlatforms) "--build=${stdenv.buildPlatform.config}"
++ optional (elem "host" configurePlatforms) "--host=${stdenv.hostPlatform.config}"
++ optional (elem "target" configurePlatforms) "--target=${stdenv.targetPlatform.config}";
++ (
Copy link
Contributor

Choose a reason for hiding this comment

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

We can avoid this list concatenation in the common case by testing the following booleans.

  1. attrs ? configureFlags: the derivation specified configureFlags
  2. attrs ? configurePlatforms: the derivation specified configurePlatforms

The common case is !attrs ? configureFlags and !attrs ? configurePlatforms, which ought to just be defaultConfigurePlatformsFlags.

Here's the truth table that I'm thinking of.

attrs ? configureFlags attrs ? configurePlatforms Meaning Result
false false Defaults in every case defaultConfigurePlatformsFlags
false true Non-default platforms, need to test for target Do elem "target" logic on the platforms
true false Some flags are set, default platforms (other common case) configureFlags ++ defaultConfigurePlatformsFlags
true true Rare case configureFlags plus the elem target logic.

What do you think?

@github-project-automation github-project-automation bot moved this to In Progress in Stdenv Aug 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
6.topic: stdenv Standard environment 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux.
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

2 participants