From fe75f160324672d639469dc2da69f70d4eb466a4 Mon Sep 17 00:00:00 2001 From: Jude Taylor Date: Thu, 18 Jun 2015 10:03:32 -0700 Subject: [PATCH] move pure stdenv into a new directory, bring back the old one remove __impure from non-darwin OSes --- pkgs/stdenv/darwin/default.nix | 362 +++++------------- pkgs/stdenv/darwin/make-bootstrap-tools.nix | 10 +- pkgs/stdenv/default.nix | 8 +- pkgs/stdenv/generic/default.nix | 14 +- pkgs/stdenv/pure-darwin/default.nix | 297 ++++++++++++++ .../pure-darwin/make-bootstrap-tools.nix | 286 ++++++++++++++ pkgs/stdenv/pure-darwin/trivial-bootstrap.sh | 66 ++++ .../pure-darwin/unpack-bootstrap-tools.sh | 54 +++ 8 files changed, 830 insertions(+), 267 deletions(-) create mode 100644 pkgs/stdenv/pure-darwin/default.nix create mode 100644 pkgs/stdenv/pure-darwin/make-bootstrap-tools.nix create mode 100644 pkgs/stdenv/pure-darwin/trivial-bootstrap.sh create mode 100644 pkgs/stdenv/pure-darwin/unpack-bootstrap-tools.sh diff --git a/pkgs/stdenv/darwin/default.nix b/pkgs/stdenv/darwin/default.nix index d4b17a7909c7..ac396ecdf12b 100644 --- a/pkgs/stdenv/darwin/default.nix +++ b/pkgs/stdenv/darwin/default.nix @@ -4,294 +4,144 @@ , config ? {} }: -let - fetch = { file, sha256 }: import { - url = "https://dl.dropboxusercontent.com/u/2857322/${file}"; - inherit sha256; - executable = true; - }; - - bootstrapFiles = { - sh = fetch { file = "sh"; sha256 = "1qakpg37vl61jnkplz13m3g1csqr85cg8ybp6jwiv6apmg26isnm"; }; - bzip2 = fetch { file = "bzip2"; sha256 = "1gxa67255q9v00j1vn1mzyrnbwys2g1102cx02vpcyvvrl4vqxr0"; }; - mkdir = fetch { file = "mkdir"; sha256 = "1yfl8w65ksji7fggrbvqxw8lp0gm02qilk11n9axj2jxay53ngvg"; }; - cpio = fetch { file = "cpio"; sha256 = "0nssyg19smgcblwq1mfcw4djbd85md84d2f093qcqkbigdjg484b"; }; - }; - tarball = fetch { file = "bootstrap-tools.9.cpio.bz2"; sha256 = "0fd79k7gy3z3sba5w4f4lnrcpiwff31vw02480x1pdry8bbgbf2j"; }; -in rec { +rec { allPackages = import ../../top-level/all-packages.nix; - commonPreHook = '' - export NIX_ENFORCE_PURITY=1 + bootstrapTools = derivation { + inherit system; + + name = "trivial-bootstrap-tools"; + builder = "/bin/sh"; + args = [ ./trivial-bootstrap.sh ]; + + mkdir = "/bin/mkdir"; + ln = "/bin/ln"; + }; + + # The simplest stdenv possible to run fetchadc and get the Apple command-line tools + stage0 = rec { + fetchurl = import ../../build-support/fetchurl { + inherit stdenv; + curl = bootstrapTools; + }; + + stdenv = import ../generic { + inherit system config; + name = "stdenv-darwin-boot-0"; + shell = "/bin/bash"; + initialPath = [ bootstrapTools ]; + fetchurlBoot = fetchurl; + cc = "/no-such-path"; + }; + }; + + buildTools = import ../../os-specific/darwin/command-line-tools { + inherit (stage0) stdenv fetchurl; + xar = bootstrapTools; + gzip = bootstrapTools; + cpio = bootstrapTools; + }; + + preHook = '' export NIX_IGNORE_LD_THROUGH_GCC=1 + export NIX_DONT_SET_RPATH=1 + export NIX_NO_SELF_RPATH=1 + dontFixLibtool=1 stripAllFlags=" " # the Darwin "strip" command doesn't know "-s" + xargsFlags=" " export MACOSX_DEPLOYMENT_TARGET=10.7 - export SDKROOT= + # Use the 10.9 SDK if we're running on 10.9, and 10.10 if we're + # running on 10.10. We need to use the 10.10 headers for functions + # like readlinkat() that are dynamically detected by configure + # scripts. Very impure, obviously. + export SDKROOT=$(/usr/bin/xcrun --sdk macosx"$(/usr/bin/sw_vers -productVersion | /usr/bin/cut -d. -f1,2)" --show-sdk-path 2> /dev/null || echo /) + export NIX_CFLAGS_COMPILE+=" --sysroot=/var/empty -idirafter $SDKROOT/usr/include -F$SDKROOT/System/Library/Frameworks -Wno-multichar -Wno-deprecated-declarations" + export NIX_LDFLAGS_AFTER+=" -L$SDKROOT/usr/lib" export CMAKE_OSX_ARCHITECTURES=x86_64 ''; - # libSystem and its transitive dependencies. Get used to this; it's a recurring theme in darwin land - libSystemClosure = [ - "/usr/lib/libSystem.dylib" - "/usr/lib/libSystem.B.dylib" - "/usr/lib/libobjc.A.dylib" - "/usr/lib/libobjc.dylib" - "/usr/lib/libauto.dylib" - "/usr/lib/libc++abi.dylib" - "/usr/lib/libc++.1.dylib" - "/usr/lib/libDiagnosticMessagesClient.dylib" - "/usr/lib/system" - ]; + # A stdenv that wraps the Apple command-line tools and our other trivial symlinked bootstrap tools + stage1 = rec { + nativePrefix = "${buildTools.tools}/Library/Developer/CommandLineTools/usr"; - # The one dependency of /bin/sh :( - binShClosure = [ "/usr/lib/libncurses.5.4.dylib" ]; + stdenv = import ../generic { + name = "stdenv-darwin-boot-1"; - bootstrapTools = derivation rec { - inherit system tarball; + inherit system config; + inherit (stage0.stdenv) shell fetchurlBoot; - name = "bootstrap-tools"; - builder = bootstrapFiles.sh; # Not a filename! Attribute 'sh' on bootstrapFiles - args = [ ./unpack-bootstrap-tools.sh ]; + initialPath = stage0.stdenv.initialPath ++ [ nativePrefix ]; - inherit (bootstrapFiles) mkdir bzip2 cpio; + preHook = preHook + "\n" + '' + export NIX_LDFLAGS_AFTER+=" -L/usr/lib" + export NIX_ENFORCE_PURITY= + export NIX_CFLAGS_COMPILE+=" -isystem ${nativePrefix}/include/c++/v1 -stdlib=libc++" + export NIX_CFLAGS_LINK+=" -stdlib=libc++ -Wl,-rpath,${nativePrefix}/lib" + ''; - __impureHostDeps = binShClosure ++ libSystemClosure; - }; - - stageFun = step: last: {shell ? "${bootstrapTools}/bin/sh", - overrides ? (pkgs: {}), - extraPreHook ? "", - extraBuildInputs ? with last.pkgs; [ xz darwin.CF libcxx ], - extraInitialPath ? [], - allowedRequisites ? null}: - let - thisStdenv = import ../generic { - inherit system config shell extraBuildInputs allowedRequisites; - - name = "stdenv-darwin-boot-${toString step}"; - - cc = if isNull last then "/no-such-path" else import ../../build-support/cc-wrapper { - inherit shell; - inherit (last) stdenv; - inherit (last.pkgs.darwin) dyld; - - nativeTools = true; - nativePrefix = bootstrapTools; - nativeLibc = false; - libc = last.pkgs.darwin.Libsystem; - cc = { name = "clang-9.9.9"; outPath = bootstrapTools; }; + cc = import ../../build-support/cc-wrapper { + nativeTools = true; + nativePrefix = nativePrefix; + nativeLibc = true; + stdenv = stage0.stdenv; + shell = "/bin/bash"; + cc = { + name = "clang-9.9.9"; + cc = "/usr"; + outPath = nativePrefix; }; - - preHook = stage0.stdenv.lib.optionalString (shell == "${bootstrapTools}/bin/sh") '' - # Don't patch #!/interpreter because it leads to retained - # dependencies on the bootstrapTools in the final stdenv. - dontPatchShebangs=1 - '' + '' - ${commonPreHook} - ${extraPreHook} - ''; - initialPath = extraInitialPath ++ [ bootstrapTools ]; - fetchurlBoot = import ../../build-support/fetchurl { - stdenv = stage0.stdenv; - curl = bootstrapTools; - }; - - # The stdenvs themselves don't use mkDerivation, so I need to specify this here - __stdenvImpureHostDeps = binShClosure ++ libSystemClosure; - __extraImpureHostDeps = binShClosure ++ libSystemClosure; - - extraAttrs = { inherit platform; }; - overrides = pkgs: (overrides pkgs) // { fetchurl = thisStdenv.fetchurlBoot; }; + isClang = true; }; - - thisPkgs = allPackages { - inherit system platform; - bootStdenv = thisStdenv; - }; - in { stdenv = thisStdenv; pkgs = thisPkgs; }; - - stage0 = stageFun 0 null { - overrides = orig: with stage0; rec { - darwin = orig.darwin // { - Libsystem = stdenv.mkDerivation { - name = "bootstrap-Libsystem"; - buildCommand = '' - mkdir -p $out - ln -s ${bootstrapTools}/lib $out/lib - ln -s ${bootstrapTools}/include-Libsystem $out/include - ''; - }; - dyld = bootstrapTools; - }; - - libcxx = stdenv.mkDerivation { - name = "bootstrap-libcxx"; - phases = [ "installPhase" "fixupPhase" ]; - installPhase = '' - mkdir -p $out/lib $out/include - ln -s ${bootstrapTools}/lib/libc++.dylib $out/lib/libc++.dylib - ln -s ${bootstrapTools}/include/c++ $out/include/c++ - ''; - setupHook = ../../development/compilers/llvm/3.5/libc++/setup-hook.sh; - }; - - libcxxabi = stdenv.mkDerivation { - name = "bootstrap-libcxxabi"; - buildCommand = '' - mkdir -p $out/lib - ln -s ${bootstrapTools}/lib/libc++abi.dylib $out/lib/libc++abi.dylib - ''; - }; - }; - - extraBuildInputs = []; - }; - - persistent0 = _: {}; - - stage1 = with stage0; stageFun 1 stage0 { - extraPreHook = "export NIX_CFLAGS_COMPILE+=\" -F${bootstrapTools}/Library/Frameworks\""; - extraBuildInputs = [ pkgs.libcxx ]; - - allowedRequisites = - [ bootstrapTools ] ++ (with pkgs; [ libcxx libcxxabi ]) ++ [ pkgs.darwin.Libsystem ]; - - overrides = persistent0; - }; - - persistent1 = orig: with stage1.pkgs; { - inherit - zlib patchutils m4 scons flex perl bison unifdef unzip openssl icu python - libxml2 gettext sharutils gmp libarchive ncurses pkg-config libedit groff - openssh sqlite sed serf openldap db cyrus-sasl expat apr-util subversion xz - findfreetype libssh curl cmake autoconf automake libtool ed cpio coreutils; - - darwin = orig.darwin // { - inherit (darwin) - dyld Libsystem xnu configd libdispatch libclosure launchd; + pkgs = allPackages { + inherit system platform; + bootStdenv = stdenv; }; }; - stage2 = with stage1; stageFun 2 stage1 { - allowedRequisites = - [ bootstrapTools ] ++ - (with pkgs; [ xz libcxx libcxxabi icu ]) ++ - (with pkgs.darwin; [ dyld Libsystem CF ]); + stage2 = rec { + stdenv = import ../generic { + name = "stdenv-darwin-boot-2"; - overrides = persistent1; - }; + inherit system config; + inherit (stage1.stdenv) shell fetchurlBoot preHook cc; - persistent2 = orig: with stage2.pkgs; { - inherit - patchutils m4 scons flex perl bison unifdef unzip openssl python - gettext sharutils libarchive pkg-config groff bash subversion - openssh sqlite sed serf openldap db cyrus-sasl expat apr-util - findfreetype libssh curl cmake autoconf automake libtool cpio - libcxx libcxxabi; - - darwin = orig.darwin // { - inherit (darwin) - dyld Libsystem xnu configd libdispatch libclosure launchd libiconv; + initialPath = [ stage1.pkgs.xz ] ++ stage1.stdenv.initialPath; + }; + pkgs = allPackages { + inherit system platform; + bootStdenv = stdenv; }; }; - stage3 = with stage2; stageFun 3 stage2 { - shell = "${pkgs.bash}/bin/bash"; + # Use stage1 to build a whole set of actual tools so we don't have to rely on the Apple prebuilt ones or + # the ugly symlinked bootstrap tools anymore. + stage3 = with stage2; import ../generic { + name = "stdenv-darwin-boot-3"; - # We have a valid shell here (this one has no bootstrap-tools runtime deps) so stageFun - # enables patchShebangs above. Unfortunately, patchShebangs ignores our $SHELL setting - # and instead goes by $PATH, which happens to contain bootstrapTools. So it goes and - # patches our shebangs back to point at bootstrapTools. This makes sure bash comes first. - extraInitialPath = [ pkgs.bash ]; - - allowedRequisites = - [ bootstrapTools ] ++ - (with pkgs; [ icu bash libcxx libcxxabi ]) ++ - (with pkgs.darwin; [ dyld Libsystem ]); - - overrides = persistent2; - }; - - persistent3 = orig: with stage3.pkgs; { - inherit - gnumake gzip gnused bzip2 gawk ed xz patch bash - libcxxabi libcxx ncurses libffi zlib llvm gmp pcre gnugrep - coreutils findutils diffutils patchutils; - - llvmPackages = orig.llvmPackages // { - inherit (llvmPackages) llvm clang-unwrapped; - }; - - darwin = orig.darwin // { - inherit (darwin) dyld Libsystem libiconv; - }; - }; - - stage4 = with stage3; stageFun 4 stage3 { - shell = "${pkgs.bash}/bin/bash"; - extraInitialPath = [ pkgs.bash ]; - overrides = persistent3; - }; - - persistent4 = orig: with stage4.pkgs; { - inherit - gnumake gzip gnused bzip2 gawk ed xz patch bash - libcxxabi libcxx ncurses libffi zlib icu llvm gmp pcre gnugrep - coreutils findutils diffutils patchutils binutils binutils-raw; - - llvmPackages = orig.llvmPackages // { - inherit (llvmPackages) llvm clang-unwrapped; - }; - - darwin = orig.darwin // { - inherit (darwin) dyld Libsystem cctools CF libiconv; - }; - }; - - stage5 = with stage4; import ../generic rec { inherit system config; inherit (stdenv) fetchurlBoot; - name = "stdenv-darwin"; + initialPath = (import ../common-path.nix) { inherit pkgs; }; - preHook = commonPreHook; - - __stdenvImpureHostDeps = binShClosure ++ libSystemClosure; - __extraImpureHostDeps = binShClosure ++ libSystemClosure; - - initialPath = import ../common-path.nix { inherit pkgs; }; - shell = "${pkgs.bash}/bin/bash"; + preHook = preHook + "\n" + '' + export NIX_ENFORCE_PURITY=1 + ''; cc = import ../../build-support/cc-wrapper { - inherit stdenv shell; - nativeTools = false; - nativeLibc = false; - inherit (pkgs) coreutils binutils; - inherit (pkgs.darwin) dyld; - cc = pkgs.llvmPackages.clang-unwrapped; - libc = pkgs.darwin.Libsystem; + inherit stdenv; + nativeTools = false; + nativeLibc = true; + binutils = pkgs.darwin.cctools; + cc = pkgs.llvmPackages.clang-unwrapped; + coreutils = pkgs.coreutils; + shell = "${pkgs.bash}/bin/bash"; + extraPackages = [ pkgs.libcxx ]; + isClang = true; }; - extraBuildInputs = with pkgs; [ darwin.CF libcxx ]; - - extraAttrs = { - inherit platform bootstrapTools; - libc = pkgs.darwin.Libsystem; - shellPackage = pkgs.bash; - }; - - allowedRequisites = (with pkgs; [ - xz libcxx libcxxabi icu gmp gnumake findutils bzip2 llvm zlib libffi - coreutils ed diffutils gnutar gzip ncurses gnused bash gawk - gnugrep llvmPackages.clang-unwrapped patch pcre binutils-raw binutils gettext - ]) ++ (with pkgs.darwin; [ - dyld Libsystem CF cctools libiconv - ]); - - overrides = orig: persistent4 orig // { - clang = cc; - inherit cc; - }; + shell = "${pkgs.bash}/bin/bash"; }; + + stdenvDarwin = stage3; } diff --git a/pkgs/stdenv/darwin/make-bootstrap-tools.nix b/pkgs/stdenv/darwin/make-bootstrap-tools.nix index 433638dd1bde..636410fdd788 100644 --- a/pkgs/stdenv/darwin/make-bootstrap-tools.nix +++ b/pkgs/stdenv/darwin/make-bootstrap-tools.nix @@ -63,15 +63,13 @@ rec { cp -d ${gnugrep.pcre}/lib/libpcre*.dylib $out/lib cp -d ${libiconv}/lib/libiconv*.dylib $out/lib - cp -d ${gettext}/lib/libintl*.dylib $out/lib - chmod +x $out/lib/libintl*.dylib # Copy what we need of clang - cp -d ${llvmPackages.clang-unwrapped}/bin/clang $out/bin - cp -d ${llvmPackages.clang-unwrapped}/bin/clang++ $out/bin - cp -d ${llvmPackages.clang-unwrapped}/bin/clang-3.6 $out/bin + cp -d ${llvmPackages.clang}/bin/clang $out/bin + cp -d ${llvmPackages.clang}/bin/clang++ $out/bin + cp -d ${llvmPackages.clang}/bin/clang-3.5 $out/bin - cp -rL ${llvmPackages.clang-unwrapped}/lib/clang $out/lib + cp -rL ${llvmPackages.clang}/lib/clang $out/lib cp -d ${libcxx}/lib/libc++*.dylib $out/lib cp -d ${libcxxabi}/lib/libc++abi*.dylib $out/lib diff --git a/pkgs/stdenv/default.nix b/pkgs/stdenv/default.nix index 28ba80014717..71bdc3e8f829 100644 --- a/pkgs/stdenv/default.nix +++ b/pkgs/stdenv/default.nix @@ -37,7 +37,13 @@ rec { stdenvLinux = (import ./linux { inherit system allPackages platform config lib; }).stdenvLinux; # Darwin standard environment. - stdenvDarwin = (import ./darwin { inherit system allPackages platform config;}).stage5; + stdenvDarwin = (import ./darwin { inherit system allPackages platform config;}).stdenvDarwin; + + # Pure Darwin standard environment. Allows building with the sandbox enabled. To use, + # you can add this to your nixpkgs config: + # + # replaceStdenv = {pkgs}: pkgs.allStdenvs.stdenvDarwinPure + stdenvDarwinPure = (import ./pure-darwin { inherit system allPackages platform config;}).stage5; # Select the appropriate stdenv for the platform `system'. stdenv = diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix index bdad51949308..07486093da83 100644 --- a/pkgs/stdenv/generic/default.nix +++ b/pkgs/stdenv/generic/default.nix @@ -21,6 +21,8 @@ let whitelist = config.whitelistedLicenses or []; blacklist = config.blacklistedLicenses or []; + ifDarwin = attrs: if system == "x86_64-darwin" then attrs else {}; + onlyLicenses = list: lib.lists.all (license: let l = lib.licenses.${license.shortName or "BROKEN"} or false; in @@ -132,7 +134,9 @@ let assert licenseAllowed attrs; lib.addPassthru (derivation ( - (removeAttrs attrs ["meta" "passthru" "crossAttrs" "pos"]) + (removeAttrs attrs + ["meta" "passthru" "crossAttrs" "pos" + "__impureHostDeps" "__propagatedImpureHostDeps"]) // (let buildInputs = attrs.buildInputs or []; nativeBuildInputs = attrs.nativeBuildInputs or []; @@ -161,14 +165,14 @@ let nativeBuildInputs = nativeBuildInputs ++ (if crossConfig == null then buildInputs else []); propagatedNativeBuildInputs = propagatedNativeBuildInputs ++ (if crossConfig == null then propagatedBuildInputs else []); - + } // ifDarwin { __impureHostDeps = computedImpureHostDeps ++ computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ++ __impureHostDeps ++ __extraImpureHostDeps ++ [ "/dev/zero" "/dev/random" "/dev/urandom" "/bin/sh" ]; - __propagatedImpureHostDeps = lib.unique (lib.sort (x: y: x < y) (computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps)); + __propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps; }))) ( { # The meta attribute is passed in the resulting attribute set, @@ -193,7 +197,6 @@ let (if isNull allowedRequisites then {} else { allowedRequisites = allowedRequisites ++ defaultNativeBuildInputs; }) // { inherit system name; - __impureHostDeps = __stdenvImpureHostDeps; builder = shell; @@ -202,6 +205,9 @@ let setup = setupScript; inherit preHook initialPath shell defaultNativeBuildInputs; + } + // ifDarwin { + __impureHostDeps = __stdenvImpureHostDeps; }) // rec { diff --git a/pkgs/stdenv/pure-darwin/default.nix b/pkgs/stdenv/pure-darwin/default.nix new file mode 100644 index 000000000000..d4b17a7909c7 --- /dev/null +++ b/pkgs/stdenv/pure-darwin/default.nix @@ -0,0 +1,297 @@ +{ system ? builtins.currentSystem +, allPackages ? import ../../top-level/all-packages.nix +, platform ? null +, config ? {} +}: + +let + fetch = { file, sha256 }: import { + url = "https://dl.dropboxusercontent.com/u/2857322/${file}"; + inherit sha256; + executable = true; + }; + + bootstrapFiles = { + sh = fetch { file = "sh"; sha256 = "1qakpg37vl61jnkplz13m3g1csqr85cg8ybp6jwiv6apmg26isnm"; }; + bzip2 = fetch { file = "bzip2"; sha256 = "1gxa67255q9v00j1vn1mzyrnbwys2g1102cx02vpcyvvrl4vqxr0"; }; + mkdir = fetch { file = "mkdir"; sha256 = "1yfl8w65ksji7fggrbvqxw8lp0gm02qilk11n9axj2jxay53ngvg"; }; + cpio = fetch { file = "cpio"; sha256 = "0nssyg19smgcblwq1mfcw4djbd85md84d2f093qcqkbigdjg484b"; }; + }; + tarball = fetch { file = "bootstrap-tools.9.cpio.bz2"; sha256 = "0fd79k7gy3z3sba5w4f4lnrcpiwff31vw02480x1pdry8bbgbf2j"; }; +in rec { + allPackages = import ../../top-level/all-packages.nix; + + commonPreHook = '' + export NIX_ENFORCE_PURITY=1 + export NIX_IGNORE_LD_THROUGH_GCC=1 + stripAllFlags=" " # the Darwin "strip" command doesn't know "-s" + export MACOSX_DEPLOYMENT_TARGET=10.7 + export SDKROOT= + export CMAKE_OSX_ARCHITECTURES=x86_64 + ''; + + # libSystem and its transitive dependencies. Get used to this; it's a recurring theme in darwin land + libSystemClosure = [ + "/usr/lib/libSystem.dylib" + "/usr/lib/libSystem.B.dylib" + "/usr/lib/libobjc.A.dylib" + "/usr/lib/libobjc.dylib" + "/usr/lib/libauto.dylib" + "/usr/lib/libc++abi.dylib" + "/usr/lib/libc++.1.dylib" + "/usr/lib/libDiagnosticMessagesClient.dylib" + "/usr/lib/system" + ]; + + # The one dependency of /bin/sh :( + binShClosure = [ "/usr/lib/libncurses.5.4.dylib" ]; + + bootstrapTools = derivation rec { + inherit system tarball; + + name = "bootstrap-tools"; + builder = bootstrapFiles.sh; # Not a filename! Attribute 'sh' on bootstrapFiles + args = [ ./unpack-bootstrap-tools.sh ]; + + inherit (bootstrapFiles) mkdir bzip2 cpio; + + __impureHostDeps = binShClosure ++ libSystemClosure; + }; + + stageFun = step: last: {shell ? "${bootstrapTools}/bin/sh", + overrides ? (pkgs: {}), + extraPreHook ? "", + extraBuildInputs ? with last.pkgs; [ xz darwin.CF libcxx ], + extraInitialPath ? [], + allowedRequisites ? null}: + let + thisStdenv = import ../generic { + inherit system config shell extraBuildInputs allowedRequisites; + + name = "stdenv-darwin-boot-${toString step}"; + + cc = if isNull last then "/no-such-path" else import ../../build-support/cc-wrapper { + inherit shell; + inherit (last) stdenv; + inherit (last.pkgs.darwin) dyld; + + nativeTools = true; + nativePrefix = bootstrapTools; + nativeLibc = false; + libc = last.pkgs.darwin.Libsystem; + cc = { name = "clang-9.9.9"; outPath = bootstrapTools; }; + }; + + preHook = stage0.stdenv.lib.optionalString (shell == "${bootstrapTools}/bin/sh") '' + # Don't patch #!/interpreter because it leads to retained + # dependencies on the bootstrapTools in the final stdenv. + dontPatchShebangs=1 + '' + '' + ${commonPreHook} + ${extraPreHook} + ''; + initialPath = extraInitialPath ++ [ bootstrapTools ]; + fetchurlBoot = import ../../build-support/fetchurl { + stdenv = stage0.stdenv; + curl = bootstrapTools; + }; + + # The stdenvs themselves don't use mkDerivation, so I need to specify this here + __stdenvImpureHostDeps = binShClosure ++ libSystemClosure; + __extraImpureHostDeps = binShClosure ++ libSystemClosure; + + extraAttrs = { inherit platform; }; + overrides = pkgs: (overrides pkgs) // { fetchurl = thisStdenv.fetchurlBoot; }; + }; + + thisPkgs = allPackages { + inherit system platform; + bootStdenv = thisStdenv; + }; + in { stdenv = thisStdenv; pkgs = thisPkgs; }; + + stage0 = stageFun 0 null { + overrides = orig: with stage0; rec { + darwin = orig.darwin // { + Libsystem = stdenv.mkDerivation { + name = "bootstrap-Libsystem"; + buildCommand = '' + mkdir -p $out + ln -s ${bootstrapTools}/lib $out/lib + ln -s ${bootstrapTools}/include-Libsystem $out/include + ''; + }; + dyld = bootstrapTools; + }; + + libcxx = stdenv.mkDerivation { + name = "bootstrap-libcxx"; + phases = [ "installPhase" "fixupPhase" ]; + installPhase = '' + mkdir -p $out/lib $out/include + ln -s ${bootstrapTools}/lib/libc++.dylib $out/lib/libc++.dylib + ln -s ${bootstrapTools}/include/c++ $out/include/c++ + ''; + setupHook = ../../development/compilers/llvm/3.5/libc++/setup-hook.sh; + }; + + libcxxabi = stdenv.mkDerivation { + name = "bootstrap-libcxxabi"; + buildCommand = '' + mkdir -p $out/lib + ln -s ${bootstrapTools}/lib/libc++abi.dylib $out/lib/libc++abi.dylib + ''; + }; + + }; + + extraBuildInputs = []; + }; + + persistent0 = _: {}; + + stage1 = with stage0; stageFun 1 stage0 { + extraPreHook = "export NIX_CFLAGS_COMPILE+=\" -F${bootstrapTools}/Library/Frameworks\""; + extraBuildInputs = [ pkgs.libcxx ]; + + allowedRequisites = + [ bootstrapTools ] ++ (with pkgs; [ libcxx libcxxabi ]) ++ [ pkgs.darwin.Libsystem ]; + + overrides = persistent0; + }; + + persistent1 = orig: with stage1.pkgs; { + inherit + zlib patchutils m4 scons flex perl bison unifdef unzip openssl icu python + libxml2 gettext sharutils gmp libarchive ncurses pkg-config libedit groff + openssh sqlite sed serf openldap db cyrus-sasl expat apr-util subversion xz + findfreetype libssh curl cmake autoconf automake libtool ed cpio coreutils; + + darwin = orig.darwin // { + inherit (darwin) + dyld Libsystem xnu configd libdispatch libclosure launchd; + }; + }; + + stage2 = with stage1; stageFun 2 stage1 { + allowedRequisites = + [ bootstrapTools ] ++ + (with pkgs; [ xz libcxx libcxxabi icu ]) ++ + (with pkgs.darwin; [ dyld Libsystem CF ]); + + overrides = persistent1; + }; + + persistent2 = orig: with stage2.pkgs; { + inherit + patchutils m4 scons flex perl bison unifdef unzip openssl python + gettext sharutils libarchive pkg-config groff bash subversion + openssh sqlite sed serf openldap db cyrus-sasl expat apr-util + findfreetype libssh curl cmake autoconf automake libtool cpio + libcxx libcxxabi; + + darwin = orig.darwin // { + inherit (darwin) + dyld Libsystem xnu configd libdispatch libclosure launchd libiconv; + }; + }; + + stage3 = with stage2; stageFun 3 stage2 { + shell = "${pkgs.bash}/bin/bash"; + + # We have a valid shell here (this one has no bootstrap-tools runtime deps) so stageFun + # enables patchShebangs above. Unfortunately, patchShebangs ignores our $SHELL setting + # and instead goes by $PATH, which happens to contain bootstrapTools. So it goes and + # patches our shebangs back to point at bootstrapTools. This makes sure bash comes first. + extraInitialPath = [ pkgs.bash ]; + + allowedRequisites = + [ bootstrapTools ] ++ + (with pkgs; [ icu bash libcxx libcxxabi ]) ++ + (with pkgs.darwin; [ dyld Libsystem ]); + + overrides = persistent2; + }; + + persistent3 = orig: with stage3.pkgs; { + inherit + gnumake gzip gnused bzip2 gawk ed xz patch bash + libcxxabi libcxx ncurses libffi zlib llvm gmp pcre gnugrep + coreutils findutils diffutils patchutils; + + llvmPackages = orig.llvmPackages // { + inherit (llvmPackages) llvm clang-unwrapped; + }; + + darwin = orig.darwin // { + inherit (darwin) dyld Libsystem libiconv; + }; + }; + + stage4 = with stage3; stageFun 4 stage3 { + shell = "${pkgs.bash}/bin/bash"; + extraInitialPath = [ pkgs.bash ]; + overrides = persistent3; + }; + + persistent4 = orig: with stage4.pkgs; { + inherit + gnumake gzip gnused bzip2 gawk ed xz patch bash + libcxxabi libcxx ncurses libffi zlib icu llvm gmp pcre gnugrep + coreutils findutils diffutils patchutils binutils binutils-raw; + + llvmPackages = orig.llvmPackages // { + inherit (llvmPackages) llvm clang-unwrapped; + }; + + darwin = orig.darwin // { + inherit (darwin) dyld Libsystem cctools CF libiconv; + }; + }; + + stage5 = with stage4; import ../generic rec { + inherit system config; + inherit (stdenv) fetchurlBoot; + + name = "stdenv-darwin"; + + preHook = commonPreHook; + + __stdenvImpureHostDeps = binShClosure ++ libSystemClosure; + __extraImpureHostDeps = binShClosure ++ libSystemClosure; + + initialPath = import ../common-path.nix { inherit pkgs; }; + shell = "${pkgs.bash}/bin/bash"; + + cc = import ../../build-support/cc-wrapper { + inherit stdenv shell; + nativeTools = false; + nativeLibc = false; + inherit (pkgs) coreutils binutils; + inherit (pkgs.darwin) dyld; + cc = pkgs.llvmPackages.clang-unwrapped; + libc = pkgs.darwin.Libsystem; + }; + + extraBuildInputs = with pkgs; [ darwin.CF libcxx ]; + + extraAttrs = { + inherit platform bootstrapTools; + libc = pkgs.darwin.Libsystem; + shellPackage = pkgs.bash; + }; + + allowedRequisites = (with pkgs; [ + xz libcxx libcxxabi icu gmp gnumake findutils bzip2 llvm zlib libffi + coreutils ed diffutils gnutar gzip ncurses gnused bash gawk + gnugrep llvmPackages.clang-unwrapped patch pcre binutils-raw binutils gettext + ]) ++ (with pkgs.darwin; [ + dyld Libsystem CF cctools libiconv + ]); + + overrides = orig: persistent4 orig // { + clang = cc; + inherit cc; + }; + }; +} diff --git a/pkgs/stdenv/pure-darwin/make-bootstrap-tools.nix b/pkgs/stdenv/pure-darwin/make-bootstrap-tools.nix new file mode 100644 index 000000000000..433638dd1bde --- /dev/null +++ b/pkgs/stdenv/pure-darwin/make-bootstrap-tools.nix @@ -0,0 +1,286 @@ +{system ? builtins.currentSystem}: + +with import ../../top-level/all-packages.nix {inherit system;}; + +rec { + # We want coreutils without ACL support. + coreutils_ = coreutils.override (orig: { + aclSupport = false; + }); + + build = stdenv.mkDerivation { + name = "build"; + + buildInputs = [nukeReferences cpio]; + + buildCommand = '' + mkdir -p $out/bin $out/lib + + # Our (fake) loader + cp -d ${darwin.dyld}/lib/dyld $out/lib/ + + # C standard library stuff + cp -d ${darwin.Libsystem}/lib/*.o $out/lib/ + cp -d ${darwin.Libsystem}/lib/*.dylib $out/lib/ + cp -d ${darwin.Libsystem}/lib/system/*.dylib $out/lib/ + + # Resolv is actually a link to another package, so let's copy it properly + rm $out/lib/libresolv.9.dylib + cp -L ${darwin.Libsystem}/lib/libresolv.9.dylib $out/lib + + cp -rL ${darwin.Libsystem}/include $out + chmod -R u+w $out/include + cp -rL ${icu}/include* $out/include + cp -rL ${libiconv}/include/* $out/include + cp -rL ${gnugrep.pcre}/include/* $out/include + mv $out/include $out/include-Libsystem + + # Copy coreutils, bash, etc. + cp ${coreutils_}/bin/* $out/bin + (cd $out/bin && rm vdir dir sha*sum pinky factor pathchk runcon shuf who whoami shred users) + + cp ${bash}/bin/bash $out/bin + cp ${findutils}/bin/find $out/bin + cp ${findutils}/bin/xargs $out/bin + cp -d ${diffutils}/bin/* $out/bin + cp -d ${gnused}/bin/* $out/bin + cp -d ${gnugrep}/bin/grep $out/bin + cp ${gawk}/bin/gawk $out/bin + cp -d ${gawk}/bin/awk $out/bin + cp ${gnutar}/bin/tar $out/bin + cp ${gzip}/bin/gzip $out/bin + cp ${bzip2}/bin/bzip2 $out/bin + cp -d ${gnumake}/bin/* $out/bin + cp -d ${patch}/bin/* $out/bin + cp -d ${xz}/bin/xz $out/bin + + # This used to be in-nixpkgs, but now is in the bundle + # because I can't be bothered to make it partially static + cp ${curl}/bin/curl $out/bin + cp -d ${curl}/lib/libcurl*.dylib $out/lib + cp -d ${libssh2}/lib/libssh*.dylib $out/lib + cp -d ${openssl}/lib/*.dylib $out/lib + + cp -d ${gnugrep.pcre}/lib/libpcre*.dylib $out/lib + cp -d ${libiconv}/lib/libiconv*.dylib $out/lib + cp -d ${gettext}/lib/libintl*.dylib $out/lib + chmod +x $out/lib/libintl*.dylib + + # Copy what we need of clang + cp -d ${llvmPackages.clang-unwrapped}/bin/clang $out/bin + cp -d ${llvmPackages.clang-unwrapped}/bin/clang++ $out/bin + cp -d ${llvmPackages.clang-unwrapped}/bin/clang-3.6 $out/bin + + cp -rL ${llvmPackages.clang-unwrapped}/lib/clang $out/lib + + cp -d ${libcxx}/lib/libc++*.dylib $out/lib + cp -d ${libcxxabi}/lib/libc++abi*.dylib $out/lib + + mkdir $out/include + cp -rd ${libcxx}/include/c++ $out/include + + cp -d ${icu}/lib/libicu*.dylib $out/lib + cp -d ${zlib}/lib/libz.* $out/lib + cp -d ${gmpxx}/lib/libgmp*.* $out/lib + cp -d ${xz}/lib/liblzma*.* $out/lib + + # Copy binutils. + for i in as ld ar ranlib nm strip otool install_name_tool dsymutil; do + cp ${darwin.cctools}/bin/$i $out/bin + done + + cp -rd ${pkgs.darwin.CF}/Library $out + + chmod -R u+w $out + + nuke-refs $out/bin/* + + rpathify() { + local libs=$(${darwin.cctools}/bin/otool -L "$1" | tail -n +2 | grep -o "$NIX_STORE.*-\S*") || true + for lib in $libs; do + ${darwin.cctools}/bin/install_name_tool -change $lib "@rpath/$(basename $lib)" "$1" + done + } + + fix_dyld() { + # This is clearly a hack. Once we have an install_name_tool-alike that can patch dyld, this will be nicer. + ${perl}/bin/perl -i -0777 -pe 's/\/nix\/store\/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-dyld-239\.4\/lib\/dyld/\/usr\/lib\/dyld\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/sg' "$1" + } + + # Strip executables even further + for i in $out/bin/*; do + if test -x $i -a ! -L $i; then + chmod +w $i + + fix_dyld $i + strip $i || true + fi + done + + for i in $out/bin/* $out/lib/*.dylib $out/lib/clang/3.5.0/lib/darwin/*.dylib $out/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation; do + if test -x $i -a ! -L $i; then + echo "Adding rpath to $i" + rpathify $i + fi + done + + nuke-refs $out/lib/* + nuke-refs $out/lib/clang/3.5.0/lib/darwin/* + nuke-refs $out/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation + + mkdir $out/.pack + mv $out/* $out/.pack + mv $out/.pack $out/pack + + mkdir $out/on-server + (cd $out/pack && (find | cpio -o -H newc)) | bzip2 > $out/on-server/bootstrap-tools.cpio.bz2 + + mkdir $out/in-nixpkgs + cp ${stdenv.shell} $out/in-nixpkgs/sh + cp ${cpio}/bin/cpio $out/in-nixpkgs + cp ${coreutils_}/bin/mkdir $out/in-nixpkgs + cp ${bzip2}/bin/bzip2 $out/in-nixpkgs + + chmod u+w $out/in-nixpkgs/* + strip $out/in-nixpkgs/* + nuke-refs $out/in-nixpkgs/* + + for i in $out/in-nixpkgs/*; do + fix_dyld $i + done + ''; + + allowedReferences = []; + }; + + host = stdenv.mkDerivation { + name = "host"; + + buildCommand = '' + mkdir -p $out/nix-support + + for i in "${build}/on-server/"*; do + echo "file binary-dist $i" >> $out/nix-support/hydra-build-products + done + + echo "darwin-bootstrap-tools-$(date +%Y.%m.%d)" >> $out/nix-support/hydra-release-name + ''; + + allowedReferences = [ build ]; + }; + + unpack = stdenv.mkDerivation { + name = "unpack"; + + # This is by necessity a near-duplicate of unpack-bootstrap-tools.sh. If we refer to it directly, + # we can't make any changes to it due to our testing stdenv depending on it. Think of this as the + # unpack-bootstrap-tools.sh for the next round of bootstrap tools. + # TODO: think through alternate designs, such as hosting this script as an output of the process. + buildCommand = '' + # Unpack the bootstrap tools tarball. + echo Unpacking the bootstrap tools... + $mkdir $out + $bzip2 -d < $tarball | (cd $out && $cpio -i) + + # Set the ELF interpreter / RPATH in the bootstrap binaries. + echo Patching the tools... + + export PATH=$out/bin + + for i in $out/bin/*; do + if ! test -L $i; then + echo patching $i + install_name_tool -add_rpath $out/lib $i || true + fi + done + + for i in $out/lib/*.dylib $out/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation; do + if ! test -L $i; then + echo patching $i + + id=$(otool -D "$i" | tail -n 1) + install_name_tool -id "$(dirname $i)/$(basename $id)" $i + + libs=$(otool -L "$i" | tail -n +2 | grep -v Libsystem | cat) + if [ -n "$libs" ]; then + install_name_tool -add_rpath $out/lib $i + fi + fi + done + + ln -s bash $out/bin/sh + ln -s bzip2 $out/bin/bunzip2 + + cat >$out/bin/dsymutil << EOF + #!$out/bin/sh + EOF + ''; + + tarball = "${build}/on-server/bootstrap-tools.cpio.bz2"; + + mkdir = "${build}/in-nixpkgs/mkdir"; + bzip2 = "${build}/in-nixpkgs/bzip2"; + cpio = "${build}/in-nixpkgs/cpio"; + + allowedReferences = [ "out" ]; + }; + + test = stdenv.mkDerivation { + name = "test"; + + realBuilder = "${unpack}/bin/bash"; + + buildCommand = '' + export PATH=${unpack}/bin + ls -l + mkdir $out + mkdir $out/bin + sed --version + find --version + diff --version + patch --version + make --version + awk --version + grep --version + clang --version + xz --version + + # The grep will return a nonzero exit code if there is no match, and we want to assert that we have + # an SSL-capable curl + curl --version | grep SSL + + ${build}/in-nixpkgs/sh -c 'echo Hello World' + + export flags="-idirafter ${unpack}/include-Libsystem --sysroot=${unpack} -L${unpack}/lib" + + export CPP="clang -E $flags" + export CC="clang $flags -Wl,-rpath,${unpack}/lib -Wl,-v" + export CXX="clang++ $flags --stdlib=libc++ -lc++abi -isystem${unpack}/include/c++/v1 -Wl,-rpath,${unpack}/lib -Wl,-v" + + echo '#include ' >> foo.c + echo '#include ' >> foo.c + echo '#include ' >> foo.c + echo 'int main() { printf("Hello World\n"); return 0; }' >> foo.c + $CC -o $out/bin/foo foo.c + $out/bin/foo + + echo '#include ' >> bar.c + echo 'int main() { CFShow(CFSTR("Hullo")); return 0; }' >> bar.c + $CC -F${unpack}/Library/Frameworks -framework CoreFoundation -o $out/bin/bar bar.c + $out/bin/bar + + echo '#include ' >> bar.cc + echo 'int main() { std::cout << "Hello World\n"; }' >> bar.cc + $CXX -v -o $out/bin/bar bar.cc + $out/bin/bar + + tar xvf ${hello.src} + cd hello-* + ./configure --prefix=$out + make + make install + + $out/bin/hello + ''; + }; +} diff --git a/pkgs/stdenv/pure-darwin/trivial-bootstrap.sh b/pkgs/stdenv/pure-darwin/trivial-bootstrap.sh new file mode 100644 index 000000000000..0915b378d4f0 --- /dev/null +++ b/pkgs/stdenv/pure-darwin/trivial-bootstrap.sh @@ -0,0 +1,66 @@ + +# Building bootstrap tools +echo Building the trivial bootstrap environment... +$mkdir -p $out/bin + +$ln -s $ln $out/bin/ln + +PATH=$out/bin/ + +cd $out/bin + +ln -s $mkdir +ln -s /bin/sh +ln -s /bin/cp +ln -s /bin/mv +ln -s /bin/rm +ln -s /bin/ls +ln -s /bin/ps +ln -s /bin/cat +ln -s /bin/bash +ln -s /bin/echo +ln -s /bin/expr +ln -s /bin/test +ln -s /bin/date +ln -s /bin/chmod +ln -s /bin/rmdir +ln -s /bin/sleep +ln -s /bin/hostname + +ln -s /usr/bin/id +ln -s /usr/bin/od +ln -s /usr/bin/tr +ln -s /usr/bin/wc +ln -s /usr/bin/cut +ln -s /usr/bin/cmp +ln -s /usr/bin/sed +ln -s /usr/bin/tar +ln -s /usr/bin/xar +ln -s /usr/bin/awk +ln -s /usr/bin/env +ln -s /usr/bin/tee +ln -s /usr/bin/comm +ln -s /usr/bin/cpio +ln -s /usr/bin/curl +ln -s /usr/bin/find +ln -s /usr/bin/grep +ln -s /usr/bin/gzip +ln -s /usr/bin/head +ln -s /usr/bin/tail +ln -s /usr/bin/sort +ln -s /usr/bin/uniq +ln -s /usr/bin/less +ln -s /usr/bin/true +ln -s /usr/bin/diff +ln -s /usr/bin/egrep +ln -s /usr/bin/fgrep +ln -s /usr/bin/patch +ln -s /usr/bin/uname +ln -s /usr/bin/touch +ln -s /usr/bin/split +ln -s /usr/bin/xargs +ln -s /usr/bin/which +ln -s /usr/bin/install +ln -s /usr/bin/basename +ln -s /usr/bin/dirname +ln -s /usr/bin/readlink \ No newline at end of file diff --git a/pkgs/stdenv/pure-darwin/unpack-bootstrap-tools.sh b/pkgs/stdenv/pure-darwin/unpack-bootstrap-tools.sh new file mode 100644 index 000000000000..8033c7004d93 --- /dev/null +++ b/pkgs/stdenv/pure-darwin/unpack-bootstrap-tools.sh @@ -0,0 +1,54 @@ +set -e + +# Unpack the bootstrap tools tarball. +echo Unpacking the bootstrap tools... +$mkdir $out +$bzip2 -d < $tarball | (cd $out && $cpio -i) + +# Set the ELF interpreter / RPATH in the bootstrap binaries. +echo Patching the tools... + +export PATH=$out/bin + +for i in $out/bin/*; do + if ! test -L $i; then + echo patching $i + install_name_tool -add_rpath $out/lib $i || true + fi +done + +for i in $out/lib/*.dylib $out/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation; do + if ! test -L $i; then + echo patching $i + + id=$(otool -D "$i" | tail -n 1) + install_name_tool -id "$(dirname $i)/$(basename $id)" $i + + libs=$(otool -L "$i" | tail -n +2 | grep -v libSystem | cat) + if [ -n "$libs" ]; then + install_name_tool -add_rpath $out/lib $i + fi + fi +done + +ln -s bash $out/bin/sh +ln -s bzip2 $out/bin/bunzip2 + +# Provide a gunzip script. +cat > $out/bin/gunzip < $out/bin/egrep +echo "exec $out/bin/grep -E \"\$@\"" >> $out/bin/egrep +echo "#! $out/bin/sh" > $out/bin/fgrep +echo "exec $out/bin/grep -F \"\$@\"" >> $out/bin/fgrep + +cat >$out/bin/dsymutil << EOF +#!$out/bin/sh +EOF + +chmod +x $out/bin/egrep $out/bin/fgrep $out/bin/dsymutil