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