Repairing `codesign_allocate` on Darwin

TL;DR: Could someone please suggest the correct way to make the tiny change Comparing NixOS:master...Smaug123:aarch-signing · NixOS/nixpkgs · GitHub , which is my non-working attempt?

Why I’m making this change: I’m building a flake (A flake.lock from my machine · Smaug123/lean4@f3723b6 · GitHub) on Monterey, Apple Silicon, and getting the following log:

       > ld: warning: directory not found for option '-L/nix/store/smpng2rrp1dfnik729h4gg917mm0y4ws-leanc/lib/lean'
       > libc++abi: terminating with uncaught exception of type std::runtime_error: Failed to spawn codesign_allocate: No such file or directory
       > /nix/store/apxhw055i0z86i3m27xn81w0qg2ssp1q-post-link-sign-hook: line 2: 83986 Abort trap: 6           CODESIGN_ALLOCATE=codesign_allocate /nix/store/hr987fj9ib6v70mmi9jiw5iykkc0zi2f-sigtool-0.1.2/bin/codesign -f -s - "$linkerOutput"
       > clang-11: error: linker command failed with exit code 134 (use -v to see invocation)

This error appears to come from https://github.com/Smaug123/nixpkgs/blob/283d622397539f196416657da9dc804a4ca89846/pkgs/top-level/darwin-packages.nix#L123 .
I believe the root cause is that codesign_allocate is not on the path, and that the correct fix is to refer to it explicitly within the store. There’s a few of it floating around my store (one example being /nix/store/380ds19rqnzkq8s7hvykxgz96fcsnk6z-cctools-binutils-darwin-949.0.1/bin/codesign_allocate).

I’ve produced Comparing NixOS:master...Smaug123:aarch-signing · NixOS/nixpkgs · GitHub as an attempt to fix this, but it doesn’t work: a run of nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD" results in an enormous stack trace which starts as follows:

error: value is a string while a set was expected

       at /Users/patrick/.cache/nixpkgs-review/rev-b737b8f4416ee50654ff6fe8ce9b780855aa0755-1/nixpkgs/pkgs/os-specific/darwin/apple-source-releases/libiconv/default.nix:20:7:

           19|     mv $out/lib/libiconv.dylib $out/lib/libiconv-nocharset.dylib
           20|     ${stdenv.cc.bintools.targetPrefix}install_name_tool -id $out/lib/libiconv-nocharset.dylib $out/lib/libiconv-nocharset.dylib
             |       ^
           21|

       … while evaluating the attribute 'cc.bintools.targetPrefix'

       at /Users/patrick/.cache/nixpkgs-review/rev-b737b8f4416ee50654ff6fe8ce9b780855aa0755-1/nixpkgs/pkgs/stdenv/generic/default.nix:168:14:

          167|
          168|       inherit cc hasCC;
             |              ^
          169|     }

At this point I’m simply lost. Can anyone help?

Have you managed to work around or through this? I am just picking up Nix for the first time and this is a blocker…

I see the open PR, but don’t know enough Nix to use it locally.

1 Like

I have not, sorry :frowning:

@dodsonmg If you do indeed want to try the PR…

The specifics of how to use it locally will depend on what you’re doing and how (and your setup).

Since the question of how to use changes from a PR against nixpkgs is general (but context-sensitive), you may have an easier time getting help via chat (in the main Nix / NixOS room in the NixOS Matrix space linked from Nix Community | Nix & NixOS) or by opening a new thread on that question.

@abathur Thanks! I just joined the NixOS Matrix space (and the one for MacOS users!) and have already received some great help.

1 Like

Did you figure out a local fix for this? I’d like to use Lean 4, but it seems to to be blocked on this PR: darwin.postLinkSignHook: fix reference to codesign_allocate by Kha · Pull Request #150074 · NixOS/nixpkgs · GitHub

For context, I generated a new Lean 4 project using:

nix flake new mypkg -t github:leanprover/lean4

This yielded the following mypkg/flake.nix:

{
  description = "My Lean package";

  inputs.lean.url = github:leanprover/lean4;
  inputs.flake-utils.url = github:numtide/flake-utils;

  outputs = { self, lean, flake-utils }: flake-utils.lib.eachDefaultSystem (system:
    let
      leanPkgs = lean.packages.${system};
      pkg = leanPkgs.buildLeanPackage {
        name = "MyPackage";  # must match the name of the top-level .lean file
        src = ./.;
      };
    in {
      packages = pkg // {
        inherit (leanPkgs) lean;
      };

      defaultPackage = pkg.modRoot;
    });
}

Running:

cd mypkg
nix build

Resulted in:

warning: creating lock file '/Users/.../mypkg/flake.lock'
error: builder for '/nix/store/h9accn51z0crmyaa4rfd0y2lckq2irl0-lean.drv' failed with exit code 134;
      last 4 log lines:
      > ld: warning: directory not found for option '-L/nix/store/6wgmj8l3cdcqyimf5nmskmpk608xbk9a-leanc/lib/lean'
      > libc++abi: terminating with uncaught exception of type std::runtime_error: Failed to spawn codesign_allocate: No such file or directory
      > /nix/store/apxhw055i0z86i3m27xn81w0qg2ssp1q-post-link-sign-hook: line 2: 29820 Abort trap: 6           CODESIGN_ALLOCATE=codesign_allocate /nix/store/hr987fj9ib6v70mmi9jiw5iykkc0zi2f-sigtool-0.1.2/bin/codesign -f -s - "$linkerOutput"
      > clang-11: error: linker command failed with exit code 134 (use -v to see invocation)
      For full logs, run 'nix log /nix/store/h9accn51z0crmyaa4rfd0y2lckq2irl0-lean.drv'.
error: 1 dependencies of derivation '/nix/store/270p8cgirm29bbj0cca6a25w4r6cf34m-print-lean-deps.drv' failed to build
error: 1 dependencies of derivation '/nix/store/7gyvqgngbgb33kn7r6vysajp54iibyj5-MyPackage-deps.drv' failed to build
(use '--show-trace' to show detailed location information)
nix log /nix/store/h9accn51z0crmyaa4rfd0y2lckq2irl0-lean.drv
ld: warning: directory not found for option '-L/nix/store/6wgmj8l3cdcqyimf5nmskmpk608xbk9a-leanc/lib/lean'
libc++abi: terminating with uncaught exception of type std::runtime_error: Failed to spawn codesign_allocate: No such file or directory
/nix/store/apxhw055i0z86i3m27xn81w0qg2ssp1q-post-link-sign-hook: line 2: 29820 Abort trap: 6           CODESIGN_ALLOCATE=codesign_allocate /nix/store/hr987fj9ib6v70mmi9jiw5iykkc0zi2f-sigtool-0.1.2/bin/codesign -f -s - "$linkerOutput"
clang-11: error: linker command failed with exit code 134 (use -v to see invocation)

I tried using the fix from https://github.com/NixOS/nixpkgs/pull/150074, by adding an overlay like this:

{
  description = "My Lean package";

  inputs.lean.url = github:leanprover/lean4;
  inputs.flake-utils.url = github:numtide/flake-utils;

  outputs = { self, lean, flake-utils }: flake-utils.lib.eachDefaultSystem (system:
    let
      # Fix for `codesign_allocate` (see https://github.com/NixOS/nixpkgs/pull/148282)
      fix-codesign-allocate-overlay = final: prev:
        let targetPrefix = prev.lib.optionalString (prev.stdenv.targetPlatform != prev.stdenv.hostPlatform)
          (prev.stdenv.targetPlatform.config + "-");
        in
        {
          postLinkSignHook = prev.pkgs.writeTextFile {
            name = "post-link-sign-hook";
            executable = true;

            text = ''
              CODESIGN_ALLOCATE=${targetPrefix}codesign_allocate \
              CODESIGN_ALLOCATE=${prev.pkgs.cctools}/bin/${prev.pkgs.cctools.targetPrefix}codesign_allocate \
                ${prev.pkgs.sigtool}/bin/codesign -f -s - "$linkerOutput"
            '';
          };
        };
      leanPkgs = import lean.packages.${system} {
        overlays = [ fix-codesign-allocate-overlay ];
      };
      pkg = leanPkgs.buildLeanPackage {
        name = "MyPackage"; # must match the name of the top-level .lean file
        src = ./.;
      };
    in
    {
      packages = pkg // {
        inherit (leanPkgs) lean;
      };

      defaultPackage = pkg.modRoot;
    });
}

But this doesn’t seem to have any affect at all - lean still fails to build with the same error about codesign_allocate. We suspect that this is because the overlay is not being applied to lean early enough, but I’m not sure how to fix this locally.

Anyway, hoping that by posting this here I can help others who might also be struggling with this make further progress.

For future reference, my conversation about this on Matrix can be found here.

The Lean flake does not expose a parameter for passing a Nixpkgs overlay. You should be able to do something like

 nix flake lock --override-input lean/nixpkgs github:sternenseemann/nixpkgs/codesign-hook-abs-path

to temporarily override Lean’s nixpkgs input with the PR.

1 Like

Thanks, I’ll give that a go. I’m guessing I’d need to remember to do something like this when updating the lockfile:

nix flake update --override-input lean/nixpkgs github:sternenseemann/nixpkgs/codesign-hook-abs-path

It’s rather uhhh ‘fun’ that this change seems to mean I need to build the full dependency tree scratch (including C libraries, compilers, etc)? Is there a way to speed this up with this approach? I do have the cachix stuff set up for Lean, but maybe this is invalidated when I overode the input? I just wanted that small fix to be used at the very end of the build of Lean. :woozy_face:

Right, this is pretty inconvenient until the PR is merged… TBH, I would suggest to just use the standard elan setup in that case, it’s what basically everyone else uses for Lean.

1 Like

For anybody else who stumbles across this thread, I wanted to summarize because it wasn’t initially obvious to me:

Adding darwin.cctools to the PATH for the affected derivation will fix the problem (since darwin.cctools provides codesign_allocate). One way to do so is something like:

nativeBuildInputs = lib.optional stdenv.isDarwin darwin.cctools;

That workaround would no longer be necessary once something like darwin.postFixupSignHook: use absolute path to codesign_allocate by sternenseemann · Pull Request #148282 · NixOS/nixpkgs · GitHub is merged.

1 Like

I’d be happy if someone picks this up and tries to figure out how to fix the errors it seemed to cause. I have no ability to do so, as I don’t own any aarch64-darwin hardware and implemented this patch blindly.

Having a quick look now - merged in master to produce GitHub - Smaug123/nixpkgs at codesign-hook-abs-path, currently using it to build hello on aarch64-darwin. (It’s rebuilding the entire world.)

I am out of my depth entirely, I just don’t know enough about the bootstrap process :frowning: