about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLluís Batlle i Rossell <viric@vicerveza.homeunix.net>2009-11-22 19:51:45 +0000
committerLluís Batlle i Rossell <viric@vicerveza.homeunix.net>2009-11-22 19:51:45 +0000
commit585ba8c27f766a15abcab22c232170f6ae1cc0a9 (patch)
tree6b2411a130c9683b6696a63da584e56137029caf
parent9dcff09187d5e41ed9bf4d841243a4bf6082c719 (diff)
downloadnixlib-585ba8c27f766a15abcab22c232170f6ae1cc0a9.tar
nixlib-585ba8c27f766a15abcab22c232170f6ae1cc0a9.tar.gz
nixlib-585ba8c27f766a15abcab22c232170f6ae1cc0a9.tar.bz2
nixlib-585ba8c27f766a15abcab22c232170f6ae1cc0a9.tar.lz
nixlib-585ba8c27f766a15abcab22c232170f6ae1cc0a9.tar.xz
nixlib-585ba8c27f766a15abcab22c232170f6ae1cc0a9.tar.zst
nixlib-585ba8c27f766a15abcab22c232170f6ae1cc0a9.zip
Big fixes in the cross build:
- Before this changes, cflags and ldflags for the native and the cross compiler
  got mixed. Not all the gcc-wrapper/gcc-cross-wrapper variables are
  independant now, but enough, I think.
- Fixed the generic stdenv expression, which did a big mess on buildInputs and
  buildNativeInputs. Now it distinguishes when there is a stdenvCross or not.
  Maybe we should have a single stdenv and forget about the stdenvCross
  adapter - this could end in a stdenv a bit complex, but simpler than the
  generic stdenv + adapter.
- Added basic support in pkgconfig for cross-builds: a single PKG_CONFIG_PATH
  now works for both the cross and the native compilers, but I think this
  should work well for most cases I can think of.
- I tried to fix the guile expression to cross-biuld; guile is built, but not
  its manual, so the derivation still fails. Guile requires patching to
  cross-build, as far as I understnad.
- Made the glibcCross build to be done through the usage of a
  gcc-cross-wrapper over the gcc-cross-stage-static, instead of using it
  directly.
- Trying to make physfs (a neverball dependency) cross build.
- Updated the gcc expression to support building a cross compiler without getting
  derivation variables mixed with those of the stdenvCross.

svn path=/nixpkgs/branches/stdenv-updates/; revision=18534
-rw-r--r--pkgs/build-support/gcc-cross-wrapper/add-flags10
-rw-r--r--pkgs/build-support/gcc-cross-wrapper/default.nix4
-rw-r--r--pkgs/build-support/gcc-cross-wrapper/gcc-wrapper.sh14
-rw-r--r--pkgs/build-support/gcc-cross-wrapper/ld-wrapper.sh10
-rw-r--r--pkgs/build-support/gcc-cross-wrapper/setup-hook.sh18
-rw-r--r--pkgs/development/compilers/gcc-4.3/builder.sh8
-rw-r--r--pkgs/development/compilers/gcc-4.3/default.nix2
-rw-r--r--pkgs/development/interpreters/guile/default.nix15
-rw-r--r--pkgs/development/libraries/glibc-2.9/default.nix9
-rw-r--r--pkgs/development/libraries/physfs/default.nix2
-rwxr-xr-xpkgs/development/tools/build-managers/cmake/setup-hook.sh13
-rw-r--r--pkgs/development/tools/misc/pkgconfig/setup-hook.sh6
-rw-r--r--pkgs/os-specific/linux/kernel-headers/2.6.28.nix4
-rw-r--r--pkgs/servers/x11/xorg/overrides.nix1
-rw-r--r--pkgs/stdenv/adapters.nix9
-rw-r--r--pkgs/stdenv/generic/default.nix14
-rw-r--r--pkgs/stdenv/generic/setup.sh9
-rw-r--r--pkgs/top-level/all-packages.nix37
18 files changed, 119 insertions, 66 deletions
diff --git a/pkgs/build-support/gcc-cross-wrapper/add-flags b/pkgs/build-support/gcc-cross-wrapper/add-flags
index ac1e58ebb812..9ff4522e800b 100644
--- a/pkgs/build-support/gcc-cross-wrapper/add-flags
+++ b/pkgs/build-support/gcc-cross-wrapper/add-flags
@@ -1,5 +1,5 @@
-export NIX_CFLAGS_COMPILE="@cflagsCompile@ $NIX_CFLAGS_COMPILE"
-export NIX_CFLAGS_LINK="@cflagsLink@ $NIX_CFLAGS_LINK"
-export NIX_LDFLAGS="@ldflags@ $NIX_LDFLAGS"
-export NIX_LDFLAGS_BEFORE="@ldflagsBefore@ $NIX_LDFLAGS_BEFORE"
-export NIX_GLIBC_FLAGS_SET=1
+export NIX_CROSS_CFLAGS_COMPILE="@cflagsCompile@ $NIX_CROSS_CFLAGS_COMPILE"
+export NIX_CROSS_CFLAGS_LINK="@cflagsLink@ $NIX_CROSS_CFLAGS_LINK"
+export NIX_CROSS_LDFLAGS="@ldflags@ $NIX_CROSS_LDFLAGS"
+export NIX_CROSS_LDFLAGS_BEFORE="@ldflagsBefore@ $NIX_CROSS_LDFLAGS_BEFORE"
+export NIX_CROSS_GLIBC_FLAGS_SET=1
diff --git a/pkgs/build-support/gcc-cross-wrapper/default.nix b/pkgs/build-support/gcc-cross-wrapper/default.nix
index 140432adfbca..362e378273dd 100644
--- a/pkgs/build-support/gcc-cross-wrapper/default.nix
+++ b/pkgs/build-support/gcc-cross-wrapper/default.nix
@@ -6,7 +6,7 @@
 # variables so that the compiler and the linker just "work".
 
 { name ? "", stdenv, nativeTools, nativeLibc, noLibc ? false, nativePrefix ? ""
-, gcc ? null, libc ? null, binutils ? null, shell ? "", cross ? ""
+, gcc ? null, libc ? null, binutils ? null, shell ? "", cross
 }:
 
 assert nativeTools -> nativePrefix != "";
@@ -32,6 +32,6 @@ stdenv.mkDerivation {
     };
 
   passthru = {
-    inherit cross;
+    target = cross;
   };
 }
diff --git a/pkgs/build-support/gcc-cross-wrapper/gcc-wrapper.sh b/pkgs/build-support/gcc-cross-wrapper/gcc-wrapper.sh
index e5a2f5e65bb1..491de8f7f984 100644
--- a/pkgs/build-support/gcc-cross-wrapper/gcc-wrapper.sh
+++ b/pkgs/build-support/gcc-cross-wrapper/gcc-wrapper.sh
@@ -4,7 +4,7 @@ if test -n "$NIX_GCC_WRAPPER_START_HOOK"; then
     source "$NIX_GCC_WRAPPER_START_HOOK"
 fi
 
-if test -z "$NIX_GLIBC_FLAGS_SET"; then
+if test -z "$NIX_CROSS_GLIBC_FLAGS_SET"; then
     source @out@/nix-support/add-flags
 fi
 
@@ -63,28 +63,28 @@ fi
 
 
 # Add the flags for the C compiler proper.
-extraAfter=($NIX_CFLAGS_COMPILE)
+extraAfter=($NIX_CROSS_CFLAGS_COMPILE)
 extraBefore=()
 
 if test "$dontLink" != "1"; then
 
     # Add the flags that should only be passed to the compiler when
     # linking.
-    extraAfter=(${extraAfter[@]} $NIX_CFLAGS_LINK)
+    extraAfter=(${extraAfter[@]} $NIX_CROSS_CFLAGS_LINK)
 
     # Add the flags that should be passed to the linker (and prevent
-    # `ld-wrapper' from adding NIX_LDFLAGS again).
-    for i in $NIX_LDFLAGS_BEFORE; do
+    # `ld-wrapper' from adding NIX_CROSS_LDFLAGS again).
+    for i in $NIX_CROSS_LDFLAGS_BEFORE; do
         extraBefore=(${extraBefore[@]} "-Wl,$i")
     done
-    for i in $NIX_LDFLAGS; do
+    for i in $NIX_CROSS_LDFLAGS; do
 	if test "${i:0:3}" = "-L/"; then
 	    extraAfter=(${extraAfter[@]} "$i")
 	else
 	    extraAfter=(${extraAfter[@]} "-Wl,$i")
 	fi
     done
-    export NIX_LDFLAGS_SET=1
+    export NIX_CROSS_LDFLAGS_SET=1
 
     if test "$NIX_STRIP_DEBUG" = "1"; then
         # Add executable-stripping flags.
diff --git a/pkgs/build-support/gcc-cross-wrapper/ld-wrapper.sh b/pkgs/build-support/gcc-cross-wrapper/ld-wrapper.sh
index f3ff33f5c251..226fad833599 100644
--- a/pkgs/build-support/gcc-cross-wrapper/ld-wrapper.sh
+++ b/pkgs/build-support/gcc-cross-wrapper/ld-wrapper.sh
@@ -4,7 +4,7 @@ if test -n "$NIX_LD_WRAPPER_START_HOOK"; then
     source "$NIX_LD_WRAPPER_START_HOOK"
 fi
 
-if test -z "$NIX_GLIBC_FLAGS_SET"; then
+if test -z "$NIX_CROSS_GLIBC_FLAGS_SET"; then
     source @out@/nix-support/add-flags
 fi
 
@@ -14,7 +14,7 @@ source @out@/nix-support/utils
 # Optionally filter out paths not refering to the store.
 params=("$@")
 if test "$NIX_ENFORCE_PURITY" = "1" -a -n "$NIX_STORE" \
-        -a \( -z "$NIX_IGNORE_LD_THROUGH_GCC" -o -z "$NIX_LDFLAGS_SET" \); then
+        -a \( -z "$NIX_IGNORE_LD_THROUGH_GCC" -o -z "$NIX_CROSS_LDFLAGS_SET" \); then
     rest=()
     n=0
     while test $n -lt ${#params[*]}; do
@@ -44,9 +44,9 @@ fi
 extra=()
 extraBefore=()
 
-if test -z "$NIX_LDFLAGS_SET"; then
-    extra=(${extra[@]} $NIX_LDFLAGS)
-    extraBefore=(${extraBefore[@]} $NIX_LDFLAGS_BEFORE)
+if test -z "$NIX_CROSS_LDFLAGS_SET"; then
+    extra=(${extra[@]} $NIX_CROSS_LDFLAGS)
+    extraBefore=(${extraBefore[@]} $NIX_CROSS_LDFLAGS_BEFORE)
 fi
 
 
diff --git a/pkgs/build-support/gcc-cross-wrapper/setup-hook.sh b/pkgs/build-support/gcc-cross-wrapper/setup-hook.sh
index 99618cb21124..d854f5ff0d7c 100644
--- a/pkgs/build-support/gcc-cross-wrapper/setup-hook.sh
+++ b/pkgs/build-support/gcc-cross-wrapper/setup-hook.sh
@@ -1,14 +1,14 @@
-addCVars () {
+crossAddCVars () {
     if test -d $1/include; then
-        export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -I$1/include"
+        export NIX_CROSS_CFLAGS_COMPILE="$NIX_CROSS_CFLAGS_COMPILE -I$1/include"
     fi
 
     if test -d $1/lib; then
-        export NIX_LDFLAGS="$NIX_LDFLAGS -L$1/lib"
+        export NIX_CROSS_LDFLAGS="$NIX_CROSS_LDFLAGS -L$1/lib"
     fi
 }
 
-crossEnvHooks=(${crossEnvHooks[@]} addCVars)
+crossEnvHooks=(${crossEnvHooks[@]} crossAddCVars)
 
 # Note: these come *after* $out in the PATH (see setup.sh).
 
@@ -22,10 +22,18 @@ fi
 
 if test -n "@libc@"; then
     PATH=$PATH:@libc@/bin
-    addCVars @libc@
+    crossAddCVars @libc@
 fi
 
 configureFlags="$configureFlags --build=$system --host=$crossConfig"
 # Disabling the tests when cross compiling, as usually the tests are meant for
 # native compilations.
 doCheck=""
+
+# Add the output as an rpath.
+if test "$NIX_NO_SELF_RPATH" != "1"; then
+    export NIX_CROSS_LDFLAGS="-rpath $out/lib -rpath-link $out/lib $NIX_CROSS_LDFLAGS"
+    if test -n "$NIX_LIB64_IN_SELF_RPATH"; then
+        export NIX_CROSS_LDFLAGS="-rpath $out/lib64 -rpath-link $out/lib $NIX_CROSS_LDFLAGS"
+    fi
+fi
diff --git a/pkgs/development/compilers/gcc-4.3/builder.sh b/pkgs/development/compilers/gcc-4.3/builder.sh
index 69e2a0b137ea..6c3671bf7cbd 100644
--- a/pkgs/development/compilers/gcc-4.3/builder.sh
+++ b/pkgs/development/compilers/gcc-4.3/builder.sh
@@ -40,7 +40,7 @@ if test "$noSysDirs" = "1"; then
         export NIX_EXTRA_LDFLAGS="$NIX_EXTRA_LDFLAGS -Wl,$i"
     done
 
-    if test -n "$crossConfig"; then
+    if test -n "$targetConfig"; then
         if test -z "$crossStageStatic"; then
             extraXCFlags="-B${glibcCross}/lib -idirafter ${glibcCross}/include"
             extraXLDFlags="-L${glibcCross}/lib"
@@ -71,7 +71,7 @@ if test "$noSysDirs" = "1"; then
             )
     fi
 
-    if test -n "$crossConfig" -a "$crossStageStatic" == 1; then
+    if test -n "$targetConfig" -a "$crossStageStatic" == 1; then
         # We don't want the gcc build to assume there will be a libc providing
         # limits.h in this stagae
         makeFlagsArray=( \
@@ -86,7 +86,7 @@ if test "$noSysDirs" = "1"; then
     fi
 fi
 
-if test -n "$crossConfig"; then
+if test -n "$targetConfig"; then
     # The host strip will destroy everything in the target binaries otherwise
     dontStrip=1
 fi
@@ -127,7 +127,7 @@ postInstall() {
 }
 
 
-if test -z "$crossConfig"; then
+if test -z "$targetConfig"; then
     if test -z "$profiledCompiler"; then
         buildFlags="bootstrap $buildFlags"
     else    
diff --git a/pkgs/development/compilers/gcc-4.3/default.nix b/pkgs/development/compilers/gcc-4.3/default.nix
index 898d9b0b478a..efd058756b33 100644
--- a/pkgs/development/compilers/gcc-4.3/default.nix
+++ b/pkgs/development/compilers/gcc-4.3/default.nix
@@ -78,7 +78,7 @@ stdenv.mkDerivation ({
     
   inherit noSysDirs profiledCompiler staticCompiler crossStageStatic
     binutilsCross glibcCross;
-  crossConfig = if (cross != null) then cross.config else null;
+  targetConfig = if (cross != null) then cross.config else null;
 
   buildInputs = [texinfo gmp mpfr]
     ++ (optionals langTreelang [bison flex])
diff --git a/pkgs/development/interpreters/guile/default.nix b/pkgs/development/interpreters/guile/default.nix
index 5be39a20f5a5..905e475aba27 100644
--- a/pkgs/development/interpreters/guile/default.nix
+++ b/pkgs/development/interpreters/guile/default.nix
@@ -9,19 +9,26 @@ stdenv.mkDerivation rec {
   };
 
   buildNativeInputs = [ makeWrapper ];
-  propagatedBuildInputs = [ libtool gmp ];
-  propagatedBuildNativeInputs = [readline gawk];
+  buildInputs = [ libtool ];
+  propagatedBuildInputs = [ readline gmp libtool ];
+  propagatedBuildNativeInputs = [ gawk ];
 
   postInstall = ''
     wrapProgram $out/bin/guile-snarf --prefix PATH : "${gawk}/bin"
   '';
 
-  NIX_DEBUG=1;
-
   preBuild = ''
     sed -e '/lt_dlinit/a  lt_dladdsearchdir("'$out/lib'");' -i libguile/dynl.c
   '';
 
+  # Guile needs patching to preset results for the configure tests
+  # about pthreads, which work only in native builds.
+  preConfigure = ''
+    if test -n "$crossConfig"; then
+      configureFlags="--with-threads=no $configureFlags"
+    fi
+  '';
+
   doCheck = true;
 
   setupHook = ./setup-hook.sh;
diff --git a/pkgs/development/libraries/glibc-2.9/default.nix b/pkgs/development/libraries/glibc-2.9/default.nix
index 98e281c19180..50dc51bdcb71 100644
--- a/pkgs/development/libraries/glibc-2.9/default.nix
+++ b/pkgs/development/libraries/glibc-2.9/default.nix
@@ -1,10 +1,11 @@
 { stdenv, fetchurl, kernelHeaders
 , installLocales ? true
 , profilingLibraries ? false
-, cross ? null
 , gccCross ? null
 }:
-
+let
+    cross = if gccCross != null then gccCross.target else null;
+in
 stdenv.mkDerivation rec {
   name = "glibc-2.9" +
     stdenv.lib.optionalString (cross != null) "-${cross.config}";
@@ -67,8 +68,6 @@ stdenv.mkDerivation rec {
     "--with-headers=${kernelHeaders}/include"
     (if profilingLibraries then "--enable-profile" else "--disable-profile")
   ] ++ stdenv.lib.optionals (cross != null) [
-    "--host=${cross.config}"
-    "--build=${stdenv.system}"
     "--with-tls"
     "--enable-kernel=2.6.0"
     "--without-fp"
@@ -79,7 +78,7 @@ stdenv.mkDerivation rec {
     "--without-fp"
   ] else []);
 
-  buildInputs = stdenv.lib.optionals (cross != null) [ gccCross ];
+  buildNativeInputs = stdenv.lib.optionals (cross != null) [ gccCross ];
 
   preInstall = ''
     ensureDir $out/lib
diff --git a/pkgs/development/libraries/physfs/default.nix b/pkgs/development/libraries/physfs/default.nix
index 3eb9a980c819..79ddf9cfe11a 100644
--- a/pkgs/development/libraries/physfs/default.nix
+++ b/pkgs/development/libraries/physfs/default.nix
@@ -8,7 +8,7 @@ stdenv.mkDerivation rec {
     sha256 = "072hqprni4vf4ax6b659s2xxrbz0y6iziarsczawbhi69m4azpyb";
   };
 
-  buildInputs = [ cmake ];
+  buildNativeInputs = [ cmake ];
 
   meta = {
     homepage = http://icculus.org/physfs/;
diff --git a/pkgs/development/tools/build-managers/cmake/setup-hook.sh b/pkgs/development/tools/build-managers/cmake/setup-hook.sh
index 835b9000c68d..5fdd66aaace0 100755
--- a/pkgs/development/tools/build-managers/cmake/setup-hook.sh
+++ b/pkgs/development/tools/build-managers/cmake/setup-hook.sh
@@ -32,6 +32,13 @@ cmakeConfigurePhase()
         cmakeFlags="-DCMAKE_INSTALL_PREFIX=$prefix $cmakeFlags"
     fi
 
+    if test -n "$crossConfig"; then
+        # By now it supports linux builds only. We should set the proper
+        # CMAKE_SYSTEM_NAME otherwise.
+        # http://www.cmake.org/Wiki/CMake_Cross_Compiling
+        cmakeFlags="-DCMAKE_CXX_COMPILER=$crossConfig-g++ -DCMAKE_C_COMPILER=$crossConfig-gcc $cmakeFlags"
+    fi
+
     echo "cmake flags: $cmakeFlags ${cmakeFlagsArray[@]}"
 
     cmake ${cmakeDir:-.} $cmakeFlags ${cmakeFlagsArray[@]}
@@ -43,4 +50,8 @@ if test -z "$dontUseCmakeConfigure"; then
     configurePhase=cmakeConfigurePhase
 fi
 
-envHooks=(${envHooks[@]} addCMakeParams)
+if test -n "$crossConfig"; then
+    crossEnvHooks=(${crossEnvHooks[@]} addCMakeParams)
+else
+    envHooks=(${envHooks[@]} addCMakeParams)
+fi
diff --git a/pkgs/development/tools/misc/pkgconfig/setup-hook.sh b/pkgs/development/tools/misc/pkgconfig/setup-hook.sh
index ea592b36d11e..77a69fb18781 100644
--- a/pkgs/development/tools/misc/pkgconfig/setup-hook.sh
+++ b/pkgs/development/tools/misc/pkgconfig/setup-hook.sh
@@ -3,4 +3,8 @@ addPkgConfigPath () {
     addToSearchPath PKG_CONFIG_PATH $1/share/pkgconfig
 }
 
-envHooks=(${envHooks[@]} addPkgConfigPath)
+if test -n "$crossConfig"; then
+    crossEnvHooks=(${crossEnvHooks[@]} addPkgConfigPath)
+else
+    envHooks=(${envHooks[@]} addPkgConfigPath)
+fi
diff --git a/pkgs/os-specific/linux/kernel-headers/2.6.28.nix b/pkgs/os-specific/linux/kernel-headers/2.6.28.nix
index 69849112d81f..4392e894e961 100644
--- a/pkgs/os-specific/linux/kernel-headers/2.6.28.nix
+++ b/pkgs/os-specific/linux/kernel-headers/2.6.28.nix
@@ -14,7 +14,7 @@ stdenv.mkDerivation {
     sha256 = "0hifjh75sinifr5138v22zwbpqln6lhn65k8b57a1dyzlqca7cl9";
   };
 
-  crossConfig = if (cross != null) then cross.config else null;
+  targetConfig = if (cross != null) then cross.config else null;
 
   platform = 
     if cross != null then cross.arch else
@@ -37,7 +37,7 @@ stdenv.mkDerivation {
   '';
 
   buildPhase = ''
-    if test -n "$crossConfig"; then
+    if test -n "$targetConfig"; then
        export ARCH=$platform
     fi
     make mrproper headers_check
diff --git a/pkgs/servers/x11/xorg/overrides.nix b/pkgs/servers/x11/xorg/overrides.nix
index 4f25334e3972..fb360e433bb0 100644
--- a/pkgs/servers/x11/xorg/overrides.nix
+++ b/pkgs/servers/x11/xorg/overrides.nix
@@ -30,6 +30,7 @@ in
   libxcb = attrs : attrs // {
     # I only remove python from the original, and add xproto. I don't know how
     # to achieve that referring to attrs.buildInputs.
+    # I should use: builtins.unsafeDiscardStringContext
     buildInputs = [args.pkgconfig args.libxslt xorg.libpthreadstubs /*xorg.python*/
         xorg.libXau xorg.xcbproto xorg.libXdmcp ] ++ [ xorg.xproto ];
     buildNativeInputs = [ args.python ];
diff --git a/pkgs/stdenv/adapters.nix b/pkgs/stdenv/adapters.nix
index e21a9e02d292..698253c0c63a 100644
--- a/pkgs/stdenv/adapters.nix
+++ b/pkgs/stdenv/adapters.nix
@@ -130,12 +130,21 @@ rec {
             # And the same for propagatedBuildInputs.
             buildDrv = stdenv.mkDerivation args;
 
+            # Temporary expression until the cross_renaming, to handle the
+            # case of pkgconfig given as buildInput, but to be used as
+            # buildNativeInput.
+            hostAsBuildDrv = drv: builtins.unsafeDiscardStringContext
+                drv.buildDrv.drvPath == builtins.unsafeDiscardStringContext
+                drv.hostDrv.drvPath;
+            nativeInputsFromBuildInputs = stdenv.lib.filter (hostAsBuildDrv) buildInputs;
+
             # We should overwrite the input attributes in hostDrv, to overwrite
             # the defaults for only-native builds in the base stdenv
             hostDrv = if (cross == null) then buildDrv else
                 stdenv.mkDerivation (args // {
                     name = name + "-" + cross.config;
                     buildNativeInputs = buildNativeInputsDrvs
+                      ++ nativeInputsFromBuildInputs
                       ++ [ gccCross binutilsCross ] ++
                       stdenv.lib.optional selfNativeBuildInput buildDrv;
                     buildInputs = buildInputsDrvs;
diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix
index 0755ee46904b..0ae71d183dec 100644
--- a/pkgs/stdenv/generic/default.nix
+++ b/pkgs/stdenv/generic/default.nix
@@ -55,6 +55,8 @@ let
                 propagatedBuildNativeInputs = if attrs ?
                     propagatedBuildNativeInputs then
                     attrs.propagatedBuildNativeInputs else [];
+                crossConfig = if (attrs ? crossConfig) then attrs.crossConfig else
+                   null;
             in
             {
               builder = if attrs ? realBuilder then attrs.realBuilder else shell;
@@ -64,12 +66,14 @@ let
               system = result.system;
 
               # That build by the cross compiler
-              buildInputs = [];
-              propagatedBuildInputs = [];
+              buildInputs = lib.optionals (crossConfig != null) buildInputs;
+              propagatedBuildInputs = lib.optionals (crossConfig != null)
+                  propagatedBuildInputs;
               # That build by the usual native compiler
-              buildNativeInputs = buildInputs ++ buildNativeInputs;
-              propagatedBuildNativeInputs = propagatedBuildInputs ++
-                propagatedBuildNativeInputs;
+              buildNativeInputs = buildNativeInputs ++ lib.optionals
+                (crossConfig == null) buildInputs;
+              propagatedBuildNativeInputs = propagatedBuildNativeInputs ++
+                lib.optionals (crossConfig == null) propagatedBuildInputs;
             }))
           )
           # The meta attribute is passed in the resulting attribute set,
diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh
index 62d441439d88..631182f6b7c3 100644
--- a/pkgs/stdenv/generic/setup.sh
+++ b/pkgs/stdenv/generic/setup.sh
@@ -124,6 +124,7 @@ if test -z "$SHELL"; then echo "SHELL not set"; exit 1; fi
 
 # Hack: run gcc's setup hook.
 envHooks=()
+crossEnvHooks=()
 if test -f $NIX_GCC/nix-support/setup-hook; then
     source $NIX_GCC/nix-support/setup-hook
 fi
@@ -203,10 +204,16 @@ for i in $nativePkgs; do
     addToNativeEnv $i
 done
 
-crossEnvHooks=()
 addToCrossEnv() {
     local pkg=$1
 
+    # Some programs put important build scripts (freetype-config and similar)
+    # into their hostDrv bin path. Intentionally these should go after
+    # the nativePkgs in PATH.
+    if test -d $1/bin; then
+        addToSearchPath _PATH $1/bin
+    fi
+
     # Run the package-specific hooks set by the setup-hook scripts.
     for i in "${crossEnvHooks[@]}"; do
         $i $pkg
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 014f9e18021b..aadf74ed7538 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -183,6 +183,8 @@ let
         }
       else stdenvCross;
 
+  forceBuildDrv = drv : drv // { hostDrv = drv.buildDrv; };
+
   # A stdenv capable of building 32-bit binaries.  On x86_64-linux,
   # it uses GCC compiled with multilib support; on i686-linux, it's
   # just the plain stdenv.
@@ -1776,7 +1778,6 @@ let
   }));
 
   gcc43_realCross = cross : makeOverridable (import ../development/compilers/gcc-4.3) {
-    #stdenv = overrideGCC stdenv (wrapGCCWith (import ../build-support/gcc-wrapper) glibc_multi gcc);
     inherit stdenv fetchurl texinfo gmp mpfr noSysDirs cross;
     binutilsCross = binutilsCross cross;
     glibcCross = glibcCross cross;
@@ -1786,18 +1787,18 @@ let
   };
 
   gccCrossStageStatic = cross: wrapGCCCross {
-    gcc = (gcc43_realCross cross).override {
+    gcc = forceBuildDrv ((gcc43_realCross cross).override {
         crossStageStatic = true;
         langCC = false;
         glibcCross = null;
-    };
+    });
     libc = null;
     binutils = binutilsCross cross;
     inherit cross;
   };
 
   gccCrossStageFinal = cross: wrapGCCCross {
-    gcc = gcc43_realCross cross;
+    gcc = forceBuildDrv (gcc43_realCross cross);
     libc = glibcCross cross;
     binutils = binutilsCross cross;
     inherit cross;
@@ -2220,12 +2221,12 @@ let
   wrapGCCCross =
     {gcc, libc, binutils, cross, shell ? "", name ? "gcc-cross-wrapper"}:
     
-    import ../build-support/gcc-cross-wrapper {
+    forceBuildDrv (import ../build-support/gcc-cross-wrapper {
       nativeTools = false;
       nativeLibc = false;
       noLibc = (libc == null);
       inherit stdenv gcc binutils libc shell name cross;
-    };
+    });
 
   # FIXME: This is a specific hack for GCC-UPC.  Eventually, we may
   # want to merge `gcc-upc-wrapper' and `gcc-wrapper'.
@@ -2605,10 +2606,10 @@ let
       inherit fetchurl stdenv noSysDirs;
     });
 
-  binutilsCross = cross : import ../development/tools/misc/binutils {
+  binutilsCross = cross : forceBuildDrv (import ../development/tools/misc/binutils {
       inherit stdenv fetchurl cross;
       noSysDirs = true;
-  };
+  });
 
   bison = bison23;
 
@@ -2885,7 +2886,7 @@ let
      cross_renaming: we should make all programs use pkgconfig as
      buildNativeInput after the renaming.
      */
-  pkgconfig = pkgconfigReal // { hostDrv = pkgconfigReal.buildDrv; };
+  pkgconfig = forceBuildDrv pkgconfigReal;
 
   radare = import ../development/tools/analysis/radare {
     inherit stdenv fetchurl pkgconfig libusb readline gtkdialog python
@@ -3427,26 +3428,28 @@ let
     installLocales = getPkgConfig "glibc" "locales" false;
   };
 
-  glibc29Cross = cross : makeOverridable (import ../development/libraries/glibc-2.9) {
-    inherit stdenv fetchurl cross;
+  glibc29Cross = cross: forceBuildDrv (makeOverridable (import ../development/libraries/glibc-2.9) {
+    inherit stdenv fetchurl;
     gccCross = gccCrossStageStatic cross;
     kernelHeaders = kernelHeadersCross cross;
     installLocales = getPkgConfig "glibc" "locales" false;
-  };
+  });
+
+  glibcCross = cross: glibc29Cross cross;
 
   glibc211 = makeOverridable (import ../development/libraries/glibc-2.11) {
     inherit fetchurl stdenv kernelHeaders;
     installLocales = getPkgConfig "glibc" "locales" false;
   };
 
-  glibc211Cross = cross : makeOverridable (import ../development/libraries/glibc-2.11) {
+  glibc211CrossReal = cross : forceBuildDrv (makeOverridable (import ../development/libraries/glibc-2.11) {
     inherit stdenv fetchurl cross;
     gccCross = gccCrossStageStatic cross;
     kernelHeaders = kernelHeadersCross cross;
     installLocales = getPkgConfig "glibc" "locales" false;
-  };
+  });
 
-  glibcCross = cross: glibc29Cross cross;
+  glibc211Cross = cross : forceBuildDrv (glibc211CrossReal cross);
 
   eglibc = import ../development/libraries/eglibc {
     inherit fetchsvn stdenv kernelHeaders;
@@ -5395,9 +5398,9 @@ let
 
   kernelHeaders = kernelHeaders_2_6_28;
 
-  kernelHeadersCross = cross : import ../os-specific/linux/kernel-headers/2.6.28.nix {
+  kernelHeadersCross = cross : forceBuildDrv (import ../os-specific/linux/kernel-headers/2.6.28.nix {
     inherit stdenv fetchurl cross perl;
-  };
+  });
 
   kernelHeaders_2_6_18 = import ../os-specific/linux/kernel-headers/2.6.18.5.nix {
     inherit fetchurl stdenv unifdef;