diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2004-04-04 22:02:41 +0000 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2004-04-04 22:02:41 +0000 |
commit | beaff0a8929b14bca736cb96a1bbf4c2e1c604d6 (patch) | |
tree | c93f32f82be57ea066cc2ebb5c919fe1b9f4b7ad | |
parent | 0d4967fc35631ebfe9869739d01e713d60bd21ff (diff) | |
download | nixlib-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/TODO | 30 | ||||
-rw-r--r-- | pkgs/build-support/gcc-wrapper/builder.sh | 4 | ||||
-rw-r--r-- | pkgs/build-support/gcc-wrapper/ld-wrapper.sh | 78 | ||||
-rw-r--r-- | pkgs/build-support/gcc-wrapper/setup-hook.sh | 2 | ||||
-rw-r--r-- | pkgs/development/compilers/gcc/builder.sh | 31 | ||||
-rw-r--r-- | pkgs/development/libraries/glibc/builder.sh | 9 | ||||
-rw-r--r-- | pkgs/development/tools/build-managers/gnumake/log.diff | 4 | ||||
-rw-r--r-- | pkgs/test/rpath/builder.sh | 79 | ||||
-rw-r--r-- | pkgs/test/rpath/default.nix | 18 | ||||
-rw-r--r-- | pkgs/test/rpath/src/hello1.c | 7 | ||||
-rw-r--r-- | pkgs/test/rpath/src/hello2.cc | 7 | ||||
-rw-r--r-- | pkgs/test/rpath/src/hello3.c | 9 | ||||
-rw-r--r-- | pkgs/test/rpath/src/text.c | 4 |
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"; +} |