summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2004-04-04 22:02:41 +0000
committerEelco Dolstra <eelco.dolstra@logicblox.com>2004-04-04 22:02:41 +0000
commitbeaff0a8929b14bca736cb96a1bbf4c2e1c604d6 (patch)
treec93f32f82be57ea066cc2ebb5c919fe1b9f4b7ad
parent0d4967fc35631ebfe9869739d01e713d60bd21ff (diff)
downloadnixlib-beaff0a8929b14bca736cb96a1bbf4c2e1c604d6.tar
nixlib-beaff0a8929b14bca736cb96a1bbf4c2e1c604d6.tar.gz
nixlib-beaff0a8929b14bca736cb96a1bbf4c2e1c604d6.tar.bz2
nixlib-beaff0a8929b14bca736cb96a1bbf4c2e1c604d6.tar.lz
nixlib-beaff0a8929b14bca736cb96a1bbf4c2e1c604d6.tar.xz
nixlib-beaff0a8929b14bca736cb96a1bbf4c2e1c604d6.tar.zst
nixlib-beaff0a8929b14bca736cb96a1bbf4c2e1c604d6.zip
* Ensure that when building gcc, libstdc++ is linked against the
  libgcc of the gcc being built, not the gcc building it.
* Only include a directory in the rpath of an executable/library if it
  is actually used.  Before, the `/lib' directory of every build input
  was added to the rpath, causing many unnecessary retained
  dependencies.  For instance, Perl has a `/lib' directory, but most
  applications whose build process uses Perl don't actually link
  against Perl.  (Also added a test for this.)
* After building glibc, remove glibcbug, to prevent a retained
  dependency on gcc.
* Add a newline after `building X' in GNU Make.

svn path=/nixpkgs/trunk/; revision=911
-rw-r--r--pkgs/TODO30
-rw-r--r--pkgs/build-support/gcc-wrapper/builder.sh4
-rw-r--r--pkgs/build-support/gcc-wrapper/ld-wrapper.sh78
-rw-r--r--pkgs/build-support/gcc-wrapper/setup-hook.sh2
-rw-r--r--pkgs/development/compilers/gcc/builder.sh31
-rw-r--r--pkgs/development/libraries/glibc/builder.sh9
-rw-r--r--pkgs/development/tools/build-managers/gnumake/log.diff4
-rw-r--r--pkgs/test/rpath/builder.sh79
-rw-r--r--pkgs/test/rpath/default.nix18
-rw-r--r--pkgs/test/rpath/src/hello1.c7
-rw-r--r--pkgs/test/rpath/src/hello2.cc7
-rw-r--r--pkgs/test/rpath/src/hello3.c9
-rw-r--r--pkgs/test/rpath/src/text.c4
13 files changed, 235 insertions, 47 deletions
diff --git a/pkgs/TODO b/pkgs/TODO
index 60b614d687c9..c63a40d85bc6 100644
--- a/pkgs/TODO
+++ b/pkgs/TODO
@@ -8,31 +8,5 @@
 
 * Inform freedesktop people that Xaw requires Xpm.
 
-* Only add --rpath FOO/lib if FOO/lib is actually used, otherwise we
-  get lots of unneccesarily retained dependencies.
-
-* After building gcc, filter out this sillyness in .../lib/libsupc++.la and .../lib/libstdc++.la:
-
-    /nix/store/fd3dba2a24f0242af8ea7e896380be7e-gcc-3.3.3/lib/libsupc++.la:dependency_libs='
--L/tmp/nix-26124-33/build/i686-pc-linux-gnu/libstdc++-v3/src
--L/tmp/nix-26124-33/build/i686-pc-linux-gnu/libstdc++-v3/src/.libs -lm
--L/tmp/nix-26124-33/build/gcc
--L/nix/store/e173bb830ba5f727ae63e0673d929bc7-gcc-3.3.3/bin
--L/nix/store/23ef1e01b61105fee5ef8b47faf30675-glibc-2.3.2/lib
--L/nix/store/6d3bf84aeb18d6d92a25ce9692b0f4d2-gcc-3.3.3/lib -lgcc_s
--lc -lgcc_s'
-
-    /nix/store/fd3dba2a24f0242af8ea7e896380be7e-gcc-3.3.3/lib/libstdc++.la:dependency_libs='
--L/tmp/nix-26124-33/build/i686-pc-linux-gnu/libstdc++-v3/src
--L/tmp/nix-26124-33/build/i686-pc-linux-gnu/libstdc++-v3/src/.libs -lm
--lm -lm -L/tmp/nix-26124-33/build/gcc
--L/nix/store/e173bb830ba5f727ae63e0673d929bc7-gcc-3.3.3/bin
--L/nix/store/23ef1e01b61105fee5ef8b47faf30675-glibc-2.3.2/lib
--L/nix/store/6d3bf84aeb18d6d92a25ce9692b0f4d2-gcc-3.3.3/lib -lgcc_s
--lc -lgcc_s -lm -lgcc_s -lc -lgcc_s'
-
-  in particular references to /tmp/nix... and to /nix/store/...-
-
-  i.e., basically all -L... switches
-
-  this causes lots of unneccesarily retained dependencies
+* After building gcc, filter out references to /tmp/nix... in
+  .../lib/libsupc++.la and .../lib/libstdc++.la
diff --git a/pkgs/build-support/gcc-wrapper/builder.sh b/pkgs/build-support/gcc-wrapper/builder.sh
index 96d1bfc6be74..c0c0c53a7a67 100644
--- a/pkgs/build-support/gcc-wrapper/builder.sh
+++ b/pkgs/build-support/gcc-wrapper/builder.sh
@@ -10,14 +10,14 @@ if test -z "$nativeGlibc"; then
     # /usr/lib.  The real solution is of course to prevent those paths
     # from being used by gcc in the first place.
     cflagsCompile="$cflagsCompile -B$glibc/lib -isystem $glibc/include"
-    ldflags="$ldflags -L$glibc/lib -rpath $glibc/lib -dynamic-linker $glibc/lib/ld-linux.so.2"
+    ldflags="$ldflags -L$glibc/lib -dynamic-linker $glibc/lib/ld-linux.so.2"
 fi
 
 if test -n "$nativeTools"; then
     gccPath="$nativePrefix/bin"
     ldPath="$nativePrefix/bin"
 else
-    ldflags="$ldflags -L$gcc/lib -rpath $gcc/lib"
+    ldflags="$ldflags -L$gcc/lib"
     gccPath="$gcc/bin"
     ldPath="$binutils/bin"
 fi
diff --git a/pkgs/build-support/gcc-wrapper/ld-wrapper.sh b/pkgs/build-support/gcc-wrapper/ld-wrapper.sh
index 1bfc86d5c6c3..d90b290e0076 100644
--- a/pkgs/build-support/gcc-wrapper/ld-wrapper.sh
+++ b/pkgs/build-support/gcc-wrapper/ld-wrapper.sh
@@ -47,6 +47,84 @@ if test -z "$NIX_LDFLAGS_SET"; then
     extra=(${extra[@]} $NIX_LDFLAGS)
 fi
 
+
+# Add all used dynamic libraries to the rpath.
+if test "$NIX_DONT_SET_RPATH" != "1"; then
+
+    # First, find all -L... switches.
+    allParams=("${params[@]}" ${extra[@]})
+    libPath=""
+    addToLibPath() {
+        local path="$1"
+        if test "${path:0:1}" != "/"; then return 0; fi
+        case "$path" in
+            *..*|*./*|*/.*|*//*)
+                local path2
+                if path2=$(readlink -f "$path"); then
+                    path="$path2"
+                fi
+                ;;
+        esac
+        case $libPath in
+            *\ $path\ *) return 0 ;;
+        esac
+        libPath="$libPath $path "
+    }
+    n=0
+    while test $n -lt ${#allParams[*]}; do
+        p=${allParams[n]}
+        p2=${allParams[$((n+1))]}
+        if test "${p:0:3}" = "-L/"; then
+            addToLibPath ${p:2}
+        elif test "$p" = "-L"; then
+            addToLibPath ${p2}
+            n=$((n + 1))
+        fi
+        n=$((n + 1))
+    done
+
+    # Second, for each -l... switch, find the directory containing the
+    # library and add it to the rpath.
+    rpath=""
+    addToRPath() {
+        # If the path is not in the store, don't add it to the rpath.
+        # This typically happens for libraries in /tmp that are later
+        # copied to $out/lib.  If not, we're screwed.
+        if test "${1:0:${#NIX_STORE}}" != "$NIX_STORE"; then return 0; fi
+        case $rpath in
+            *\ $1\ *) return 0 ;;
+        esac
+        rpath="$rpath $1 "
+    }
+    findLib() {
+        for i in $libPath; do
+            if test -f $i/lib$1.so; then
+                addToRPath $i
+            fi
+        done
+    }
+    n=0
+    while test $n -lt ${#allParams[*]}; do
+        p=${allParams[n]}
+        p2=${allParams[$((n+1))]}
+        if test "${p:0:2}" = "-l"; then
+            findLib ${p:2}
+        elif test "$p" = "-l"; then
+            # I haven't seen `-l foo', but you never know...
+            findLib ${p2}
+            n=$((n + 1))
+        fi
+        n=$((n + 1))
+    done
+
+    # Finally, add `-rpath' switches.
+    for i in $rpath; do
+        extra=(${extra[@]} -rpath $i)
+    done
+
+fi
+
+
 # Optionally print debug info.
 if test "$NIX_DEBUG" = "1"; then
   echo "original flags to @ld@:" >&2
diff --git a/pkgs/build-support/gcc-wrapper/setup-hook.sh b/pkgs/build-support/gcc-wrapper/setup-hook.sh
index a52ca43d9df8..7a7ea8226919 100644
--- a/pkgs/build-support/gcc-wrapper/setup-hook.sh
+++ b/pkgs/build-support/gcc-wrapper/setup-hook.sh
@@ -4,7 +4,7 @@ addCVars () {
     fi
 
     if test -d $1/lib; then
-        export NIX_LDFLAGS="$NIX_LDFLAGS -L$1/lib -rpath $1/lib"
+        export NIX_LDFLAGS="$NIX_LDFLAGS -L$1/lib"
     fi
 }
 
diff --git a/pkgs/development/compilers/gcc/builder.sh b/pkgs/development/compilers/gcc/builder.sh
index c97c9823b34f..22d1e38707a0 100644
--- a/pkgs/development/compilers/gcc/builder.sh
+++ b/pkgs/development/compilers/gcc/builder.sh
@@ -40,21 +40,38 @@ postConfigure() {
     if test "$noSysDirs" = "1"; then
         # Patch some of the makefiles to force linking against our own
         # glibc.
-        . $NIX_GCC/nix-support/add-flags # add glibc/gcc flags
-        extraflags="-Wl,-s $NIX_CFLAGS_COMPILE $NIX_CFLAGS_LINK"
-        for i in $NIX_LDFLAGS; do
-            extraflags="$extraflags -Wl,$i"
-        done
+        if test -e $NIX_GCC/nix-support/orig-glibc; then
+            glibc=$(cat $NIX_GCC/nix-support/orig-glibc)
+            # Ugh.  Copied from gcc-wrapper/builder.sh.  We can't just
+            # source in $NIX_GCC/nix-support/add-flags, since that
+            # would cause *this* GCC to be linked against the
+            # *previous* GCC.  Need some more modularity there.
+            extraFlags="-Wl,-s -B$glibc/lib -isystem $glibc/include \
+                -L$glibc/lib -Wl,-dynamic-linker -Wl,$glibc/lib/ld-linux.so.2"
+
+            # Oh, what a hack.  I should be shot for this.
+            # In stage 1, we should link against the previous GCC, but
+            # not afterwards.  Otherwise we retain a dependency.
+            # However, ld-wrapper, which adds the linker flags for the
+            # previous GCC, is also used in stage 2/3.  We can prevent
+            # it from adding them by NIX_GLIBC_FLAGS_SET, but then
+            # gcc-wrapper will also not add them, thereby causing
+            # stage 1 to fail.  So we use a trick to only set the
+            # flags in gcc-wrapper.
+            hook=$(pwd)/ld-wrapper-hook
+            echo "NIX_GLIBC_FLAGS_SET=1" > $hook
+            export NIX_LD_WRAPPER_START_HOOK=$hook
+        fi
 
         mf=Makefile
         sed \
-            -e "s^FLAGS_FOR_TARGET =\(.*\)^FLAGS_FOR_TARGET = \1 $extraflags^" \
+            -e "s^FLAGS_FOR_TARGET =\(.*\)^FLAGS_FOR_TARGET = \1 $extraFlags^" \
             < $mf > $mf.tmp
         mv $mf.tmp $mf
 
         mf=gcc/Makefile
         sed \
-            -e "s^X_CFLAGS =\(.*\)^X_CFLAGS = \1 $extraflags^" \
+            -e "s^X_CFLAGS =\(.*\)^X_CFLAGS = \1 $extraFlags^" \
             < $mf > $mf.tmp
         mv $mf.tmp $mf
 
diff --git a/pkgs/development/libraries/glibc/builder.sh b/pkgs/development/libraries/glibc/builder.sh
index 23fac6ab9b75..3c253c2d2643 100644
--- a/pkgs/development/libraries/glibc/builder.sh
+++ b/pkgs/development/libraries/glibc/builder.sh
@@ -4,13 +4,6 @@ export NIX_NO_SELF_RPATH=1
 . $stdenv/setup
 
 
-# !!! Toss the linker flags.  Any sort of rpath is fatal.
-# This probably will cause a failure when building in a pure Nix
-# environment.
-export NIX_LDFLAGS=
-export NIX_GLIBC_FLAGS_SET=1
-
-
 postUnpack() {
     cd $sourceRoot
     unpackFile $linuxthreadsSrc
@@ -35,6 +28,8 @@ postInstall() {
     make localedata/install-locales
     rm $out/etc/ld.so.cache
     (cd $out/include && ln -s $kernelHeaders/include/* .) || exit 1
+    # `glibcbug' causes a retained dependency on the C compiler.
+    rm $out/bin/glibcbug
 }
 
 postInstall=postInstall
diff --git a/pkgs/development/tools/build-managers/gnumake/log.diff b/pkgs/development/tools/build-managers/gnumake/log.diff
index 26cc3315c5b5..fa90acfe8de5 100644
--- a/pkgs/development/tools/build-managers/gnumake/log.diff
+++ b/pkgs/development/tools/build-managers/gnumake/log.diff
@@ -108,14 +108,14 @@ diff -rc make-3.80-orig/make.h make-3.80/make.h
 + extern int logNestingStderr;
 diff -rc make-3.80-orig/remake.c make-3.80/remake.c
 *** make-3.80-orig/remake.c	2002-08-08 02:11:19.000000000 +0200
---- make-3.80/remake.c	2004-04-02 17:43:00.000000000 +0200
+--- make-3.80/remake.c	2004-04-04 23:10:19.000000000 +0200
 ***************
 *** 1049,1055 ****
 --- 1049,1059 ----
         /* The normal case: start some commands.  */
         if (!touch_flag || file->cmds->any_recurse)
   	{
-+           fprintf(stderr, "\e[pbuilding %s", file->name);
++           fprintf(stderr, "\e[pbuilding %s\n", file->name);
 +           logNestingStderr++;
   	  execute_file_commands (file);
 +           fprintf(stderr, "\e[q");
diff --git a/pkgs/test/rpath/builder.sh b/pkgs/test/rpath/builder.sh
new file mode 100644
index 000000000000..0a75e1cd33a7
--- /dev/null
+++ b/pkgs/test/rpath/builder.sh
@@ -0,0 +1,79 @@
+export NIX_DEBUG=1
+
+. $stdenv/setup
+
+mkdir $out
+mkdir $out/bin
+
+
+# 1: link statically against glibc.
+res=$out/bin/hello1
+gcc -static $src/hello1.c -o $res
+
+case $(ldd $res) in
+  *"not a dynamic executable"*)
+        ;;
+  *)
+        echo "$res not statically linked!"
+        exit 1
+esac
+
+
+# 2: link dynamically against glibc.
+res=$out/bin/hello2
+gcc $src/hello1.c -o $res
+
+case $(ldd $res) in
+  */store/*glibc*/lib/libc.so*/store/*glibc*/lib/ld-linux.so*)
+        ;;
+  *)
+        echo "$res not dynamically linked / bad rpath!"
+        exit 1
+        ;;
+esac
+
+
+# 3: link C++ dynamically against glibc / libstdc++.
+res=$out/bin/hello3
+g++ $src/hello2.cc -o $res
+
+case $(ldd $res) in
+  */store/*gcc*/lib/*libstdc++*/store/*glibc*/lib/libm*/store/*gcc*/lib/libgcc_s*/store/*glibc*/lib/libc.so*/store/*glibc*/lib/ld-linux.so*)
+        ;;
+  *)
+        echo "$res not dynamically linked / bad rpath!"
+        exit 1
+        ;;
+esac
+
+
+# 4: build dynamic library locally, link against it, copy it.
+res=$out/bin/hello4
+mkdir bla
+gcc -shared $src/text.c -o bla/libtext.so 
+gcc $src/hello3.c -o $res -L$(pwd)/bla -ltext
+mkdir $out/lib
+
+case $(ldd $res) in
+  */tmp*)
+        echo "$res depends on file in /tmp!"
+        exit 1
+        ;;
+esac
+
+cp bla/libtext.so $out/lib
+
+case $(ldd $res) in
+  */store/*glibc*/lib/libc.so*/store/*glibc*/lib/ld-linux.so*)
+        ;;
+  *)
+        echo "$res not dynamically linked / bad rpath!"
+        exit 1
+        ;;
+esac
+
+
+# Run the programs we just made.
+for i in $out/bin/*; do
+    $i
+done
diff --git a/pkgs/test/rpath/default.nix b/pkgs/test/rpath/default.nix
new file mode 100644
index 000000000000..f0903420c96a
--- /dev/null
+++ b/pkgs/test/rpath/default.nix
@@ -0,0 +1,18 @@
+let {
+  system = "i686-linux";
+
+  stdenvs = (import ../../system/stdenvs.nix) {
+    inherit system;
+    allPackages = import ../../system/all-packages-generic.nix;
+  };
+
+  stdenv = stdenvs.stdenvLinuxBoot2;
+
+  test = stdenv.mkDerivation {
+    name = "rpath-test";
+    builder = ./builder.sh;
+    src = ./src;
+  };
+
+  body = test;
+}
diff --git a/pkgs/test/rpath/src/hello1.c b/pkgs/test/rpath/src/hello1.c
new file mode 100644
index 000000000000..c44d7c4a936d
--- /dev/null
+++ b/pkgs/test/rpath/src/hello1.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(int argc, char * * argv)
+{
+    printf("Hello World!\n");
+    return 0;
+}
diff --git a/pkgs/test/rpath/src/hello2.cc b/pkgs/test/rpath/src/hello2.cc
new file mode 100644
index 000000000000..0dc34766f5f1
--- /dev/null
+++ b/pkgs/test/rpath/src/hello2.cc
@@ -0,0 +1,7 @@
+#include <iostream>
+
+int main(int argc, char * * argv)
+{
+    std::cout << "Hello World!\n";
+    return 0;
+}
diff --git a/pkgs/test/rpath/src/hello3.c b/pkgs/test/rpath/src/hello3.c
new file mode 100644
index 000000000000..2b2308360da4
--- /dev/null
+++ b/pkgs/test/rpath/src/hello3.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+char * text();
+
+int main(int argc, char * * argv)
+{
+    printf(text());
+    return 0;
+}
diff --git a/pkgs/test/rpath/src/text.c b/pkgs/test/rpath/src/text.c
new file mode 100644
index 000000000000..3d85ca23f795
--- /dev/null
+++ b/pkgs/test/rpath/src/text.c
@@ -0,0 +1,4 @@
+char * text()
+{
+    return "Hello World!\n";
+}