diff --git a/lib/customisation.nix b/lib/customisation.nix index 3e6e279824be4..d24d23b3a5575 100644 --- a/lib/customisation.nix +++ b/lib/customisation.nix @@ -185,4 +185,33 @@ rec { }; in self; + # Use this if you want to override the native derivation of a + # package without affecting the cross-compiled derivation. + overrideNativeDrv = newNativeDrv: old: + if old ? crossDrv + then + let + nativeDrv = newNativeDrv; + crossDrv = old.crossDrv; + override = newArgs: overrideNativeDrv + (newNativeDrv.override newArgs) (old.override newArgs); + in nativeDrv // { inherit crossDrv nativeDrv override; } + else + newNativeDrv; + + # Given a set of new packages and a set of old packages, produces a + # set with the same attribute names as the set of new packages, where + # each attribute value is a derivation that has the native derivation + # from the new set but the cross derivation (crossDrv) from the old + # set. + overrideNativeDrvs = newPkgs: oldPkgs: + let + overrider = attr: { + name = attr; + value = if oldPkgs ? "${attr}" then + (overrideNativeDrv newPkgs.${attr} oldPkgs.${attr}) + else (throw "wtf ${attr}"); + }; + names = builtins.attrNames newPkgs; + in builtins.listToAttrs (map overrider names); } diff --git a/pkgs/development/compilers/gcc/5/default.nix b/pkgs/development/compilers/gcc/5/default.nix index 3d75c0e76daaf..3065f108ebedb 100644 --- a/pkgs/development/compilers/gcc/5/default.nix +++ b/pkgs/development/compilers/gcc/5/default.nix @@ -62,6 +62,10 @@ with builtins; let version = "5.4.0"; sha256 = "0fihlcy5hnksdxk0sn6bvgnyq8gfrgs8m794b1jxwd1dxinzg3b0"; + # Rename the libcCross argument so we can redefine libcCross to + # null for the native compiler. + libcCrossArg = libcCross; + # Whether building a cross-compiler for GNU/Hurd. crossGNU = cross != null && cross.config == "i586-pc-gnu"; @@ -210,7 +214,12 @@ in # We need all these X libraries when building AWT with GTK+. assert x11Support -> (filter (x: x == null) ([ gtk2 libart_lgpl ] ++ xlibs)) == []; -stdenv.mkDerivation ({ +stdenv.mkDerivationWithCrossArg ( hostCrossSystem: + let + targetCrossSystem = if cross != null then cross else hostCrossSystem; + libcCross = if targetCrossSystem != null then libcCrossArg else null; + in { + name = "${name}${if stripped then "" else "-debug"}-${version}" + crossNameAddon; builder = ../builder.sh; diff --git a/pkgs/development/libraries/boehm-gc/default.nix b/pkgs/development/libraries/boehm-gc/default.nix index fb1f177d96950..b957e1593c9e6 100644 --- a/pkgs/development/libraries/boehm-gc/default.nix +++ b/pkgs/development/libraries/boehm-gc/default.nix @@ -17,8 +17,11 @@ stdenv.mkDerivation rec { doCheck = true; - # Don't run the native `strip' when cross-compiling. - dontStrip = stdenv ? cross; + # This is just here because it was present in previous commits and + # we want to avoid a meaningless mass rebuild. + dontStrip = false; + + crossAttrs.dontStrip = true; # Don't run the native `strip' when cross-compiling. postInstall = '' diff --git a/pkgs/development/libraries/libffi/default.nix b/pkgs/development/libraries/libffi/default.nix index b203f6346476b..3ff3cb62a06dc 100644 --- a/pkgs/development/libraries/libffi/default.nix +++ b/pkgs/development/libraries/libffi/default.nix @@ -21,7 +21,11 @@ stdenv.mkDerivation rec { inherit doCheck; - dontStrip = stdenv ? cross; # Don't run the native `strip' when cross-compiling. + # This is just here because it was present in previous commits and + # we want to avoid a meaningless mass rebuild. + dontStrip = false; + + crossAttrs.dontStrip = true; # Don't run the native `strip' when cross-compiling. # Install headers and libs in the right places. postFixup = '' diff --git a/pkgs/development/libraries/libxml2/default.nix b/pkgs/development/libraries/libxml2/default.nix index 80354b10f3b99..a8c6a5e86118a 100644 --- a/pkgs/development/libraries/libxml2/default.nix +++ b/pkgs/development/libraries/libxml2/default.nix @@ -1,9 +1,12 @@ { stdenv, lib, fetchurl, zlib, xz, python2, findXMLCatalogs, libiconv, fetchpatch -, pythonSupport ? (! stdenv ? cross) }: - -let - python = python2; -in stdenv.mkDerivation rec { +, pythonSupport ? null }: + +stdenv.mkDerivationWithCrossArg(cross: + let + pythonSupportReally = if pythonSupport != null then pythonSupport + else cross == null; + python = assert pythonSupportReally; python2; + in rec { name = "libxml2-${version}"; version = "2.9.4"; @@ -28,10 +31,10 @@ in stdenv.mkDerivation rec { }; outputs = [ "bin" "dev" "out" "doc" ] - ++ lib.optional pythonSupport "py"; - propagatedBuildOutputs = "out bin" + lib.optionalString pythonSupport " py"; + ++ lib.optional pythonSupportReally "py"; + propagatedBuildOutputs = "out bin" + lib.optionalString pythonSupportReally " py"; - buildInputs = lib.optional pythonSupport python + buildInputs = lib.optional pythonSupportReally python # Libxml2 has an optional dependency on liblzma. However, on impure # platforms, it may end up using that from /usr/lib, and thus lack a # RUNPATH for that, leading to undefined references for its users. @@ -39,7 +42,7 @@ in stdenv.mkDerivation rec { propagatedBuildInputs = [ zlib findXMLCatalogs ]; - configureFlags = lib.optional pythonSupport "--with-python=${python}" + configureFlags = lib.optional pythonSupportReally "--with-python=${python}" ++ [ "--exec_prefix=$dev" ]; enableParallelBuilding = true; @@ -55,9 +58,9 @@ in stdenv.mkDerivation rec { propagatedBuildInputs = [ findXMLCatalogs libiconv ]; }; - preInstall = lib.optionalString pythonSupport + preInstall = lib.optionalString pythonSupportReally ''substituteInPlace python/libxml2mod.la --replace "${python}" "$py"''; - installFlags = lib.optionalString pythonSupport + installFlags = lib.optionalString pythonSupportReally ''pythondir="$(py)/lib/${python.libPrefix}/site-packages"''; postFixup = '' @@ -75,4 +78,4 @@ in stdenv.mkDerivation rec { platforms = lib.platforms.unix; maintainers = [ lib.maintainers.eelco ]; }; -} +}) diff --git a/pkgs/development/libraries/readline/6.3.nix b/pkgs/development/libraries/readline/6.3.nix index 80cc7e923b834..dfb8385f75728 100644 --- a/pkgs/development/libraries/readline/6.3.nix +++ b/pkgs/development/libraries/readline/6.3.nix @@ -28,8 +28,12 @@ stdenv.mkDerivation rec { in import ./readline-6.3-patches.nix patch); - # Don't run the native `strip' when cross-compiling. - dontStrip = stdenv ? cross; + # This is just here because it was present in previous commits and + # we want to avoid a meaningless mass rebuild. + dontStrip = false; + + crossAttrs.dontStrip = true; # Don't run the native `strip' when cross-compiling. + bash_cv_func_sigsetjmp = if stdenv.isCygwin then "missing" else null; meta = with stdenv.lib; { diff --git a/pkgs/development/tools/misc/libtool/libtool2.nix b/pkgs/development/tools/misc/libtool/libtool2.nix index a81255212da5b..281058bb42eff 100644 --- a/pkgs/development/tools/misc/libtool/libtool2.nix +++ b/pkgs/development/tools/misc/libtool/libtool2.nix @@ -21,9 +21,13 @@ stdenv.mkDerivation rec { # leads to the failure of a number of tests. doCheck = false; + # This is just here because it was present in previous commits and + # we want to avoid a meaningless mass-rebuild. + dontStrip = false; + # Don't run the native `strip' when cross-compiling. This breaks at least # with `.a' files for MinGW. - dontStrip = stdenv ? cross; + crossAttrs.dontStrip = true; meta = { description = "GNU Libtool, a generic library support script"; diff --git a/pkgs/stdenv/adapters.nix b/pkgs/stdenv/adapters.nix index 11f9a43c035e7..aab8c836e879e 100644 --- a/pkgs/stdenv/adapters.nix +++ b/pkgs/stdenv/adapters.nix @@ -57,7 +57,7 @@ rec { # Return a modified stdenv that adds a cross compiler to the # builds. makeStdenvCross = stdenv: cross: binutilsCross: gccCross: stdenv // - { mkDerivation = {name ? "", buildInputs ? [], nativeBuildInputs ? [], + rec { mkDerivation = {name ? "", buildInputs ? [], nativeBuildInputs ? [], propagatedBuildInputs ? [], propagatedNativeBuildInputs ? [], selfNativeBuildInput ? false, ...}@args: let @@ -115,6 +115,21 @@ rec { in nativeDrv // { inherit crossDrv nativeDrv; }; + + # mkDerivationWithCrossArg allows us to make arbitary changes to + # derivation depending on what system we are cross-compiling for, without + # affecting the native derivation. The argument to + # mkDerivationWithCrossArg, attrFunc, should be a function that takes a + # single argument named cross. When cross is null, attrFunc should return + # the attributes for making a native version of the derivation (one that + # runs on the system on which it was built). When cross is not null, it + # will be equal to the top-level crossSystem argument (and equal to + # stdenv.cross), and attrFunc should return the attributes for + # cross-compiling a derivation to be run on the specified system. + mkDerivationWithCrossArg = attrFunc: + let nativeDrv = (mkDerivation (attrFunc null)).nativeDrv; + crossDrv = (mkDerivation (attrFunc cross)).crossDrv; + in nativeDrv // { inherit crossDrv nativeDrv; }; } // { inherit cross gccCross binutilsCross; ccCross = gccCross; diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix index bd35970e0d120..2c51f74a96615 100644 --- a/pkgs/stdenv/generic/default.nix +++ b/pkgs/stdenv/generic/default.nix @@ -264,6 +264,9 @@ let # derivation (e.g., in assertions). passthru); + # This gets overridden in makeStdvenvCross to do something more useful. + mkDerivationWithCrossArg = attrFunc: mkDerivation (attrFunc null); + # The stdenv that we are producing. result = derivation ( @@ -343,6 +346,8 @@ let inherit mkDerivation; + inherit mkDerivationWithCrossArg; + # For convenience, bring in the library functions in lib/ so # packages don't have to do that themselves. inherit lib; diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix index 9900fc6dd3d58..c65d3aa8b8527 100644 --- a/pkgs/stdenv/linux/default.nix +++ b/pkgs/stdenv/linux/default.nix @@ -278,12 +278,10 @@ rec { ]; */ - overrides = pkgs: { - gcc = cc; - + overrides = lib.overrideNativeDrvs { inherit (stage4.pkgs) gzip bzip2 xz bash binutils coreutils diffutils findutils gawk - glibc gnumake gnused gnutar gnugrep gnupatch patchelf + gcc glibc gnumake gnused gnutar gnugrep gnupatch patchelf attr acl paxctl zlib pcre; }; }; diff --git a/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix b/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix index af82788d3fa95..e70f2ba9957af 100644 --- a/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix +++ b/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix @@ -71,7 +71,7 @@ let gnumake = pkgs.gnumake.crossDrv; patch = pkgs.patch.crossDrv; patchelf = pkgs.patchelf.crossDrv; - gcc = pkgs.gcc.cc.crossDrv; + gcc = pkgs.gcc.crossDrv.cc; gmpxx = pkgs.gmpxx.crossDrv; mpfr = pkgs.mpfr.crossDrv; zlib = pkgs.zlib.crossDrv; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 6d1dbc3c607c0..738e4b65d1f76 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -4674,18 +4674,18 @@ in gccApple = throw "gccApple is no longer supported"; - gccCrossStageStatic = let - libcCross1 = - if stdenv.cross.libc == "msvcrt" then windows.mingw_w64_headers - else if stdenv.cross.libc == "libSystem" then darwin.xcode - else null; - in wrapGCCCross { - gcc = forceNativeDrv (gcc.cc.override { + gccCrossStageStatic = + wrapGCCCross { + gcc = forceNativeDrv (callPackage ../development/compilers/gcc/5 { cross = crossSystem; crossStageStatic = true; - langCC = false; + noSysDirs = true; + isl = isl_0_14; libcCross = libcCross1; enableShared = false; + langCC = false; + langObjC = false; + langObjCpp = false; }); libc = libcCross1; binutils = binutilsCross; @@ -4701,13 +4701,19 @@ in }; gccCrossStageFinal = wrapGCCCross { - gcc = forceNativeDrv (gcc.cc.override { + gcc = forceNativeDrv (callPackage ../development/compilers/gcc/5 { cross = crossSystem; crossStageStatic = false; + noSysDirs = true; + isl = isl_0_14; + libcCross = libcCross; # XXX: We have troubles cross-compiling libstdc++ on MinGW (see # ), so don't even try. langCC = crossSystem.config != "i686-pc-mingw32"; + + langObjC = false; + langObjCpp = false; }); libc = libcCross; binutils = binutilsCross; @@ -7184,8 +7190,13 @@ in linuxHeaders = linuxHeadersCross; }); - # We can choose: - libcCrossChooser = name: if name == "glibc" then glibcCross + libcCross1 = + if stdenv.cross.libc == "msvcrt" then windows.mingw_w64_headers + else if stdenv.cross.libc == "libSystem" then darwin.xcode + else null; + + libcCrossChooser = name: + if name == "glibc" then glibcCross else if name == "uclibc" then uclibcCross else if name == "msvcrt" then windows.mingw_w64 else if name == "libSystem" then darwin.xcode @@ -8081,14 +8092,17 @@ in # glibc provides libiconv so systems with glibc don't need to build libiconv # separately, but we also provide libiconvReal, which will always be a - # standalone libiconv, just in case you want it - libiconv = if crossSystem != null then - (if crossSystem.libc == "glibc" then libcCross - else if crossSystem.libc == "libSystem" then darwin.libiconv - else libiconvReal) - else if stdenv.isGlibc then glibcIconv stdenv.cc.libc - else if stdenv.isDarwin then darwin.libiconv - else libiconvReal; + # standalone libiconv, just in case you want it. + libiconv = + let + nativeDrv = if stdenv.isGlibc then stdenv.cc.libc + else if stdenv.isDarwin then darwin.libiconv + else libiconvReal; + crossDrv = + if crossSystem.libc == "glibc" then libcCross + else if crossSystem.libc == "libSystem" then darwin.libiconv + else libiconvReal.crossDrv; + in nativeDrv // { inherit crossDrv nativeDrv; }; glibcIconv = libc: let inherit (builtins.parseDrvName libc.name) name version; diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix index 1d6305151ca63..d00f8f726ef57 100644 --- a/pkgs/top-level/stage.nix +++ b/pkgs/top-level/stage.nix @@ -58,15 +58,11 @@ let aliases = self: super: import ./aliases.nix super; - # stdenvOverrides is used to avoid circular dependencies for building - # the standard build environment. This mechanism uses the override - # mechanism to implement some staged compilation of the stdenv. - # - # We don't want stdenv overrides in the case of cross-building, or - # otherwise the basic overridden packages will not be built with the - # crossStdenv adapter. + # stdenvOverrides is used to avoid having multiple of versions + # of certain dependencies that were used in bootstrapping the + # standard environment. stdenvOverrides = self: super: - lib.optionalAttrs (crossSystem == null && super.stdenv ? overrides) + lib.optionalAttrs (super.stdenv ? overrides) (super.stdenv.overrides super); # Allow packages to be overridden globally via the `packageOverrides'