at master 9.9 kB view raw
1#! @shell@ 2# NOTE: This wrapper is derived from cc-wrapper.sh, and is hopefully somewhat 3# diffable with the original, so changes can be merged if necessary. 4set -eu -o pipefail +o posix 5shopt -s nullglob 6 7if (( "${NIX_DEBUG:-0}" >= 7 )); then 8 set -x 9fi 10 11cc_wrapper="@cc_wrapper@" 12 13source $cc_wrapper/nix-support/utils.bash 14 15source $cc_wrapper/nix-support/darwin-sdk-setup.bash 16 17expandResponseParams "$@" 18 19# Check if we should wrap this Swift invocation at all, and how. Specifically, 20# there are some internal tools we don't wrap, plus swift-frontend doesn't link 21# and doesn't understand linker flags. This follows logic in 22# `lib/DriverTool/driver.cpp`. 23prog=@prog@ 24progName="$(basename "$prog")" 25firstArg="${params[0]:-}" 26isFrontend=0 27isRepl=0 28 29# These checks follow `shouldRunAsSubcommand`. 30if [[ "$progName" == swift ]]; then 31 case "$firstArg" in 32 "" | -* | *.* | */* | repl) 33 ;; 34 *) 35 exec "swift-$firstArg" "${params[@]:1}" 36 ;; 37 esac 38fi 39 40# These checks follow the first part of `run_driver`. 41# 42# NOTE: The original function short-circuits, but we can't here, because both 43# paths must be wrapped. So we use an 'isFrontend' flag instead. 44case "$firstArg" in 45 -frontend) 46 isFrontend=1 47 # Ensure this stays the first argument. 48 params=( "${params[@]:1}" ) 49 extraBefore+=( "-frontend" ) 50 ;; 51 -modulewrap) 52 # Don't wrap this integrated tool. 53 exec "$prog" "${params[@]}" 54 ;; 55 repl) 56 isRepl=1 57 params=( "${params[@]:1}" ) 58 ;; 59 --driver-mode=*) 60 ;; 61 *) 62 if [[ "$progName" == swift-frontend ]]; then 63 isFrontend=1 64 fi 65 ;; 66esac 67 68# For many tasks, Swift reinvokes swift-driver, the new driver implementation 69# written in Swift. It needs some help finding the executable, though, and 70# reimplementing the logic here is little effort. These checks follow 71# `shouldDisallowNewDriver`. 72if [[ 73 $isFrontend = 0 && 74 -n "@swiftDriver@" && 75 -z "${SWIFT_USE_OLD_DRIVER:-}" && 76 ( "$progName" == "swift" || "$progName" == "swiftc" ) 77]]; then 78 prog=@swiftDriver@ 79 # Driver mode must be the very first argument. 80 extraBefore+=( "--driver-mode=$progName" ) 81 if [[ $isRepl = 1 ]]; then 82 extraBefore+=( "-repl" ) 83 fi 84 85 # Ensure swift-driver invokes the unwrapped frontend (instead of finding 86 # the wrapped one via PATH), because we don't have to wrap a second time. 87 export SWIFT_DRIVER_SWIFT_FRONTEND_EXEC="@swift@/bin/swift-frontend" 88 89 # Ensure swift-driver can find the LLDB with Swift support for the REPL. 90 export SWIFT_DRIVER_LLDB_EXEC="@swift@/bin/lldb" 91fi 92 93path_backup="$PATH" 94 95# That @-vars are substituted separately from bash evaluation makes 96# shellcheck think this, and others like it, are useless conditionals. 97# shellcheck disable=SC2157 98if [[ -n "@coreutils_bin@" && -n "@gnugrep_bin@" ]]; then 99 PATH="@coreutils_bin@/bin:@gnugrep_bin@/bin" 100fi 101 102# Parse command line options and set several variables. 103# For instance, figure out if linker flags should be passed. 104# GCC prints annoying warnings when they are not needed. 105isCxx=0 106dontLink=$isFrontend 107 108for p in "${params[@]}"; do 109 case "$p" in 110 -enable-cxx-interop | -enable-experimental-cxx-interop) 111 isCxx=1 ;; 112 esac 113done 114 115# NOTE: We don't modify these for Swift, but sourced scripts may use them. 116cxxInclude=1 117cxxLibrary=1 118cInclude=1 119 120linkType=$(checkLinkType "${params[@]}") 121 122# Optionally filter out paths not refering to the store. 123if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "$NIX_STORE" ]]; then 124 kept=() 125 nParams=${#params[@]} 126 declare -i n=0 127 while (( "$n" < "$nParams" )); do 128 p=${params[n]} 129 p2=${params[n+1]:-} # handle `p` being last one 130 n+=1 131 132 skipNext=false 133 path="" 134 case "$p" in 135 -[IL]/*) path=${p:2} ;; 136 -[IL]) path=$p2 skipNext=true ;; 137 esac 138 139 if [[ -n $path ]] && badPath "$path"; then 140 skip "$path" 141 $skipNext && n+=1 142 continue 143 fi 144 145 kept+=("$p") 146 done 147 # Old bash empty array hack 148 params=(${kept+"${kept[@]}"}) 149fi 150 151# Flirting with a layer violation here. 152if [ -z "${NIX_BINTOOLS_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then 153 source @bintools@/nix-support/add-flags.sh 154fi 155 156# Put this one second so libc ldflags take priority. 157if [ -z "${NIX_CC_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then 158 source $cc_wrapper/nix-support/add-flags.sh 159fi 160 161# Only add darwin min version flag and set up `DEVELOPER_DIR` if a default darwin min version is set, 162# which is a signal that we're targeting darwin. (Copied from add-flags in libc but tailored for Swift). 163if [ "@darwinMinVersion@" ]; then 164 # Make sure the wrapped Swift compiler can find the overlays in the SDK. 165 NIX_SWIFTFLAGS_COMPILE+=" -I $SDKROOT/usr/lib/swift" 166 NIX_LDFLAGS_@suffixSalt@+=" -L $SDKROOT/usr/lib/swift" 167fi 168 169if [[ "$isCxx" = 1 ]]; then 170 if [[ "$cxxInclude" = 1 ]]; then 171 NIX_CFLAGS_COMPILE_@suffixSalt@+=" $NIX_CXXSTDLIB_COMPILE_@suffixSalt@" 172 fi 173 if [[ "$cxxLibrary" = 1 ]]; then 174 NIX_CFLAGS_LINK_@suffixSalt@+=" $NIX_CXXSTDLIB_LINK_@suffixSalt@" 175 fi 176fi 177 178source $cc_wrapper/nix-support/add-hardening.sh 179 180# Add the flags for the C compiler proper. 181addCFlagsToList() { 182 declare -n list="$1" 183 shift 184 185 for ((i = 1; i <= $#; i++)); do 186 local val="${!i}" 187 case "$val" in 188 # Pass through using -Xcc, but also convert to Swift -I. 189 # These have slightly different meaning for Clang, but Swift 190 # doesn't have exact equivalents. 191 -isystem | -idirafter) 192 i=$((i + 1)) 193 list+=("-Xcc" "$val" "-Xcc" "${!i}" "-I" "${!i}") 194 ;; 195 # Simple rename. 196 -iframework) 197 i=$((i + 1)) 198 list+=("-Fsystem" "${!i}") 199 ;; 200 # Pass through verbatim. 201 -I | -Fsystem) 202 i=$((i + 1)) 203 list+=("${val}" "${!i}") 204 ;; 205 -I* | -L* | -F*) 206 list+=("${val}") 207 ;; 208 # Pass through using -Xcc. 209 *) 210 list+=("-Xcc" "$val") 211 ;; 212 esac 213 done 214} 215for i in ${NIX_SWIFTFLAGS_COMPILE:-}; do 216 extraAfter+=("$i") 217done 218for i in ${NIX_SWIFTFLAGS_COMPILE_BEFORE:-}; do 219 extraBefore+=("$i") 220done 221addCFlagsToList extraAfter $NIX_CFLAGS_COMPILE_@suffixSalt@ 222addCFlagsToList extraBefore ${hardeningCFlags[@]+"${hardeningCFlags[@]}"} $NIX_CFLAGS_COMPILE_BEFORE_@suffixSalt@ 223 224if [ "$dontLink" != 1 ]; then 225 226 # Add the flags that should only be passed to the compiler when 227 # linking. 228 addCFlagsToList extraAfter $(filterRpathFlags "$linkType" $NIX_CFLAGS_LINK_@suffixSalt@) 229 230 # Add the flags that should be passed to the linker (and prevent 231 # `ld-wrapper' from adding NIX_LDFLAGS_@suffixSalt@ again). 232 for i in $(filterRpathFlags "$linkType" $NIX_LDFLAGS_BEFORE_@suffixSalt@); do 233 extraBefore+=("-Xlinker" "$i") 234 done 235 if [[ "$linkType" == dynamic && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; then 236 extraBefore+=("-Xlinker" "-dynamic-linker=$NIX_DYNAMIC_LINKER_@suffixSalt@") 237 fi 238 for i in $(filterRpathFlags "$linkType" $NIX_LDFLAGS_@suffixSalt@); do 239 if [ "${i:0:3}" = -L/ ]; then 240 extraAfter+=("$i") 241 else 242 extraAfter+=("-Xlinker" "$i") 243 fi 244 done 245 export NIX_LINK_TYPE_@suffixSalt@=$linkType 246fi 247 248# TODO: If we ever need to expand functionality of this hook, it may no longer 249# be compatible with Swift. Right now, it is only used on Darwin to force 250# -target, which also happens to work with Swift. 251if [[ -e $cc_wrapper/nix-support/add-local-cc-cflags-before.sh ]]; then 252 source $cc_wrapper/nix-support/add-local-cc-cflags-before.sh 253fi 254 255for ((i=0; i < ${#extraBefore[@]}; i++));do 256 case "${extraBefore[i]}" in 257 -target) 258 i=$((i + 1)) 259 # On Darwin only, need to change 'aarch64' to 'arm64'. 260 extraBefore[i]="${extraBefore[i]/aarch64-apple-/arm64-apple-}" 261 # On Darwin, Swift requires the triple to be annotated with a version. 262 # TODO: Assumes macOS. 263 extraBefore[i]="${extraBefore[i]/-apple-darwin/-apple-macosx${MACOSX_DEPLOYMENT_TARGET:-11.0}}" 264 ;; 265 -march=*|-mcpu=*|-mfloat-abi=*|-mfpu=*|-mmode=*|-mthumb|-marm|-mtune=*) 266 [[ i -gt 0 && ${extraBefore[i-1]} == -Xcc ]] && continue 267 extraBefore=( 268 "${extraBefore[@]:0:i}" 269 -Xcc 270 "${extraBefore[@]:i:${#extraBefore[@]}}" 271 ) 272 i=$((i + 1)) 273 ;; 274 esac 275done 276 277# As a very special hack, if the arguments are just `-v', then don't 278# add anything. This is to prevent `gcc -v' (which normally prints 279# out the version number and returns exit code 0) from printing out 280# `No input files specified' and returning exit code 1. 281if [ "$*" = -v ]; then 282 extraAfter=() 283 extraBefore=() 284fi 285 286# Optionally print debug info. 287if (( "${NIX_DEBUG:-0}" >= 1 )); then 288 # Old bash workaround, see ld-wrapper for explanation. 289 echo "extra flags before to $prog:" >&2 290 printf " %q\n" ${extraBefore+"${extraBefore[@]}"} >&2 291 echo "original flags to $prog:" >&2 292 printf " %q\n" ${params+"${params[@]}"} >&2 293 echo "extra flags after to $prog:" >&2 294 printf " %q\n" ${extraAfter+"${extraAfter[@]}"} >&2 295fi 296 297PATH="$path_backup" 298# Old bash workaround, see above. 299 300if (( "${NIX_CC_USE_RESPONSE_FILE:-@use_response_file_by_default@}" >= 1 )); then 301 exec "$prog" @<(printf "%q\n" \ 302 ${extraBefore+"${extraBefore[@]}"} \ 303 ${params+"${params[@]}"} \ 304 ${extraAfter+"${extraAfter[@]}"}) 305else 306 exec "$prog" \ 307 ${extraBefore+"${extraBefore[@]}"} \ 308 ${params+"${params[@]}"} \ 309 ${extraAfter+"${extraAfter[@]}"} 310fi