From 688fff92ded502db4f2e9b93f93d87da31338da2 Mon Sep 17 00:00:00 2001 From: Martin Bravenboer Date: Thu, 17 Aug 2006 00:54:32 +0000 Subject: Major work on the mingw stdenv. Basics now works. - clone of fetchurl that invokes a given chmod to workaround problems with inappropriate file permissions (executable files are not allowed by Nix) - cygpath tool to determine the full windows path of a cygwin tool. This tool is used to give fetchurl the windows path to chmod. - native curl.exe - gcc-wrapper no longer used - all-packages.nix: allows stdenv to specify fetchurl. svn path=/nixpkgs/trunk/; revision=6140 --- pkgs/stdenv/mingw/builder.sh | 8 +++ pkgs/stdenv/mingw/cygpath/builder.sh | 5 ++ pkgs/stdenv/mingw/cygpath/default.nix | 9 +++ pkgs/stdenv/mingw/default-builder.sh | 2 + pkgs/stdenv/mingw/default.nix | 73 ++++++++++++--------- pkgs/stdenv/mingw/fetchurl/builder.sh | 36 +++++++++++ pkgs/stdenv/mingw/fetchurl/default.nix | 28 +++++++++ pkgs/stdenv/mingw/gcc-wrapper/builder.sh | 91 +++++++++++++++++++++++++++ pkgs/stdenv/mingw/gcc-wrapper/default.nix | 23 +++++++ pkgs/stdenv/mingw/gcc-wrapper/gcc-wrapper.sh | 91 +++++++++++++++++++++++++++ pkgs/stdenv/mingw/pkgs/curl.exe | Bin 0 -> 240128 bytes pkgs/stdenv/mingw/pkgs/default.nix | 25 ++++++++ pkgs/stdenv/mingw/pkgs/single-exe-builder.sh | 5 ++ pkgs/stdenv/mingw/setup.sh | 15 ++++- pkgs/stdenv/mingw/simple-stdenv/builder.sh | 1 + 15 files changed, 382 insertions(+), 30 deletions(-) create mode 100755 pkgs/stdenv/mingw/cygpath/builder.sh create mode 100755 pkgs/stdenv/mingw/cygpath/default.nix create mode 100755 pkgs/stdenv/mingw/default-builder.sh create mode 100755 pkgs/stdenv/mingw/fetchurl/builder.sh create mode 100644 pkgs/stdenv/mingw/fetchurl/default.nix create mode 100644 pkgs/stdenv/mingw/gcc-wrapper/builder.sh create mode 100644 pkgs/stdenv/mingw/gcc-wrapper/default.nix create mode 100644 pkgs/stdenv/mingw/gcc-wrapper/gcc-wrapper.sh create mode 100755 pkgs/stdenv/mingw/pkgs/curl.exe create mode 100644 pkgs/stdenv/mingw/pkgs/single-exe-builder.sh (limited to 'pkgs/stdenv') diff --git a/pkgs/stdenv/mingw/builder.sh b/pkgs/stdenv/mingw/builder.sh index c81f2949e31bf..cfafde6b00dc7 100755 --- a/pkgs/stdenv/mingw/builder.sh +++ b/pkgs/stdenv/mingw/builder.sh @@ -1,8 +1,16 @@ +# the other stdenv could change the SHELL variable, +# so we have to remember its value. +origShell=$SHELL +origGcc=$GCC + source $STDENV/setup source $SUBSTITUTE mkdir $OUT +SHELL=$origShell +GCC=$origGcc + substitute "$SETUP" "$OUT/setup" \ --subst-var INITIALPATH \ --subst-var GCC \ diff --git a/pkgs/stdenv/mingw/cygpath/builder.sh b/pkgs/stdenv/mingw/cygpath/builder.sh new file mode 100755 index 0000000000000..3061900ee0c92 --- /dev/null +++ b/pkgs/stdenv/mingw/cygpath/builder.sh @@ -0,0 +1,5 @@ +source $stdenv/setup + +mkdir $out +result="$(cygpath --mixed $path)" +echo "\"$result\"" > $out/default.nix diff --git a/pkgs/stdenv/mingw/cygpath/default.nix b/pkgs/stdenv/mingw/cygpath/default.nix new file mode 100755 index 0000000000000..a0554c1d41dee --- /dev/null +++ b/pkgs/stdenv/mingw/cygpath/default.nix @@ -0,0 +1,9 @@ +{stdenv}: path : + +import ( + stdenv.mkDerivation { + name = "cygpath"; + builder = ./builder.sh; + inherit path; + } +) diff --git a/pkgs/stdenv/mingw/default-builder.sh b/pkgs/stdenv/mingw/default-builder.sh new file mode 100755 index 0000000000000..422699971ed6e --- /dev/null +++ b/pkgs/stdenv/mingw/default-builder.sh @@ -0,0 +1,2 @@ +source $STDENV/setup +genericBuild diff --git a/pkgs/stdenv/mingw/default.nix b/pkgs/stdenv/mingw/default.nix index 5895346049158..05542321d8f67 100644 --- a/pkgs/stdenv/mingw/default.nix +++ b/pkgs/stdenv/mingw/default.nix @@ -59,35 +59,26 @@ let { stdenvFinal = let { body = - stdenv // mkDerivationFun; + stdenv // mkDerivationFun // { inherit fetchurl; }; shell = msys + /bin/sh + ".exe"; - gccWrapper = (import ../../build-support/gcc-wrapper) { - name = "mingw-gcc-wrapper"; - nativeTools = false; - nativeGlibc = true; - shell = msysShell; - binutils = binutils; - gcc = gccCore // { langC = true; langCC = false; langF77 = false; }; - - /** - * Tricky: gcc-wrapper cannot be constructed using the MSYS shell - * so we use the Cygwin shell. - */ - stdenv = stdenvInit1; - }; - stdenv = stdenvInit2.mkDerivation { name = "stdenv-mingw"; builder = ./builder.sh; substitute = ../../build-support/substitute/substitute.sh; setup = ./setup.sh; - initialPath = [mingwRuntimeSrc w32apiSrc make msys]; - gcc = gccWrapper; + + /** + * binutils is on the path because it contains dlltool, which + * is invoked on the PATH by some packages. + */ + initialPath = [make binutils gccCore gccCpp mingwRuntimeSrc w32apiSrc msys]; + gcc = gccCore; shell = msysShell; + inherit curl; }; mkDerivationFun = { @@ -98,27 +89,42 @@ let { { 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)]; + ["-e" (if attrs ? builder then attrs.builder else ./default-builder.sh)]; inherit stdenv system; + C_INCLUDE_PATH = mingwRuntimeSrc + "/include" + ":" + w32apiSrc + "/include"; + CPLUS_INCLUDE_PATH = mingwRuntimeSrc + "/include" + ":" + w32apiSrc + "/include"; + LIBRARY_PATH = mingwRuntimeSrc + "/lib" + ":" + w32apiSrc + "/lib"; }) ) // { meta = if attrs ? meta then attrs.meta else {}; }; }; }; - /** - * Fetchurl, based on Cygwin curl in stdenvInit1 + * fetchurl */ - fetchurl = + fetchurlInit1 = import ../../build-support/fetchurl { stdenv = stdenvInit1; + curl = + (import ./pkgs).curl { + stdenv = stdenvInit1; + }; + }; - /** - * use native curl in Cygwin. We could consider to use curl.exe, - * which is widely available (or we could bootstrap it ourselves) - */ - curl = null; + cygpath = + import ./cygpath { + stdenv = stdenvInit1; + }; + + /** + * Hack: we need the cygpath of the Cygwin chmod. + */ + fetchurl = + import ./fetchurl { + stdenv = stdenvInit2; + curl = curl + "/bin/curl.exe"; + chmod = cygpath "/usr/bin/chmod"; }; /** @@ -131,7 +137,7 @@ let { name = "msys-1.0.11"; builder = ./msys-builder.sh; src = - fetchurl { + fetchurlInit1 { url = http://www.cs.uu.nl/people/martin/msys-1.0.11.tar.gz; md5 = "85ce547934797019d2d642ec3b53934b"; }; @@ -143,12 +149,23 @@ let { /** * Binary packages, based on stdenvInit2 */ + curl = + (import ./pkgs).curl { + stdenv = stdenvInit2; + }; + gccCore = (import ./pkgs).gccCore { stdenv = stdenvInit2; inherit fetchurl; }; + gccCpp = + (import ./pkgs).gccCpp { + stdenv = stdenvInit2; + inherit fetchurl; + }; + make = (import ./pkgs).make { stdenv = stdenvInit2; diff --git a/pkgs/stdenv/mingw/fetchurl/builder.sh b/pkgs/stdenv/mingw/fetchurl/builder.sh new file mode 100755 index 0000000000000..fb1386285b690 --- /dev/null +++ b/pkgs/stdenv/mingw/fetchurl/builder.sh @@ -0,0 +1,36 @@ +if test -z "$out"; then + stdenv="$STDENV" + url="$URL" + id="$ID" + outputHashAlgo="$OUTPUTHASHALGO" + outputHash="$OUTPUTHASH" + chmod=$CHMOD + curl=$CURL +fi + +source $stdenv/setup + +if test -z "$out"; then + out="$OUT" +fi + +header "downloading $out from $url" +echo "curl is $curl" +$curl --fail --location --max-redirs 20 "$url" > "$out" + +if test "$NIX_OUTPUT_CHECKED" != "1"; then + if test "$outputHashAlgo" != "md5"; then + echo "hashes other than md5 are unsupported in Nix <= 0.7, upgrade to Nix 0.8" + exit 1 + fi + actual=$(md5sum -b "$out" | cut -c1-32) + if test "$actual" != "$id"; then + echo "hash is $actual, expected $id" + exit 1 + fi +fi + +echo "chmod is $chmod" +$chmod a-x $out + +stopNest diff --git a/pkgs/stdenv/mingw/fetchurl/default.nix b/pkgs/stdenv/mingw/fetchurl/default.nix new file mode 100644 index 0000000000000..b4d278b2686fd --- /dev/null +++ b/pkgs/stdenv/mingw/fetchurl/default.nix @@ -0,0 +1,28 @@ +{stdenv, curl, chmod}: + +{url, outputHash ? "", outputHashAlgo ? "", md5 ? "", sha1 ? "", sha256 ? ""}: + +assert (outputHash != "" && outputHashAlgo != "") + || md5 != "" || sha1 != "" || sha256 != ""; + +stdenv.mkDerivation { + name = baseNameOf (toString url); + builder = ./builder.sh; + + # Compatibility with Nix <= 0.7. + id = md5; + + # New-style output content requirements. + outputHashAlgo = if outputHashAlgo != "" then outputHashAlgo else + if sha256 != "" then "sha256" else if sha1 != "" then "sha1" else "md5"; + outputHash = if outputHash != "" then outputHash else + if sha256 != "" then sha256 else if sha1 != "" then sha1 else md5; + + inherit url chmod curl; + + # We borrow these environment variables from the caller to allow + # easy proxy configuration. This is impure, but a fixed-output + # derivation like fetchurl is allowed to do so since its result is + # by definition pure. + impureEnvVars = ["http_proxy" "https_proxy" "ftp_proxy" "all_proxy" "no_proxy"]; +} diff --git a/pkgs/stdenv/mingw/gcc-wrapper/builder.sh b/pkgs/stdenv/mingw/gcc-wrapper/builder.sh new file mode 100644 index 0000000000000..e67a73adb44af --- /dev/null +++ b/pkgs/stdenv/mingw/gcc-wrapper/builder.sh @@ -0,0 +1,91 @@ +source $STDENV/setup +source $SUBSTITUTE + +if test -z "$out"; then + out="$OUT" + shell="$SHELL" + gcc="$GCC" + binutils="$BINUTILS" +fi + +# Force gcc to use ld-wrapper.sh when calling ld. +# cflagsCompile="-B $OUT/bin/" + +# 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 $MINGWRUNTIME/lib/ -B $W32API/lib/ -isystem $MINGWRUNTIME/include -isystem $W32API/include" +# ldflags="$ldflags -L$MINGWRUNTIME/lib -L$W32API" +# ldflagsBefore="-dynamic-linker $glibc/lib/ld-linux.so.2" Martin: no idea what to do with this on mingw. + + +ldflags="$ldflags -L$gcc/lib" +gccPath="$gcc/bin" +ldPath="$BINUTILS/bin" + +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 "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" +} + +echo "gccpath: $gccPath" +mkGccWrapper $out/bin/gcc $gccPath/gcc.exe +ln -s $out/bin/gcc $out/bin/cc + +# mkGccWrapper $out/bin/g++ $gccPath/g++.exe +# ln -s $out/bin/g++ $out/bin/c++ + +# mkGccWrapper $out/bin/g77 $gccPath/g77.exe +# ln -s $out/bin/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/stdenv/mingw/gcc-wrapper/default.nix b/pkgs/stdenv/mingw/gcc-wrapper/default.nix new file mode 100644 index 0000000000000..360a1c6b3b742 --- /dev/null +++ b/pkgs/stdenv/mingw/gcc-wrapper/default.nix @@ -0,0 +1,23 @@ +# 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". + +{stdenv, gcc, mingwRuntime, w32api, binutils, shell}: + +stdenv.mkDerivation { + name = "mingw-gcc-wrapper"; + builder = ./builder.sh; + substitute = ../../../build-support/substitute/substitute.sh; + setupHook = ../../../build-support/gcc-wrapper/setup-hook.sh; + gccWrapper = ../../../build-support/gcc-wrapper/gcc-wrapper.sh; + ldWrapper = ../../../build-support/gcc-wrapper/ld-wrapper.sh; + utils = ../../../build-support/gcc-wrapper/utils.sh; + addFlags = ../../../build-support/gcc-wrapper/add-flags; + inherit gcc mingwRuntime w32api binutils shell; + langC = gcc.langC; + langCC = gcc.langCC; + langF77 = gcc.langF77; +} diff --git a/pkgs/stdenv/mingw/gcc-wrapper/gcc-wrapper.sh b/pkgs/stdenv/mingw/gcc-wrapper/gcc-wrapper.sh new file mode 100644 index 0000000000000..9bcd519738635 --- /dev/null +++ b/pkgs/stdenv/mingw/gcc-wrapper/gcc-wrapper.sh @@ -0,0 +1,91 @@ +#! @shell@ -e + +params="$@" + +if test -n "$NIX_GCC_WRAPPER_START_HOOK"; then + source "$NIX_GCC_WRAPPER_START_HOOK" +fi + +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 + +source @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 + +# 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 + +# As a very special hack, if the arguments are just `-v', then don't +# add anything. This is to prevent `gcc -v' (which normally prints +# out the version number and returns exit code 0) from printing out +# `No input files specified' and returning exit code 1. +if test "$*" = "-v"; then + extraAfter="" + extraBefore="" +fi + +if test -n "$NIX_GCC_WRAPPER_EXEC_HOOK"; then + source "$NIX_GCC_WRAPPER_EXEC_HOOK" +fi + +# Call the real `gcc'. Filter out warnings from stderr about unused +# `-B' flags, since they confuse some programs. Deep bash magic to +# apply grep to stderr (by swapping stdin/stderr twice). +if test -z "$NIX_GCC_NEEDS_GREP"; then + @gccProg@ $extraBefore $params $extraAfter +else + (@gccProg@ $extraBefore $params $extraAfter 3>&2 2>&1 1>&3- \ + | (grep -v 'file path prefix' || true); exit ${PIPESTATUS[0]}) 3>&2 2>&1 1>&3- + exit $? +fi diff --git a/pkgs/stdenv/mingw/pkgs/curl.exe b/pkgs/stdenv/mingw/pkgs/curl.exe new file mode 100755 index 0000000000000..0a02fa0af5ca6 Binary files /dev/null and b/pkgs/stdenv/mingw/pkgs/curl.exe differ diff --git a/pkgs/stdenv/mingw/pkgs/default.nix b/pkgs/stdenv/mingw/pkgs/default.nix index 00e0fd87cfb6b..fb4fb10cbc257 100755 --- a/pkgs/stdenv/mingw/pkgs/default.nix +++ b/pkgs/stdenv/mingw/pkgs/default.nix @@ -3,6 +3,17 @@ */ rec { + /** + * Curl, binary + */ + curl = {stdenv} : + stdenv.mkDerivation { + name = "curl-7.15.4"; + exename = "curl.exe"; + builder = ./single-exe-builder.sh; + src = ./curl.exe; + }; + /** * Make. Binary. */ @@ -31,6 +42,20 @@ rec { }; }; + /** + * GCC C++. Binary. + */ + gccCpp = {stdenv, fetchurl} : + stdenv.mkDerivation { + name = "mingw-gcc-g++-3.4.2-20040916-1"; + builder = ./bin-builder.sh; + src = + fetchurl { + url = http://surfnet.dl.sourceforge.net/sourceforge/mingw/gcc-g++-3.4.2-20040916-1.tar.gz; + md5 = "e5c7eb2c1e5f7e10842eac03d1d6fcdc"; + }; + }; + /** * binutils. Binary. */ diff --git a/pkgs/stdenv/mingw/pkgs/single-exe-builder.sh b/pkgs/stdenv/mingw/pkgs/single-exe-builder.sh new file mode 100644 index 0000000000000..d6a2e2668d4f7 --- /dev/null +++ b/pkgs/stdenv/mingw/pkgs/single-exe-builder.sh @@ -0,0 +1,5 @@ +source $STDENV/setup + +mkdir $OUT +mkdir $OUT/bin +cp $SRC $OUT/bin/$EXENAME diff --git a/pkgs/stdenv/mingw/setup.sh b/pkgs/stdenv/mingw/setup.sh index dd8b4605de082..8e144a26139dc 100755 --- a/pkgs/stdenv/mingw/setup.sh +++ b/pkgs/stdenv/mingw/setup.sh @@ -18,10 +18,19 @@ for i in $NIX_GCC @INITIALPATH@; do PATH=$PATH${PATH:+:}$i/bin done -if test "$NIX_DEBUG" = "1"; then - echo "Initial path: $PATH" +# Hack: the /tmp of Cygwin is different from the /tmp in MSYS +if test -d $NIX_BUILD_TOP; then + echo "Nix build top already exists. Strange." +else + mkdir $NIX_BUILD_TOP + cd $NIX_BUILD_TOP fi +# if test "$NIX_DEBUG" = "1"; then + echo "Initial path: $PATH" + echo "$buildInputs" +# fi + # Execute the pre-hook. export SHELL=@SHELL@ @@ -202,6 +211,8 @@ trap "closeNest" EXIT # then go to the build directory and source in `env-vars' to reproduce # the environment used for building. dumpVars() { + pwd + ls if test "$noDumpEnvVars" != "1"; then export > $NIX_BUILD_TOP/env-vars fi diff --git a/pkgs/stdenv/mingw/simple-stdenv/builder.sh b/pkgs/stdenv/mingw/simple-stdenv/builder.sh index 960810dc9545b..650f6fb082f73 100644 --- a/pkgs/stdenv/mingw/simple-stdenv/builder.sh +++ b/pkgs/stdenv/mingw/simple-stdenv/builder.sh @@ -1,6 +1,7 @@ if test -z "$out"; then out="$OUT" initialPath="$INITIALPATH" + shell="$SHELL" fi setupPath= -- cgit 1.4.1