Basic stdenv for mingw. No compiler yet and setup needs more fixing.

svn path=/nixpkgs/trunk/; revision=6124
This commit is contained in:
Martin Bravenboer 2006-08-15 21:25:14 +00:00
parent 42187add34
commit 5992b95b64
6 changed files with 730 additions and 41 deletions

9
pkgs/stdenv/mingw/builder.sh Executable file
View File

@ -0,0 +1,9 @@
source $STDENV/setup
source $SUBSTITUTE
mkdir $OUT
substitute "$SETUP" "$OUT/setup" \
--subst-var INITIALPATH \
--subst-var GCC \
--subst-var SHELL

View File

@ -15,33 +15,24 @@ let {
import ./simple-stdenv {
inherit system;
name = "stdenv-initial-cygwin";
shell = "/bin/bash";
shell = "/bin/bash.exe";
path = ["/usr/bin" "/bin"];
};
/**
* Initial standard environment based on MSYS tools.
* From this point, cygwin should no longer by involved.
* From this point, Cygwin should no longer by involved.
*/
stdenvInit2 =
import ./simple-stdenv {
name = "stdenv-initial-msys";
inherit system;
shell = msys + /bin/sh + ".exe";
path = [msys];
/**
* Instruct MSYS to change the uname
* The PATH manipulation in /etc/profile is not relevant for now:
* This will be overridden anyway.
*/
extraEnv = {
MSYSTEM = "MSYS";
};
name = "stdenv-initial-msys";
shell = msys + /bin/sh.exe;
path = [(msys + /bin)];
};
/**
* Fetchurl, based on native curl in stdenvInit1
* Fetchurl, based on Cygwin curl in stdenvInit1
*/
fetchurl =
import ../../build-support/fetchurl {
@ -61,27 +52,52 @@ let {
stdenvInit1.mkDerivation {
name = "msys-1.0.11";
builder = ./msys-builder.sh;
src = ./msys-1.0.11.tar.gz;
/* fetchurl {
url = http://www.cs.uu.nl/people/martin/msys-1.0.11.tar.gz;
md5 = "7e76eec10a205ea63ada6a4e834cc468";
}; */
src =
fetchurl {
url = http://www.cs.uu.nl/people/martin/msys-1.0.11.tar.gz;
md5 = "85ce547934797019d2d642ec3b53934b";
};
};
/**
* Complete standard environment
* Complete standard environment, based on generic stdenv.
* It would be better to make the generic stdenv usable on
* MINGW (i.e. make all environment variables CAPS).
*/
body =
import ../generic {
name = "stdenv-mingw";
# preHook = ./prehook.sh;
initialPath = [msys];
stdenv = stdenvInit2;
shell = msys + /bin/sh + ".exe";
gcc = msys;
};
}
let {
body =
stdenv // mkDerivationFun;
shell = msys + /bin/sh + ".exe";
stdenv =
stdenvInit2.mkDerivation {
name = "stdenv-mingw";
builder = ./builder.sh;
substitute = ../../build-support/substitute/substitute.sh;
setup = ./setup.sh;
initialPath = [msys];
inherit shell;
gcc = msys; # TODO
};
mkDerivationFun = {
mkDerivation = attrs:
(derivation (
(removeAttrs attrs ["meta"])
//
{
builder = if attrs ? realBuilder then attrs.realBuilder else shell;
args = if attrs ? args then attrs.args else
["-e" (if attrs ? builder then attrs.builder else ../generic/default-builder.sh)];
inherit stdenv system;
})
)
// { meta = if attrs ? meta then attrs.meta else {}; };
};
};
}
/*

View File

@ -3,3 +3,13 @@ source $stdenv/setup
mkdir $out
cd $out
tar zxvf $src
# Make the Nix store available to MSYS.
# Hack: we are assuming that the stdenv is based on Cygwin.
nixdir="$(cygpath --windows /nix)"
mkdir $out/nix
cat > $out/etc/fstab <<EOF
#Win32_Path Mount_Point
$nixdir /nix
EOF

646
pkgs/stdenv/mingw/setup.sh Executable file
View File

@ -0,0 +1,646 @@
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@
# 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
source $NIX_GCC/nix-support/setup-hook
fi
# Ensure that the given directory exists.
ensureDir() {
local dir=$1
if ! test -x "$dir"; then mkdir -p "$dir"; fi
}
# Called when some build action fails. If $succeedOnFailure is set,
# create the file `$out/nix-support/failed' to signal failure, and
# exit normally. Otherwise, exit with failure.
fail() {
exitCode=$?
if test "$succeedOnFailure" = 1; then
ensureDir "$out/nix-support"
touch "$out/nix-support/failed"
exit 0
else
exit $?
fi
}
# Allow the caller to augment buildInputs (it's not always possible to
# do this before the call to setup.sh, since the PATH is empty at that
# point; here we have a basic Unix environment).
if test -n "$addInputsHook"; then
$addInputsHook
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
source $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 "$ignoreFailedInputs" != "1" -a -e $1/nix-support/failed; then
echo "failed input $1" >&2
fail
fi
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,--strip-debug"
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
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
# This function is useful for debugging broken Nix builds. It dumps
# all environment variables to a file `env-vars' in the build
# directory. If the build fails and the `-K' option is used, you can
# then go to the build directory and source in `env-vars' to reproduce
# the environment used for building.
dumpVars() {
if test "$noDumpEnvVars" != "1"; then
export > $NIX_BUILD_TOP/env-vars
fi
}
# Redirect stdout/stderr to a named pipe connected to a `tee' process
# that writes the specified file (and also to our original stdout).
# The original stdout is saved in descriptor 3.
startLog() {
local logFile=${logNr}_$1
logNr=$((logNr + 1))
if test "$logPhases" = 1; then
ensureDir $logDir
exec 3>&1
if test "$dontLogThroughTee" != 1; then
# This required named pipes (fifos).
logFifo=$NIX_BUILD_TOP/log_fifo
test -p $logFifo || mkfifo $logFifo
startLogWrite "$logDir/$logFile" "$logFifo"
exec > $logFifo 2>&1
else
exec > $logDir/$logFile 2>&1
fi
fi
}
# Factored into a separate function so that it can be overriden.
startLogWrite() {
tee "$1" < "$2" &
logWriterPid=$!
}
if test -z "$logDir"; then
logDir=$out/log
fi
logNr=0
# Restore the original stdout/stderr.
stopLog() {
if test "$logPhases" = 1; then
exec >&3 2>&1
# Wait until the tee process has died. Otherwise output from
# different phases may be mixed up.
if test -n "$logWriterPid"; then
wait $logWriterPid
logWriterPid=
rm $logFifo
fi
fi
}
# 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-z0-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 || fail
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"
# By default, add write permission to the sources. This is often
# necessary when sources have been copied from other store
# locations.
if test "dontMakeSourcesWritable" != 1; then
chmod -R +w $sourceRoot
fi
if test -n "$postUnpack"; then
$postUnpack
fi
}
unpackPhase() {
header "unpacking sources"
startLog "unpack"
unpackW
stopLog
stopNest
}
patchW() {
if test -n "$patchPhase"; then
$patchPhase
return
fi
for i in $patches; do
header "applying patch $i" 3
patch -p1 < $i || fail
stopNest
done
}
patchPhase() {
if test -z "$patchPhase" -a -z "$patches"; then return; fi
header "patching sources"
startLog "patch"
patchW
stopLog
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 "$prefix"; then
prefix="$out";
fi
if test "$useTempPrefix" = "1"; then
prefix="$NIX_BUILD_TOP/tmp_prefix";
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=$prefix $configureFlags"
fi
echo "configure flags: $configureFlags"
$configureScript $configureFlags || fail
if test -n "$postConfigure"; then
$postConfigure
fi
}
configurePhase() {
header "configuring"
startLog "configure"
configureW
stopLog
stopNest
}
buildW() {
if test -n "$buildPhase"; then
$buildPhase
return
fi
if test -n "$preBuild"; then
$preBuild
fi
echo "make flags: $makeFlags"
make $makeFlags || fail
if test -n "$postBuild"; then
$postBuild
fi
}
buildPhase() {
if test "$dontBuild" = 1; then
return
fi
header "building"
startLog "build"
buildW
stopLog
stopNest
}
checkW() {
if test -n "$checkPhase"; then
$checkPhase
return
fi
if test -z "$checkTarget"; then
checkTarget="check"
fi
echo "check flags: $checkFlags"
make $checkFlags $checkTarget || fail
}
checkPhase() {
if test "$doCheck" != 1; then
return
fi
header "checking"
startLog "check"
checkW
stopLog
stopNest
}
patchELF() {
# Patch all ELF executables and shared libraries.
header "patching ELF executables and libraries"
find "$prefix" \( \
\( -type f -a -name "*.so*" \) -o \
\( -type f -a -perm +0100 \) \
\) -print -exec patchelf --shrink-rpath {} \;
stopNest
}
installW() {
if test -n "$installPhase"; then
$installPhase
return
fi
if test -n "$preInstall"; then
$preInstall
fi
ensureDir "$prefix"
if test -z "$dontMakeInstall"; then
echo "install flags: $installFlags"
make install $installFlags || fail
fi
if test -z "$dontStrip" -a "$NIX_STRIP_DEBUG" = 1; then
find "$prefix" -name "*.a" -exec echo stripping {} \; \
-exec strip -S {} \; || fail
fi
if test "$havePatchELF" = 1 -a -z "$dontPatchELF"; then
patchELF "$prefix"
fi
if test -n "$propagatedBuildInputs"; then
ensureDir "$out/nix-support"
echo "$propagatedBuildInputs" > "$out/nix-support/propagated-build-inputs"
fi
if test -n "$postInstall"; then
$postInstall
fi
}
installPhase() {
if test "$dontInstall" = 1; then
return
fi
header "installing"
startLog "install"
installW
stopLog
stopNest
}
distW() {
if test -n "$distPhase"; then
$distPhase
return
fi
if test -n "$preDist"; then
$preDist
fi
if test -z "$distTarget"; then
distTarget="dist"
fi
echo "dist flags: $distFlags"
make $distFlags $distTarget || fail
if test "$dontCopyDist" != 1; then
ensureDir "$out/tarballs"
if test -z "$tarballs"; then
tarballs="*.tar.gz"
fi
# Note: don't quote $tarballs, since we explicitly permit
# wildcards in there.
cp -pvd $tarballs $out/tarballs
fi
if test -n "$postDist"; then
$postDist
fi
}
distPhase() {
if test "$doDist" != 1; then
return
fi
header "creating distribution"
startLog "dist"
distW
stopLog
stopNest
}
genericBuild() {
header "building $out"
unpackPhase
cd $sourceRoot
if test -z "$phases"; then
phases="patchPhase configurePhase buildPhase checkPhase \
installPhase distPhase";
fi
for i in $phases; do
dumpVars
$i
done
stopNest
}
dumpVars

View File

@ -1,12 +1,18 @@
if test -z "$out"; then
out="$OUT"
initialPath="$INITIALPATH"
fi
setupPath=
for i in $initialPath; do
setupPath=$setupPath${setupPath:+:}$i
done
PATH=$setupPath
echo $setupPath
export PATH
mkdir $out
cat > $out/setup <<EOF
PATH=$setupPath
export PATH
@ -23,4 +29,5 @@ stopNest() {
echo "Nothing to do"
}
EOF
chmod +x $out/setup

View File

@ -1,24 +1,25 @@
# Here we construct an absolutely trivial `initial' standard
# environment. It's not actually a functional stdenv, since there is
# not necessarily a working C compiler. We need this to build
# gcc-wrapper et al. for the native stdenv.
{system, name, shell, path, extraEnv ? {}}:
{ system
, name
, shell
, path
, extraEnv ? {}
, extraShellOptions ? []
}:
let {
body =
derivation {
derivation ({
inherit system name;
initialPath = path;
builder = shell;
args = ["-e" ./builder.sh];
}
args = extraShellOptions ++ ["-e" ./builder.sh];
} // extraEnv)
// {
mkDerivation = attrs:
derivation ((removeAttrs attrs ["meta"]) // {
builder = shell;
args = ["-e" attrs.builder];
args = extraShellOptions ++ ["-e" attrs.builder];
stdenv = body;
system = body.system;
}