Merge pull request #330481 from philiptaron/issue-208242/stdenv/darwin/make-bootstrap-tools.nix

freshBootstrapTools: refactor to use callPackage style for Darwin

authored by toonn and committed by GitHub 9857d640 54770984

+486 -388
+25
pkgs/stdenv/darwin/bootstrap-tools.nix
···
··· 1 + { 2 + lib, 3 + stdenv, 4 + bootstrapTools, 5 + unpack, 6 + }: 7 + 8 + builtins.derivation { 9 + inherit (stdenv.hostPlatform) system; 10 + 11 + name = "bootstrap-tools"; 12 + builder = "${unpack}/bin/bash"; 13 + 14 + args = [ 15 + "${unpack}/bootstrap-tools-unpack.sh" 16 + bootstrapTools 17 + ]; 18 + 19 + PATH = lib.makeBinPath [ 20 + (builtins.placeholder "out") 21 + unpack 22 + ]; 23 + 24 + allowedReferences = [ "out" ]; 25 + }
+46 -388
pkgs/stdenv/darwin/make-bootstrap-tools.nix
··· 1 - { pkgspath ? ../../.., test-pkgspath ? pkgspath 2 - , localSystem ? { system = builtins.currentSystem; } 3 - , crossSystem ? null 4 - , bootstrapFiles ? null 5 }: 6 7 - let cross = if crossSystem != null 8 - then { inherit crossSystem; } 9 - else {}; 10 - custom-bootstrap = if bootstrapFiles != null 11 - then { stdenvStages = args: 12 - let args' = args // { bootstrapFiles = bootstrapFiles; }; 13 - in (import "${pkgspath}/pkgs/stdenv/darwin" args'); 14 - } 15 - else {}; 16 - in with import pkgspath ({ inherit localSystem; } // cross // custom-bootstrap); 17 - 18 - rec { 19 - build = stdenv.mkDerivation { 20 - name = "stdenv-bootstrap-tools"; 21 - 22 - nativeBuildInputs = [ dumpnar nukeReferences ]; 23 - 24 - buildCommand = let 25 - inherit (lib) 26 - getBin 27 - getDev 28 - getLib 29 - ; 30 - 31 - coreutils_ = (coreutils.override (args: { 32 - # We want coreutils without ACL support. 33 - aclSupport = false; 34 - # Cannot use a single binary build, or it gets dynamically linked against gmp. 35 - singleBinary = false; 36 - })).overrideAttrs (oa: { 37 - # Increase header size to be able to inject extra RPATHs. Otherwise 38 - # x86_64-darwin build fails as: 39 - # https://cache.nixos.org/log/g5wyq9xqshan6m3kl21bjn1z88hx48rh-stdenv-bootstrap-tools.drv 40 - NIX_LDFLAGS = (oa.NIX_LDFLAGS or "") + " -headerpad_max_install_names"; 41 - }); 42 - 43 - # Avoid messing with libkrb5 and libnghttp2. 44 - curl_ = curlMinimal.override (args: { 45 - gssSupport = false; 46 - http2Support = false; 47 - scpSupport = false; 48 - }); 49 - 50 - unpackScript = writeText "bootstrap-tools-unpack.sh" '' 51 - set -euo pipefail 52 - 53 - echo Unpacking the bootstrap tools... >&2 54 - mkdir $out 55 - tar xf "$1" -C $out 56 - 57 - updateInstallName() { 58 - local path="$1" 59 - 60 - cp "$path" "$path.new" 61 - install_name_tool -id "$path" "$path.new" 62 - codesign -f -i "$(basename "$path")" -s - "$path.new" 63 - mv -f "$path.new" "$path" 64 - } 65 - 66 - find $out/lib -type f -name '*.dylib' -print0 | while IFS= read -r -d $'\0' lib; do 67 - updateInstallName "$lib" 68 - done 69 - 70 - # as is a wrapper around clang. need to replace the nuked store paths 71 - sed -i 's|/.*/bin/|'"$out"'/bin/|' $out/bin/as 72 - 73 - # Provide a gunzip script. 74 - cat > $out/bin/gunzip <<EOF 75 - #!$out/bin/sh 76 - exec $out/bin/gzip -d "\$@" 77 - EOF 78 - chmod +x $out/bin/gunzip 79 - 80 - # Provide fgrep/egrep. 81 - echo "#! $out/bin/sh" > $out/bin/egrep 82 - echo "exec $out/bin/grep -E \"\$@\"" >> $out/bin/egrep 83 - echo "#! $out/bin/sh" > $out/bin/fgrep 84 - echo "exec $out/bin/grep -F \"\$@\"" >> $out/bin/fgrep 85 - 86 - cat >$out/bin/dsymutil << EOF 87 - #!$out/bin/sh 88 - EOF 89 - 90 - chmod +x $out/bin/egrep $out/bin/fgrep $out/bin/dsymutil 91 - ''; 92 - 93 - in 94 - '' 95 - mkdir -p $out/bin $out/lib $out/lib/darwin 96 - 97 - ${lib.optionalString stdenv.targetPlatform.isx86_64 '' 98 - # Copy libSystem's .o files for various low-level boot stuff. 99 - cp -d ${getLib darwin.Libsystem}/lib/*.o $out/lib 100 - 101 - # Resolv is actually a link to another package, so let's copy it properly 102 - cp -L ${getLib darwin.Libsystem}/lib/libresolv.9.dylib $out/lib 103 - ''} 104 - 105 - cp -rL ${getDev darwin.Libsystem}/include $out 106 - chmod -R u+w $out/include 107 - cp -rL ${getDev libiconv}/include/* $out/include 108 - cp -rL ${getDev gnugrep.pcre2}/include/* $out/include 109 - mv $out/include $out/include-Libsystem 110 - 111 - # Copy binutils. 112 - for i in as ld ar ranlib nm strip otool install_name_tool lipo codesign_allocate; do 113 - cp ${getBin darwin.binutils-unwrapped}/bin/$i $out/bin 114 - done 115 - cp -d ${getLib ld64}/lib/libcodedirectory*.dylib $out/lib 116 - 117 - # Copy coreutils, bash, etc. 118 - cp ${getBin coreutils_}/bin/* $out/bin 119 - (cd $out/bin && rm vdir dir sha*sum pinky factor pathchk runcon shuf who whoami shred users) 120 - 121 - cp -d ${getBin bash}/bin/{ba,}sh $out/bin 122 - cp -d ${getBin diffutils}/bin/* $out/bin 123 - cp ${getBin findutils}/bin/{find,xargs} $out/bin 124 - cp -d ${getBin gawk}/bin/{g,}awk $out/bin 125 - cp -d ${getBin gnugrep}/bin/grep $out/bin 126 - cp -d ${getBin gnumake}/bin/* $out/bin 127 - cp -d ${getBin gnused}/bin/* $out/bin 128 - cp -d ${getBin patch}/bin/* $out/bin 129 - 130 - cp -d ${getLib gettext}/lib/libintl*.dylib $out/lib 131 - cp -d ${getLib gnugrep.pcre2}/lib/libpcre2*.dylib $out/lib 132 - cp -d ${getLib libiconv}/lib/lib*.dylib $out/lib 133 - cp -d ${getLib libxml2}/lib/libxml2*.dylib $out/lib 134 - cp -d ${getLib ncurses}/lib/libncurses*.dylib $out/lib 135 - 136 - # copy package extraction tools 137 - cp -d ${getBin bzip2}/bin/b{,un}zip2 $out/bin 138 - cp ${getBin cpio}/bin/cpio $out/bin 139 - cp ${getBin gnutar}/bin/tar $out/bin 140 - cp ${getBin gzip}/bin/.gzip-wrapped $out/bin/gzip 141 - cp ${getBin pbzx}/bin/pbzx $out/bin 142 - cp ${getBin xz}/bin/xz $out/bin 143 - cp -d ${getLib bzip2}/lib/libbz2*.dylib $out/lib 144 - cp -d ${getLib gmpxx}/lib/libgmp*.dylib $out/lib 145 - cp -d ${getLib xar}/lib/libxar*.dylib $out/lib 146 - cp -d ${getLib xz}/lib/liblzma*.dylib $out/lib 147 - cp -d ${getLib zlib}/lib/libz*.dylib $out/lib 148 - 149 - # This used to be in-nixpkgs, but now is in the bundle 150 - # because I can't be bothered to make it partially static 151 - cp ${getBin curl_}/bin/curl $out/bin 152 - cp -d ${getLib curl_}/lib/libcurl*.dylib $out/lib 153 - cp -d ${getLib openssl}/lib/*.dylib $out/lib 154 - 155 - # Copy what we need of clang 156 - cp -d ${getBin llvmPackages.clang-unwrapped}/bin/clang{,++,-cl,-cpp,-[0-9]*} $out/bin 157 - cp -d ${getLib llvmPackages.clang-unwrapped}/lib/libclang-cpp*.dylib $out/lib 158 - cp -rd ${getLib llvmPackages.clang-unwrapped}/lib/clang $out/lib 159 - 160 - cp -d ${getLib llvmPackages.libcxx}/lib/libc++*.dylib $out/lib 161 - mkdir -p $out/lib/darwin 162 - cp -d ${getLib llvmPackages.compiler-rt}/lib/darwin/libclang_rt.{,profile_}osx.a $out/lib/darwin 163 - cp -d ${getLib llvmPackages.compiler-rt}/lib/libclang_rt.{,profile_}osx.a $out/lib 164 - cp -d ${getLib llvmPackages.llvm}/lib/libLLVM.dylib $out/lib 165 - cp -d ${getLib libffi}/lib/libffi*.dylib $out/lib 166 - 167 - mkdir $out/include 168 - cp -rd ${getDev llvmPackages.libcxx}/include/c++ $out/include 169 - 170 - # copy .tbd assembly utils 171 - cp ${getBin darwin.rewrite-tbd}/bin/rewrite-tbd $out/bin 172 - cp -d ${getLib libyaml}/lib/libyaml*.dylib $out/lib 173 - 174 - # copy sigtool 175 - cp -d ${getBin darwin.sigtool}/bin/{codesign,sigtool} $out/bin 176 - 177 - cp -d ${getLib darwin.libtapi}/lib/libtapi*.dylib $out/lib 178 - 179 - # tools needed to unpack bootstrap archive 180 - mkdir -p unpack/bin unpack/lib 181 - cp -d ${getBin bash}/bin/{bash,sh} unpack/bin 182 - cp ${getBin coreutils_}/bin/mkdir unpack/bin 183 - cp ${getBin gnutar}/bin/tar unpack/bin 184 - cp ${getBin xz}/bin/xz unpack/bin 185 - cp -d ${getLib gettext}/lib/libintl*.dylib unpack/lib 186 - cp -d ${getLib libiconv}/lib/lib*.dylib unpack/lib 187 - cp -d ${getLib xz}/lib/liblzma*.dylib unpack/lib 188 - cp ${unpackScript} unpack/bootstrap-tools-unpack.sh 189 - 190 - # 191 - # All files copied. Perform processing to update references to point into 192 - # the archive 193 - # 194 - 195 - chmod -R u+w $out unpack 196 - 197 - # - change nix store library paths to use @rpath/library 198 - # - if needed add an rpath containing lib/ 199 - # - strip executable 200 - rpathify() { 201 - local libs=$(${stdenv.cc.targetPrefix}otool -L "$1" | tail -n +2 | grep -o "$NIX_STORE.*-\S*" || true) 202 - local lib rpath 203 - for lib in $libs; do 204 - ${stdenv.cc.targetPrefix}install_name_tool -change $lib "@rpath/$(basename "$lib")" "$1" 205 - done 206 - 207 - case "$(dirname "$1")" in 208 - */bin) 209 - # Strip executables even further 210 - ${stdenv.cc.targetPrefix}strip "$i" 211 - rpath='@executable_path/../lib' 212 - ;; 213 - */lib) 214 - # the '/.' suffix is required 215 - rpath='@loader_path/.' 216 - ;; 217 - */lib/darwin) 218 - rpath='@loader_path/..' 219 - ;; 220 - *) 221 - echo unkown executable $1 >&2 222 - exit 1 223 - ;; 224 - esac 225 226 - # if shared object contains references add an rpath to lib/ 227 - if ${stdenv.cc.targetPrefix}otool -l "$1"| grep -q '@rpath/'; then 228 - ${stdenv.cc.targetPrefix}install_name_tool -add_rpath "$rpath" "$1" 229 - fi 230 } 231 232 - # check that linked library paths exist in lib 233 - # must be run after rpathify is performed 234 - checkDeps() { 235 - local deps=$(${stdenv.cc.targetPrefix}otool -l "$1"| grep -o '@rpath/[^ ]*' || true) 236 - local lib 237 - shopt -s extglob 238 - for lib in $deps; do 239 - local root="''${1/\/@(lib|bin)\/*}" 240 - if [[ ! -e $root/''${lib/@rpath/lib} ]]; then 241 - echo "error: $1 missing lib for $lib" >&2 242 - exit 1 243 - fi 244 - done 245 - shopt -u extglob 246 - } 247 248 - for i in {unpack,$out}/bin/* {unpack,$out}/lib{,/darwin}/*.dylib; do 249 - if [[ ! -L $i ]] && isMachO "$i"; then 250 - rpathify "$i" 251 - checkDeps "$i" 252 - fi 253 - done 254 255 - nuke-refs {unpack,$out}/bin/* 256 - nuke-refs {unpack,$out}/lib/* 257 - nuke-refs $out/lib/darwin/* 258 - 259 - mkdir $out/.pack 260 - mv $out/* $out/.pack 261 - mv $out/.pack $out/pack 262 - 263 - mkdir $out/on-server 264 - cp -r unpack $out 265 - 266 - XZ_OPT="-9 -T $NIX_BUILD_CORES" tar cvJf $out/on-server/bootstrap-tools.tar.xz \ 267 - --hard-dereference --sort=name --numeric-owner --owner=0 --group=0 --mtime=@1 -C $out/pack . 268 - dumpnar $out/unpack | xz -9 -T $NIX_BUILD_CORES > $out/on-server/unpack.nar.xz 269 - ''; 270 - 271 - allowedReferences = []; 272 - 273 - meta = { 274 - maintainers = [ lib.maintainers.copumpkin ]; 275 - }; 276 - }; 277 - 278 - bootstrapFiles = { 279 - bootstrapTools = "${build}/on-server/bootstrap-tools.tar.xz"; 280 - unpack = runCommand "unpack" { allowedReferences = []; } '' 281 - cp -r ${build}/unpack $out 282 - ''; 283 }; 284 285 - bootstrapTools = derivation { 286 - inherit (stdenv.hostPlatform) system; 287 - 288 - name = "bootstrap-tools"; 289 - builder = "${bootstrapFiles.unpack}/bin/bash"; 290 - 291 - args = [ 292 - "${bootstrapFiles.unpack}/bootstrap-tools-unpack.sh" 293 - bootstrapFiles.bootstrapTools 294 - ]; 295 - 296 - PATH = lib.makeBinPath [ 297 - (placeholder "out") 298 - bootstrapFiles.unpack 299 - ]; 300 - 301 - allowedReferences = [ "out" ]; 302 - }; 303 - 304 - test = derivation { 305 - name = "test-bootstrap-tools"; 306 - inherit (stdenv.hostPlatform) system; 307 - builder = "${bootstrapTools}/bin/bash"; 308 - args = [ "-euo" "pipefail" "-c" "eval \"$buildCommand\"" ]; 309 - PATH = lib.makeBinPath [ bootstrapTools ]; 310 - tools = bootstrapTools; 311 - "${stdenv.cc.darwinMinVersionVariable}" = stdenv.cc.darwinMinVersion; 312 - 313 - # Create a pure environment where we use just what's in the bootstrap tools. 314 - buildCommand = '' 315 - mkdir -p $out/bin 316 - 317 - for exe in $tools/bin/*; do 318 - [[ $exe =~ bunzip2|codesign.*|false|install_name_tool|ld|lipo|pbzx|ranlib|rewrite-tbd|sigtool ]] && continue 319 - $exe --version > /dev/null || { echo $exe failed >&2; exit 1; } 320 - done 321 - 322 - # run all exes that don't take a --version flag 323 - bunzip2 -h 324 - codesign --help 325 - codesign_allocate -i $tools/bin/true -r -o true 326 - false || (($? == 1)) 327 - install_name_tool -id true true 328 - ld -v 329 - lipo -info true 330 - pbzx -v 331 - # ranlib gets tested bulding hello 332 - rewrite-tbd </dev/null 333 - sigtool -h 334 - rm true 335 - 336 - # The grep will return a nonzero exit code if there is no match, and we want to assert that we have 337 - # an SSL-capable curl 338 - curl --version | grep SSL 339 - 340 - # This approximates a bootstrap version of libSystem can that be 341 - # assembled via fetchurl. Adapted from main libSystem expression. 342 - mkdir libSystem-boot 343 - cp -vr \ 344 - ${stdenv.cc.libc_dev}/lib/libSystem.B.tbd \ 345 - ${stdenv.cc.libc_dev}/lib/system \ 346 - libSystem-boot 347 - 348 - sed -i "s|/usr/lib/system/|$PWD/libSystem-boot/system/|g" libSystem-boot/libSystem.B.tbd 349 - ln -s libSystem.B.tbd libSystem-boot/libSystem.tbd 350 - # End of bootstrap libSystem 351 - 352 - export flags="-idirafter $tools/include-Libsystem --sysroot=$tools -L$tools/lib -L$PWD/libSystem-boot" 353 - 354 - export CPP="clang -E $flags" 355 - export CC="clang $flags" 356 - export CXX="clang++ $flags --stdlib=libc++ -isystem$tools/include/c++/v1" 357 - 358 - # NOTE: These tests do a separate 'install' step (using cp), because 359 - # having clang write directly to the final location apparently will make 360 - # running the executable fail signature verification. (SIGKILL'd) 361 - # 362 - # Suspect this is creating a corrupt entry in the kernel cache, but it is 363 - # unique to cctools ld. (The problem goes away with `-fuse-ld=lld`.) 364 - 365 - echo '#include <stdio.h>' >> hello1.c 366 - echo '#include <float.h>' >> hello1.c 367 - echo '#include <limits.h>' >> hello1.c 368 - echo 'int main() { printf("Hello World\n"); return 0; }' >> hello1.c 369 - $CC -o hello1 hello1.c 370 - cp hello1 $out/bin/ 371 - $out/bin/hello1 372 - 373 - echo '#include <iostream>' >> hello3.cc 374 - echo 'int main() { std::cout << "Hello World\n"; }' >> hello3.cc 375 - $CXX -v -o hello3 hello3.cc 376 - cp hello3 $out/bin/ 377 - $out/bin/hello3 378 - 379 - # test that libc++.dylib rpaths are correct so it can reference libc++abi.dylib when linked. 380 - # using -Wl,-flat_namespace is required to generate an error 381 - mkdir libtest/ 382 - ln -s $tools/lib/libc++.dylib libtest/ 383 - clang++ -Wl,-flat_namespace -idirafter $tools/include-Libsystem -isystem$tools/include/c++/v1 \ 384 - --sysroot=$tools -L./libtest -L$PWD/libSystem-boot hello3.cc 385 - 386 - tar xvf ${hello.src} 387 - cd hello-* 388 - # hello configure detects -liconv is needed but doesn't add to the link step 389 - LDFLAGS=-liconv ./configure --prefix=$out 390 - make 391 - make install 392 - $out/bin/hello 393 - ''; 394 - }; 395 396 # The ultimate test: bootstrap a whole stdenv from the tools specified above and get a package set out of it 397 # eg: nix-build -A freshBootstrapTools.test-pkgs.stdenv ··· 400 # that platform. 401 localSystem = if crossSystem != null then crossSystem else localSystem; 402 403 - stdenvStages = args: let 404 - args' = args // { inherit bootstrapFiles; }; 405 - in (import (test-pkgspath + "/pkgs/stdenv/darwin") args'); 406 }; 407 }
··· 1 + { 2 + pkgspath ? ../../.., 3 + test-pkgspath ? pkgspath, 4 + localSystem ? { 5 + system = builtins.currentSystem; 6 + }, 7 + crossSystem ? null, 8 + bootstrapFiles ? null, 9 }: 10 11 + let 12 + cross = if crossSystem != null then { inherit crossSystem; } else { }; 13 14 + custom-bootstrap = 15 + if bootstrapFiles != null then 16 + { 17 + stdenvStages = 18 + args: 19 + let 20 + args' = args // { 21 + bootstrapFiles = bootstrapFiles; 22 + }; 23 + in 24 + (import "${pkgspath}/pkgs/stdenv/darwin" args'); 25 } 26 + else 27 + { }; 28 29 + pkgs = import pkgspath ({ inherit localSystem; } // cross // custom-bootstrap); 30 31 + build = pkgs.callPackage ./stdenv-bootstrap-tools.nix { }; 32 33 + bootstrapTools = pkgs.callPackage ./bootstrap-tools.nix { 34 + inherit (build.bootstrapFiles) bootstrapTools unpack; 35 }; 36 37 + test = pkgs.callPackage ./test-bootstrap-tools.nix { inherit bootstrapTools; }; 38 39 # The ultimate test: bootstrap a whole stdenv from the tools specified above and get a package set out of it 40 # eg: nix-build -A freshBootstrapTools.test-pkgs.stdenv ··· 43 # that platform. 44 localSystem = if crossSystem != null then crossSystem else localSystem; 45 46 + stdenvStages = 47 + args: 48 + let 49 + args' = args // { 50 + inherit (build) bootstrapFiles; 51 + }; 52 + in 53 + (import (test-pkgspath + "/pkgs/stdenv/darwin") args'); 54 }; 55 + in 56 + { 57 + inherit 58 + build 59 + bootstrapTools 60 + test 61 + test-pkgs 62 + ; 63 + 64 + inherit (build) bootstrapFiles; 65 }
+306
pkgs/stdenv/darwin/stdenv-bootstrap-tools.nix
···
··· 1 + { 2 + lib, 3 + stdenv, 4 + bash, 5 + bzip2, 6 + coreutils, 7 + cpio, 8 + curlMinimal, 9 + darwin, 10 + diffutils, 11 + dumpnar, 12 + findutils, 13 + gawk, 14 + gettext, 15 + gmpxx, 16 + gnugrep, 17 + gnumake, 18 + gnused, 19 + gnutar, 20 + gzip, 21 + ld64, 22 + libffi, 23 + libiconv, 24 + libxml2, 25 + libyaml, 26 + llvmPackages, 27 + ncurses, 28 + nukeReferences, 29 + openssl, 30 + patch, 31 + pbzx, 32 + runCommand, 33 + writeText, 34 + xar, 35 + xz, 36 + zlib, 37 + }: 38 + stdenv.mkDerivation (finalAttrs: { 39 + name = "stdenv-bootstrap-tools"; 40 + 41 + nativeBuildInputs = [ 42 + dumpnar 43 + nukeReferences 44 + ]; 45 + 46 + buildCommand = 47 + let 48 + inherit (lib) getBin getDev getLib; 49 + 50 + coreutils_ = 51 + (coreutils.override (prevArgs: { 52 + # We want coreutils without ACL support. 53 + aclSupport = false; 54 + # Cannot use a single binary build, or it gets dynamically linked against gmp. 55 + singleBinary = false; 56 + })).overrideAttrs 57 + (prevAttrs: { 58 + # Increase header size to be able to inject extra RPATHs. Otherwise 59 + # x86_64-darwin build fails as: 60 + # https://cache.nixos.org/log/g5wyq9xqshan6m3kl21bjn1z88hx48rh-stdenv-bootstrap-tools.drv 61 + NIX_LDFLAGS = (prevAttrs.NIX_LDFLAGS or "") + " -headerpad_max_install_names"; 62 + }); 63 + 64 + # Avoid messing with libkrb5 and libnghttp2. 65 + curl_ = curlMinimal.override (prevArgs: { 66 + gssSupport = false; 67 + http2Support = false; 68 + scpSupport = false; 69 + }); 70 + 71 + unpackScript = writeText "bootstrap-tools-unpack.sh" '' 72 + set -euo pipefail 73 + 74 + echo Unpacking the bootstrap tools... >&2 75 + mkdir $out 76 + tar xf "$1" -C $out 77 + 78 + updateInstallName() { 79 + local path="$1" 80 + 81 + cp "$path" "$path.new" 82 + install_name_tool -id "$path" "$path.new" 83 + codesign -f -i "$(basename "$path")" -s - "$path.new" 84 + mv -f "$path.new" "$path" 85 + } 86 + 87 + find $out/lib -type f -name '*.dylib' -print0 | while IFS= read -r -d $'\0' lib; do 88 + updateInstallName "$lib" 89 + done 90 + 91 + # as is a wrapper around clang. need to replace the nuked store paths 92 + sed -i 's|/.*/bin/|'"$out"'/bin/|' $out/bin/as 93 + 94 + # Provide a gunzip script. 95 + cat > $out/bin/gunzip <<EOF 96 + #!$out/bin/sh 97 + exec $out/bin/gzip -d "\$@" 98 + EOF 99 + chmod +x $out/bin/gunzip 100 + 101 + # Provide fgrep/egrep. 102 + echo "#! $out/bin/sh" > $out/bin/egrep 103 + echo "exec $out/bin/grep -E \"\$@\"" >> $out/bin/egrep 104 + echo "#! $out/bin/sh" > $out/bin/fgrep 105 + echo "exec $out/bin/grep -F \"\$@\"" >> $out/bin/fgrep 106 + 107 + cat >$out/bin/dsymutil << EOF 108 + #!$out/bin/sh 109 + EOF 110 + 111 + chmod +x $out/bin/egrep $out/bin/fgrep $out/bin/dsymutil 112 + ''; 113 + 114 + in 115 + '' 116 + mkdir -p $out/bin $out/lib $out/lib/darwin 117 + 118 + ${lib.optionalString stdenv.targetPlatform.isx86_64 '' 119 + # Copy libSystem's .o files for various low-level boot stuff. 120 + cp -d ${getLib darwin.Libsystem}/lib/*.o $out/lib 121 + 122 + # Resolv is actually a link to another package, so let's copy it properly 123 + cp -L ${getLib darwin.Libsystem}/lib/libresolv.9.dylib $out/lib 124 + ''} 125 + 126 + cp -rL ${getDev darwin.Libsystem}/include $out 127 + chmod -R u+w $out/include 128 + cp -rL ${getDev libiconv}/include/* $out/include 129 + cp -rL ${getDev gnugrep.pcre2}/include/* $out/include 130 + mv $out/include $out/include-Libsystem 131 + 132 + # Copy binutils. 133 + for i in as ld ar ranlib nm strip otool install_name_tool lipo codesign_allocate; do 134 + cp ${getBin darwin.binutils-unwrapped}/bin/$i $out/bin 135 + done 136 + cp -d ${getLib ld64}/lib/libcodedirectory*.dylib $out/lib 137 + 138 + # Copy coreutils, bash, etc. 139 + cp ${getBin coreutils_}/bin/* $out/bin 140 + (cd $out/bin && rm vdir dir sha*sum pinky factor pathchk runcon shuf who whoami shred users) 141 + 142 + cp -d ${getBin bash}/bin/{ba,}sh $out/bin 143 + cp -d ${getBin diffutils}/bin/* $out/bin 144 + cp ${getBin findutils}/bin/{find,xargs} $out/bin 145 + cp -d ${getBin gawk}/bin/{g,}awk $out/bin 146 + cp -d ${getBin gnugrep}/bin/grep $out/bin 147 + cp -d ${getBin gnumake}/bin/* $out/bin 148 + cp -d ${getBin gnused}/bin/* $out/bin 149 + cp -d ${getBin patch}/bin/* $out/bin 150 + 151 + cp -d ${getLib gettext}/lib/libintl*.dylib $out/lib 152 + cp -d ${getLib gnugrep.pcre2}/lib/libpcre2*.dylib $out/lib 153 + cp -d ${getLib libiconv}/lib/lib*.dylib $out/lib 154 + cp -d ${getLib libxml2}/lib/libxml2*.dylib $out/lib 155 + cp -d ${getLib ncurses}/lib/libncurses*.dylib $out/lib 156 + 157 + # copy package extraction tools 158 + cp -d ${getBin bzip2}/bin/b{,un}zip2 $out/bin 159 + cp ${getBin cpio}/bin/cpio $out/bin 160 + cp ${getBin gnutar}/bin/tar $out/bin 161 + cp ${getBin gzip}/bin/.gzip-wrapped $out/bin/gzip 162 + cp ${getBin pbzx}/bin/pbzx $out/bin 163 + cp ${getBin xz}/bin/xz $out/bin 164 + cp -d ${getLib bzip2}/lib/libbz2*.dylib $out/lib 165 + cp -d ${getLib gmpxx}/lib/libgmp*.dylib $out/lib 166 + cp -d ${getLib xar}/lib/libxar*.dylib $out/lib 167 + cp -d ${getLib xz}/lib/liblzma*.dylib $out/lib 168 + cp -d ${getLib zlib}/lib/libz*.dylib $out/lib 169 + 170 + # This used to be in-nixpkgs, but now is in the bundle 171 + # because I can't be bothered to make it partially static 172 + cp ${getBin curl_}/bin/curl $out/bin 173 + cp -d ${getLib curl_}/lib/libcurl*.dylib $out/lib 174 + cp -d ${getLib openssl}/lib/*.dylib $out/lib 175 + 176 + # Copy what we need of clang 177 + cp -d ${getBin llvmPackages.clang-unwrapped}/bin/clang{,++,-cl,-cpp,-[0-9]*} $out/bin 178 + cp -d ${getLib llvmPackages.clang-unwrapped}/lib/libclang-cpp*.dylib $out/lib 179 + cp -rd ${getLib llvmPackages.clang-unwrapped}/lib/clang $out/lib 180 + 181 + cp -d ${getLib llvmPackages.libcxx}/lib/libc++*.dylib $out/lib 182 + mkdir -p $out/lib/darwin 183 + cp -d ${getLib llvmPackages.compiler-rt}/lib/darwin/libclang_rt.{,profile_}osx.a $out/lib/darwin 184 + cp -d ${getLib llvmPackages.compiler-rt}/lib/libclang_rt.{,profile_}osx.a $out/lib 185 + cp -d ${getLib llvmPackages.llvm}/lib/libLLVM.dylib $out/lib 186 + cp -d ${getLib libffi}/lib/libffi*.dylib $out/lib 187 + 188 + mkdir $out/include 189 + cp -rd ${getDev llvmPackages.libcxx}/include/c++ $out/include 190 + 191 + # copy .tbd assembly utils 192 + cp ${getBin darwin.rewrite-tbd}/bin/rewrite-tbd $out/bin 193 + cp -d ${getLib libyaml}/lib/libyaml*.dylib $out/lib 194 + 195 + # copy sigtool 196 + cp -d ${getBin darwin.sigtool}/bin/{codesign,sigtool} $out/bin 197 + 198 + cp -d ${getLib darwin.libtapi}/lib/libtapi*.dylib $out/lib 199 + 200 + # tools needed to unpack bootstrap archive 201 + mkdir -p unpack/bin unpack/lib 202 + cp -d ${getBin bash}/bin/{bash,sh} unpack/bin 203 + cp ${getBin coreutils_}/bin/mkdir unpack/bin 204 + cp ${getBin gnutar}/bin/tar unpack/bin 205 + cp ${getBin xz}/bin/xz unpack/bin 206 + cp -d ${getLib gettext}/lib/libintl*.dylib unpack/lib 207 + cp -d ${getLib libiconv}/lib/lib*.dylib unpack/lib 208 + cp -d ${getLib xz}/lib/liblzma*.dylib unpack/lib 209 + cp ${unpackScript} unpack/bootstrap-tools-unpack.sh 210 + 211 + # 212 + # All files copied. Perform processing to update references to point into 213 + # the archive 214 + # 215 + 216 + chmod -R u+w $out unpack 217 + 218 + # - change nix store library paths to use @rpath/library 219 + # - if needed add an rpath containing lib/ 220 + # - strip executable 221 + rpathify() { 222 + local libs=$(${stdenv.cc.targetPrefix}otool -L "$1" | tail -n +2 | grep -o "$NIX_STORE.*-\S*" || true) 223 + local lib rpath 224 + for lib in $libs; do 225 + ${stdenv.cc.targetPrefix}install_name_tool -change $lib "@rpath/$(basename "$lib")" "$1" 226 + done 227 + 228 + case "$(dirname "$1")" in 229 + */bin) 230 + # Strip executables even further 231 + ${stdenv.cc.targetPrefix}strip "$i" 232 + rpath='@executable_path/../lib' 233 + ;; 234 + */lib) 235 + # the '/.' suffix is required 236 + rpath='@loader_path/.' 237 + ;; 238 + */lib/darwin) 239 + rpath='@loader_path/..' 240 + ;; 241 + *) 242 + echo unkown executable $1 >&2 243 + exit 1 244 + ;; 245 + esac 246 + 247 + # if shared object contains references add an rpath to lib/ 248 + if ${stdenv.cc.targetPrefix}otool -l "$1"| grep -q '@rpath/'; then 249 + ${stdenv.cc.targetPrefix}install_name_tool -add_rpath "$rpath" "$1" 250 + fi 251 + } 252 + 253 + # check that linked library paths exist in lib 254 + # must be run after rpathify is performed 255 + checkDeps() { 256 + local deps=$(${stdenv.cc.targetPrefix}otool -l "$1"| grep -o '@rpath/[^ ]*' || true) 257 + local lib 258 + shopt -s extglob 259 + for lib in $deps; do 260 + local root="''${1/\/@(lib|bin)\/*}" 261 + if [[ ! -e $root/''${lib/@rpath/lib} ]]; then 262 + echo "error: $1 missing lib for $lib" >&2 263 + exit 1 264 + fi 265 + done 266 + shopt -u extglob 267 + } 268 + 269 + for i in {unpack,$out}/bin/* {unpack,$out}/lib{,/darwin}/*.dylib; do 270 + if [[ ! -L $i ]] && isMachO "$i"; then 271 + rpathify "$i" 272 + checkDeps "$i" 273 + fi 274 + done 275 + 276 + nuke-refs {unpack,$out}/bin/* 277 + nuke-refs {unpack,$out}/lib/* 278 + nuke-refs $out/lib/darwin/* 279 + 280 + mkdir $out/.pack 281 + mv $out/* $out/.pack 282 + mv $out/.pack $out/pack 283 + 284 + mkdir $out/on-server 285 + cp -r unpack $out 286 + 287 + XZ_OPT="-9 -T $NIX_BUILD_CORES" tar cvJf $out/on-server/bootstrap-tools.tar.xz \ 288 + --hard-dereference --sort=name --numeric-owner --owner=0 --group=0 --mtime=@1 -C $out/pack . 289 + dumpnar $out/unpack | xz -9 -T $NIX_BUILD_CORES > $out/on-server/unpack.nar.xz 290 + ''; 291 + 292 + allowedReferences = [ ]; 293 + 294 + passthru = { 295 + bootstrapFiles = { 296 + bootstrapTools = "${finalAttrs.finalPackage}/on-server/bootstrap-tools.tar.xz"; 297 + unpack = runCommand "unpack" { allowedReferences = [ ]; } '' 298 + cp -r ${finalAttrs.finalPackage}/unpack $out 299 + ''; 300 + }; 301 + }; 302 + 303 + meta = { 304 + maintainers = [ lib.maintainers.copumpkin ]; 305 + }; 306 + })
+109
pkgs/stdenv/darwin/test-bootstrap-tools.nix
···
··· 1 + { 2 + lib, 3 + stdenv, 4 + bootstrapTools, 5 + hello, 6 + }: 7 + 8 + builtins.derivation { 9 + name = "test-bootstrap-tools"; 10 + 11 + inherit (stdenv.hostPlatform) system; 12 + 13 + builder = "${bootstrapTools}/bin/bash"; 14 + 15 + args = [ 16 + "-euo" 17 + "pipefail" 18 + "-c" 19 + "eval \"$buildCommand\"" 20 + ]; 21 + 22 + PATH = lib.makeBinPath [ bootstrapTools ]; 23 + 24 + tools = bootstrapTools; 25 + 26 + "${stdenv.cc.darwinMinVersionVariable}" = stdenv.cc.darwinMinVersion; 27 + 28 + # Create a pure environment where we use just what's in the bootstrap tools. 29 + buildCommand = '' 30 + mkdir -p $out/bin 31 + 32 + for exe in $tools/bin/*; do 33 + [[ $exe =~ bunzip2|codesign.*|false|install_name_tool|ld|lipo|pbzx|ranlib|rewrite-tbd|sigtool ]] && continue 34 + $exe --version > /dev/null || { echo $exe failed >&2; exit 1; } 35 + done 36 + 37 + # run all exes that don't take a --version flag 38 + bunzip2 -h 39 + codesign --help 40 + codesign_allocate -i $tools/bin/true -r -o true 41 + false || (($? == 1)) 42 + install_name_tool -id true true 43 + ld -v 44 + lipo -info true 45 + pbzx -v 46 + # ranlib gets tested bulding hello 47 + rewrite-tbd </dev/null 48 + sigtool -h 49 + rm true 50 + 51 + # The grep will return a nonzero exit code if there is no match, and we want to assert that we have 52 + # an SSL-capable curl 53 + curl --version | grep SSL 54 + 55 + # This approximates a bootstrap version of libSystem can that be 56 + # assembled via fetchurl. Adapted from main libSystem expression. 57 + mkdir libSystem-boot 58 + cp -vr \ 59 + ${stdenv.cc.libc_dev}/lib/libSystem.B.tbd \ 60 + ${stdenv.cc.libc_dev}/lib/system \ 61 + libSystem-boot 62 + 63 + sed -i "s|/usr/lib/system/|$PWD/libSystem-boot/system/|g" libSystem-boot/libSystem.B.tbd 64 + ln -s libSystem.B.tbd libSystem-boot/libSystem.tbd 65 + # End of bootstrap libSystem 66 + 67 + export flags="-idirafter $tools/include-Libsystem --sysroot=$tools -L$tools/lib -L$PWD/libSystem-boot" 68 + 69 + export CPP="clang -E $flags" 70 + export CC="clang $flags" 71 + export CXX="clang++ $flags --stdlib=libc++ -isystem$tools/include/c++/v1" 72 + 73 + # NOTE: These tests do a separate 'install' step (using cp), because 74 + # having clang write directly to the final location apparently will make 75 + # running the executable fail signature verification. (SIGKILL'd) 76 + # 77 + # Suspect this is creating a corrupt entry in the kernel cache, but it is 78 + # unique to cctools ld. (The problem goes away with `-fuse-ld=lld`.) 79 + 80 + echo '#include <stdio.h>' >> hello1.c 81 + echo '#include <float.h>' >> hello1.c 82 + echo '#include <limits.h>' >> hello1.c 83 + echo 'int main() { printf("Hello World\n"); return 0; }' >> hello1.c 84 + $CC -o hello1 hello1.c 85 + cp hello1 $out/bin/ 86 + $out/bin/hello1 87 + 88 + echo '#include <iostream>' >> hello3.cc 89 + echo 'int main() { std::cout << "Hello World\n"; }' >> hello3.cc 90 + $CXX -v -o hello3 hello3.cc 91 + cp hello3 $out/bin/ 92 + $out/bin/hello3 93 + 94 + # test that libc++.dylib rpaths are correct so it can reference libc++abi.dylib when linked. 95 + # using -Wl,-flat_namespace is required to generate an error 96 + mkdir libtest/ 97 + ln -s $tools/lib/libc++.dylib libtest/ 98 + clang++ -Wl,-flat_namespace -idirafter $tools/include-Libsystem -isystem$tools/include/c++/v1 \ 99 + --sysroot=$tools -L./libtest -L$PWD/libSystem-boot hello3.cc 100 + 101 + tar xvf ${hello.src} 102 + cd hello-* 103 + # hello configure detects -liconv is needed but doesn't add to the link step 104 + LDFLAGS=-liconv ./configure --prefix=$out 105 + make 106 + make install 107 + $out/bin/hello 108 + ''; 109 + }