Skip to content

comp-builder: add per-component buildJobs option (#1479) - #2546

Open
hamishmack wants to merge 1 commit into
masterfrom
hkm/issue-1479-build-jobs
Open

comp-builder: add per-component buildJobs option (#1479)#2546
hamishmack wants to merge 1 commit into
masterfrom
hkm/issue-1479-build-jobs

Conversation

@hamishmack

Copy link
Copy Markdown
Collaborator

Summary

Adds a first-class, per-component buildJobs option so memory-hungry packages can reduce or disable parallel building — the long-standing request in #1479.

The v1 builder previously hardcoded enableParallelBuilding = true (builder/comp-builder.nix) and baked -j$(($NIX_BUILD_CORES > 4 ? 4 : $NIX_BUILD_CORES)) into the Setup build invocation, with no way to override short of an undocumented trailing -j1 in setupBuildFlags.

Change

New nullable option in modules/component-options.nix:

packages.foo.components.exes.bar.buildJobs = 1;   # sequential, low-memory
  • null (default) → unchanged: -j capped at min(NIX_BUILD_CORES, 4), enableParallelBuilding = true
  • 1-j1 and enableParallelBuilding = false
  • N → pinned -jN, enableParallelBuilding = true

Wired through builder/comp-builder.nix via a buildJobsFlag binding and enableParallelBuilding = buildJobs != 1.

Default behaviour is byte-identical when the option is unset: the emitted flag string is exactly the original literal and enableParallelBuilding stays true (null != 1), so no existing derivation changes hash.

Scope: v1 only

Deliberately scoped to the v1 builder. The v2 builder (comp-v2-builder.nix) documents that it cannot faithfully reproduce per-component differentiation, and a v2 slice may build several components at once, so a per-component job count doesn't map cleanly onto v2. The option's description says so.

Tests

Adds test/build-jobs (registered in test/default.nix). It builds the cabal-simple project three ways (default, buildJobs = 1, buildJobs = 3) and asserts — at eval level, without compiling — on the resulting exe component's buildPhase string and enableParallelBuilding:

  • default keeps the capped -j expression and enableParallelBuilding = true
  • buildJobs = 1 emits -j1, drops the capped default, and sets enableParallelBuilding = false
  • buildJobs = 3 emits -j3 and keeps enableParallelBuilding = true

Verification done

  • Both edited nix files and the new test nix-instantiate --parse cleanly.
  • nix-instantiate test/default.nix --argstr compiler-nix-name ghc9124 -A build-jobs.run succeeds, i.e. the module option is accepted and all 7 eval assertions pass (they guard the run derivation via assert, so instantiation would abort if any failed).
  • Direct eval confirmed the branch logic: unset → original literal + true; 1-j1 + false; 8-j8 + true.

Closes #1479.

Parallel building was unconditionally on, with the v1 builder baking
`-j$(($NIX_BUILD_CORES > 4 ? 4 : $NIX_BUILD_CORES))` into `Setup build`
and hardcoding `enableParallelBuilding = true`. Memory-hungry packages
had no first-class way to reduce or disable this.

Add a nullable `buildJobs` component option (modules/component-options.nix):
  * null (default) -> unchanged capped `-j` behaviour
  * 1              -> sequential build (`-j1`, enableParallelBuilding off)
  * N              -> pinned `-jN`

Wire it through builder/comp-builder.nix (buildJobsFlag + enableParallelBuilding).
The default (option unset) produces a byte-identical build phase and
`enableParallelBuilding = true`, so existing derivations are unchanged.

Scoped to the v1 builder: v2 slices explicitly cannot reproduce
per-component differentiation faithfully (see comp-v2-builder.nix), and a
slice may cover multiple components, so a per-component job count does not
map onto v2.

Adds test/build-jobs asserting (at eval level, no compile) that the
component buildPhase and enableParallelBuilding reflect the option for
the default, buildJobs=1 and buildJobs=3 cases.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a per-component buildJobs option to the v1 component builder so individual components can pin or disable Cabal parallelism (and align enableParallelBuilding), addressing the resource-usage concerns raised in #1479.

Changes:

  • Introduces packages.<pkg>.components.<kind>.<name>.buildJobs (nullable positive int) in modules/component-options.nix.
  • Wires the option into the v1 builder (builder/comp-builder.nix) via a computed buildJobsFlag and enableParallelBuilding = buildJobs != 1.
  • Adds an eval-level test (test/build-jobs) asserting the resulting buildPhase string and enableParallelBuilding for default / 1 / 3.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
test/default.nix Registers the new build-jobs test in the test suite.
test/build-jobs/default.nix Adds eval-only assertions for buildJobs effects on buildPhase and enableParallelBuilding.
modules/component-options.nix Defines the new per-component buildJobs module option and its documentation/type.
builder/comp-builder.nix Implements the v1 builder behavior: constructs -j flag from buildJobs and toggles enableParallelBuilding.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +20 to +28
description = ''
Number of jobs to pass to `Setup build` as `-jN` for this component.
`null` (the default) keeps the standard behaviour of `-j` capped at
`min(NIX_BUILD_CORES, 4)`. Set to `1` to build sequentially (useful
for memory-hungry packages that OOM under parallel builds), or to any
other positive integer to pin the parallelism. Only affects the v1
(`builderVersion = 1`) builder.
'';
type = lib.types.nullOr lib.types.ints.positive;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose an option to control parallel building

2 participants