From 9783d27b7a4f404c1fa10cb26454ba3305635aed Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Tue, 18 Oct 2011 16:37:28 +0000 Subject: [PATCH 1/3] Bump llvm and clang to 2.9 svn path=/nixpkgs/trunk/; revision=29878 --- .../compilers/llvm/clang-include-paths.patch | 20 ++++++++--------- pkgs/development/compilers/llvm/default.nix | 22 ++++++++++--------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/pkgs/development/compilers/llvm/clang-include-paths.patch b/pkgs/development/compilers/llvm/clang-include-paths.patch index 5c80e5821451..aaa9a5fc4b5f 100644 --- a/pkgs/development/compilers/llvm/clang-include-paths.patch +++ b/pkgs/development/compilers/llvm/clang-include-paths.patch @@ -1,15 +1,15 @@ diff -ru -x '*~' a/tools/clang/lib/Frontend/InitHeaderSearch.cpp b/tools/clang/lib/Frontend/InitHeaderSearch.cpp ---- a/tools/clang/lib/Frontend/InitHeaderSearch.cpp 2010-09-03 18:45:53.000000000 +0200 -+++ b/tools/clang/lib/Frontend/InitHeaderSearch.cpp 2011-02-05 14:59:08.669573190 +0100 -@@ -443,6 +443,7 @@ - AddPath(*i, System, false, false, false); - return; - } +--- a/tools/clang/lib/Frontend/InitHeaderSearch.cpp 2011-03-21 20:24:04.000000000 -0400 ++++ b/tools/clang/lib/Frontend/InitHeaderSearch.cpp 2011-10-18 12:09:50.624355551 -0400 +@@ -438,6 +438,7 @@ + + void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple, + const HeaderSearchOptions &HSOpts) { +#if 0 llvm::Triple::OSType os = triple.getOS(); + switch (os) { - case llvm::Triple::Win32: -@@ -532,6 +533,8 @@ +@@ -559,6 +560,8 @@ } AddPath("/usr/include", System, false, false, false); @@ -18,7 +18,7 @@ diff -ru -x '*~' a/tools/clang/lib/Frontend/InitHeaderSearch.cpp b/tools/clang/l } void InitHeaderSearch:: -@@ -550,6 +553,7 @@ +@@ -577,6 +580,7 @@ triple); return; } @@ -26,7 +26,7 @@ diff -ru -x '*~' a/tools/clang/lib/Frontend/InitHeaderSearch.cpp b/tools/clang/l // FIXME: temporary hack: hard-coded paths. switch (os) { case llvm::Triple::Cygwin: -@@ -769,6 +773,10 @@ +@@ -847,6 +851,10 @@ default: break; } diff --git a/pkgs/development/compilers/llvm/default.nix b/pkgs/development/compilers/llvm/default.nix index 4229e43949a3..0c5117f445f2 100644 --- a/pkgs/development/compilers/llvm/default.nix +++ b/pkgs/development/compilers/llvm/default.nix @@ -1,12 +1,14 @@ { stdenv, fetchurl, gcc, flex, perl, libtool, groff , buildClang ? false }: +let version = "2.9"; in + stdenv.mkDerivation ({ - name = "llvm-2.8"; - + name = "llvm-${version}"; + src = fetchurl { - url = http://llvm.org/releases/2.8/llvm-2.8.tgz; - sha256 = "0fyl2gk2ld28isz9bq4f6r4dhqm9vljfj3pdfwlc2v0w5xsdpb95"; + url = "http://llvm.org/releases/${version}/llvm-${version}.tgz"; + sha256 = "0y9pgdakn3n0vf8zs6fjxjw6972nyw4rkfwwza6b8a3ll77kc4k6"; }; buildInputs = [ gcc flex perl groff ]; @@ -17,7 +19,7 @@ stdenv.mkDerivation ({ homepage = http://llvm.org/; description = "Collection of modular and reusable compiler and toolchain technologies"; license = "BSD"; - maintainers = with stdenv.lib.maintainers; [viric]; + maintainers = with stdenv.lib.maintainers; [viric shlevy]; platforms = with stdenv.lib.platforms; all; }; } @@ -30,17 +32,17 @@ stdenv.mkDerivation ({ else if (stdenv.system == "x86_64-linux") then "x86_64-unknown-linux-gnu" else throw "System not supported"; in { - name = "clang-2.8"; + name = "clang-${version}"; srcClang = fetchurl { - url = http://llvm.org/releases/2.8/clang-2.8.tgz; - sha256 = "1hg0vqmyr4wdy686l2bga0rpin41v0q9ds2k5659m8z6acali0zd"; + url = "http://llvm.org/releases/${version}/clang-${version}.tgz"; + sha256 = "1pq9g7qxw761dp6gx3amx39kl9p4zhlymmn8gfmcnw9ag0zizi3h"; }; prePatch = '' pushd tools unpackFile $srcClang - mv clang-2.8 clang + mv clang-${version} clang popd find ''; @@ -59,7 +61,7 @@ stdenv.mkDerivation ({ homepage = http://clang.llvm.org/; description = "A C language family frontend for LLVM"; license = "BSD"; - maintainers = with stdenv.lib.maintainers; [viric]; + maintainers = with stdenv.lib.maintainers; [viric shlevy]; platforms = with stdenv.lib.platforms; linux; }; } From db619f2d55ce346b6d9d72905de643ba495cf55a Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Tue, 18 Oct 2011 20:03:09 +0000 Subject: [PATCH 2/3] First try at a clang-wrapper. Hello world compiles\! svn path=/nixpkgs/trunk/; revision=29879 --- pkgs/build-support/clang-wrapper/add-flags | 24 +++ pkgs/build-support/clang-wrapper/builder.sh | 131 ++++++++++++++ .../clang-wrapper/clang-wrapper.sh | 152 +++++++++++++++++ pkgs/build-support/clang-wrapper/default.nix | 84 +++++++++ .../build-support/clang-wrapper/ld-wrapper.sh | 161 ++++++++++++++++++ .../build-support/clang-wrapper/setup-hook.sh | 33 ++++ pkgs/build-support/clang-wrapper/utils.sh | 23 +++ pkgs/development/compilers/llvm/default.nix | 2 + pkgs/top-level/all-packages.nix | 16 +- 9 files changed, 623 insertions(+), 3 deletions(-) create mode 100644 pkgs/build-support/clang-wrapper/add-flags create mode 100644 pkgs/build-support/clang-wrapper/builder.sh create mode 100644 pkgs/build-support/clang-wrapper/clang-wrapper.sh create mode 100644 pkgs/build-support/clang-wrapper/default.nix create mode 100644 pkgs/build-support/clang-wrapper/ld-wrapper.sh create mode 100644 pkgs/build-support/clang-wrapper/setup-hook.sh create mode 100644 pkgs/build-support/clang-wrapper/utils.sh diff --git a/pkgs/build-support/clang-wrapper/add-flags b/pkgs/build-support/clang-wrapper/add-flags new file mode 100644 index 000000000000..3b0645471531 --- /dev/null +++ b/pkgs/build-support/clang-wrapper/add-flags @@ -0,0 +1,24 @@ +# `-B@out@/bin' forces clang to use ld-wrapper.sh when calling ld. +export NIX_CFLAGS_COMPILE="-B@out@/bin/ $NIX_CFLAGS_COMPILE" + +if test -e @out@/nix-support/libc-cflags; then + export NIX_CFLAGS_COMPILE="$(cat @out@/nix-support/libc-cflags) $NIX_CFLAGS_COMPILE" +fi + +if test -e @out@/nix-support/clang-cflags; then + export NIX_CFLAGS_COMPILE="$(cat @out@/nix-support/clang-cflags) $NIX_CFLAGS_COMPILE" +fi + +if test -e @out@/nix-support/libc-ldflags; then + export NIX_LDFLAGS="$NIX_LDFLAGS $(cat @out@/nix-support/libc-ldflags)" +fi + +if test -e @out@/nix-support/clang-ldflags; then + export NIX_LDFLAGS="$NIX_LDFLAGS $(cat @out@/nix-support/clang-ldflags)" +fi + +if test -e @out@/nix-support/libc-ldflags-before; then + export NIX_LDFLAGS_BEFORE="$(cat @out@/nix-support/libc-ldflags-before) $NIX_LDFLAGS_BEFORE" +fi + +export NIX_CLANG_WRAPPER_FLAGS_SET=1 diff --git a/pkgs/build-support/clang-wrapper/builder.sh b/pkgs/build-support/clang-wrapper/builder.sh new file mode 100644 index 000000000000..dc039605d031 --- /dev/null +++ b/pkgs/build-support/clang-wrapper/builder.sh @@ -0,0 +1,131 @@ +source $stdenv/setup + + +ensureDir $out/bin +ensureDir $out/nix-support + + +if test -z "$nativeLibc"; then + dynamicLinker="$libc/lib/$dynamicLinker" + echo $dynamicLinker > $out/nix-support/dynamic-linker + + if test -e $libc/lib/32/ld-linux.so.2; then + echo $libc/lib/32/ld-linux.so.2 > $out/nix-support/dynamic-linker-m32 + fi + + # The "-B$libc/lib/" flag is a quick hack to force clang to link + # against the crt1.o from our own glibc, rather than the one in + # /usr/lib. (This is only an issue when using an `impure' + # compiler/linker, i.e., one that searches /usr/lib and so on.) + echo "-B$libc/lib/ -idirafter $libc/include" > $out/nix-support/libc-cflags + + echo "-L$libc/lib" > $out/nix-support/libc-ldflags + + # The dynamic linker is passed in `ldflagsBefore' to allow + # explicit overrides of the dynamic linker by callers to clang/ld + # (the *last* value counts, so ours should come first). + echo "-dynamic-linker $dynamicLinker" > $out/nix-support/libc-ldflags-before +fi + +if test -n "$nativeTools"; then + clangPath="$nativePrefix/bin" + ldPath="$nativePrefix/bin" +else + basePath=`echo $gcc/lib/*/*/*` + # Need libgcc until the llvm compiler-rt library is complete + clangLDFlags="$clangLDFlags -L$basePath" + if test -e "$gcc/lib64"; then + clangLDFlags="$clangLDFlags -L$gcc/lib64" + else + clangLDFlags="$clangLDFlags -L$gcc/lib" + fi + + clangLDFlags="$clangLDFlags -L$clang/lib" + echo "$clangLDFlags" > $out/nix-support/clang-ldflags + + # Need files like crtbegin.o from gcc + # It's unclear if these will ever be provided by an LLVM project + clangCFlags="$clangCFlags -B$basePath" + + clangCFlags="$clangCFlags -I$clang/lib/clang/$clangVersion/include" + echo "$clangCFlags" > $out/nix-support/clang-cflags + + clangPath="$clang/bin" + ldPath="$binutils/bin" +fi + + +doSubstitute() { + local src=$1 + local dst=$2 + # Can't use substitute() here, because replace may not have been + # built yet (in the bootstrap). + sed \ + -e "s^@out@^$out^g" \ + -e "s^@shell@^$shell^g" \ + -e "s^@clang@^$clang^g" \ + -e "s^@clangProg@^$clangProg^g" \ + -e "s^@binutils@^$binutils^g" \ + -e "s^@coreutils@^$coreutils^g" \ + -e "s^@libc@^$libc^g" \ + -e "s^@ld@^$ldPath/ld^g" \ + < "$src" > "$dst" +} + + +# Make wrapper scripts around clang and clang++. Also make symlinks +# cc and c++ +mkClangWrapper() { + local dst=$1 + local src=$2 + + if ! test -f "$src"; then + echo "$src does not exist (skipping)" + return 1 + fi + + clangProg="$src" + doSubstitute "$clangWrapper" "$dst" + chmod +x "$dst" +} + +if mkClangWrapper $out/bin/clang $clangPath/clang +then + ln -sv clang $out/bin/cc +fi + +if mkClangWrapper $out/bin/clang++ $clangPath/clang++ +then + ln -sv clang++ $out/bin/c++ +fi + + +# Create a symlink to as (the assembler). This is useful when a +# clang-wrapper is installed in a user environment, as it ensures that +# the right assembler is called. +ln -s $ldPath/as $out/bin/as + + +# 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 Clang and +# libc. +test -n "$clang" && echo $clang > $out/nix-support/orig-clang +test -n "$libc" && echo $libc > $out/nix-support/orig-libc + +doSubstitute "$addFlags" "$out/nix-support/add-flags.sh" + +doSubstitute "$setupHook" "$out/nix-support/setup-hook" + +cp -p $utils $out/nix-support/utils.sh + + +# Propagate the wrapped clang so that if you install the wrapper, you get +# llvm tools, the manpages, etc. as well (including for binutils +# and Glibc). +if test -z "$nativeTools"; then + echo $clang $binutils $libc > $out/nix-support/propagated-user-env-packages +fi diff --git a/pkgs/build-support/clang-wrapper/clang-wrapper.sh b/pkgs/build-support/clang-wrapper/clang-wrapper.sh new file mode 100644 index 000000000000..473adba86271 --- /dev/null +++ b/pkgs/build-support/clang-wrapper/clang-wrapper.sh @@ -0,0 +1,152 @@ +#! @shell@ -e + +if test -n "$NIX_CLANG_WRAPPER_START_HOOK"; then + source "$NIX_CLANG_WRAPPER_START_HOOK" +fi + +if test -z "$NIX_CLANG_WRAPPER_FLAGS_SET"; then + source @out@/nix-support/add-flags.sh +fi + +source @out@/nix-support/utils.sh + + +# Figure out if linker flags should be passed. Clang prints annoying +# warnings when they are not needed. (does it really? Copied from gcc-wrapper) +dontLink=0 +getVersion=0 +nonFlagArgs=0 + +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 + elif test "$i" = "-x"; then + # At least for the cases c-header or c++-header we should set dontLink. + # I expect no one use -x other than making precompiled headers. + dontLink=1 + elif test "${i:0:1}" != "-"; then + nonFlagArgs=1 + elif test "$i" = "-m32"; then + if test -e @out@/nix-support/dynamic-linker-m32; then + NIX_LDFLAGS="$NIX_LDFLAGS -dynamic-linker $(cat @out@/nix-support/dynamic-linker-m32)" + fi + fi +done + +# If we pass a flag like -Wl, then clang will call the linker unless it +# can figure out that it has to do something else (e.g., because of a +# "-c" flag). So if no non-flag arguments are given, don't pass any +# linker flags. This catches cases like "clang" (should just print +# "clang: no input files") and "clang -v" (should print the version). +if test "$nonFlagArgs" = "0"; then + dontLink=1 +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 + +# As a very special hack, if the arguments are just `-v', then don't +# add anything. This is to prevent `clang -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 + +# Optionally print debug info. +if test "$NIX_DEBUG" = "1"; then + echo "original flags to @clangProg@:" >&2 + for i in "${params[@]}"; do + echo " $i" >&2 + done + echo "extraBefore flags to @clangProg@:" >&2 + for i in ${extraBefore[@]}; do + echo " $i" >&2 + done + echo "extraAfter flags to @clangProg@:" >&2 + for i in ${extraAfter[@]}; do + echo " $i" >&2 + done +fi + +if test -n "$NIX_CLANG_WRAPPER_EXEC_HOOK"; then + source "$NIX_CLANG_WRAPPER_EXEC_HOOK" +fi + + +# Call the real `clang'. 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_CLANG_NEEDS_GREP"; then + @clangProg@ ${extraBefore[@]} "${params[@]}" ${extraAfter[@]} +else + (@clangProg@ ${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/build-support/clang-wrapper/default.nix b/pkgs/build-support/clang-wrapper/default.nix new file mode 100644 index 000000000000..4730a7969e2a --- /dev/null +++ b/pkgs/build-support/clang-wrapper/default.nix @@ -0,0 +1,84 @@ +# The Nix `clang' 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, nativeLibc, nativePrefix ? "" +, clang ? null, libc ? null, binutils ? null, coreutils ? null, shell ? "" +, zlib ? null +}: + +assert nativeTools -> nativePrefix != ""; +assert !nativeTools -> clang != null && binutils != null && coreutils != null; +assert !nativeLibc -> libc != null; + +let + + clangVersion = (builtins.parseDrvName clang.name).version; + clangName = (builtins.parseDrvName clang.name).name; + +in + +stdenv.mkDerivation { + name = + (if name != "" then name else clangName + "-wrapper") + + (if clang != null && clangVersion != "" then "-" + clangVersion else ""); + + builder = ./builder.sh; + setupHook = ./setup-hook.sh; + clangWrapper = ./clang-wrapper.sh; + ldWrapper = ./ld-wrapper.sh; + utils = ./utils.sh; + addFlags = ./add-flags; + + inherit nativeTools nativeLibc nativePrefix clang clangVersion; + gcc = clang.gcc; + libc = if nativeLibc then null else libc; + binutils = if nativeTools then null else binutils; + # The wrapper scripts use 'cat', so we may need coreutils + coreutils = if nativeTools then null else coreutils; + + langC = true; + langCC = true; + shell = if shell == "" then stdenv.shell else + if builtins.isAttrs shell then (shell + shell.shellPath) + else shell; + + crossAttrs = { + shell = shell.hostDrv + shell.hostDrv.shellPath; + libc = libc.hostDrv; + coreutils = coreutils.hostDrv; + binutils = binutils.hostDrv; + clang = clang.hostDrv; + # + # This is not the best way to do this. I think the reference should be + # the style in the gcc-cross-wrapper, but to keep a stable stdenv now I + # do this sufficient if/else. + dynamicLinker = + (if stdenv.cross.arch == "arm" then "ld-linux.so.3" else + if stdenv.cross.arch == "mips" then "ld.so.1" else + if stdenv.lib.hasSuffix "pc-gnu" stdenv.cross.config then "ld.so.1" else + abort "don't know the name of the dynamic linker for this platform"); + }; + + meta = + let clang_ = if clang != null then clang else {}; in + (if clang_ ? meta then removeAttrs clang.meta ["priority"] else {}) // + { description = + stdenv.lib.attrByPath ["meta" "description"] "System C compiler" clang_ + + " (wrapper script)"; + }; + + # The dynamic linker has different names on different Linux platforms. + dynamicLinker = + if !nativeLibc then + (if stdenv.system == "i686-linux" then "ld-linux.so.2" else + if stdenv.system == "x86_64-linux" then "ld-linux-x86-64.so.2" else + if stdenv.system == "armv5tel-linux" then "ld-linux.so.3" else + if stdenv.system == "powerpc-linux" then "ld.so.1" else + if stdenv.system == "mips64-linux" then "ld.so.1" else + abort "don't know the name of the dynamic linker for this platform") + else ""; +} diff --git a/pkgs/build-support/clang-wrapper/ld-wrapper.sh b/pkgs/build-support/clang-wrapper/ld-wrapper.sh new file mode 100644 index 000000000000..48378778ba9e --- /dev/null +++ b/pkgs/build-support/clang-wrapper/ld-wrapper.sh @@ -0,0 +1,161 @@ +#! @shell@ -e + +if test -n "$NIX_LD_WRAPPER_START_HOOK"; then + source "$NIX_LD_WRAPPER_START_HOOK" +fi + +if test -z "$NIX_CLANG_WRAPPER_FLAGS_SET"; then + source @out@/nix-support/add-flags.sh +fi + +source @out@/nix-support/utils.sh + + +# 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_CLANG" -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 + + 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 " + } + + 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 " + } + + libs="" + addToLibs() { + libs="$libs $1" + } + + rpath="" + + # First, find all -L... switches. + allParams=("${params[@]}" ${extra[@]}) + 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)) + elif test "$p" = "-l"; then + addToLibs ${p2} + n=$((n + 1)) + elif test "${p:0:2}" = "-l"; then + addToLibs ${p:2} + elif test "$p" = "-dynamic-linker"; then + # Ignore the dynamic linker argument, or it + # will get into the next 'elif'. We don't want + # the dynamic linker path rpath to go always first. + n=$((n + 1)) + elif [[ "$p" =~ ^[^-].*\.so($|\.) ]]; then + # This is a direct reference to a shared library, so add + # its directory to the rpath. + path="$(dirname "$p")"; + addToRPath "${path}" + fi + n=$((n + 1)) + done + + # Second, for each directory in the library search path (-L...), + # see if it contains a dynamic library used by a -l... flag. If + # so, add the directory to the rpath. + # It's important to add the rpath in the order of -L..., so + # the link time chosen objects will be those of runtime linking. + + for i in $libPath; do + for j in $libs; do + if test -f "$i/lib$j.so"; then + addToRPath $i + break + fi + done + 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 + source "$NIX_LD_WRAPPER_EXEC_HOOK" +fi + +exec @ld@ ${extraBefore[@]} "${params[@]}" ${extra[@]} diff --git a/pkgs/build-support/clang-wrapper/setup-hook.sh b/pkgs/build-support/clang-wrapper/setup-hook.sh new file mode 100644 index 000000000000..74365a527043 --- /dev/null +++ b/pkgs/build-support/clang-wrapper/setup-hook.sh @@ -0,0 +1,33 @@ +addCVars () { + if test -d $1/include; then + export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -I$1/include" + fi + + if test -d $1/lib64; then + export NIX_LDFLAGS="$NIX_LDFLAGS -L$1/lib64" + 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 "@clang@"; then + addToSearchPath PATH @clang@/bin +fi + +if test -n "@binutils@"; then + addToSearchPath PATH @binutils@/bin +fi + +if test -n "@libc@"; then + addToSearchPath PATH @libc@/bin +fi + +if test -n "@coreutils@"; then + addToSearchPath PATH @coreutils@/bin +fi diff --git a/pkgs/build-support/clang-wrapper/utils.sh b/pkgs/build-support/clang-wrapper/utils.sh new file mode 100644 index 000000000000..9a664e1d1e6b --- /dev/null +++ b/pkgs/build-support/clang-wrapper/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/development/compilers/llvm/default.nix b/pkgs/development/compilers/llvm/default.nix index 0c5117f445f2..3044acede210 100644 --- a/pkgs/development/compilers/llvm/default.nix +++ b/pkgs/development/compilers/llvm/default.nix @@ -57,6 +57,8 @@ stdenv.mkDerivation ({ tools/clang/lib/Frontend/InitHeaderSearch.cpp ''; + passthru = { gcc = gcc.gcc; }; + meta = { homepage = http://clang.llvm.org/; description = "A C language family frontend for LLVM"; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index d44c6f7ce93d..3660c152a169 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -1640,9 +1640,7 @@ let ccl = builderDefsPackage ../development/compilers/ccl {}; - clang = llvm.override { - buildClang = true; - }; + clang = wrapClang (llvm.override { buildClang = true; }); clangSVN = llvmSVN.override { buildClang = true; @@ -2426,6 +2424,18 @@ let inherit stdenv binutils coreutils zlib; }; + wrapClangWith = clangWrapper: glibc: baseClang: clangWrapper { + nativeTools = stdenv ? gcc && stdenv.gcc.nativeTools; + nativeLibc = stdenv ? gcc && stdenv.gcc.nativeLibc; + nativePrefix = if stdenv ? gcc then stdenv.gcc.nativePrefix else ""; + clang = baseClang; + libc = glibc; + shell = bash; + inherit stdenv binutils coreutils zlib; + }; + + wrapClang = wrapClangWith (import ../build-support/clang-wrapper) glibc; + wrapGCC = wrapGCCWith (import ../build-support/gcc-wrapper) glibc; wrapGCCCross = From 1ed93241cde41d856684d0d7dbfc943e7835b65c Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Wed, 19 Oct 2011 04:14:55 +0000 Subject: [PATCH 3/3] clang: Don't send extra -I flags to the linker svn path=/nixpkgs/trunk/; revision=29883 --- .../compilers/llvm/clang-ld-flags.patch | 45 +++++++++++++++++++ pkgs/development/compilers/llvm/default.nix | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 pkgs/development/compilers/llvm/clang-ld-flags.patch diff --git a/pkgs/development/compilers/llvm/clang-ld-flags.patch b/pkgs/development/compilers/llvm/clang-ld-flags.patch new file mode 100644 index 000000000000..fc625a0e0b7d --- /dev/null +++ b/pkgs/development/compilers/llvm/clang-ld-flags.patch @@ -0,0 +1,45 @@ +diff -Naur a/tools/clang/lib/Driver/ToolChains.cpp b/tools/clang/lib/Driver/ToolChains.cpp +--- a/tools/clang/lib/Driver/ToolChains.cpp 2011-03-21 17:29:27.000000000 -0400 ++++ b/tools/clang/lib/Driver/ToolChains.cpp 2011-10-18 19:43:48.999590771 -0400 +@@ -1482,12 +1482,9 @@ + Lib = Lib64; + } + +- llvm::sys::Path LinkerPath(Base + "/../../../../" + GccTriple + "/bin/ld"); +- if (!llvm::sys::fs::exists(LinkerPath.str(), Exists) && Exists) +- Linker = LinkerPath.str(); +- else +- Linker = GetProgramPath("ld"); ++ Linker = GetProgramPath("ld"); + ++#if 0 + LinuxDistro Distro = DetectLinuxDistro(Arch); + + if (IsUbuntu(Distro)) { +@@ -1531,6 +1528,7 @@ + Paths.push_back(Base + "/../../.."); + if (Arch == getArch() && IsUbuntu(Distro)) + Paths.push_back("/usr/lib/" + GccTriple); ++#endif + } + + bool Linux::HasNativeLLVMSupport() const { +diff -Naur a/tools/clang/lib/Driver/Tools.cpp b/tools/clang/lib/Driver/Tools.cpp +--- a/tools/clang/lib/Driver/Tools.cpp 2011-03-06 18:31:01.000000000 -0500 ++++ b/tools/clang/lib/Driver/Tools.cpp 2011-10-18 18:44:00.799604267 -0400 +@@ -3619,6 +3619,7 @@ + ToolChain.getArch() == llvm::Triple::thumb || + (!Args.hasArg(options::OPT_static) && + !Args.hasArg(options::OPT_shared))) { ++#if 0 + CmdArgs.push_back("-dynamic-linker"); + if (ToolChain.getArch() == llvm::Triple::x86) + CmdArgs.push_back("/lib/ld-linux.so.2"); +@@ -3627,6 +3628,7 @@ + CmdArgs.push_back("/lib/ld-linux.so.3"); + else + CmdArgs.push_back("/lib64/ld-linux-x86-64.so.2"); ++#endif + } + + CmdArgs.push_back("-o"); diff --git a/pkgs/development/compilers/llvm/default.nix b/pkgs/development/compilers/llvm/default.nix index 3044acede210..c98005417c94 100644 --- a/pkgs/development/compilers/llvm/default.nix +++ b/pkgs/development/compilers/llvm/default.nix @@ -47,7 +47,7 @@ stdenv.mkDerivation ({ find ''; - patches = [ ./clang-include-paths.patch ]; + patches = [ ./clang-include-paths.patch ./clang-ld-flags.patch ]; # Set up the header file paths preConfigure = ''