From 0217d8b20459a19f9235230f8ad61eebf0eca851 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 10 May 2005 12:59:28 +0000 Subject: [PATCH] * Add a simple standard environment for FreeBSD. * Use the system Perl on all non-i686-linux platforms. * Don't build Python support in libxml2 on most platforms. svn path=/nixpkgs/trunk/; revision=3019 --- .../gcc-wrapper-freebsd/add-flags | 5 + .../gcc-wrapper-freebsd/builder.sh | 94 ++++++++++++ .../gcc-wrapper-freebsd/default.nix | 30 ++++ .../gcc-wrapper-freebsd/gcc-wrapper.sh | 118 ++++++++++++++ .../gcc-wrapper-freebsd/ld-wrapper.sh | 145 ++++++++++++++++++ .../gcc-wrapper-freebsd/setup-hook.sh | 25 +++ .../gcc-wrapper-freebsd/utils.sh | 23 +++ pkgs/stdenv/freebsd/default.nix | 19 +++ pkgs/stdenv/freebsd/prehook.sh | 1 + pkgs/system/all-packages-generic.nix | 3 +- pkgs/system/all-packages.nix | 1 + pkgs/system/stdenvs.nix | 16 ++ 12 files changed, 479 insertions(+), 1 deletion(-) create mode 100644 pkgs/build-support/gcc-wrapper-freebsd/add-flags create mode 100644 pkgs/build-support/gcc-wrapper-freebsd/builder.sh create mode 100644 pkgs/build-support/gcc-wrapper-freebsd/default.nix create mode 100644 pkgs/build-support/gcc-wrapper-freebsd/gcc-wrapper.sh create mode 100644 pkgs/build-support/gcc-wrapper-freebsd/ld-wrapper.sh create mode 100644 pkgs/build-support/gcc-wrapper-freebsd/setup-hook.sh create mode 100644 pkgs/build-support/gcc-wrapper-freebsd/utils.sh create mode 100644 pkgs/stdenv/freebsd/default.nix create mode 100644 pkgs/stdenv/freebsd/prehook.sh diff --git a/pkgs/build-support/gcc-wrapper-freebsd/add-flags b/pkgs/build-support/gcc-wrapper-freebsd/add-flags new file mode 100644 index 000000000000..ac1e58ebb812 --- /dev/null +++ b/pkgs/build-support/gcc-wrapper-freebsd/add-flags @@ -0,0 +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 diff --git a/pkgs/build-support/gcc-wrapper-freebsd/builder.sh b/pkgs/build-support/gcc-wrapper-freebsd/builder.sh new file mode 100644 index 000000000000..cf3953e2820b --- /dev/null +++ b/pkgs/build-support/gcc-wrapper-freebsd/builder.sh @@ -0,0 +1,94 @@ +. $stdenv/setup +. $substitute + + +# Force gcc to use ld-wrapper.sh when calling ld. +cflagsCompile="-B$out/bin/" + +if test -z "$nativeGlibc"; then + # The "-B$glibc/lib/" flag is a quick hack to force gcc to link + # against the crt1.o from our own glibc, rather than the one in + # /usr/lib. The real solution is of course to prevent those paths + # from being used by gcc in the first place. + # The dynamic linker is passed in `ldflagsBefore' to allow + # explicit overrides of the dynamic linker by callers to gcc/ld + # (the *last* value counts, so ours should come first). + cflagsCompile="$cflagsCompile -B$glibc/lib/ -isystem $glibc/include" + ldflags="$ldflags -L$glibc/lib" + ldflagsBefore="-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" + gccPath="$gcc/bin" + ldPath="$binutils/bin" +fi + + +mkdir $out +mkdir $out/bin +mkdir $out/nix-support + + +doSubstitute() { + local src=$1 + local dst=$2 + substitute "$src" "$dst" \ + --subst-var "out" \ + --subst-var "shell" \ + --subst-var "gcc" \ + --subst-var "gccProg" \ + --subst-var "binutils" \ + --subst-var "glibc" \ + --subst-var "cflagsCompile" \ + --subst-var "cflagsLink" \ + --subst-var "ldflags" \ + --subst-var "ldflagsBefore" \ + --subst-var-by "ld" "$ldPath/ld" +} + + +# Make wrapper scripts around gcc, g++, and g77. Also make symlinks +# cc, c++, and f77. +mkGccWrapper() { + local dst=$1 + local src=$2 + + if ! test -f "$src"; then + echo "$src does not exist (skipping)" + return + fi + + gccProg="$src" + doSubstitute "$gccWrapper" "$dst" + chmod +x "$dst" +} + +mkGccWrapper $out/bin/gcc $gccPath/gcc +ln -s gcc $out/bin/cc + +mkGccWrapper $out/bin/g++ $gccPath/g++ +ln -s g++ $out/bin/c++ + +mkGccWrapper $out/bin/g77 $gccPath/g77 +ln -s g77 $out/bin/f77 + + +# Make a wrapper around the linker. +doSubstitute "$ldWrapper" "$out/bin/ld" +chmod +x "$out/bin/ld" + + +# Emit a setup hook. Also store the path to the original GCC and +# Glibc. +test -n "$gcc" && echo $gcc > $out/nix-support/orig-gcc +test -n "$glibc" && echo $glibc > $out/nix-support/orig-glibc + +doSubstitute "$addFlags" "$out/nix-support/add-flags" + +doSubstitute "$setupHook" "$out/nix-support/setup-hook" + +cp -p $utils $out/nix-support/utils diff --git a/pkgs/build-support/gcc-wrapper-freebsd/default.nix b/pkgs/build-support/gcc-wrapper-freebsd/default.nix new file mode 100644 index 000000000000..4296aef67c8b --- /dev/null +++ b/pkgs/build-support/gcc-wrapper-freebsd/default.nix @@ -0,0 +1,30 @@ +# The Nix `gcc' stdenv.mkDerivation is not directly usable, since it doesn't +# know where the C library and standard header files are. Therefore +# the compiler produced by that package cannot be installed directly +# in a user environment and used from the command line. This +# stdenv.mkDerivation provides a wrapper that sets up the right environment +# variables so that the compiler and the linker just "work". + +{ name ? "", stdenv, nativeTools, nativeGlibc, nativePrefix ? "" +, gcc ? null, glibc ? null, binutils ? null, shell ? "" +}: + +assert nativeTools -> nativePrefix != ""; +assert !nativeTools -> gcc != null && binutils != null; +assert !nativeGlibc -> glibc != null; + +stdenv.mkDerivation { + builder = ./builder.sh; + substitute = ../substitute/substitute.sh; + setupHook = ./setup-hook.sh; + gccWrapper = ./gcc-wrapper.sh; + ldWrapper = ./ld-wrapper.sh; + utils = ./utils.sh; + addFlags = ./add-flags; + inherit nativeTools nativeGlibc nativePrefix gcc glibc binutils; + name = if name == "" then gcc.name else name; + langC = if nativeTools then true else gcc.langC; + langCC = if nativeTools then true else gcc.langCC; + langF77 = if nativeTools then false else gcc.langF77; + shell = if shell == "" then stdenv.shell else shell; +} diff --git a/pkgs/build-support/gcc-wrapper-freebsd/gcc-wrapper.sh b/pkgs/build-support/gcc-wrapper-freebsd/gcc-wrapper.sh new file mode 100644 index 000000000000..ac61cc1e176f --- /dev/null +++ b/pkgs/build-support/gcc-wrapper-freebsd/gcc-wrapper.sh @@ -0,0 +1,118 @@ +#! @shell@ -e + +if test -n "$NIX_GCC_WRAPPER_START_HOOK"; then + . "$NIX_GCC_WRAPPER_START_HOOK" +fi + +if test -z "$NIX_GLIBC_FLAGS_SET"; then + . @out@/nix-support/add-flags +fi + +. @out@/nix-support/utils + + +# Figure out if linker flags should be passed. GCC prints annoying +# warnings when they are not needed. +dontLink=0 +if test "$*" = "-v" -o -z "$*"; then + dontLink=1 +else + for i in "$@"; do + if test "$i" = "-c"; then + dontLink=1 + elif test "$i" = "-S"; then + dontLink=1 + elif test "$i" = "-E"; then + dontLink=1 + elif test "$i" = "-E"; then + dontLink=1 + elif test "$i" = "-M"; then + dontLink=1 + elif test "$i" = "-MM"; then + dontLink=1 + fi + done +fi + + +# Optionally filter out paths not refering to the store. +params=("$@") +if test "$NIX_ENFORCE_PURITY" = "1" -a -n "$NIX_STORE"; then + rest=() + n=0 + while test $n -lt ${#params[*]}; do + p=${params[n]} + p2=${params[$((n+1))]} + if test "${p:0:3}" = "-L/" && badPath "${p:2}"; then + skip $p + elif test "$p" = "-L" && badPath "$p2"; then + n=$((n + 1)); skip $p2 + elif test "${p:0:3}" = "-I/" && badPath "${p:2}"; then + skip $p + elif test "$p" = "-I" && badPath "$p2"; then + n=$((n + 1)); skip $p2 + elif test "$p" = "-isystem" && badPath "$p2"; then + n=$((n + 1)); skip $p2 + else + rest=("${rest[@]}" "$p") + fi + n=$((n + 1)) + done + params=("${rest[@]}") +fi + + +# Add the flags for the C compiler proper. +extraAfter=($NIX_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) + + # 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 + extraBefore=(${extraBefore[@]} "-Wl,$i") + done + for i in $NIX_LDFLAGS; do + if test "${i:0:3}" = "-L/"; then + extraAfter=(${extraAfter[@]} "$i") + else + extraAfter=(${extraAfter[@]} "-Wl,$i") + fi + done + export NIX_LDFLAGS_SET=1 + + if test "$NIX_STRIP_DEBUG" = "1"; then + # Add executable-stripping flags. + extraAfter=(${extraAfter[@]} $NIX_CFLAGS_STRIP) + fi +fi + +# Optionally print debug info. +if test "$NIX_DEBUG" = "1"; then + echo "original flags to @gccProg@:" >&2 + for i in "${params[@]}"; do + echo " $i" >&2 + done + echo "extraBefore flags to @gccProg@:" >&2 + for i in ${extraBefore[@]}; do + echo " $i" >&2 + done + echo "extraAfter flags to @gccProg@:" >&2 + for i in ${extraAfter[@]}; do + echo " $i" >&2 + done +fi + +if test -n "$NIX_GCC_WRAPPER_EXEC_HOOK"; then + . "$NIX_GCC_WRAPPER_EXEC_HOOK" +fi + +res=0 +@gccProg@ ${extraBefore[@]} "${params[@]}" ${extraAfter[@]} 2> $NIX_BUILD_TOP/.gcc.errors || res=$? +grep -v 'file path prefix' < $NIX_BUILD_TOP/.gcc.errors >&2 || true +exit $res diff --git a/pkgs/build-support/gcc-wrapper-freebsd/ld-wrapper.sh b/pkgs/build-support/gcc-wrapper-freebsd/ld-wrapper.sh new file mode 100644 index 000000000000..fbf7186ad276 --- /dev/null +++ b/pkgs/build-support/gcc-wrapper-freebsd/ld-wrapper.sh @@ -0,0 +1,145 @@ +#! @shell@ -e + +if test -n "$NIX_LD_WRAPPER_START_HOOK"; then + . "$NIX_LD_WRAPPER_START_HOOK" +fi + +if test -z "$NIX_GLIBC_FLAGS_SET"; then + . @out@/nix-support/add-flags +fi + +. @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 + rest=() + n=0 + while test $n -lt ${#params[*]}; do + p=${params[n]} + p2=${params[$((n+1))]} + if test "${p:0:3}" = "-L/" && badPath "${p:2}"; then + skip $p + elif test "$p" = "-L" && badPath "$p2"; then + n=$((n + 1)); skip $p2 + elif test "$p" = "-rpath" && badPath "$p2"; then + n=$((n + 1)); skip $p2 + elif test "$p" = "-dynamic-linker" && badPath "$p2"; then + n=$((n + 1)); skip $p2 + elif test "${p:0:1}" = "/" && badPath "$p"; then + # We cannot skip this; barf. + echo "impure path \`$p' used in link" >&2 + exit 1 + else + rest=("${rest[@]}" "$p") + fi + n=$((n + 1)) + done + params=("${rest[@]}") +fi + + +extra=() +extraBefore=() + +if test -z "$NIX_LDFLAGS_SET"; then + extra=(${extra[@]} $NIX_LDFLAGS) + extraBefore=(${extraBefore[@]} $NIX_LDFLAGS_BEFORE) +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 + for i in "${params[@]}"; do + echo " $i" >&2 + done + echo "extra flags to @ld@:" >&2 + for i in ${extra[@]}; do + echo " $i" >&2 + done +fi + +if test -n "$NIX_LD_WRAPPER_EXEC_HOOK"; then + . "$NIX_LD_WRAPPER_EXEC_HOOK" +fi + +exec @ld@ ${extraBefore[@]} "${params[@]}" ${extra[@]} diff --git a/pkgs/build-support/gcc-wrapper-freebsd/setup-hook.sh b/pkgs/build-support/gcc-wrapper-freebsd/setup-hook.sh new file mode 100644 index 000000000000..7a7ea8226919 --- /dev/null +++ b/pkgs/build-support/gcc-wrapper-freebsd/setup-hook.sh @@ -0,0 +1,25 @@ +addCVars () { + if test -d $1/include; then + export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -I$1/include" + fi + + if test -d $1/lib; then + export NIX_LDFLAGS="$NIX_LDFLAGS -L$1/lib" + fi +} + +envHooks=(${envHooks[@]} addCVars) + +# Note: these come *after* $out in the PATH (see setup.sh). + +if test -n "@gcc@"; then + PATH=$PATH:@gcc@/bin +fi + +if test -n "@binutils@"; then + PATH=$PATH:@binutils@/bin +fi + +if test -n "@glibc@"; then + PATH=$PATH:@glibc@/bin +fi diff --git a/pkgs/build-support/gcc-wrapper-freebsd/utils.sh b/pkgs/build-support/gcc-wrapper-freebsd/utils.sh new file mode 100644 index 000000000000..9a664e1d1e6b --- /dev/null +++ b/pkgs/build-support/gcc-wrapper-freebsd/utils.sh @@ -0,0 +1,23 @@ +skip () { + if test "$NIX_DEBUG" = "1"; then + echo "skipping impure path $1" >&2 + fi +} + + +# Checks whether a path is impure. E.g., `/lib/foo.so' is impure, but +# `/nix/store/.../lib/foo.so' isn't. +badPath() { + local p=$1 + + # Relative paths are okay (since they're presumably relative to + # the temporary build directory). + if test "${p:0:1}" != "/"; then return 1; fi + + # Otherwise, the path should refer to the store or some temporary + # directory (including the build directory). + test \ + "${p:0:${#NIX_STORE}}" != "$NIX_STORE" -a \ + "${p:0:4}" != "/tmp" -a \ + "${p:0:${#NIX_BUILD_TOP}}" != "$NIX_BUILD_TOP" +} diff --git a/pkgs/stdenv/freebsd/default.nix b/pkgs/stdenv/freebsd/default.nix new file mode 100644 index 000000000000..2fa92f7d95ba --- /dev/null +++ b/pkgs/stdenv/freebsd/default.nix @@ -0,0 +1,19 @@ +{stdenv, genericStdenv, gccWrapper}: + +genericStdenv { + name = "stdenv-native"; + preHook = ./prehook.sh; + initialPath = "/usr/local /usr /"; + + inherit stdenv; + + gcc = gccWrapper { + name = "gcc-native"; + nativeTools = true; + nativeGlibc = true; + nativePrefix = "/usr"; + inherit stdenv; + }; + + shell = "/bin/bash"; +} diff --git a/pkgs/stdenv/freebsd/prehook.sh b/pkgs/stdenv/freebsd/prehook.sh new file mode 100644 index 000000000000..1714586999e1 --- /dev/null +++ b/pkgs/stdenv/freebsd/prehook.sh @@ -0,0 +1 @@ +export NIX_ENFORCE_PURITY= diff --git a/pkgs/system/all-packages-generic.nix b/pkgs/system/all-packages-generic.nix index ae25f98b38f8..cafe75d0977e 100644 --- a/pkgs/system/all-packages-generic.nix +++ b/pkgs/system/all-packages-generic.nix @@ -487,7 +487,7 @@ rec { inherit stdenv; }; - perl = if stdenv.system == "powerpc-darwin" then sysPerl else realPerl; + perl = if stdenv.system != "i686-linux" then sysPerl else realPerl; python = (import ../development/interpreters/python) { inherit fetchurl stdenv zlib; @@ -602,6 +602,7 @@ rec { libxml2 = (import ../development/libraries/libxml2) { inherit fetchurl stdenv zlib python; + pythonSupport = stdenv.system == "i686-linux"; }; libxslt = (import ../development/libraries/libxslt) { diff --git a/pkgs/system/all-packages.nix b/pkgs/system/all-packages.nix index 75a824c6db03..55f705ebd433 100644 --- a/pkgs/system/all-packages.nix +++ b/pkgs/system/all-packages.nix @@ -12,6 +12,7 @@ # Select the right instantiation. body = if system == "i686-linux" then stdenvs.stdenvLinuxPkgs + else if system == "i686-freebsd" then stdenvs.stdenvFreeBSDPkgs else if system == "powerpc-darwin" then stdenvs.stdenvDarwinPkgs else stdenvs.stdenvNativePkgs; } diff --git a/pkgs/system/stdenvs.nix b/pkgs/system/stdenvs.nix index 5af6c80338dd..c9088e57ce8a 100644 --- a/pkgs/system/stdenvs.nix +++ b/pkgs/system/stdenvs.nix @@ -69,6 +69,22 @@ }; + # FreeBSD standard environment. Right now this is more or less the + # same as the native environemnt. Eventually we'll want a pure + # environment similar to stdenvLinux. + stdenvFreeBSD = (import ../stdenv/freebsd) { + stdenv = stdenvInitial; + inherit genericStdenv; + gccWrapper = import ../build-support/gcc-wrapper-freebsd; + }; + + stdenvFreeBSDPkgs = allPackages { + stdenv = stdenvFreeBSD; + bootCurl = null; + noSysDirs = false; + }; + + stdenvTestPkgs = allPackages { stdenv = (import ../stdenv/nix-linux-static).stdenvInitial; bootCurl = (import ../stdenv/nix-linux-static).curl;