Skip to content

Conversation

edolstra
Copy link
Member

@edolstra edolstra commented Oct 3, 2025

Motivation

These are helper programs that execute derivations for specified system types (e.g. using QEMU to emulate another system type).

To use, set external-builders:

external-builders = [{"systems": ["aarch64-linux"], "program": "/path/to/external-builder.py"}]

The external builder gets one command line argument, the path to a JSON file containing all necessary information about the derivation:

{
  "args": [...],
  "builder": "/nix/store/kwcyvgdg98n98hqapaz8sw92pc2s78x6-bash-5.2p37/bin/bash",
  "env": {
    "HOME": "/homeless-shelter",
    ...
  },
  "realStoreDir": "/tmp/nix/nix/store",
  "storeDir": "/nix/store",
  "tmpDir": "/tmp/nix-shell.dzQ2hE/nix-build-patchelf-0.14.3.drv-46/build",
  "tmpDirInSandbox": "/build"
}

Context

Upstreamed from Determinate Nix (DeterminateSystems#78). This is the mechanism that allows doing Linux builds on macOS.


Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

These are helper programs that execute derivations for specified
system types (e.g. using QEMU to emulate another system type).

To use, set `external-builders`:

  external-builders = [{"systems": ["aarch64-linux"], "program": "/path/to/external-builder.py"}]

The external builder gets one command line argument, the path to a JSON file containing all necessary information about the derivation:

  {
    "args": [...],
    "builder": "/nix/store/kwcyvgdg98n98hqapaz8sw92pc2s78x6-bash-5.2p37/bin/bash",
    "env": {
      "HOME": "/homeless-shelter",
      ...
    },
    "realStoreDir": "/tmp/nix/nix/store",
    "storeDir": "/nix/store",
    "tmpDir": "/tmp/nix-shell.dzQ2hE/nix-build-patchelf-0.14.3.drv-46/build",
    "tmpDirInSandbox": "/build"
  }

Co-authored-by: Cole Helbling <[email protected]>
@edolstra edolstra requested a review from Ericson2314 as a code owner October 3, 2025 13:16
@github-actions github-actions bot added the with-tests Issues related to testing. PRs with tests have some priority label Oct 3, 2025
@edolstra edolstra force-pushed the external-derivation-builder branch from 95246b0 to 73e4c40 Compare October 3, 2025 14:32
Copy link
Member

@Mic92 Mic92 left a comment

Choose a reason for hiding this comment

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

Sounds like a useful feature to have.

Setting<ExternalBuilders> externalBuilders{
this,
{},
"external-builders",
Copy link
Member

Choose a reason for hiding this comment

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

This is a privileged nix option, right?

std::unique_ptr<DerivationBuilder> makeDerivationBuilder(
LocalStore & store, std::unique_ptr<DerivationBuilderCallbacks> miscMethods, DerivationBuilderParams params)
{
if (auto builder = ExternalDerivationBuilder::newIfSupported(store, miscMethods, params))
Copy link
Member

Choose a reason for hiding this comment

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

Does this filter out builtin derivations?

"/nix/store/vj1c3wf9…-source-stdenv.sh",
"/nix/store/shkw4qm9…-default-builder.sh"
],
"builder": "/nix/store/s1qkj0ph…-bash-5.2p37/bin/bash",
Copy link
Member

Choose a reason for hiding this comment

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

The following are not needed?

    "inputDrvs": {
      "ag533xlxphzj8nh4y9wsksf057fgsls0-hello-2.12.2.tar.gz.drv": {
        "dynamicOutputs": {},
        "outputs": [
          "out"
        ]
      },
      "j3aid0i43g57xkf4z9fbiqcbb4ljb06r-stdenv-darwin.drv": {
        "dynamicOutputs": {},
        "outputs": [
          "out"
        ]
      },
      "pmlwjrsjfdk5r9j1mw97hm3pj0mc8lqk-version-check-hook.drv": {
        "dynamicOutputs": {},
        "outputs": [
          "out"
        ]
      },
      "sbx1ghn3g6vaad1i8m730zbdsa3m9lyv-bash-5.3p3.drv": {
        "dynamicOutputs": {},
        "outputs": [
          "out"
        ]
      }
    },
    "inputSrcs": [
      "l622p70vy8k5sh7y5wizi5f2mic6ynpg-source-stdenv.sh",
      "shkw4qm9qcw5sc5n1k5jznc83ny02r39-default-builder.sh"
    ],

Comment on lines +55 to +64
for (auto & i : drv.args)
l.push_back(rewriteStrings(i, inputRewrites));
json.emplace("args", std::move(l));
}
{
auto j = nlohmann::json::object();
for (auto & [name, value] : env)
j.emplace(name, rewriteStrings(value, inputRewrites));
json.emplace("env", std::move(j));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't it make sense to reuse the existing shored-up JSON derivation format @Ericson2314 has worked on?

Comment on lines +78 to +83
pid = startProcess([&]() {
openSlave();
try {
commonChildInit();

Strings args = {externalBuilder.program};
Copy link
Contributor

Choose a reason for hiding this comment

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

Considering that this will be run in the daemon would it be prudent to start dropping capabilities before executing the child?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
with-tests Issues related to testing. PRs with tests have some priority
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants