summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--pkgs/stdenv/darwin/prehook.sh1
-rw-r--r--pkgs/stdenv/generic-branch/builder.sh22
-rw-r--r--pkgs/stdenv/generic-branch/default-builder.sh2
-rw-r--r--pkgs/stdenv/generic-branch/default.nix33
-rw-r--r--pkgs/stdenv/generic-branch/docs.txt93
-rw-r--r--pkgs/stdenv/generic-branch/setup.sh426
-rw-r--r--pkgs/system/stdenvs.nix3
7 files changed, 579 insertions, 1 deletions
diff --git a/pkgs/stdenv/darwin/prehook.sh b/pkgs/stdenv/darwin/prehook.sh
index 530ee929152..d2f00c59257 100644
--- a/pkgs/stdenv/darwin/prehook.sh
+++ b/pkgs/stdenv/darwin/prehook.sh
@@ -2,3 +2,4 @@ export NIX_ENFORCE_PURITY=
 export NIX_DONT_SET_RPATH=1
 export NIX_NO_SELF_RPATH=1
 dontFixLibtool=1
+NIX_STRIP_DEBUG=0
\ No newline at end of file
diff --git a/pkgs/stdenv/generic-branch/builder.sh b/pkgs/stdenv/generic-branch/builder.sh
new file mode 100644
index 00000000000..bbcd19448cb
--- /dev/null
+++ b/pkgs/stdenv/generic-branch/builder.sh
@@ -0,0 +1,22 @@
+p1=$param1
+p2=$param2
+p3=$param3
+p4=$param4
+p5=$param5
+
+. $stdenv/setup
+
+mkdir $out || exit 1
+
+sed \
+ -e "s^@preHook@^$preHook^g" \
+ -e "s^@postHook@^$postHook^g" \
+ -e "s^@initialPath@^$initialPath^g" \
+ -e "s^@gcc@^$gcc^g" \
+ -e "s^@shell@^$shell^g" \
+ -e "s^@param1@^$p1^g" \
+ -e "s^@param2@^$p2^g" \
+ -e "s^@param3@^$p3^g" \
+ -e "s^@param4@^$p4^g" \
+ -e "s^@param5@^$p5^g" \
+ < $setup > $out/setup || exit 1
diff --git a/pkgs/stdenv/generic-branch/default-builder.sh b/pkgs/stdenv/generic-branch/default-builder.sh
new file mode 100644
index 00000000000..9a297c67f6e
--- /dev/null
+++ b/pkgs/stdenv/generic-branch/default-builder.sh
@@ -0,0 +1,2 @@
+. $stdenv/setup
+genericBuild
diff --git a/pkgs/stdenv/generic-branch/default.nix b/pkgs/stdenv/generic-branch/default.nix
new file mode 100644
index 00000000000..3aa2d3bfac0
--- /dev/null
+++ b/pkgs/stdenv/generic-branch/default.nix
@@ -0,0 +1,33 @@
+{ stdenv, name, preHook ? null, postHook ? null, initialPath, gcc, shell
+, param1 ? "", param2 ? "", param3 ? "", param4 ? "", param5 ? ""
+}:
+
+let {
+
+  body =
+
+    stdenv.mkDerivation {
+      inherit name;
+
+      builder = ./builder.sh;
+
+      setup = ./setup.sh;
+
+      inherit preHook postHook initialPath gcc shell;
+
+      # TODO: make this more elegant.
+      inherit param1 param2 param3 param4 param5;
+    }
+
+    # Add a utility function to produce derivations that use this
+    # stdenv and its shell.
+    // {
+      mkDerivation = attrs: derivation (attrs // {
+        builder = shell;
+        args = ["-e" (if attrs ? builder then attrs.builder else ./default-builder.sh)];
+        stdenv = body;
+        system = body.system;
+      });
+    };
+
+}
diff --git a/pkgs/stdenv/generic-branch/docs.txt b/pkgs/stdenv/generic-branch/docs.txt
new file mode 100644
index 00000000000..060f3cd154b
--- /dev/null
+++ b/pkgs/stdenv/generic-branch/docs.txt
@@ -0,0 +1,93 @@
+* genericBuild performs a generic build of (typically) autotool-style
+  packages
+
+  
+* unpack phase
+
+** may be overriden by setting $unpackPhase to point at a function that
+   unpacks the source (which should set $sourceRoot)
+
+** the generic unpacker unpacks all sources specified by $srcs, or
+   $src if $srcs is empty
+
+** supports tar, bzipped tar, gzipped tar, compressed tar, zip
+
+** zip must be in scope (in $buildinputs)
+
+** additional file types may be supported by setting $findUnpacker,
+   which is called with a single argument specifying the file to be
+   unpacked
+
+** $findUnpacker should set $unpackCmd, specifying the full command to
+   unpack the file (must include the file name)
+
+** alternatively, $unpackCmd can be set before calling the generic
+   builder (e.g., 'unpackCmd="unrar x $src"'); this only works if
+   there is a single source file
+
+** the generic unpacker then sets $sourceRoot to the name of the
+   directory created by unpacking the source archives
+
+** the source archives should produce only one directory
+
+** alternatively, $setSourceRoot may be set to a function that sets
+   $sourceRoot
+
+
+* the generic builder then chdirs to $sourceRoot
+
+
+* patch phase (skipped if neither $patchPhase nor $patches are set)
+
+** may be overriden by setting $patchPhase to point at a function that
+   unpacks the source (which should set $sourceRoot)
+
+** if the $patches variable is set, it runs `patch -p1 < ...' in
+   $sourceRoot for each element in $patches (the `patch' command
+   should be in $PATH; note that it isn't in the standard environment)
+
+
+* configuration phase
+
+** may be overriden by setting $configurePhase to point at a function
+
+** calls $preConfigurer first, if set (useful for running
+   autoconf/automake)
+
+** the configure script is specified by $configureScript, which
+   defaults to ./configure
+   
+** if no executable file exists at $configureScript, does nothing
+
+** if a file ./ltmain.sh exists and $dontFixLibtool is not set, calls
+   function fixLibtool to remove its default search path (/usr etc.)
+
+** adds "--prefix=$out" to $configureFlags unless $dontAddPrefix is
+   set
+
+** calls $configureScript with $configureFlags
+
+** calls $postConfigurer, if set (useful for any last-minute patches
+   prior to building)
+
+
+* build phase
+
+** may be overriden by setting $buildPhase to point at a function
+
+** runs make with flags $makeFlags
+
+
+* install phase
+
+** may be overriden by setting $installPhase to point at a function
+
+** runs make with flags $installFlags
+
+** unless $dontStrip is set or $NIX_STRIP_DEBUG is not 1, finds all *.a
+   files in $out and runs "strip -S" on them (executables and dynamic
+   libraries can be stripped automatically by setting NIX_STRIP_DEBUG
+   to 1 (default))
+
+** if $propagatedBuildInputs is set, its contents are written to
+   $out/nix-support/propagated-build-inputs
diff --git a/pkgs/stdenv/generic-branch/setup.sh b/pkgs/stdenv/generic-branch/setup.sh
new file mode 100644
index 00000000000..9638d5a78a2
--- /dev/null
+++ b/pkgs/stdenv/generic-branch/setup.sh
@@ -0,0 +1,426 @@
+set -e
+
+test -z $NIX_GCC && NIX_GCC=@gcc@
+
+
+# Set up the initial path.
+PATH=
+for i in $NIX_GCC @initialPath@; do
+    PATH=$PATH${PATH:+:}$i/bin
+done
+
+if test "$NIX_DEBUG" = "1"; then
+    echo "Initial path: $PATH"
+fi
+
+
+# Execute the pre-hook.
+export SHELL=@shell@
+param1=@param1@
+param2=@param2@
+param3=@param3@
+param4=@param4@
+param5=@param5@
+if test -n "@preHook@"; then
+    . @preHook@
+fi
+
+
+# Check that the pre-hook initialised SHELL.
+if test -z "$SHELL"; then echo "SHELL not set"; exit 1; fi
+
+
+# Hack: run gcc's setup hook.
+envHooks=()
+if test -f $NIX_GCC/nix-support/setup-hook; then
+    . $NIX_GCC/nix-support/setup-hook
+fi
+
+    
+# Recursively find all build inputs.
+findInputs()
+{
+    local pkg=$1
+
+    case $pkgs in
+        *\ $pkg\ *)
+            return 0
+            ;;
+    esac
+    
+    pkgs="$pkgs $pkg "
+
+    if test -f $pkg/nix-support/setup-hook; then
+        . $pkg/nix-support/setup-hook
+    fi
+    
+    if test -f $pkg/nix-support/propagated-build-inputs; then
+        for i in $(cat $pkg/nix-support/propagated-build-inputs); do
+            findInputs $i
+        done
+    fi
+}
+
+pkgs=""
+if test -n "$buildinputs"; then
+    buildInputs="$buildinputs" # compatibility
+fi
+for i in $buildInputs $propagatedBuildInputs; do
+    findInputs $i
+done
+
+
+# Set the relevant environment variables to point to the build inputs
+# found above.
+addToEnv()
+{
+    local pkg=$1
+
+    if test -d $1/bin; then
+        export _PATH=$_PATH${_PATH:+:}$1/bin
+    fi
+
+    for i in "${envHooks[@]}"; do
+        $i $pkg
+    done
+}
+
+for i in $pkgs; do
+    addToEnv $i
+done
+
+
+# Add the output as an rpath.
+if test "$NIX_NO_SELF_RPATH" != "1"; then
+    export NIX_LDFLAGS="-rpath $out/lib $NIX_LDFLAGS"
+fi
+
+
+# Strip debug information by default.
+if test -z "$NIX_STRIP_DEBUG"; then
+    export NIX_STRIP_DEBUG=1
+    export NIX_CFLAGS_STRIP="-g0 -Wl,-s"
+fi    
+
+
+# Do we know where the store is?  This is required for purity checking.
+if test -z "$NIX_STORE"; then
+    echo "Error: you have an old version of Nix that does not set the" \
+        "NIX_STORE variable.  Please upgrade." >&2
+    exit 1
+fi
+
+
+# We also need to know the root of the build directory for purity checking.
+if test -z "$NIX_BUILD_TOP"; then
+    echo "Error: you have an old version of Nix that does not set the" \
+        "NIX_BUILD_TOP variable.  Please upgrade." >&2
+    exit 1
+fi
+
+
+# Set the TZ (timezone) environment variable, otherwise commands like
+# `date' will complain (e.g., `Tue Mar 9 10:01:47 Local time zone must
+# be set--see zic manual page 2004').
+export TZ=UTC
+
+
+# Execute the post-hook.
+if test -n "@postHook@"; then
+    . @postHook@
+fi
+
+PATH=$_PATH${_PATH:+:}$PATH
+if test "$NIX_DEBUG" = "1"; then
+    echo "Final path: $PATH"
+fi
+
+
+######################################################################
+# What follows is the generic builder.
+
+
+nestingLevel=0
+
+startNest() {
+    nestingLevel=$(($nestingLevel + 1))
+    echo -en "\e[$1p"
+}
+
+stopNest() {
+    nestingLevel=$(($nestingLevel - 1))
+    echo -en "\e[q"
+}
+
+header() {
+    startNest "$2"
+    echo "$1"
+}
+
+# Make sure that even when we exit abnormally, the original nesting
+# level is properly restored.
+closeNest() {
+    while test $nestingLevel -gt 0; do
+        stopNest
+    done
+}
+
+trap "closeNest" EXIT
+
+
+# Utility function: return the base name of the given path, with the
+# prefix `HASH-' removed, if present.
+stripHash() {
+    strippedName=$(basename $1);
+    if echo "$strippedName" | grep -q '^[a-f0-9]\{32\}-'; then
+        strippedName=$(echo "$strippedName" | cut -c34-)
+    fi
+}
+
+
+unpackFile() {
+    local file=$1
+    local cmd
+
+    case $file in
+        *.tar) cmd="tar xvf $file";;
+        *.tar.gz | *.tgz | *.tar.Z) cmd="tar xvfz $file";;
+        *.tar.bz2 | *.tbz2) cmd="tar xvfj $file";;
+        *.zip) cmd="unzip $file";;
+        *)
+            if test -d "$file"; then
+                stripHash $file
+                cmd="cp -prvd $file $strippedName"
+            else
+                if test -n "$findUnpacker"; then
+                    $findUnpacker $1;
+                fi
+                if test -z "$unpackCmd"; then
+                    echo "source archive $file has unknown type"
+                    exit 1
+                fi
+                cmd=$unpackCmd
+            fi
+            ;;
+    esac
+
+    header "unpacking source archive $file (using $cmd)" 3
+    $cmd
+    stopNest
+}
+
+
+unpackW() {
+    if test -n "$unpackPhase"; then
+        $unpackPhase
+        return
+    fi
+
+    if test -z "$srcs"; then
+        if test -z "$src"; then
+            echo 'variable $src or $srcs should point to the source'
+            exit 1
+        fi
+        srcs="$src"
+    fi
+
+    # To determine the source directory created by unpacking the
+    # source archives, we record the contents of the current
+    # directory, then look below which directory got added.  Yeah,
+    # it's rather hacky.
+    local dirsBefore=""
+    for i in *; do
+        if test -d "$i"; then
+            dirsBefore="$dirsBefore $i "
+        fi
+    done
+
+    # Unpack all source archives.
+    for i in $srcs; do
+        unpackFile $i
+    done
+
+    # Find the source directory.
+    if test -n "$setSourceRoot"; then
+        $setSourceRoot
+    else
+        sourceRoot=
+        for i in *; do
+            if test -d "$i"; then
+                case $dirsBefore in
+                    *\ $i\ *)
+                        ;;
+                    *)
+                        if test -n "$sourceRoot"; then
+                            echo "unpacker produced multiple directories"
+                            exit 1
+                        fi
+                        sourceRoot=$i
+                        ;;
+                esac
+            fi
+        done
+    fi
+
+    if test -z "$sourceRoot"; then
+        echo "unpacker appears to have produced no directories"
+        exit 1
+    fi
+
+    echo "source root is $sourceRoot"
+
+    if test -n "$postUnpack"; then
+        $postUnpack
+    fi
+}
+
+
+unpackPhase() {
+    header "unpacking sources"
+    unpackW
+    stopNest
+}
+
+
+patchW() {
+    if test -n "$patchPhase"; then
+        $patchPhase
+        return
+    fi
+
+    for i in $patches; do
+        header "applying patch $i" 3
+        patch -p1 < $i
+        stopNest
+    done
+}
+
+
+patchPhase() {
+    if test -z "$patchPhase" -a -z "$patches"; then return; fi
+    header "patching sources"
+    patchW
+    stopNest
+}
+
+
+fixLibtool() {
+    sed 's^eval sys_lib_.*search_path=.*^^' < $1 > $1.tmp
+    mv $1.tmp $1
+}
+
+
+configureW() {
+    if test -n "$configurePhase"; then
+        $configurePhase
+        return
+    fi
+
+    if test -n "$preConfigure"; then
+        $preConfigure
+    fi
+
+    if test -z "$configureScript"; then
+        configureScript=./configure
+        if ! test -x $configureScript; then
+            echo "no configure script, doing nothing"
+            return
+        fi
+    fi
+
+    if test -z "$dontFixLibtool"; then
+        for i in $(find . -name "ltmain.sh"); do
+            echo "fixing libtool script $i"
+            fixLibtool $i
+        done
+    fi
+
+    if test -z "$dontAddPrefix"; then
+        configureFlags="--prefix=$out $configureFlags"
+    fi
+
+    echo "configure flags: $configureFlags"
+    $configureScript $configureFlags
+
+    if test -n "$postConfigure"; then
+        $postConfigure
+    fi
+}
+
+
+configurePhase() {
+    header "configuring"
+    configureW
+    stopNest
+}
+
+
+buildW() {
+    if test -n "$buildPhase"; then
+        $buildPhase
+        return
+    fi
+
+    if test -z "$dontMake"; then
+        echo "make flags: $makeFlags"
+        make $makeFlags
+    fi
+}
+
+
+buildPhase() {
+    header "building"
+    buildW
+    stopNest
+}
+
+
+installW() {
+    if test -n "$installPhase"; then
+        $installPhase
+        return
+    fi
+    
+    if test -n "$preInstall"; then
+        $preInstall
+    fi
+
+    if ! test -x "$out"; then mkdir "$out"; fi
+    
+    if test -z "$dontMakeInstall"; then
+        echo "install flags: $installFlags"
+        make install $installFlags
+    fi
+
+    if test -z "$dontStrip" -a "$NIX_STRIP_DEBUG" = 1; then
+        find "$out" -name "*.a" -exec echo stripping {} \; -exec strip -S {} \;
+    fi
+
+    if test -n "$propagatedBuildInputs"; then
+        if ! test -x "$out/nix-support"; then mkdir "$out/nix-support"; fi
+        echo "$propagatedBuildInputs" > "$out/nix-support/propagated-build-inputs"
+    fi
+
+    if test -n "$postInstall"; then
+        $postInstall
+    fi
+}
+
+
+installPhase() {
+    header "installing"
+    installW
+    stopNest
+}
+
+
+genericBuild() {
+    header "building $out"
+    unpackPhase
+    cd $sourceRoot
+    patchPhase
+    configurePhase
+    buildPhase
+    installPhase
+    stopNest
+}
diff --git a/pkgs/system/stdenvs.nix b/pkgs/system/stdenvs.nix
index dfbca8a2468..f580478cdd0 100644
--- a/pkgs/system/stdenvs.nix
+++ b/pkgs/system/stdenvs.nix
@@ -138,7 +138,8 @@
   # (essentially it's just the native environment).
   stdenvDarwin = (import ../stdenv/darwin) {
     stdenv = stdenvInitial;
-    inherit genericStdenv gccWrapper;
+    genericStdenv = import ../stdenv/generic-branch;
+    inherit gccWrapper;
   };
 
   stdenvDarwinPkgs = allPackages {