mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-10-31 14:41:27 +00:00
* 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:
parent
0d4967fc35
commit
beaff0a892
30
pkgs/TODO
30
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
79
pkgs/test/rpath/builder.sh
Normal file
79
pkgs/test/rpath/builder.sh
Normal 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
|
18
pkgs/test/rpath/default.nix
Normal file
18
pkgs/test/rpath/default.nix
Normal 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;
|
||||
}
|
7
pkgs/test/rpath/src/hello1.c
Normal file
7
pkgs/test/rpath/src/hello1.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char * * argv)
|
||||
{
|
||||
printf("Hello World!\n");
|
||||
return 0;
|
||||
}
|
7
pkgs/test/rpath/src/hello2.cc
Normal file
7
pkgs/test/rpath/src/hello2.cc
Normal file
@ -0,0 +1,7 @@
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char * * argv)
|
||||
{
|
||||
std::cout << "Hello World!\n";
|
||||
return 0;
|
||||
}
|
9
pkgs/test/rpath/src/hello3.c
Normal file
9
pkgs/test/rpath/src/hello3.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include <stdio.h>
|
||||
|
||||
char * text();
|
||||
|
||||
int main(int argc, char * * argv)
|
||||
{
|
||||
printf(text());
|
||||
return 0;
|
||||
}
|
4
pkgs/test/rpath/src/text.c
Normal file
4
pkgs/test/rpath/src/text.c
Normal file
@ -0,0 +1,4 @@
|
||||
char * text()
|
||||
{
|
||||
return "Hello World!\n";
|
||||
}
|
Loading…
Reference in New Issue
Block a user