Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at netboot-syslinux-multiplatform 400 lines 14 kB view raw
1# The Nixpkgs CC is not directly usable, since it doesn't know where 2# the C library and standard header files are. Therefore the compiler 3# produced by that package cannot be installed directly in a user 4# environment and used from the command line. So we use a wrapper 5# script that sets up the right environment variables so that the 6# compiler and the linker just "work". 7 8{ name ? "" 9, lib 10, stdenvNoCC 11, bintools ? null, libc ? null, coreutils ? null, shell ? stdenvNoCC.shell, gnugrep ? null 12, netbsd ? null, netbsdCross ? null 13, sharedLibraryLoader ? 14 if libc == null then 15 null 16 else if stdenvNoCC.targetPlatform.isNetBSD then 17 if !(targetPackages ? netbsdCross) then 18 netbsd.ld_elf_so 19 else if libc != targetPackages.netbsdCross.headers then 20 targetPackages.netbsdCross.ld_elf_so 21 else 22 null 23 else 24 lib.getLib libc 25, nativeTools, noLibc ? false, nativeLibc, nativePrefix ? "" 26, propagateDoc ? bintools != null && bintools ? man 27, extraPackages ? [], extraBuildCommands ? "" 28, isGNU ? bintools.isGNU or false 29, isLLVM ? bintools.isLLVM or false 30, isCCTools ? bintools.isCCTools or false 31, buildPackages ? {} 32, targetPackages ? {} 33, useMacosReexportHack ? false 34, wrapGas ? false 35 36# Darwin code signing support utilities 37, postLinkSignHook ? null, signingUtils ? null 38}: 39 40with lib; 41 42assert nativeTools -> !propagateDoc && nativePrefix != ""; 43assert !nativeTools -> 44 bintools != null && coreutils != null && gnugrep != null; 45assert !(nativeLibc && noLibc); 46assert (noLibc || nativeLibc) == (libc == null); 47 48let 49 stdenv = stdenvNoCC; 50 inherit (stdenv) hostPlatform targetPlatform; 51 52 # Prefix for binaries. Customarily ends with a dash separator. 53 # 54 # TODO(@Ericson2314) Make unconditional, or optional but always true by 55 # default. 56 targetPrefix = lib.optionalString (targetPlatform != hostPlatform) 57 (targetPlatform.config + "-"); 58 59 bintoolsVersion = lib.getVersion bintools; 60 bintoolsName = lib.removePrefix targetPrefix (lib.getName bintools); 61 62 libc_bin = if libc == null then "" else getBin libc; 63 libc_dev = if libc == null then "" else getDev libc; 64 libc_lib = if libc == null then "" else getLib libc; 65 bintools_bin = if nativeTools then "" else getBin bintools; 66 # The wrapper scripts use 'cat' and 'grep', so we may need coreutils. 67 coreutils_bin = if nativeTools then "" else getBin coreutils; 68 69 # See description in cc-wrapper. 70 suffixSalt = replaceStrings ["-" "."] ["_" "_"] targetPlatform.config; 71 72 # The dynamic linker has different names on different platforms. This is a 73 # shell glob that ought to match it. 74 dynamicLinker = 75 /**/ if sharedLibraryLoader == null then "" 76 else if targetPlatform.libc == "musl" then "${sharedLibraryLoader}/lib/ld-musl-*" 77 else if targetPlatform.libc == "uclibc" then "${sharedLibraryLoader}/lib/ld*-uClibc.so.1" 78 else if (targetPlatform.libc == "bionic" && targetPlatform.is32bit) then "/system/bin/linker" 79 else if (targetPlatform.libc == "bionic" && targetPlatform.is64bit) then "/system/bin/linker64" 80 else if targetPlatform.libc == "nblibc" then "${sharedLibraryLoader}/libexec/ld.elf_so" 81 else if targetPlatform.system == "i686-linux" then "${sharedLibraryLoader}/lib/ld-linux.so.2" 82 else if targetPlatform.system == "x86_64-linux" then "${sharedLibraryLoader}/lib/ld-linux-x86-64.so.2" 83 else if targetPlatform.system == "powerpc64le-linux" then "${sharedLibraryLoader}/lib/ld64.so.2" 84 # ARM with a wildcard, which can be "" or "-armhf". 85 else if (with targetPlatform; isAarch32 && isLinux) then "${sharedLibraryLoader}/lib/ld-linux*.so.3" 86 else if targetPlatform.system == "aarch64-linux" then "${sharedLibraryLoader}/lib/ld-linux-aarch64.so.1" 87 else if targetPlatform.system == "powerpc-linux" then "${sharedLibraryLoader}/lib/ld.so.1" 88 else if targetPlatform.isMips then "${sharedLibraryLoader}/lib/ld.so.1" 89 # `ld-linux-riscv{32,64}-<abi>.so.1` 90 else if targetPlatform.isRiscV then "${sharedLibraryLoader}/lib/ld-linux-riscv*.so.1" 91 else if targetPlatform.isLoongArch64 then "${sharedLibraryLoader}/lib/ld-linux-loongarch*.so.1" 92 else if targetPlatform.isDarwin then "/usr/lib/dyld" 93 else if targetPlatform.isFreeBSD then "/libexec/ld-elf.so.1" 94 else if lib.hasSuffix "pc-gnu" targetPlatform.config then "ld.so.1" 95 else ""; 96 97 expand-response-params = 98 lib.optionalString (buildPackages ? stdenv && buildPackages.stdenv.hasCC && buildPackages.stdenv.cc != "/dev/null") 99 (import ../expand-response-params { inherit (buildPackages) stdenv; }); 100 101in 102 103stdenv.mkDerivation { 104 pname = targetPrefix 105 + (if name != "" then name else "${bintoolsName}-wrapper"); 106 version = if bintools == null then "" else bintoolsVersion; 107 108 preferLocalBuild = true; 109 110 outputs = [ "out" ] ++ optionals propagateDoc ([ "man" ] ++ optional (bintools ? info) "info"); 111 112 passthru = { 113 inherit targetPrefix suffixSalt; 114 inherit bintools libc nativeTools nativeLibc nativePrefix isGNU isLLVM; 115 116 emacsBufferSetup = pkgs: '' 117 ; We should handle propagation here too 118 (mapc 119 (lambda (arg) 120 (when (file-directory-p (concat arg "/lib")) 121 (setenv "NIX_LDFLAGS_${suffixSalt}" (concat (getenv "NIX_LDFLAGS_${suffixSalt}") " -L" arg "/lib"))) 122 (when (file-directory-p (concat arg "/lib64")) 123 (setenv "NIX_LDFLAGS_${suffixSalt}" (concat (getenv "NIX_LDFLAGS_${suffixSalt}") " -L" arg "/lib64")))) 124 '(${concatStringsSep " " (map (pkg: "\"${pkg}\"") pkgs)})) 125 ''; 126 }; 127 128 dontBuild = true; 129 dontConfigure = true; 130 131 enableParallelBuilding = true; 132 133 unpackPhase = '' 134 src=$PWD 135 ''; 136 137 installPhase = 138 '' 139 mkdir -p $out/bin $out/nix-support 140 141 wrap() { 142 local dst="$1" 143 local wrapper="$2" 144 export prog="$3" 145 export use_response_file_by_default=${if isCCTools then "1" else "0"} 146 substituteAll "$wrapper" "$out/bin/$dst" 147 chmod +x "$out/bin/$dst" 148 } 149 '' 150 151 + (if nativeTools then '' 152 echo ${nativePrefix} > $out/nix-support/orig-bintools 153 154 ldPath="${nativePrefix}/bin" 155 '' else '' 156 echo $bintools_bin > $out/nix-support/orig-bintools 157 158 ldPath="${bintools_bin}/bin" 159 '' 160 161 # Solaris needs an additional ld wrapper. 162 + optionalString (targetPlatform.isSunOS && nativePrefix != "") '' 163 ldPath="${nativePrefix}/bin" 164 exec="$ldPath/${targetPrefix}ld" 165 wrap ld-solaris ${./ld-solaris-wrapper.sh} 166 '') 167 168 # If we are asked to wrap `gas` and this bintools has it, 169 # then symlink it (`as` will be symlinked next). 170 # This is mainly for the wrapped gnat-bootstrap on x86-64 Darwin, 171 # as it must have both the GNU assembler from cctools (installed as `gas`) 172 # and the Clang integrated assembler (installed as `as`). 173 # See pkgs/os-specific/darwin/binutils/default.nix for details. 174 + lib.optionalString wrapGas '' 175 if [ -e $ldPath/${targetPrefix}gas ]; then 176 ln -s $ldPath/${targetPrefix}gas $out/bin/${targetPrefix}gas 177 fi 178 '' 179 180 # Create symlinks for rest of the binaries. 181 + '' 182 for binary in objdump objcopy size strings as ar nm gprof dwp c++filt addr2line \ 183 ranlib readelf elfedit dlltool dllwrap windmc windres; do 184 if [ -e $ldPath/${targetPrefix}''${binary} ]; then 185 ln -s $ldPath/${targetPrefix}''${binary} $out/bin/${targetPrefix}''${binary} 186 fi 187 done 188 189 '' + (if !useMacosReexportHack then '' 190 if [ -e ''${ld:-$ldPath/${targetPrefix}ld} ]; then 191 wrap ${targetPrefix}ld ${./ld-wrapper.sh} ''${ld:-$ldPath/${targetPrefix}ld} 192 fi 193 '' else '' 194 ldInner="${targetPrefix}ld-reexport-delegate" 195 wrap "$ldInner" ${./macos-sierra-reexport-hack.bash} ''${ld:-$ldPath/${targetPrefix}ld} 196 wrap "${targetPrefix}ld" ${./ld-wrapper.sh} "$out/bin/$ldInner" 197 unset ldInner 198 '') + '' 199 200 for variant in $ldPath/${targetPrefix}ld.*; do 201 basename=$(basename "$variant") 202 wrap $basename ${./ld-wrapper.sh} $variant 203 done 204 ''; 205 206 strictDeps = true; 207 depsTargetTargetPropagated = extraPackages; 208 209 setupHooks = [ 210 ../setup-hooks/role.bash 211 ./setup-hook.sh 212 ]; 213 214 postFixup = 215 ## 216 ## General libc support 217 ## 218 optionalString (libc != null) ('' 219 touch "$out/nix-support/libc-ldflags" 220 echo "-L${libc_lib}${libc.libdir or "/lib"}" >> $out/nix-support/libc-ldflags 221 222 echo "${libc_lib}" > $out/nix-support/orig-libc 223 echo "${libc_dev}" > $out/nix-support/orig-libc-dev 224 '' 225 226 ## 227 ## Dynamic linker support 228 ## 229 + optionalString (sharedLibraryLoader != null) '' 230 if [[ -z ''${dynamicLinker+x} ]]; then 231 echo "Don't know the name of the dynamic linker for platform '${targetPlatform.config}', so guessing instead." >&2 232 local dynamicLinker="${sharedLibraryLoader}/lib/ld*.so.?" 233 fi 234 '' 235 236 # Expand globs to fill array of options 237 + '' 238 dynamicLinker=($dynamicLinker) 239 240 case ''${#dynamicLinker[@]} in 241 0) echo "No dynamic linker found for platform '${targetPlatform.config}'." >&2;; 242 1) echo "Using dynamic linker: '$dynamicLinker'" >&2;; 243 *) echo "Multiple dynamic linkers found for platform '${targetPlatform.config}'." >&2;; 244 esac 245 246 if [ -n "''${dynamicLinker-}" ]; then 247 echo $dynamicLinker > $out/nix-support/dynamic-linker 248 249 ${if targetPlatform.isDarwin then '' 250 printf "export LD_DYLD_PATH=%q\n" "$dynamicLinker" >> $out/nix-support/setup-hook 251 '' else lib.optionalString (sharedLibraryLoader != null) '' 252 if [ -e ${sharedLibraryLoader}/lib/32/ld-linux.so.2 ]; then 253 echo ${sharedLibraryLoader}/lib/32/ld-linux.so.2 > $out/nix-support/dynamic-linker-m32 254 fi 255 touch $out/nix-support/ld-set-dynamic-linker 256 ''} 257 fi 258 '') 259 260 ## 261 ## User env support 262 ## 263 264 # Propagate the underling unwrapped bintools so that if you 265 # install the wrapper, you get tools like objdump (same for any 266 # binaries of libc). 267 + optionalString (!nativeTools) '' 268 printWords ${bintools_bin} ${if libc == null then "" else libc_bin} > $out/nix-support/propagated-user-env-packages 269 '' 270 271 ## 272 ## Man page and info support 273 ## 274 + optionalString propagateDoc ('' 275 ln -s ${bintools.man} $man 276 '' + optionalString (bintools ? info) '' 277 ln -s ${bintools.info} $info 278 '') 279 280 ## 281 ## Hardening support 282 ## 283 284 # some linkers on some platforms don't support specific -z flags 285 + '' 286 export hardening_unsupported_flags="" 287 if [[ "$($ldPath/${targetPrefix}ld -z now 2>&1 || true)" =~ un(recognized|known)\ option ]]; then 288 hardening_unsupported_flags+=" bindnow" 289 fi 290 if [[ "$($ldPath/${targetPrefix}ld -z relro 2>&1 || true)" =~ un(recognized|known)\ option ]]; then 291 hardening_unsupported_flags+=" relro" 292 fi 293 '' 294 295 + optionalString hostPlatform.isCygwin '' 296 hardening_unsupported_flags+=" pic" 297 '' 298 299 + optionalString targetPlatform.isAvr '' 300 hardening_unsupported_flags+=" relro bindnow" 301 '' 302 303 + optionalString (libc != null && targetPlatform.isAvr) '' 304 for isa in avr5 avr3 avr4 avr6 avr25 avr31 avr35 avr51 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 tiny-stack; do 305 echo "-L${getLib libc}/avr/lib/$isa" >> $out/nix-support/libc-cflags 306 done 307 '' 308 309 + optionalString stdenv.targetPlatform.isDarwin '' 310 echo "-arch ${targetPlatform.darwinArch}" >> $out/nix-support/libc-ldflags 311 '' 312 313 ## 314 ## GNU specific extra strip flags 315 ## 316 317 # TODO(@sternenseemann): make a generic strip wrapper? 318 + optionalString (bintools.isGNU or false) '' 319 wrap ${targetPrefix}strip ${./gnu-binutils-strip-wrapper.sh} \ 320 "${bintools_bin}/bin/${targetPrefix}strip" 321 '' 322 323 ### 324 ### Remove LC_UUID 325 ### 326 + optionalString (stdenv.targetPlatform.isDarwin && !(bintools.isGNU or false)) '' 327 echo "-no_uuid" >> $out/nix-support/libc-ldflags-before 328 '' 329 330 + '' 331 for flags in "$out/nix-support"/*flags*; do 332 substituteInPlace "$flags" --replace $'\n' ' ' 333 done 334 335 substituteAll ${./add-flags.sh} $out/nix-support/add-flags.sh 336 substituteAll ${./add-hardening.sh} $out/nix-support/add-hardening.sh 337 substituteAll ${../wrapper-common/utils.bash} $out/nix-support/utils.bash 338 '' 339 340 ### 341 ### Ensure consistent LC_VERSION_MIN_MACOSX 342 ### 343 + optionalString stdenv.targetPlatform.isDarwin ( 344 let 345 inherit (stdenv.targetPlatform) 346 darwinPlatform darwinSdkVersion 347 darwinMinVersion darwinMinVersionVariable; 348 in '' 349 export darwinPlatform=${darwinPlatform} 350 export darwinMinVersion=${darwinMinVersion} 351 export darwinSdkVersion=${darwinSdkVersion} 352 export darwinMinVersionVariable=${darwinMinVersionVariable} 353 substituteAll ${./add-darwin-ldflags-before.sh} $out/nix-support/add-local-ldflags-before.sh 354 '' 355 ) 356 357 ## 358 ## Code signing on Apple Silicon 359 ## 360 + optionalString (targetPlatform.isDarwin && targetPlatform.isAarch64) '' 361 echo 'source ${postLinkSignHook}' >> $out/nix-support/post-link-hook 362 363 export signingUtils=${signingUtils} 364 365 wrap \ 366 ${targetPrefix}install_name_tool \ 367 ${./darwin-install_name_tool-wrapper.sh} \ 368 "${bintools_bin}/bin/${targetPrefix}install_name_tool" 369 370 wrap \ 371 ${targetPrefix}strip ${./darwin-strip-wrapper.sh} \ 372 "${bintools_bin}/bin/${targetPrefix}strip" 373 '' 374 375 ## 376 ## Extra custom steps 377 ## 378 + extraBuildCommands; 379 380 env = { 381 # for substitution in utils.bash 382 expandResponseParams = "${expand-response-params}/bin/expand-response-params"; 383 shell = getBin shell + shell.shellPath or ""; 384 gnugrep_bin = if nativeTools then "" else gnugrep; 385 wrapperName = "BINTOOLS_WRAPPER"; 386 inherit dynamicLinker targetPrefix suffixSalt coreutils_bin; 387 inherit bintools_bin libc_bin libc_dev libc_lib; 388 }; 389 390 meta = 391 let bintools_ = if bintools != null then bintools else {}; in 392 (if bintools_ ? meta then removeAttrs bintools.meta ["priority"] else {}) // 393 { description = 394 lib.attrByPath ["meta" "description"] "System binary utilities" bintools_ 395 + " (wrapper script)"; 396 priority = 10; 397 } // optionalAttrs useMacosReexportHack { 398 platforms = lib.platforms.darwin; 399 }; 400}