forgejo-lts: 7.0.10 -> 7.0.11
[NixPkgs.git] / pkgs / stdenv / darwin / default.nix
blob2dfb34e40372e4e6bcd21b0d8260e302b637b871
1 # This file contains the standard build environment for Darwin. It is based on LLVM and is patterned
2 # after the Linux stdenv. It shares similar goals to the Linux standard environment in that the
3 # resulting environment should be built purely and not contain any references to it.
5 # For more on the design of the stdenv and updating it, see `README.md`.
7 # See also the top comments of the Linux stdenv `../linux/default.nix` for a good overview of
8 # the bootstrap process and working with it.
11   lib,
12   localSystem,
13   crossSystem,
14   config,
15   overlays,
16   crossOverlays ? [ ],
17   # Allow passing in bootstrap files directly so we can test the stdenv bootstrap process when changing the bootstrap tools
18   bootstrapFiles ? (config.replaceBootstrapFiles or lib.id) (
19     if localSystem.isAarch64 then
20       import ./bootstrap-files/aarch64-apple-darwin.nix
21     else
22       import ./bootstrap-files/x86_64-apple-darwin.nix
23   ),
26 assert crossSystem == localSystem;
28 let
29   inherit (localSystem) system;
31   sdkMajorVersion =
32     let
33       inherit (localSystem) darwinSdkVersion;
34     in
35     if lib.versionOlder darwinSdkVersion "11" then
36       lib.versions.majorMinor darwinSdkVersion
37     else
38       lib.versions.major darwinSdkVersion;
40   commonImpureHostDeps = [
41     "/bin/sh"
42     "/usr/lib/libSystem.B.dylib"
43     "/usr/lib/system/libunc.dylib" # This dependency is "hidden", so our scanning code doesn't pick it up
44   ];
46   isFromNixpkgs = pkg: !(isFromBootstrapFiles pkg);
47   isFromBootstrapFiles = pkg: pkg.passthru.isFromBootstrapFiles or false;
48   isBuiltByNixpkgsCompiler = pkg: isFromNixpkgs pkg && isFromNixpkgs pkg.stdenv.cc.cc;
49   isBuiltByBootstrapFilesCompiler = pkg: isFromNixpkgs pkg && isFromBootstrapFiles pkg.stdenv.cc.cc;
51   # Dependencies in dependency sets should be mutually exclusive.
52   mergeDisjointAttrs = lib.foldl' lib.attrsets.unionOfDisjoint { };
54   commonPreHook = ''
55     export NIX_ENFORCE_NO_NATIVE=''${NIX_ENFORCE_NO_NATIVE-1}
56     export NIX_ENFORCE_PURITY=''${NIX_ENFORCE_PURITY-1}
57     export NIX_IGNORE_LD_THROUGH_GCC=1
58   '';
60   bootstrapTools =
61     derivation (
62       {
63         inherit system;
65         name = "bootstrap-tools";
66         builder = "${bootstrapFiles.unpack}/bin/bash";
68         args = [
69           "${bootstrapFiles.unpack}/bootstrap-tools-unpack.sh"
70           bootstrapFiles.bootstrapTools
71         ];
73         PATH = lib.makeBinPath [
74           (placeholder "out")
75           bootstrapFiles.unpack
76         ];
78         __impureHostDeps = commonImpureHostDeps;
79       }
80       // lib.optionalAttrs config.contentAddressedByDefault {
81         __contentAddressed = true;
82         outputHashAlgo = "sha256";
83         outputHashMode = "recursive";
84       }
85     )
86     // {
87       passthru.isFromBootstrapFiles = true;
88     };
90   stageFun =
91     prevStage:
92     {
93       name,
94       overrides ? (self: super: { }),
95       extraNativeBuildInputs ? [ ],
96       extraPreHook ? "",
97     }:
99     let
100       cc =
101         if prevStage.llvmPackages.clang-unwrapped == null then
102           null
103         else
104           prevStage.wrapCCWith {
105             name = "${name}-clang-wrapper";
107             nativeTools = false;
108             nativeLibc = false;
110             expand-response-params = lib.optionalString (
111               prevStage.stdenv.hasCC or false && prevStage.stdenv.cc != "/dev/null"
112             ) prevStage.expand-response-params;
114             extraPackages = [ prevStage.llvmPackages.compiler-rt ];
116             extraBuildCommands =
117               let
118                 inherit (prevStage.llvmPackages) clang-unwrapped compiler-rt;
119               in
120               ''
121                 function clangResourceRootIncludePath() {
122                   clangLib="$1/lib/clang"
123                   if (( $(ls "$clangLib" | wc -l) > 1 )); then
124                     echo "Multiple LLVM versions were found at "$clangLib", but there must only be one used when building the stdenv." >&2
125                     exit 1
126                   fi
127                   echo "$clangLib/$(ls -1 "$clangLib")/include"
128                 }
130                 rsrc="$out/resource-root"
131                 mkdir "$rsrc"
132                 ln -s "$(clangResourceRootIncludePath "${lib.getLib clang-unwrapped}")" "$rsrc"
133                 ln -s "${compiler-rt.out}/lib"   "$rsrc/lib"
134                 ln -s "${compiler-rt.out}/share" "$rsrc/share"
135                 echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
136               ''
137               + lib.optionalString (isFromBootstrapFiles prevStage.llvmPackages.clang-unwrapped) ''
138                 # Work around the `-nostdlibinc` patch in the bootstrap tools.
139                 # TODO: Remove after the bootstrap tools have been updated.
140                 substituteAll ${builtins.toFile "add-flags-extra.sh" ''
141                   if [ "@darwinMinVersion@" ]; then
142                     NIX_CFLAGS_COMPILE_@suffixSalt@+=" -idirafter $SDKROOT/usr/include"
143                     NIX_CFLAGS_COMPILE_@suffixSalt@+=" -iframework $SDKROOT/System/Library/Frameworks"
144                   fi
145                 ''} add-flags-extra.sh
146                 cat add-flags-extra.sh >> $out/nix-support/add-flags.sh
147               '';
149             cc = prevStage.llvmPackages.clang-unwrapped;
150             bintools = prevStage.darwin.binutils;
152             isClang = true;
153             libc = prevStage.darwin.libSystem;
154             inherit (prevStage.llvmPackages) libcxx;
156             inherit lib;
157             inherit (prevStage) coreutils gnugrep;
159             stdenvNoCC = prevStage.ccWrapperStdenv;
160             runtimeShell = prevStage.ccWrapperStdenv.shell;
161           };
163       bash = prevStage.bash or bootstrapTools;
165       thisStdenv = import ../generic {
166         name = "${name}-stdenv-darwin";
168         buildPlatform = localSystem;
169         hostPlatform = localSystem;
170         targetPlatform = localSystem;
172         inherit config;
174         extraBuildInputs = [ prevStage.apple-sdk ];
175         inherit extraNativeBuildInputs;
177         preHook =
178           lib.optionalString (!isBuiltByNixpkgsCompiler bash) ''
179             # Don't patch #!/interpreter because it leads to retained
180             # dependencies on the bootstrapTools in the final stdenv.
181             dontPatchShebangs=1
182           ''
183           + ''
184             ${commonPreHook}
185             ${extraPreHook}
186           ''
187           + lib.optionalString (prevStage.darwin ? locale) ''
188             export PATH_LOCALE=${prevStage.darwin.locale}/share/locale
189           '';
191         shell = bash + "/bin/bash";
192         initialPath = [
193           bash
194           prevStage.file
195           bootstrapTools
196         ];
198         fetchurlBoot = import ../../build-support/fetchurl {
199           inherit lib;
200           stdenvNoCC = prevStage.ccWrapperStdenv or thisStdenv;
201           curl = bootstrapTools;
202         };
204         inherit cc;
206         # The stdenvs themselves don't use mkDerivation, so I need to specify this here
207         __stdenvImpureHostDeps = commonImpureHostDeps;
208         __extraImpureHostDeps = commonImpureHostDeps;
210         # Using the bootstrap tools curl for fetchers allows the stdenv bootstrap to avoid
211         # having a dependency on curl, allowing curl to be updated without triggering a
212         # new stdenv bootstrap on Darwin.
213         overrides =
214           self: super:
215           (overrides self super)
216           // {
217             fetchurl = thisStdenv.fetchurlBoot;
218             fetchpatch = super.fetchpatch.override { inherit (self) fetchurl; };
219             fetchzip = super.fetchzip.override { inherit (self) fetchurl; };
220           };
221       };
223     in
224     {
225       inherit config overlays;
226       stdenv = thisStdenv;
227     };
229   # Dependencies - these are packages that are rebuilt together in groups. Defining them here ensures they are
230   # asserted and overlayed together. It also removes a lot of clutter from the stage definitions.
231   #
232   # When multiple dependency sets share a dependency, it should be put in the one that will be (re)built first.
233   # That makes sure everything else will share the same dependency in the final stdenv.
235   allDeps =
236     checkFn: sets:
237     let
238       sets' = mergeDisjointAttrs sets;
239       result = lib.all checkFn (lib.attrValues sets');
240       resultDetails = lib.mapAttrs (_: checkFn) sets';
241     in
242     lib.traceIf (!result) (lib.deepSeq resultDetails resultDetails) result;
244   # These packages are built in stage 1 then never built again. They must not be included in the final overlay
245   # or as dependencies to packages that are in the final overlay. They are mostly tools used as native build inputs.
246   # Any libraries in the list must only be used as dependencies of packages in this list.
247   stage1Packages = prevStage: {
248     inherit (prevStage)
249       atf
250       autoconf
251       automake
252       bison
253       bmake
254       brotli
255       cmake
256       cpio
257       cyrus_sasl
258       ed
259       expat
260       flex
261       gettext
262       groff
263       jq
264       kyua
265       libedit
266       libtool
267       m4
268       meson
269       ninja
270       openldap
271       openssh
272       patchutils
273       pbzx
274       perl
275       pkg-config
276       python3
277       python3Minimal
278       scons
279       serf
280       sqlite
281       subversion
282       texinfo
283       unzip
284       which
285       ;
286   };
288   # These packages include both the core bintools (other than LLVM) packages as well as their dependencies.
289   bintoolsPackages = prevStage: {
290     inherit (prevStage)
291       cctools
292       ld64
293       bzip2
294       coreutils
295       gmp
296       gnugrep
297       libtapi
298       openssl
299       pcre2
300       xar
301       xz
302       ;
303   };
305   darwinPackages = prevStage: { inherit (prevStage.darwin) sigtool; };
306   darwinPackagesNoCC = prevStage: {
307     inherit (prevStage.darwin)
308       binutils
309       binutils-unwrapped
310       libSystem
311       locale
312       ;
313   };
315   # These packages are not allowed to be used in the Darwin bootstrap
316   disallowedPackages = prevStage: { inherit (prevStage) binutils-unwrapped curl; };
318   # LLVM tools packages are staged separately (xclang, stage3) from LLVM libs (xclang).
319   llvmLibrariesPackages = prevStage: { inherit (prevStage.llvmPackages) compiler-rt libcxx; };
320   llvmLibrariesDeps = _: { };
322   llvmToolsPackages = prevStage: {
323     inherit (prevStage.llvmPackages)
324       clang-unwrapped
325       libclang
326       libllvm
327       lld
328       llvm
329       ;
330   };
332   llvmToolsDeps = prevStage: { inherit (prevStage) libffi; };
334   # SDK packages include propagated packages and source release packages built during the bootstrap.
335   sdkPackages = prevStage: {
336     inherit (prevStage)
337       bash
338       libpng
339       libxml2
340       libxo
341       ncurses
342       openbsm
343       openpam
344       xcbuild
345       zlib
346       ;
347   };
348   sdkDarwinPackages = prevStage: {
349     inherit (prevStage.darwin)
350       Csu
351       adv_cmds
352       copyfile
353       libiconv
354       libresolv
355       libsbuf
356       libutil
357       system_cmds
358       ;
359   };
360   sdkPackagesNoCC = prevStage: { inherit (prevStage) apple-sdk; };
363 assert bootstrapTools.passthru.isFromBootstrapFiles or false; # sanity check
365   (
366     { }:
367     {
368       __raw = true;
370       apple-sdk = null;
372       cctools = null;
373       ld64 = null;
375       coreutils = null;
376       file = null;
377       gnugrep = null;
379       pbzx = null;
380       cpio = null;
382       jq = null;
384       darwin = {
385         binutils = null;
386         binutils-unwrapped = null;
387         libSystem = null;
388         sigtool = null;
389       };
391       llvmPackages = {
392         clang-unwrapped = null;
393         compiler-rt = null;
394         libcxx = null;
395         libllvm = null;
396       };
397     }
398   )
400   # Create a stage with the bootstrap tools. This will be used to build the subsequent stages and
401   # build up the standard environment.
402   #
403   # Note: Each stage depends only on the the packages in `prevStage`. If a package is not to be
404   # rebuilt, it should be passed through by inheriting it.
405   (
406     prevStage:
407     stageFun prevStage {
408       name = "bootstrap-stage0";
410       overrides = self: super: {
411         # We thread stage0's stdenv through under this name so downstream stages
412         # can use it for wrapping gcc too. This way, downstream stages don't need
413         # to refer to this stage directly, which violates the principle that each
414         # stage should only access the stage that came before it.
415         ccWrapperStdenv = self.stdenv;
417         bash = bootstrapTools // {
418           shellPath = "/bin/bash";
419         };
421         coreutils = bootstrapTools;
422         cpio = bootstrapTools;
423         file = null;
424         gnugrep = bootstrapTools;
425         pbzx = bootstrapTools;
427         jq = null;
429         cctools = bootstrapTools // {
430           libtool = bootstrapTools;
431           targetPrefix = "";
432           version = "boot";
433         };
435         ld64 = bootstrapTools // {
436           targetPrefix = "";
437           version = "boot";
438         };
440         darwin = super.darwin.overrideScope (
441           selfDarwin: superDarwin: {
442             binutils = super.wrapBintoolsWith {
443               name = "bootstrap-stage0-binutils-wrapper";
445               nativeTools = false;
446               nativeLibc = false;
448               expand-response-params = "";
449               libc = selfDarwin.libSystem;
451               inherit lib;
452               inherit (self) stdenvNoCC coreutils gnugrep;
453               runtimeShell = self.stdenvNoCC.shell;
455               bintools = selfDarwin.binutils-unwrapped;
457               # Bootstrap tools cctools needs the hook and wrappers to make sure things are signed properly,
458               # and additional linker flags to work around a since‐removed patch.
459               # This can be dropped once the bootstrap tools cctools has been updated to 1010.6.
460               extraBuildCommands = ''
461                 printf %s ${lib.escapeShellArg ''
462                   extraBefore+=("-F$DEVELOPER_DIR/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks")
463                   extraBefore+=("-L$DEVELOPER_DIR/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib")
464                 ''} >> $out/nix-support/add-local-ldflags-before.sh
466                 echo 'source ${selfDarwin.postLinkSignHook}' >> $out/nix-support/post-link-hook
468                 export signingUtils=${selfDarwin.signingUtils}
470                 wrap \
471                   install_name_tool ${../../build-support/bintools-wrapper/darwin-install_name_tool-wrapper.sh} \
472                   "${selfDarwin.binutils-unwrapped}/bin/install_name_tool"
474                 wrap \
475                   strip ${../../build-support/bintools-wrapper/darwin-strip-wrapper.sh} \
476                   "${selfDarwin.binutils-unwrapped}/bin/strip"
477               '';
478             };
480             binutils-unwrapped =
481               (superDarwin.binutils-unwrapped.override { enableManpages = false; }).overrideAttrs
482                 (old: {
483                   version = "boot";
484                   passthru = (old.passthru or { }) // {
485                     isFromBootstrapFiles = true;
486                   };
487                 });
489             locale = self.stdenv.mkDerivation {
490               name = "bootstrap-stage0-locale";
491               buildCommand = ''
492                 mkdir -p $out/share/locale
493               '';
494             };
496             sigtool = bootstrapTools;
497           }
498         );
500         llvmPackages =
501           super.llvmPackages
502           // (
503             let
504               tools = super.llvmPackages.tools.extend (
505                 selfTools: _: {
506                   libclang = self.stdenv.mkDerivation {
507                     name = "bootstrap-stage0-clang";
508                     version = "boot";
509                     outputs = [
510                       "out"
511                       "lib"
512                     ];
513                     buildCommand = ''
514                       mkdir -p $out/lib
515                       ln -s $out $lib
516                       ln -s ${bootstrapTools}/bin       $out/bin
517                       ln -s ${bootstrapTools}/lib/clang $out/lib
518                       ln -s ${bootstrapTools}/include   $out
519                     '';
520                     passthru = {
521                       isFromBootstrapFiles = true;
522                       hardeningUnsupportedFlags = [
523                         "fortify3"
524                         "shadowstack"
525                         "stackclashprotection"
526                         "zerocallusedregs"
527                       ];
528                     };
529                   };
530                   libllvm = self.stdenv.mkDerivation {
531                     name = "bootstrap-stage0-llvm";
532                     outputs = [
533                       "out"
534                       "lib"
535                     ];
536                     buildCommand = ''
537                       mkdir -p $out/bin $out/lib
538                       ln -s $out $lib
539                       for tool in ${toString super.darwin.binutils-unwrapped.llvm_cmds}; do
540                         cctoolsTool=''${tool//-/_}
541                         toolsrc="${bootstrapTools}/bin/$cctoolsTool"
542                         if [ -e "$toolsrc" ]; then
543                           ln -s "$toolsrc" $out/bin/llvm-$tool
544                         fi
545                       done
546                       ln -s ${bootstrapTools}/bin/dsymutil $out/bin/dsymutil
547                       ln -s ${bootstrapTools}/lib/libLLVM* $out/lib
548                     '';
549                     passthru.isFromBootstrapFiles = true;
550                   };
551                   lld = self.stdenv.mkDerivation {
552                     name = "bootstrap-stage0-lld";
553                     buildCommand = "";
554                     passthru = {
555                       isLLVM = true;
556                       isFromBootstrapFiles = true;
557                     };
558                   };
559                 }
560               );
561               libraries = super.llvmPackages.libraries.extend (
562                 _: _: {
563                   compiler-rt = self.stdenv.mkDerivation {
564                     name = "bootstrap-stage0-compiler-rt";
565                     buildCommand = ''
566                       mkdir -p $out/lib $out/share
567                       ln -s ${bootstrapTools}/lib/libclang_rt* $out/lib
568                       ln -s ${bootstrapTools}/lib/darwin       $out/lib
569                     '';
570                     passthru.isFromBootstrapFiles = true;
571                   };
572                   libcxx = self.stdenv.mkDerivation {
573                     name = "bootstrap-stage0-libcxx";
574                     buildCommand = ''
575                       mkdir -p $out/lib $out/include
576                       ln -s ${bootstrapTools}/lib/libc++.dylib $out/lib
577                       ln -s ${bootstrapTools}/include/c++      $out/include
578                     '';
579                     passthru = {
580                       isLLVM = true;
581                       isFromBootstrapFiles = true;
582                     };
583                   };
584                 }
585               );
586             in
587             { inherit tools libraries; } // tools // libraries
588           );
589       };
591       extraPreHook = ''
592         stripDebugFlags="-S" # llvm-strip does not support "-p" for Mach-O
593       '';
594     }
595   )
597   # This stage is primarily responsible for setting up versions of certain dependencies needed
598   # by the rest of the build process. This stage also builds CF and Libsystem to simplify assertions
599   # and assumptions for later by making sure both packages are present on x86_64-darwin and aarch64-darwin.
600   (
601     prevStage:
602     # previous stage0 stdenv:
603     assert allDeps isFromBootstrapFiles [
604       (llvmToolsPackages prevStage)
605       (llvmLibrariesPackages prevStage)
606       {
607         inherit (prevStage)
608           bash
609           cctools
610           coreutils
611           cpio
612           gnugrep
613           ld64
614           pbzx
615           ;
616         inherit (prevStage.darwin) binutils-unwrapped sigtool;
617       }
618     ];
620     assert allDeps isFromNixpkgs [
621       (sdkPackagesNoCC prevStage)
622       { inherit (prevStage.darwin) binutils libSystem; }
623     ];
625     stageFun prevStage {
626       name = "bootstrap-stage1";
628       overrides = self: super: {
629         inherit (prevStage) ccWrapperStdenv cctools ld64;
631         binutils-unwrapped = builtins.throw "nothing in the Darwin bootstrap should depend on GNU binutils";
632         curl = builtins.throw "nothing in the Darwin bootstrap can depend on curl";
634         # Use this stage’s CF to build CMake. It’s required but can’t be included in the stdenv.
635         cmake = self.cmakeMinimal;
637         # Use libiconvReal with gettext to break an infinite recursion.
638         gettext = super.gettext.override { libiconv = super.libiconvReal; };
640         # Disable tests because they use dejagnu, which fails to run.
641         libffi = super.libffi.override { doCheck = false; };
643         # Avoid pulling in a full python and its extra dependencies for the llvm/clang builds.
644         libxml2 = super.libxml2.override { pythonSupport = false; };
646         # Avoid pulling in openldap just to run Meson’s tests.
647         meson = super.meson.overrideAttrs { doInstallCheck = false; };
648         ninja = super.ninja.override { buildDocs = false; };
650         # pkg-config builds glib, which checks for `arpa/nameser.h` and fails to build if it can’t find it.
651         # libresolv is normally propagated by the SDK, but propagation is disabled early in the bootstrap.
652         # Trying to add libresolv as a dependency causes an infinite recursion. Use pkgconf instead.
653         pkg-config =
654           (super.pkg-config.override {
655             pkg-config = self.libpkgconf.override {
656               removeReferencesTo = self.removeReferencesTo.override {
657                 # Avoid an infinite recursion by using the previous stage‘s sigtool.
658                 signingUtils = prevStage.darwin.signingUtils.override { inherit (prevStage.darwin) sigtool; };
659               };
660             };
661             baseBinName = "pkgconf";
662           }).overrideAttrs
663             # Passthru the wrapped pkgconf’s stdenv to make the bootstrap assertions happy.
664             (
665               old: {
666                 passthru = old.passthru or { } // {
667                   inherit (self) stdenv;
668                 };
669               }
670             );
672         # Use a full Python for the bootstrap. This allows Meson to be built in stage 1 and makes it easier to build
673         # packages that have Python dependencies.
674         python3 = self.python3-bootstrap;
675         python3-bootstrap = super.python3.override {
676           self = self.python3-bootstrap;
677           pythonAttr = "python3-bootstrap";
678           enableLTO = false;
679           # Workaround for ld64 crashes on x86_64-darwin. Remove after 11.0 is made the default.
680           inherit (prevStage) apple-sdk_11;
681         };
683         scons = super.scons.override { python3Packages = self.python3.pkgs; };
685         xar = super.xarMinimal;
687         darwin = super.darwin.overrideScope (
688           selfDarwin: superDarwin: {
689             signingUtils = prevStage.darwin.signingUtils.override { inherit (selfDarwin) sigtool; };
691             postLinkSignHook = prevStage.darwin.postLinkSignHook.override { inherit (selfDarwin) sigtool; };
693             adv_cmds = superDarwin.adv_cmds.override {
694               # Break an infinite recursion between CMake and libtapi. CMake requires adv_cmds.ps, and adv_cmds
695               # requires a newer SDK that requires libtapi to build, which requires CMake.
696               inherit (prevStage) apple-sdk_11;
697             };
699             # Rewrap binutils with the real libSystem
700             binutils = superDarwin.binutils.override {
701               inherit (self) coreutils;
702               bintools = selfDarwin.binutils-unwrapped;
703               libc = selfDarwin.libSystem;
705               # Bootstrap tools cctools needs the hook and wrappers to make sure things are signed properly.
706               # This can be dropped once the bootstrap tools cctools has been updated to 1010.6.
707               extraBuildCommands = ''
708                 printf %s ${lib.escapeShellArg ''
709                   extraBefore+=("-F$DEVELOPER_DIR/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks")
710                   extraBefore+=("-L$DEVELOPER_DIR/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib")
711                 ''} >> $out/nix-support/add-local-ldflags-before.sh
713                 echo 'source ${selfDarwin.postLinkSignHook}' >> $out/nix-support/post-link-hook
715                 export signingUtils=${selfDarwin.signingUtils}
717                 wrap \
718                   install_name_tool ${../../build-support/bintools-wrapper/darwin-install_name_tool-wrapper.sh} \
719                   "${selfDarwin.binutils-unwrapped}/bin/install_name_tool"
721                 wrap \
722                   strip ${../../build-support/bintools-wrapper/darwin-strip-wrapper.sh} \
723                   "${selfDarwin.binutils-unwrapped}/bin/strip"
724               '';
725             };
727             # Avoid building unnecessary Python dependencies due to building LLVM manpages.
728             binutils-unwrapped = superDarwin.binutils-unwrapped.override {
729               inherit (self) cctools ld64;
730               enableManpages = false;
731             };
732           }
733         );
735         llvmPackages =
736           let
737             tools = super.llvmPackages.tools.extend (_: _: llvmToolsPackages prevStage);
738             libraries = super.llvmPackages.libraries.extend (_: _: llvmLibrariesPackages prevStage);
739           in
740           super.llvmPackages // { inherit tools libraries; } // tools // libraries;
741       };
743       extraNativeBuildInputs = lib.optionals localSystem.isAarch64 [
744         prevStage.updateAutotoolsGnuConfigScriptsHook
745         prevStage.gnu-config
746       ];
748       extraPreHook = ''
749         stripDebugFlags="-S" # llvm-strip does not support "-p" for Mach-O
750       '';
751     }
752   )
754   # First rebuild of LLVM. While this LLVM is linked to a bunch of junk from the bootstrap tools,
755   # the compiler-rt, libc++, and libc++abi it produces are not. The compiler will be
756   # rebuilt in a later stage, but those libraries will be used in the final stdenv.
757   (
758     prevStage:
759     # previous stage1 stdenv:
760     assert allDeps isFromBootstrapFiles [
761       (llvmLibrariesPackages prevStage)
762       (llvmToolsPackages prevStage)
763       { inherit (prevStage) ld64; }
764     ];
766     assert allDeps isBuiltByBootstrapFilesCompiler [
767       (stage1Packages prevStage)
768       (darwinPackages prevStage)
769       (llvmLibrariesDeps prevStage)
770       (llvmToolsDeps prevStage)
771       (sdkPackages prevStage)
772       (sdkDarwinPackages prevStage)
773     ];
775     assert allDeps isFromNixpkgs [
776       (darwinPackagesNoCC prevStage)
777       (sdkPackagesNoCC prevStage)
778     ];
780     stageFun prevStage {
781       name = "bootstrap-stage-xclang";
783       overrides =
784         self: super:
785         mergeDisjointAttrs [
786           (stage1Packages prevStage)
787           (disallowedPackages prevStage)
788           # Only cctools and ld64 are rebuilt from `bintoolsPackages` to avoid rebuilding their dependencies
789           # again in this stage after building them in stage 1.
790           (lib.filterAttrs (name: _: name != "ld64" && name != "cctools") (bintoolsPackages prevStage))
791           (llvmToolsDeps prevStage)
792           (sdkPackages prevStage)
793           (sdkPackagesNoCC prevStage)
794           {
795             inherit (prevStage) ccWrapperStdenv;
797             # Disable ld64’s install check phase because the required LTO libraries are not built yet.
798             ld64 = super.ld64.overrideAttrs { doInstallCheck = false; };
800             darwin = super.darwin.overrideScope (
801               selfDarwin: superDarwin:
802               darwinPackages prevStage
803               // sdkDarwinPackages prevStage
804               // {
805                 inherit (prevStage.darwin) libSystem;
806                 binutils-unwrapped = superDarwin.binutils-unwrapped.override { enableManpages = false; };
807               }
808             );
809           }
810         ];
812       extraNativeBuildInputs = lib.optionals localSystem.isAarch64 [
813         prevStage.updateAutotoolsGnuConfigScriptsHook
814         prevStage.gnu-config
815       ];
817       extraPreHook = ''
818         stripDebugFlags="-S" # llvm-strip does not support "-p" for Mach-O
819       '';
820     }
821   )
823   # This stage rebuilds the SDK. It also rebuilds bash, which will be needed in later stages
824   # to use in patched shebangs (e.g., to make sure `icu-config` uses bash from nixpkgs).
825   (
826     prevStage:
827     # previous stage-xclang stdenv:
828     assert allDeps isBuiltByBootstrapFilesCompiler [
829       (stage1Packages prevStage)
830       (bintoolsPackages prevStage)
831       (darwinPackages prevStage)
832       (llvmToolsDeps prevStage)
833       (llvmToolsPackages prevStage)
834       (sdkPackages prevStage)
835       (sdkDarwinPackages prevStage)
836     ];
838     assert allDeps isBuiltByNixpkgsCompiler [
839       (llvmLibrariesDeps prevStage)
840       (llvmLibrariesPackages prevStage)
841     ];
843     assert allDeps isFromNixpkgs [
844       (darwinPackagesNoCC prevStage)
845       (sdkPackagesNoCC prevStage)
846     ];
848     stageFun prevStage {
849       name = "bootstrap-stage2";
851       overrides =
852         self: super:
853         mergeDisjointAttrs [
854           (stage1Packages prevStage)
855           (disallowedPackages prevStage)
856           (bintoolsPackages prevStage)
857           (llvmLibrariesDeps prevStage)
858           (llvmToolsDeps prevStage)
859           {
860             inherit (prevStage) ccWrapperStdenv;
862             # Avoid an infinite recursion due to the SDK’s including ncurses, which depends on bash in its `dev` output.
863             bash = super.bash.override { stdenv = self.darwin.bootstrapStdenv; };
865             # Avoid pulling in a full python and its extra dependencies for the llvm/clang builds.
866             libxml2 = super.libxml2.override { pythonSupport = false; };
868             # Use Bash from this stage to avoid propagating Bash from a previous stage to the final stdenv.
869             ncurses = super.ncurses.override {
870               stdenv = self.darwin.bootstrapStdenv.override { shell = lib.getExe self.bash; };
871             };
873             darwin = super.darwin.overrideScope (
874               selfDarwin: superDarwin:
875               darwinPackages prevStage
876               // {
877                 inherit (prevStage.darwin) binutils-unwrapped;
878                 # Rewrap binutils so it uses the rebuilt Libsystem.
879                 binutils = superDarwin.binutils.override {
880                   inherit (prevStage) expand-response-params;
881                   libc = selfDarwin.libSystem;
882                 };
883               }
884             );
886             llvmPackages =
887               let
888                 tools = super.llvmPackages.tools.extend (
889                   _: _: llvmToolsPackages prevStage // { inherit (prevStage.llvmPackages) clangNoCompilerRtWithLibc; }
890                 );
891                 libraries = super.llvmPackages.libraries.extend (_: _: llvmLibrariesPackages prevStage);
892               in
893               super.llvmPackages // { inherit tools libraries; } // tools // libraries;
894           }
895         ];
897       extraNativeBuildInputs = lib.optionals localSystem.isAarch64 [
898         prevStage.updateAutotoolsGnuConfigScriptsHook
899         prevStage.gnu-config
900       ];
902       extraPreHook = ''
903         stripDebugFlags="-S" # llvm-strip does not support "-p" for Mach-O
904       '';
905     }
906   )
908   # Rebuild LLVM with LLVM. This stage also rebuilds certain dependencies needed by LLVM.
909   # The SDK (but not its other inputs) is also rebuilt this stage to pick up the rebuilt cctools for `libtool`.
910   (
911     prevStage:
912     # previous stage2 stdenv:
913     assert allDeps isBuiltByBootstrapFilesCompiler [
914       (stage1Packages prevStage)
915       (bintoolsPackages prevStage)
916       (darwinPackages prevStage)
917       (llvmToolsPackages prevStage)
918       (llvmToolsDeps prevStage)
919     ];
921     assert allDeps isBuiltByNixpkgsCompiler [
922       (llvmLibrariesDeps prevStage)
923       (llvmLibrariesPackages prevStage)
924       (sdkPackages prevStage)
925       (sdkDarwinPackages prevStage)
926     ];
928     assert allDeps isFromNixpkgs [
929       (darwinPackagesNoCC prevStage)
930       (sdkPackagesNoCC prevStage)
931     ];
933     stageFun prevStage {
934       name = "bootstrap-stage3";
936       overrides =
937         self: super:
938         mergeDisjointAttrs [
939           (stage1Packages prevStage)
940           (disallowedPackages prevStage)
941           (llvmLibrariesDeps prevStage)
942           (sdkPackages prevStage)
943           {
944             inherit (prevStage) ccWrapperStdenv;
946             # Disable tests because they use dejagnu, which fails to run.
947             libffi = super.libffi.override { doCheck = false; };
949             xar = super.xarMinimal;
951             darwin = super.darwin.overrideScope (
952               selfDarwin: superDarwin:
953               darwinPackages prevStage
954               // sdkDarwinPackages prevStage
955               // {
956                 inherit (prevStage.darwin) libSystem;
958                 # binutils-unwrapped needs to build the LLVM man pages, which requires a lot of Python stuff
959                 # that ultimately ends up depending on git. Fortunately, the git dependency is only for check
960                 # inputs. The following set of overrides allow the LLVM documentation to be built without
961                 # pulling curl (and other packages like ffmpeg) into the stdenv bootstrap.
962                 binutils-unwrapped = superDarwin.binutils-unwrapped.override (old: {
963                   llvm-manpages = super.llvmPackages.llvm-manpages.override {
964                     python3Packages = self.python3.pkgs.overrideScope (
965                       _: superPython: {
966                         hatch-vcs = superPython.hatch-vcs.overrideAttrs { doInstallCheck = false; };
967                         markdown-it-py = superPython.markdown-it-py.overrideAttrs { doInstallCheck = false; };
968                         mdit-py-plugins = superPython.mdit-py-plugins.overrideAttrs { doInstallCheck = false; };
969                         myst-parser = superPython.myst-parser.overrideAttrs { doInstallCheck = false; };
970                       }
971                     );
972                   };
973                 });
974               }
975             );
977             llvmPackages =
978               let
979                 libraries = super.llvmPackages.libraries.extend (_: _: llvmLibrariesPackages prevStage);
980               in
981               super.llvmPackages // { inherit libraries; } // libraries;
982           }
983         ];
985       extraNativeBuildInputs = lib.optionals localSystem.isAarch64 [
986         prevStage.updateAutotoolsGnuConfigScriptsHook
987         prevStage.gnu-config
988       ];
990       extraPreHook = ''
991         stripDebugFlags="-S" # llvm-strip does not support "-p" for Mach-O
992       '';
993     }
994   )
996   # Construct a standard environment with the new clang. Also use the new compiler to rebuild
997   # everything that will be part of the final stdenv and isn’t required by it, CF, or Libsystem.
998   (
999     prevStage:
1000     # previous stage3 stdenv:
1001     assert allDeps isBuiltByBootstrapFilesCompiler [
1002       (stage1Packages prevStage)
1003       (darwinPackages prevStage)
1004     ];
1006     assert allDeps isBuiltByNixpkgsCompiler [
1007       (bintoolsPackages prevStage)
1008       (llvmLibrariesDeps prevStage)
1009       (llvmLibrariesPackages prevStage)
1010       (llvmToolsDeps prevStage)
1011       (llvmToolsPackages prevStage)
1012       (sdkPackages prevStage)
1013       (sdkDarwinPackages prevStage)
1014     ];
1016     assert allDeps isFromNixpkgs [
1017       (darwinPackagesNoCC prevStage)
1018       (sdkPackagesNoCC prevStage)
1019     ];
1021     stageFun prevStage {
1022       name = "bootstrap-stage4";
1024       overrides =
1025         self: super:
1026         mergeDisjointAttrs [
1027           (bintoolsPackages prevStage)
1028           (disallowedPackages prevStage)
1029           (llvmLibrariesDeps prevStage)
1030           (llvmToolsDeps prevStage)
1031           (sdkPackages prevStage)
1032           (sdkPackagesNoCC prevStage)
1033           {
1034             inherit (prevStage) ccWrapperStdenv;
1036             # Rebuild locales and sigtool with the new clang.
1037             darwin = super.darwin.overrideScope (
1038               _: superDarwin:
1039               sdkDarwinPackages prevStage
1040               // {
1041                 inherit (prevStage.darwin) binutils-unwrapped libSystem;
1042                 binutils = superDarwin.binutils.override {
1043                   # Build expand-response-params with last stage like below
1044                   inherit (prevStage) expand-response-params;
1045                 };
1046                 # Avoid rebuilding bmake (and Python) just for locales
1047                 locale = superDarwin.locale.override { inherit (prevStage) bmake; };
1048               }
1049             );
1051             llvmPackages =
1052               let
1053                 tools = super.llvmPackages.tools.extend (
1054                   _: _:
1055                   llvmToolsPackages prevStage
1056                   // {
1057                     libcxxClang = super.wrapCCWith rec {
1058                       nativeTools = false;
1059                       nativeLibc = false;
1061                       inherit (prevStage) expand-response-params;
1063                       extraPackages = [ self.llvmPackages.compiler-rt ];
1065                       extraBuildCommands = ''
1066                         rsrc="$out/resource-root"
1067                         mkdir "$rsrc"
1068                         ln -s "${lib.getLib cc}/lib/clang/${lib.versions.major (lib.getVersion cc)}/include" "$rsrc"
1069                         echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
1070                         ln -s "${prevStage.llvmPackages.compiler-rt.out}/lib" "$rsrc/lib"
1071                         ln -s "${prevStage.llvmPackages.compiler-rt.out}/share" "$rsrc/share"
1072                       '';
1074                       cc = self.llvmPackages.clang-unwrapped;
1075                       bintools = self.darwin.binutils;
1077                       isClang = true;
1078                       libc = self.darwin.libSystem;
1079                       inherit (self.llvmPackages) libcxx;
1081                       inherit lib;
1082                       inherit (self)
1083                         stdenvNoCC
1084                         coreutils
1085                         gnugrep
1086                         runtimeShell
1087                         ;
1088                     };
1089                   }
1090                 );
1091                 libraries = super.llvmPackages.libraries.extend (_: _: llvmLibrariesPackages prevStage);
1092               in
1093               super.llvmPackages // { inherit tools libraries; } // tools // libraries;
1094           }
1095         ];
1097       extraNativeBuildInputs = lib.optionals localSystem.isAarch64 [
1098         prevStage.updateAutotoolsGnuConfigScriptsHook
1099         prevStage.gnu-config
1100       ];
1102       extraPreHook = ''
1103         stripDebugFlags="-S" # llvm-strip does not support "-p" for Mach-O
1104       '';
1105     }
1106   )
1108   # Construct the final stdenv. The version of LLVM provided should match the one defined in
1109   # `all-packages.nix` for Darwin. Nothing should depend on the bootstrap tools or originate from
1110   # the bootstrap tools.
1111   #
1112   # When updating the Darwin stdenv, make sure that the result has no dependency (`nix-store -qR`)
1113   # on `bootstrapTools` or the binutils built in stage 1.
1114   (
1115     prevStage:
1116     # previous stage4 stdenv:
1118     assert allDeps isBuiltByNixpkgsCompiler [
1119       (lib.filterAttrs (_: pkg: lib.getName pkg != "pkg-config-wrapper") (stage1Packages prevStage)) # pkg-config is a wrapper
1120       (bintoolsPackages prevStage)
1121       (darwinPackages prevStage)
1122       (llvmLibrariesDeps prevStage)
1123       (llvmLibrariesPackages prevStage)
1124       (llvmToolsDeps prevStage)
1125       (llvmToolsPackages prevStage)
1126       (sdkPackages prevStage)
1127       (sdkDarwinPackages prevStage)
1128       { inherit (prevStage.pkg-config) pkg-config; }
1129     ];
1131     assert allDeps isFromNixpkgs [
1132       (darwinPackagesNoCC prevStage)
1133       (sdkPackagesNoCC prevStage)
1134     ];
1136     let
1137       cc = prevStage.llvmPackages.clang;
1138     in
1139     {
1140       inherit config overlays;
1141       stdenv = import ../generic {
1142         name = "stdenv-darwin";
1144         buildPlatform = localSystem;
1145         hostPlatform = localSystem;
1146         targetPlatform = localSystem;
1148         inherit config;
1150         preHook = ''
1151           ${commonPreHook}
1152           stripDebugFlags="-S" # llvm-strip does not support "-p" for Mach-O
1153           export PATH_LOCALE=${prevStage.darwin.locale}/share/locale
1154         '';
1156         initialPath = ((import ../generic/common-path.nix) { pkgs = prevStage; });
1158         extraNativeBuildInputs = lib.optionals localSystem.isAarch64 [
1159           prevStage.updateAutotoolsGnuConfigScriptsHook
1160         ];
1162         extraBuildInputs = [ prevStage.apple-sdk ];
1164         inherit cc;
1166         shell = cc.shell;
1168         inherit (prevStage.stdenv) fetchurlBoot;
1170         extraAttrs = {
1171           inherit bootstrapTools;
1172           libc = prevStage.darwin.libSystem;
1173           shellPackage = prevStage.bash;
1174         };
1176         disallowedRequisites = [ bootstrapTools.out ];
1178         allowedRequisites =
1179           (
1180             with prevStage;
1181             [
1182               apple-sdk
1183               bash
1184               bzip2.bin
1185               bzip2.out
1186               cc.expand-response-params
1187               cctools
1188               cctools.libtool
1189               coreutils
1190               darwin.binutils
1191               darwin.binutils.bintools
1192               diffutils
1193               ed
1194               file
1195               findutils
1196               gawk
1197               gettext
1198               gmp.out
1199               gnugrep
1200               gnugrep.pcre2.out
1201               gnumake
1202               gnused
1203               gnutar
1204               gzip
1205               ld64.lib
1206               ld64.out
1207               libffi.out
1208               libtapi.out
1209               libunistring.out
1210               libxml2.out
1211               ncurses.dev
1212               ncurses.man
1213               ncurses.out
1214               openbsm
1215               openpam
1216               openssl.out
1217               patch
1218               xar.lib
1219               xcbuild
1220               xcbuild.xcrun
1221               xz.bin
1222               xz.out
1223               zlib.dev
1224               zlib.out
1225             ]
1226             ++ apple-sdk.propagatedBuildInputs
1227           )
1228           ++ lib.optionals localSystem.isAarch64 [
1229             prevStage.updateAutotoolsGnuConfigScriptsHook
1230             prevStage.gnu-config
1231           ]
1232           ++ lib.optionals localSystem.isx86_64 [ prevStage.darwin.Csu ]
1233           ++ (with prevStage.darwin; [
1234             libiconv.out
1235             libresolv.out
1236             libsbuf.out
1237             libSystem
1238             locale
1239           ])
1240           ++ (with prevStage.llvmPackages; [
1241             bintools-unwrapped
1242             clang-unwrapped
1243             (lib.getLib clang-unwrapped)
1244             compiler-rt
1245             compiler-rt.dev
1246             libcxx
1247             libcxx.dev
1248             lld
1249             llvm
1250             llvm.lib
1251           ]);
1253         __stdenvImpureHostDeps = commonImpureHostDeps;
1254         __extraImpureHostDeps = commonImpureHostDeps;
1256         overrides =
1257           self: super:
1258           mergeDisjointAttrs [
1259             (llvmLibrariesDeps prevStage)
1260             (llvmToolsDeps prevStage)
1261             (sdkPackages prevStage)
1262             (sdkPackagesNoCC prevStage)
1263             {
1264               inherit (prevStage)
1265                 diffutils
1266                 ed
1267                 file
1268                 findutils
1269                 gawk
1270                 gettext
1271                 gnumake
1272                 gnused
1273                 gnutar
1274                 gzip
1275                 patch
1276                 ;
1278               # TODO: Simplify when dropping support for macOS < 11.
1279               "apple-sdk_${builtins.replaceStrings [ "." ] [ "_" ] sdkMajorVersion}" = self.apple-sdk;
1281               darwin = super.darwin.overrideScope (
1282                 _: _:
1283                 sdkDarwinPackages prevStage
1284                 // {
1285                   inherit (prevStage.darwin) libSystem locale sigtool;
1286                 }
1287                 // lib.optionalAttrs (super.stdenv.targetPlatform == localSystem) {
1288                   inherit (prevStage.darwin) binutils binutils-unwrapped;
1289                 }
1290               );
1291             }
1292             (lib.optionalAttrs (super.stdenv.targetPlatform == localSystem) (
1293               (bintoolsPackages prevStage)
1294               // {
1295                 inherit (prevStage.llvmPackages) clang;
1296                 # Need to get rid of these when cross-compiling.
1297                 "llvmPackages_${lib.versions.major prevStage.llvmPackages.release_version}" =
1298                   let
1299                     llvmVersion = lib.versions.major prevStage.llvmPackages.release_version;
1300                     tools = super."llvmPackages_${llvmVersion}".tools.extend (
1301                       _: _: llvmToolsPackages prevStage // { inherit (prevStage.llvmPackages) clang; }
1302                     );
1303                     libraries = super."llvmPackages_${llvmVersion}".libraries.extend (
1304                       _: _: llvmLibrariesPackages prevStage
1305                     );
1306                   in
1307                   super."llvmPackages_${llvmVersion}" // { inherit tools libraries; } // tools // libraries;
1308               }
1309             ))
1310           ];
1311       };
1312     }
1313   )
1315   # This "no-op" stage is just a place to put the assertions about the final stage.
1316   (
1317     prevStage:
1318     # previous final stage stdenv:
1319     assert isBuiltByNixpkgsCompiler prevStage.cctools;
1320     assert isBuiltByNixpkgsCompiler prevStage.ld64;
1321     assert isBuiltByNixpkgsCompiler prevStage.darwin.sigtool;
1323     assert isFromNixpkgs prevStage.darwin.libSystem;
1324     assert isFromNixpkgs prevStage.darwin.binutils-unwrapped;
1326     assert isBuiltByNixpkgsCompiler prevStage.llvmPackages.clang-unwrapped;
1327     assert isBuiltByNixpkgsCompiler prevStage.llvmPackages.libllvm;
1328     assert isBuiltByNixpkgsCompiler prevStage.llvmPackages.libcxx;
1329     assert isBuiltByNixpkgsCompiler prevStage.llvmPackages.compiler-rt;
1331     # Make sure these evaluate since they were disabled explicitly in the bootstrap.
1332     assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
1333     assert isFromNixpkgs prevStage.binutils-unwrapped.src;
1334     assert isBuiltByNixpkgsCompiler prevStage.curl;
1336     # libiconv should be an alias for darwin.libiconv
1337     assert prevStage.libiconv == prevStage.darwin.libiconv;
1339     {
1340       inherit (prevStage) config overlays stdenv;
1341     }
1342   )