Merge pull request #38881 from obsidiansystems/sierra-hack

cc-wrapper: More intelligent sierra hack

authored by John Ericson and committed by GitHub 800cb8ae 5d9bd57c

+232 -83
+216 -78
pkgs/build-support/bintools-wrapper/macos-sierra-reexport-hack.bash
··· 2 3 set -eu -o pipefail 4 5 path_backup="$PATH" 6 if [ -n "@coreutils_bin@" ]; then 7 PATH="@coreutils_bin@/bin" 8 fi 9 10 - declare -r recurThreshold=300 11 12 - declare overflowCount=0 13 - for ((n=0; n < $#; ++n)); do 14 - case "${!n}" in 15 - -l*) let overflowCount+=1 ;; 16 - -reexport-l*) let overflowCount+=1 ;; 17 - *) ;; 18 esac 19 done 20 21 - declare -a allArgs=() 22 23 if (( "$overflowCount" <= "$recurThreshold" )); then 24 - allArgs=("$@") 25 - else 26 - declare -a childrenLookup=() childrenLink=() 27 28 - while (( $# )); do 29 - case "$1" in 30 - -L/*) 31 - childrenLookup+=("$1") 32 - allArgs+=("$1") 33 - ;; 34 - -L) 35 - echo "cctools LD does not support '-L foo' or '-l foo'" >&2 36 - exit 1 37 - ;; 38 - -l) 39 - echo "cctools LD does not support '-L foo' or '-l foo'" >&2 40 - exit 1 41 - ;; 42 - -lazy_library | -lazy_framework | -lto_library) 43 - # We aren't linking any "azy_library", "to_library", etc. 44 - allArgs+=("$1") 45 - ;; 46 - -lazy-l | -weak-l) allArgs+=("$1") ;; 47 - # We can't so easily prevent header issues from these. 48 - -lSystem) allArgs+=("$1") ;; 49 - # Special case as indirection seems like a bad idea for something 50 - # so fundamental. Can be removed for simplicity. 51 - -l?* | -reexport-l?*) childrenLink+=("$1") ;; 52 - *) allArgs+=("$1") ;; 53 - esac 54 55 - shift 56 - done 57 58 - declare n=0 59 - while (( $n < "${#childrenLink[@]}" )); do 60 - if [[ "${childrenLink[n]}" = -l* ]]; then 61 - childrenLink[n]="-reexport${childrenLink[n]}" 62 - fi 63 - let ++n 64 done 65 - unset n 66 67 - declare -r outputNameLibless=$(basename $( \ 68 - if [[ -z "${outputName:+isUndefined}" ]]; then 69 - echo unnamed 70 - elif [[ "${outputName:0:3}" = lib ]]; then 71 - echo "${outputName:3}" 72 - else 73 - echo "${outputName}" 74 - fi)) 75 - declare -ra children=("$outputNameLibless-reexport-delegate-0" \ 76 - "$outputNameLibless-reexport-delegate-1") 77 78 - mkdir -p "$out/lib" 79 80 - PATH="$PATH:@out@/bin" 81 82 - symbolBloatObject=$outputNameLibless-symbol-hack.o 83 - if [[ ! -e $symbolBloatObject ]]; then 84 - # `-Q` means use GNU Assembler rather than Clang, avoiding an awkward 85 - # dependency cycle. 86 - printf '.private_extern _______child_hack_foo\nchild_hack_foo:\n' \ 87 - | @targetPrefix@as -Q -- -o $symbolBloatObject 88 fi 89 90 - # first half of libs 91 - @targetPrefix@ld -macosx_version_min $MACOSX_DEPLOYMENT_TARGET -arch x86_64 -dylib \ 92 - -o "$out/lib/lib${children[0]}.dylib" \ 93 - -install_name "$out/lib/lib${children[0]}.dylib" \ 94 - "${childrenLookup[@]}" "$symbolBloatObject" \ 95 - "${childrenLink[@]:0:$((${#childrenLink[@]} / 2 ))}" 96 97 - # second half of libs 98 - @targetPrefix@ld -macosx_version_min $MACOSX_DEPLOYMENT_TARGET -arch x86_64 -dylib \ 99 - -o "$out/lib/lib${children[1]}.dylib" \ 100 - -install_name "$out/lib/lib${children[1]}.dylib" \ 101 - "${childrenLookup[@]}" "$symbolBloatObject" \ 102 - "${childrenLink[@]:$((${#childrenLink[@]} / 2 ))}" 103 104 - allArgs+=("-L$out/lib" "-l${children[0]}" "-l${children[1]}") 105 fi 106 107 PATH="$path_backup" 108 - exec @prog@ "${allArgs[@]}"
··· 2 3 set -eu -o pipefail 4 5 + # For cmd | while read; do ...; done 6 + shopt -s lastpipe 7 + 8 path_backup="$PATH" 9 if [ -n "@coreutils_bin@" ]; then 10 PATH="@coreutils_bin@/bin" 11 fi 12 13 + declare -ri recurThreshold=200 14 + declare -i overflowCount=0 15 + 16 + declare -ar origArgs=("$@") 17 + 18 + # Throw away what we won't need 19 + declare -a parentArgs=() 20 21 + while (( $# )); do 22 + case "$1" in 23 + -l) 24 + echo "cctools LD does not support '-l foo'" >&2 25 + exit 1 26 + ;; 27 + -lazy_library | -reexport_library | -upward_library | -weak_library) 28 + overflowCount+=1 29 + shift 2 30 + ;; 31 + -l* | *.so.* | *.dylib | -lazy-l* | -reexport-l* | -upward-l* | -weak-l*) 32 + overflowCount+=1 33 + shift 1 34 + ;; 35 + *.a | *.o) 36 + shift 1 37 + ;; 38 + -L | -F) 39 + # Evidentally ld doesn't like using the child's RPATH, so it still 40 + # needs these. 41 + parentArgs+=("$1" "$2") 42 + shift 2 43 + ;; 44 + -L?* | -F?*) 45 + parentArgs+=("$1") 46 + shift 1 47 + ;; 48 + -o) 49 + outputName="$2" 50 + parentArgs+=("$1" "$2") 51 + shift 2 52 + ;; 53 + -install_name | -dylib_install_name | -dynamic-linker | -plugin) 54 + parentArgs+=("$1" "$2") 55 + shift 2 56 + ;; 57 + -rpath) 58 + # Only an rpath to the child is needed, which we will add 59 + shift 2 60 + ;; 61 + *) 62 + if [[ -f "$1" ]]; then 63 + # Propabably a non-standard object file like Haskell's 64 + # `.dyn_o`. Skip it like other inputs 65 + : 66 + else 67 + parentArgs+=("$1") 68 + fi 69 + shift 1 70 + ;; 71 esac 72 done 73 74 + 75 76 if (( "$overflowCount" <= "$recurThreshold" )); then 77 + if [ -n "${NIX_DEBUG:-}" ]; then 78 + echo "ld-wrapper: Only ${overflowCount} inputs counted while ${recurThreshold} is the ceiling, linking normally. " >&2 79 + fi 80 + PATH="$path_backup" 81 + exec @prog@ "${origArgs[@]}" 82 + fi 83 84 + 85 + 86 + if [ -n "${NIX_DEBUG:-}" ]; then 87 + echo "ld-wrapper: ${overflowCount} inputs counted when ${recurThreshold} is the ceiling, inspecting further. " >&2 88 + fi 89 90 + # Collect the normalized linker input 91 + declare -a norm=() 92 93 + # Arguments are null-separated 94 + @prog@ --dump-normalized-lib-args "${origArgs[@]}" | 95 + while IFS= read -r -d '' input; do 96 + norm+=("$input") 97 done 98 99 + declare -i leafCount=0 100 + declare lastLeaf='' 101 + declare -a childrenInputs=() trailingInputs=() 102 + while (( "${#norm[@]}" )); do 103 + case "${norm[0]}" in 104 + -lazy_library | -upward_library) 105 + # TODO(@Ericson2314): Don't do that, but intersperse children 106 + # between such args. 107 + echo "ld-wrapper: Warning: Potentially changing link order" >&2 108 + trailingInputs+=("${norm[0]}" "${norm[1]}") 109 + norm=("${norm[@]:2}") 110 + ;; 111 + -reexport_library | -weak_library) 112 + childrenInputs+=("${norm[0]}" "${norm[1]}") 113 + if [[ "${norm[1]}" != "$lastLeaf" ]]; then 114 + leafCount+=1 115 + lastLeaf="${norm[1]}" 116 + fi 117 + norm=("${norm[@]:2}") 118 + ;; 119 + *.so | *.dylib) 120 + childrenInputs+=(-reexport_library "${norm[0]}") 121 + if [[ "${norm[0]}" != "$lastLeaf" ]]; then 122 + leafCount+=1 123 + lastLeaf="${norm[0]}" 124 + fi 125 + norm=("${norm[@]:1}") 126 + ;; 127 + *.o | *.a) 128 + # Don't delegate object files or static libs 129 + parentArgs+=("${norm[0]}") 130 + norm=("${norm[@]:1}") 131 + ;; 132 + *) 133 + if [[ -f "${norm[0]}" ]]; then 134 + # Propabably a non-standard object file. We'll let it by. 135 + parentArgs+=("${norm[0]}") 136 + norm=("${norm[@]:1}") 137 + else 138 + echo "ld-wrapper: Internal Error: Invalid normalized argument" >&2 139 + exit -1 140 + fi 141 + ;; 142 + esac 143 + done 144 145 146 147 + if (( "$leafCount" <= "$recurThreshold" )); then 148 + if [ -n "${NIX_DEBUG:-}" ]; then 149 + echo "ld-wrapper: Only ${leafCount} *dynamic* inputs counted while ${recurThreshold} is the ceiling, linking normally. " >&2 150 + fi 151 + PATH="$path_backup" 152 + exec @prog@ "${origArgs[@]}" 153 + fi 154 + 155 + 156 + 157 + if [ -n "${NIX_DEBUG:-}" ]; then 158 + echo "ld-wrapper: ${leafCount} *dynamic* inputs counted when ${recurThreshold} is the ceiling, delegating to children. " >&2 159 + fi 160 + 161 + declare -r outputNameLibless=$( \ 162 + if [[ -z "${outputName:+isUndefined}" ]]; then 163 + echo unnamed 164 + return 0; 165 + fi 166 + baseName=$(basename ${outputName}) 167 + if [[ "$baseName" = lib* ]]; then 168 + baseName="${baseName:3}" 169 fi 170 + echo "$baseName") 171 172 + declare -ra children=( 173 + "$outputNameLibless-reexport-delegate-0" 174 + "$outputNameLibless-reexport-delegate-1" 175 + ) 176 + 177 + mkdir -p "$out/lib" 178 + 179 + symbolBloatObject=$outputNameLibless-symbol-hack.o 180 + if [[ ! -f $symbolBloatObject ]]; then 181 + # `-Q` means use GNU Assembler rather than Clang, avoiding an awkward 182 + # dependency cycle. 183 + printf '.private_extern _______child_hack_foo\nchild_hack_foo:\n' | 184 + PATH="$PATH:@out@/bin" @targetPrefix@as -Q -- -o $symbolBloatObject 185 + fi 186 + 187 + # Split inputs between children 188 + declare -a child0Inputs=() child1Inputs=("${childrenInputs[@]}") 189 + let "countFirstChild = $leafCount / 2" || true 190 + lastLeaf='' 191 + while (( "$countFirstChild" )); do 192 + case "${child1Inputs[0]}" in 193 + -reexport_library | -weak_library) 194 + child0Inputs+=("${child1Inputs[0]}" "${child1Inputs[1]}") 195 + if [[ "${child1Inputs[1]}" != "$lastLeaf" ]]; then 196 + let countFirstChild-=1 || true 197 + lastLeaf="${child1Inputs[1]}" 198 + fi 199 + child1Inputs=("${child1Inputs[@]:2}") 200 + ;; 201 + *.so | *.dylib) 202 + child0Inputs+=(-reexport_library "${child1Inputs[0]}") 203 + if [[ "${child1Inputs[0]}" != "$lastLeaf" ]]; then 204 + let countFirstChild-=1 || true 205 + lastLeaf="${child1Inputs[1]}" 206 + fi 207 + child1Inputs=("${child1Inputs[@]:2}") 208 + ;; 209 + *) 210 + echo "ld-wrapper: Internal Error: Invalid delegated input" >&2 211 + exit -1 212 + ;; 213 + esac 214 + done 215 + 216 + 217 + # First half of libs 218 + @out@/bin/@targetPrefix@ld \ 219 + -macosx_version_min $MACOSX_DEPLOYMENT_TARGET -arch x86_64 -dylib \ 220 + -o "$out/lib/lib${children[0]}.dylib" \ 221 + -install_name "$out/lib/lib${children[0]}.dylib" \ 222 + "$symbolBloatObject" "${child0Inputs[@]}" "${trailingInputs[@]}" 223 224 + # Second half of libs 225 + @out@/bin/@targetPrefix@ld \ 226 + -macosx_version_min $MACOSX_DEPLOYMENT_TARGET -arch x86_64 -dylib \ 227 + -o "$out/lib/lib${children[1]}.dylib" \ 228 + -install_name "$out/lib/lib${children[1]}.dylib" \ 229 + "$symbolBloatObject" "${child1Inputs[@]}" "${trailingInputs[@]}" 230 231 + parentArgs+=("-L$out/lib" -rpath "$out/lib") 232 + if [[ $outputName != *reexport-delegate* ]]; then 233 + parentArgs+=("-l${children[0]}" "-l${children[1]}") 234 + else 235 + parentArgs+=("-reexport-l${children[0]}" "-reexport-l${children[1]}") 236 + fi 237 + 238 + parentArgs+=("${trailingInputs[@]}") 239 + 240 + if [ -n "${NIX_DEBUG:-}" ]; then 241 + echo "flags using delegated children to @prog@:" >&2 242 + printf " %q\n" "${parentArgs[@]}" >&2 243 fi 244 245 PATH="$path_backup" 246 + exec @prog@ "${parentArgs[@]}"
+10 -4
pkgs/os-specific/darwin/cctools/port.nix
··· 2 , llvm, libcxx, libcxxabi, clang, libuuid 3 , libobjc ? null, maloader ? null, xctoolchain ? null 4 , hostPlatform, targetPlatform 5 }: 6 7 let ··· 12 "${targetPlatform.config}-"; 13 in 14 15 - assert targetPlatform.isDarwin; 16 - 17 # Non-Darwin alternatives 18 assert (!hostPlatform.isDarwin) -> (maloader != null && xctoolchain != null); 19 ··· 22 name = "${targetPrefix}cctools-port-${version}"; 23 version = "895"; 24 25 - src = fetchFromGitHub { 26 owner = "tpoechtrager"; 27 repo = "cctools-port"; 28 rev = "2e569d765440b8cd6414a695637617521aa2375b"; # From branch 895-ld64-274.2 29 sha256 = "0l45mvyags56jfi24rawms8j2ihbc45mq7v13pkrrwppghqrdn52"; 30 - }; 31 32 outputs = [ "out" "dev" ]; 33 ··· 117 }; 118 119 meta = { 120 homepage = http://www.opensource.apple.com/source/cctools/; 121 description = "MacOS Compiler Tools (cross-platform port)"; 122 license = stdenv.lib.licenses.apsl20;
··· 2 , llvm, libcxx, libcxxabi, clang, libuuid 3 , libobjc ? null, maloader ? null, xctoolchain ? null 4 , hostPlatform, targetPlatform 5 + , enableDumpNormalizedLibArgs ? false 6 }: 7 8 let ··· 13 "${targetPlatform.config}-"; 14 in 15 16 # Non-Darwin alternatives 17 assert (!hostPlatform.isDarwin) -> (maloader != null && xctoolchain != null); 18 ··· 21 name = "${targetPrefix}cctools-port-${version}"; 22 version = "895"; 23 24 + src = fetchFromGitHub (if enableDumpNormalizedLibArgs then { 25 + owner = "tpoechtrager"; 26 + repo = "cctools-port"; 27 + # master with https://github.com/tpoechtrager/cctools-port/pull/34 28 + rev = "8395d4b2c3350356e2fb02f5e04f4f463c7388df"; 29 + sha256 = "10vbf1cfzx02q8chc77s84fp2kydjpx2y682mr6mrbb7sq5rwh8f"; 30 + } else { 31 owner = "tpoechtrager"; 32 repo = "cctools-port"; 33 rev = "2e569d765440b8cd6414a695637617521aa2375b"; # From branch 895-ld64-274.2 34 sha256 = "0l45mvyags56jfi24rawms8j2ihbc45mq7v13pkrrwppghqrdn52"; 35 + }); 36 37 outputs = [ "out" "dev" ]; 38 ··· 122 }; 123 124 meta = { 125 + broken = !targetPlatform.isDarwin; # Only supports darwin targets 126 homepage = http://www.opensource.apple.com/source/cctools/; 127 description = "MacOS Compiler Tools (cross-platform port)"; 128 license = stdenv.lib.licenses.apsl20;
+6 -1
pkgs/top-level/all-packages.nix
··· 5916 5917 clang-sierraHack = clang.override { 5918 name = "clang-wrapper-with-reexport-hack"; 5919 - bintools = clang.bintools.override { 5920 useMacosReexportHack = true; 5921 }; 5922 }; 5923
··· 5916 5917 clang-sierraHack = clang.override { 5918 name = "clang-wrapper-with-reexport-hack"; 5919 + bintools = darwin.binutils.override { 5920 useMacosReexportHack = true; 5921 + bintools = darwin.binutils.bintools.override { 5922 + cctools = darwin.cctools.override { 5923 + enableDumpNormalizedLibArgs = true; 5924 + }; 5925 + }; 5926 }; 5927 }; 5928