* 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
This commit is contained in:
Eelco Dolstra 2004-04-04 22:02:41 +00:00
parent 0d4967fc35
commit beaff0a892
13 changed files with 235 additions and 47 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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");

View File

@ -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

View File

@ -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;
}

View File

@ -0,0 +1,7 @@
#include <stdio.h>
int main(int argc, char * * argv)
{
printf("Hello World!\n");
return 0;
}

View File

@ -0,0 +1,7 @@
#include <iostream>
int main(int argc, char * * argv)
{
std::cout << "Hello World!\n";
return 0;
}

View File

@ -0,0 +1,9 @@
#include <stdio.h>
char * text();
int main(int argc, char * * argv)
{
printf(text());
return 0;
}

View File

@ -0,0 +1,4 @@
char * text()
{
return "Hello World!\n";
}