diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2017-08-03 17:25:30 -0400 |
---|---|---|
committer | John Ericson <John.Ericson@Obsidian.Systems> | 2017-08-03 17:25:30 -0400 |
commit | 8ba6012dfdc1214f5df7dc90955973be3f7562e3 (patch) | |
tree | 8a29c257fa64cbad9c370144817030a88eeb5bc2 | |
parent | 264d6641ecc7c0bea4ae0758a43c446fe52b4cd3 (diff) | |
parent | cd6c452ade3a309050f56c36c27d41b0abb0eef7 (diff) | |
download | nixlib-8ba6012dfdc1214f5df7dc90955973be3f7562e3.tar nixlib-8ba6012dfdc1214f5df7dc90955973be3f7562e3.tar.gz nixlib-8ba6012dfdc1214f5df7dc90955973be3f7562e3.tar.bz2 nixlib-8ba6012dfdc1214f5df7dc90955973be3f7562e3.tar.lz nixlib-8ba6012dfdc1214f5df7dc90955973be3f7562e3.tar.xz nixlib-8ba6012dfdc1214f5df7dc90955973be3f7562e3.tar.zst nixlib-8ba6012dfdc1214f5df7dc90955973be3f7562e3.zip |
Merge PR #27536
-rw-r--r-- | pkgs/build-support/cc-wrapper/default.nix | 15 | ||||
-rw-r--r-- | pkgs/build-support/cc-wrapper/macos-sierra-reexport-hack.bash | 106 | ||||
-rw-r--r-- | pkgs/stdenv/darwin/default.nix | 2 | ||||
-rw-r--r-- | pkgs/test/macos-sierra-shared/default.nix | 89 | ||||
-rw-r--r-- | pkgs/top-level/all-packages.nix | 11 | ||||
-rw-r--r-- | pkgs/top-level/release.nix | 1 |
6 files changed, 221 insertions, 3 deletions
diff --git a/pkgs/build-support/cc-wrapper/default.nix b/pkgs/build-support/cc-wrapper/default.nix index 09d1d4cd681a..e0cc1fc26696 100644 --- a/pkgs/build-support/cc-wrapper/default.nix +++ b/pkgs/build-support/cc-wrapper/default.nix @@ -12,6 +12,7 @@ , isGNU ? false, isClang ? cc.isClang or false, gnugrep ? null , buildPackages ? {}, hostPlatform, targetPlatform , runCommand ? null +, useMacosReexportHack ? false }: with stdenv.lib; @@ -278,7 +279,15 @@ stdenv.mkDerivation { ln -s $ldPath/${prefix}as $out/bin/${prefix}as fi - wrap ${prefix}ld ${preWrap ./ld-wrapper.sh} ''${ld:-$ldPath/${prefix}ld} + '' + (if !useMacosReexportHack then '' + wrap ${prefix}ld ${./ld-wrapper.sh} ''${ld:-$ldPath/${prefix}ld} + '' else '' + export binPrefix=${prefix} + ldInner="${prefix}ld-reexport-delegate" + wrap "$ldInner" ${./macos-sierra-reexport-hack.bash} ''${ld:-$ldPath/${prefix}ld} + wrap "${prefix}ld" ${./ld-wrapper.sh} "$out/bin/$ldInner" + unset ldInner + '') + '' if [ -e ${binutils_bin}/bin/${prefix}ld.gold ]; then wrap ${prefix}ld.gold ${preWrap ./ld-wrapper.sh} ${binutils_bin}/bin/${prefix}ld.gold @@ -386,5 +395,7 @@ stdenv.mkDerivation { { description = stdenv.lib.attrByPath ["meta" "description"] "System C compiler" cc_ + " (wrapper script)"; - }; + } // optionalAttrs useMacosReexportHack { + platforms = stdenv.lib.platforms.darwin; + }; } diff --git a/pkgs/build-support/cc-wrapper/macos-sierra-reexport-hack.bash b/pkgs/build-support/cc-wrapper/macos-sierra-reexport-hack.bash new file mode 100644 index 000000000000..b7aa7ea5c092 --- /dev/null +++ b/pkgs/build-support/cc-wrapper/macos-sierra-reexport-hack.bash @@ -0,0 +1,106 @@ +#! @shell@ + +set -eu -o pipefail + +path_backup="$PATH" +if [ -n "@coreutils_bin@" ]; then + PATH="@coreutils_bin@/bin" +fi + +declare -r recurThreshold=300 + +declare overflowCount=0 +for ((n=0; n < $#; ++n)); do + case "${!n}" in + -l*) let overflowCount+=1 ;; + -reexport-l*) let overflowCount+=1 ;; + *) ;; + esac +done + +declare -a allArgs=() + +if (( "$overflowCount" <= "$recurThreshold" )); then + allArgs=("$@") +else + declare -a childrenLookup=() childrenLink=() + + while (( $# )); do + case "$1" in + -L/*) + childrenLookup+=("$1") + allArgs+=("$1") + ;; + -L) + echo "cctools LD does not support '-L foo' or '-l foo'" >&2 + exit 1 + ;; + -l) + echo "cctools LD does not support '-L foo' or '-l foo'" >&2 + exit 1 + ;; + -lazy_library | -lazy_framework | -lto_library) + # We aren't linking any "azy_library", "to_library", etc. + allArgs+=("$1") + ;; + -lazy-l | -weak-l) allArgs+=("$1") ;; + # We can't so easily prevent header issues from these. + -lSystem) allArgs+=("$1") ;; + # Special case as indirection seems like a bad idea for something + # so fundamental. Can be removed for simplicity. + -l?* | -reexport-l?*) childrenLink+=("$1") ;; + *) allArgs+=("$1") ;; + esac + + shift + done + + declare n=0 + while (( $n < "${#childrenLink[@]}" )); do + if [[ "${childrenLink[n]}" = -l* ]]; then + childrenLink[n]="-reexport${childrenLink[n]}" + fi + let ++n + done + unset n + + declare -r outputNameLibless=$(basename $( \ + if [[ -z "${outputName:+isUndefined}" ]]; then + echo unnamed + elif [[ "${outputName:0:3}" = lib ]]; then + echo "${outputName:3}" + else + echo "${outputName}" + fi)) + declare -ra children=("$outputNameLibless-reexport-delegate-0" \ + "$outputNameLibless-reexport-delegate-1") + + mkdir -p "$out/lib" + + PATH="$PATH:@out@/bin" + + symbolBloatObject=$outputNameLibless-symbol-hack.o + if [[ ! -e $symbolBloatObject ]]; then + printf '.private_extern _______child_hack_foo\nchild_hack_foo:\n' \ + | @binPrefix@as -- -o $symbolBloatObject + fi + + # first half of libs + @binPrefix@ld -macosx_version_min $MACOSX_DEPLOYMENT_TARGET -arch x86_64 -dylib \ + -o "$out/lib/lib${children[0]}.dylib" \ + -install_name "$out/lib/lib${children[0]}.dylib" \ + "${childrenLookup[@]}" "$symbolBloatObject" \ + "${childrenLink[@]:0:$((${#childrenLink[@]} / 2 ))}" + + # second half of libs + @binPrefix@ld -macosx_version_min $MACOSX_DEPLOYMENT_TARGET -arch x86_64 -dylib \ + -o "$out/lib/lib${children[1]}.dylib" \ + -install_name "$out/lib/lib${children[1]}.dylib" \ + "${childrenLookup[@]}" "$symbolBloatObject" \ + "${childrenLink[@]:$((${#childrenLink[@]} / 2 ))}" + + allArgs+=("-L$out/lib" "-l${children[0]}" "-l${children[1]}") +fi + +PATH="$path_backup" +exec @prog@ "${allArgs[@]}" diff --git a/pkgs/stdenv/darwin/default.nix b/pkgs/stdenv/darwin/default.nix index cac33a1bebb2..74dcf2f009b3 100644 --- a/pkgs/stdenv/darwin/default.nix +++ b/pkgs/stdenv/darwin/default.nix @@ -305,7 +305,7 @@ in rec { initialPath = import ../common-path.nix { inherit pkgs; }; shell = "${pkgs.bash}/bin/bash"; - cc = import ../../build-support/cc-wrapper { + cc = lib.callPackageWith {} ../../build-support/cc-wrapper { inherit (pkgs) stdenv; inherit shell; nativeTools = false; diff --git a/pkgs/test/macos-sierra-shared/default.nix b/pkgs/test/macos-sierra-shared/default.nix new file mode 100644 index 000000000000..51e8ae53736c --- /dev/null +++ b/pkgs/test/macos-sierra-shared/default.nix @@ -0,0 +1,89 @@ +{ lib, clangStdenv, clang-sierraHack-stdenv, stdenvNoCC }: + +let + makeBigExe = stdenv: prefix: rec { + + count = 500; + + sillyLibs = lib.genList (i: stdenv.mkDerivation rec { + name = "${prefix}-fluff-${toString i}"; + unpackPhase = '' + src=$PWD + cat << 'EOF' > ${name}.c + unsigned int asdf_${toString i}(void) { + return ${toString i}; + } + EOF + ''; + buildPhase = '' + $CC -std=c99 -shared ${name}.c -o lib${name}.dylib -Wl,-install_name,$out/lib/lib${name}.dylib + ''; + installPhase = '' + mkdir -p "$out/lib" + mv lib${name}.dylib "$out/lib" + ''; + meta.platforms = lib.platforms.darwin; + }) count; + + finalExe = stdenv.mkDerivation rec { + name = "${prefix}-final-asdf"; + unpackPhase = '' + src=$PWD + cat << 'EOF' > main.cxx + + #include <cstdlib> + #include <iostream> + + ${toString (lib.genList (i: "extern \"C\" unsigned int asdf_${toString i}(void); ") count)} + + unsigned int (*funs[])(void) = { + ${toString (lib.genList (i: "asdf_${toString i},") count)} + }; + + int main(int argc, char **argv) { + bool ret; + unsigned int i = 0; + for (auto f : funs) { + if (f() != i++) { + std::cerr << "Failed to get expected response from function #" << i << std::endl; + return EXIT_FAILURE; + } + } + return EXIT_SUCCESS; + } + EOF + ''; + buildPhase = '' + $CXX -std=c++11 main.cxx ${toString (map (x: "-l${x.name}") sillyLibs)} -o ${prefix}-asdf + ''; + buildInputs = sillyLibs; + installPhase = '' + mkdir -p "$out/bin" + mv ${prefix}-asdf "$out/bin" + ''; + meta.platforms = lib.platforms.darwin; + }; + + }; + + good = makeBigExe clang-sierraHack-stdenv "good"; + + bad = makeBigExe clangStdenv "bad"; + +in stdenvNoCC.mkDerivation { + name = "macos-sierra-shared-test"; + buildInputs = [ good.finalExe bad.finalExe ]; + # TODO(@Ericson2314): Be impure or require exact MacOS version of builder? + buildCommand = '' + if bad-asdf + then echo "bad-asdf can succeed on non-sierra, OK" >&2 + else echo "bad-asdf should fail on sierra, OK" >&2 + fi + + # Must succeed on all supported MacOS versions + good-asdf + + touch $out + ''; + meta.platforms = lib.platforms.darwin; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index eb59deba7e82..103906a39d05 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -5184,6 +5184,11 @@ with pkgs; clang = llvmPackages.clang; + clang-sierraHack = clang.override { + name = "clang-wrapper-with-reexport-hack"; + useMacosReexportHack = true; + }; + clang_4 = llvmPackages_4.clang; clang_39 = llvmPackages_39.clang; clang_38 = llvmPackages_38.clang; @@ -5211,6 +5216,7 @@ with pkgs; #Use this instead of stdenv to build with clang clangStdenv = if stdenv.isDarwin then stdenv else lowPrio llvmPackages.stdenv; + clang-sierraHack-stdenv = overrideCC stdenv clang-sierraHack; libcxxStdenv = lowPrio llvmPackages.libcxxStdenv; clean = callPackage ../development/compilers/clean { }; @@ -19254,4 +19260,9 @@ with pkgs; houdini = callPackage ../applications/misc/houdini {}; xtermcontrol = callPackage ../applications/misc/xtermcontrol {}; + + # No `recurseIntoAttrs` because there's no need to nix-env these. + tests = { + macOSSierraShared = callPackage ../test/macos-sierra-shared {}; + }; } diff --git a/pkgs/top-level/release.nix b/pkgs/top-level/release.nix index be57b40fca64..0c7c67a0d03b 100644 --- a/pkgs/top-level/release.nix +++ b/pkgs/top-level/release.nix @@ -42,6 +42,7 @@ let jobs.python.x86_64-darwin jobs.rustc.x86_64-darwin jobs.go.x86_64-darwin + jobs.tests.macOSSierraShared ]; }; |