ansible-later: 2.0.22 -> 2.0.23
[NixPkgs.git] / pkgs / build-support / bintools-wrapper / default.nix
blobb54983986dbee3f36a68beb0255a2193493e88ab
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".
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 , buildPackages ? {}
29 , targetPackages ? {}
30 , useMacosReexportHack ? false
32 # Darwin code signing support utilities
33 , postLinkSignHook ? null, signingUtils ? null
36 with lib;
38 assert nativeTools -> !propagateDoc && nativePrefix != "";
39 assert !nativeTools ->
40   bintools != null && coreutils != null && gnugrep != null;
41 assert !(nativeLibc && noLibc);
42 assert (noLibc || nativeLibc) == (libc == null);
44 let
45   stdenv = stdenvNoCC;
46   inherit (stdenv) hostPlatform targetPlatform;
48   # Prefix for binaries. Customarily ends with a dash separator.
49   #
50   # TODO(@Ericson2314) Make unconditional, or optional but always true by
51   # default.
52   targetPrefix = lib.optionalString (targetPlatform != hostPlatform)
53                                         (targetPlatform.config + "-");
55   bintoolsVersion = lib.getVersion bintools;
56   bintoolsName = lib.removePrefix targetPrefix (lib.getName bintools);
58   libc_bin = if libc == null then null else getBin libc;
59   libc_dev = if libc == null then null else getDev libc;
60   libc_lib = if libc == null then null else getLib libc;
61   bintools_bin = if nativeTools then "" else getBin bintools;
62   # The wrapper scripts use 'cat' and 'grep', so we may need coreutils.
63   coreutils_bin = if nativeTools then "" else getBin coreutils;
65   # See description in cc-wrapper.
66   suffixSalt = replaceStrings ["-" "."] ["_" "_"] targetPlatform.config;
68   # The dynamic linker has different names on different platforms. This is a
69   # shell glob that ought to match it.
70   dynamicLinker =
71     /**/ if sharedLibraryLoader == null then null
72     else if targetPlatform.libc == "musl"             then "${sharedLibraryLoader}/lib/ld-musl-*"
73     else if targetPlatform.libc == "uclibc"           then "${sharedLibraryLoader}/lib/ld*-uClibc.so.1"
74     else if (targetPlatform.libc == "bionic" && targetPlatform.is32bit) then "/system/bin/linker"
75     else if (targetPlatform.libc == "bionic" && targetPlatform.is64bit) then "/system/bin/linker64"
76     else if targetPlatform.libc == "nblibc"           then "${sharedLibraryLoader}/libexec/ld.elf_so"
77     else if targetPlatform.system == "i686-linux"     then "${sharedLibraryLoader}/lib/ld-linux.so.2"
78     else if targetPlatform.system == "x86_64-linux"   then "${sharedLibraryLoader}/lib/ld-linux-x86-64.so.2"
79     else if targetPlatform.system == "powerpc64le-linux" then "${sharedLibraryLoader}/lib/ld64.so.2"
80     # ARM with a wildcard, which can be "" or "-armhf".
81     else if (with targetPlatform; isAarch32 && isLinux)   then "${sharedLibraryLoader}/lib/ld-linux*.so.3"
82     else if targetPlatform.system == "aarch64-linux"  then "${sharedLibraryLoader}/lib/ld-linux-aarch64.so.1"
83     else if targetPlatform.system == "powerpc-linux"  then "${sharedLibraryLoader}/lib/ld.so.1"
84     else if targetPlatform.isMips                     then "${sharedLibraryLoader}/lib/ld.so.1"
85     # `ld-linux-riscv{32,64}-<abi>.so.1`
86     else if targetPlatform.isRiscV                    then "${sharedLibraryLoader}/lib/ld-linux-riscv*.so.1"
87     else if targetPlatform.isDarwin                   then "/usr/lib/dyld"
88     else if targetPlatform.isFreeBSD                  then "/libexec/ld-elf.so.1"
89     else if lib.hasSuffix "pc-gnu" targetPlatform.config then "ld.so.1"
90     else null;
92   expand-response-params =
93     if buildPackages ? stdenv && buildPackages.stdenv.hasCC && buildPackages.stdenv.cc != "/dev/null"
94     then import ../expand-response-params { inherit (buildPackages) stdenv; }
95     else "";
99 stdenv.mkDerivation {
100   pname = targetPrefix
101     + (if name != "" then name else "${bintoolsName}-wrapper");
102   version = if bintools == null then null else bintoolsVersion;
104   preferLocalBuild = true;
106   inherit bintools_bin libc_bin libc_dev libc_lib coreutils_bin;
107   shell = getBin shell + shell.shellPath or "";
108   gnugrep_bin = if nativeTools then "" else gnugrep;
110   inherit targetPrefix suffixSalt;
112   outputs = [ "out" ] ++ optionals propagateDoc ([ "man" ] ++ optional (bintools ? info) "info");
114   passthru = {
115     inherit bintools libc nativeTools nativeLibc nativePrefix;
117     emacsBufferSetup = pkgs: ''
118       ; We should handle propagation here too
119       (mapc
120         (lambda (arg)
121           (when (file-directory-p (concat arg "/lib"))
122             (setenv "NIX_LDFLAGS_${suffixSalt}" (concat (getenv "NIX_LDFLAGS_${suffixSalt}") " -L" arg "/lib")))
123           (when (file-directory-p (concat arg "/lib64"))
124             (setenv "NIX_LDFLAGS_${suffixSalt}" (concat (getenv "NIX_LDFLAGS_${suffixSalt}") " -L" arg "/lib64"))))
125         '(${concatStringsSep " " (map (pkg: "\"${pkg}\"") pkgs)}))
126     '';
127   };
129   dontBuild = true;
130   dontConfigure = true;
132   enableParallelBuilding = true;
134   unpackPhase = ''
135     src=$PWD
136   '';
138   installPhase =
139     ''
140       mkdir -p $out/bin $out/nix-support
142       wrap() {
143         local dst="$1"
144         local wrapper="$2"
145         export prog="$3"
146         substituteAll "$wrapper" "$out/bin/$dst"
147         chmod +x "$out/bin/$dst"
148       }
149     ''
151     + (if nativeTools then ''
152       echo ${nativePrefix} > $out/nix-support/orig-bintools
154       ldPath="${nativePrefix}/bin"
155     '' else ''
156       echo $bintools_bin > $out/nix-support/orig-bintools
158       ldPath="${bintools_bin}/bin"
159     ''
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     '')
168     # Create symlinks for rest of the binaries.
169     + ''
170       for binary in objdump objcopy size strings as ar nm gprof dwp c++filt addr2line ranlib readelf elfedit; do
171         if [ -e $ldPath/${targetPrefix}''${binary} ]; then
172           ln -s $ldPath/${targetPrefix}''${binary} $out/bin/${targetPrefix}''${binary}
173         fi
174       done
176     '' + (if !useMacosReexportHack then ''
177       wrap ${targetPrefix}ld ${./ld-wrapper.sh} ''${ld:-$ldPath/${targetPrefix}ld}
178     '' else ''
179       ldInner="${targetPrefix}ld-reexport-delegate"
180       wrap "$ldInner" ${./macos-sierra-reexport-hack.bash} ''${ld:-$ldPath/${targetPrefix}ld}
181       wrap "${targetPrefix}ld" ${./ld-wrapper.sh} "$out/bin/$ldInner"
182       unset ldInner
183     '') + ''
185       for variant in ld.gold ld.bfd ld.lld; do
186         local underlying=$ldPath/${targetPrefix}$variant
187         [[ -e "$underlying" ]] || continue
188         wrap ${targetPrefix}$variant ${./ld-wrapper.sh} $underlying
189       done
190     '';
192   strictDeps = true;
193   depsTargetTargetPropagated = extraPackages;
195   wrapperName = "BINTOOLS_WRAPPER";
197   setupHooks = [
198     ../setup-hooks/role.bash
199     ./setup-hook.sh
200   ];
202   postFixup =
203     ##
204     ## General libc support
205     ##
206     optionalString (libc != null) (''
207       touch "$out/nix-support/libc-ldflags"
208       echo "-L${libc_lib}${libc.libdir or "/lib"}" >> $out/nix-support/libc-ldflags
210       echo "${libc_lib}" > $out/nix-support/orig-libc
211       echo "${libc_dev}" > $out/nix-support/orig-libc-dev
212     ''
214     ##
215     ## Dynamic linker support
216     ##
217     + optionalString (sharedLibraryLoader != null) ''
218       if [[ -z ''${dynamicLinker+x} ]]; then
219         echo "Don't know the name of the dynamic linker for platform '${targetPlatform.config}', so guessing instead." >&2
220         local dynamicLinker="${sharedLibraryLoader}/lib/ld*.so.?"
221       fi
222     ''
224     # Expand globs to fill array of options
225     + ''
226       dynamicLinker=($dynamicLinker)
228       case ''${#dynamicLinker[@]} in
229         0) echo "No dynamic linker found for platform '${targetPlatform.config}'." >&2;;
230         1) echo "Using dynamic linker: '$dynamicLinker'" >&2;;
231         *) echo "Multiple dynamic linkers found for platform '${targetPlatform.config}'." >&2;;
232       esac
234       if [ -n "''${dynamicLinker-}" ]; then
235         echo $dynamicLinker > $out/nix-support/dynamic-linker
237         ${if targetPlatform.isDarwin then ''
238           printf "export LD_DYLD_PATH=%q\n" "$dynamicLinker" >> $out/nix-support/setup-hook
239         '' else lib.optionalString (sharedLibraryLoader != null) ''
240           if [ -e ${sharedLibraryLoader}/lib/32/ld-linux.so.2 ]; then
241             echo ${sharedLibraryLoader}/lib/32/ld-linux.so.2 > $out/nix-support/dynamic-linker-m32
242           fi
243           touch $out/nix-support/ld-set-dynamic-linker
244         ''}
245       fi
246     '')
248     ##
249     ## User env support
250     ##
252     # Propagate the underling unwrapped bintools so that if you
253     # install the wrapper, you get tools like objdump (same for any
254     # binaries of libc).
255     + optionalString (!nativeTools) ''
256       printWords ${bintools_bin} ${if libc == null then "" else libc_bin} > $out/nix-support/propagated-user-env-packages
257     ''
259     ##
260     ## Man page and info support
261     ##
262     + optionalString propagateDoc (''
263       ln -s ${bintools.man} $man
264     '' + optionalString (bintools ? info) ''
265       ln -s ${bintools.info} $info
266     '')
268     ##
269     ## Hardening support
270     ##
272     # some linkers on some platforms don't support specific -z flags
273     + ''
274       export hardening_unsupported_flags=""
275       if [[ "$($ldPath/${targetPrefix}ld -z now 2>&1 || true)" =~ un(recognized|known)\ option ]]; then
276         hardening_unsupported_flags+=" bindnow"
277       fi
278       if [[ "$($ldPath/${targetPrefix}ld -z relro 2>&1 || true)" =~ un(recognized|known)\ option ]]; then
279         hardening_unsupported_flags+=" relro"
280       fi
281     ''
283     + optionalString hostPlatform.isCygwin ''
284       hardening_unsupported_flags+=" pic"
285     ''
287     + optionalString targetPlatform.isAvr ''
288       hardening_unsupported_flags+=" relro bindnow"
289     ''
291     + optionalString (libc != null && targetPlatform.isAvr) ''
292       for isa in avr5 avr3 avr4 avr6 avr25 avr31 avr35 avr51 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 tiny-stack; do
293         echo "-L${getLib libc}/avr/lib/$isa" >> $out/nix-support/libc-cflags
294       done
295     ''
297     + optionalString stdenv.targetPlatform.isDarwin ''
298       echo "-arch ${targetPlatform.darwinArch}" >> $out/nix-support/libc-ldflags
299     ''
301     ##
302     ## GNU specific extra strip flags
303     ##
305     # TODO(@sternenseemann): make a generic strip wrapper?
306     + optionalString (bintools.isGNU or false) ''
307       wrap ${targetPrefix}strip ${./gnu-binutils-strip-wrapper.sh} \
308         "${bintools_bin}/bin/${targetPrefix}strip"
309     ''
311     ###
312     ### Remove LC_UUID
313     ###
314     + optionalString (stdenv.targetPlatform.isDarwin && !(bintools.isGNU or false)) ''
315       echo "-no_uuid" >> $out/nix-support/libc-ldflags-before
316     ''
318     + ''
319       for flags in "$out/nix-support"/*flags*; do
320         substituteInPlace "$flags" --replace $'\n' ' '
321       done
323       substituteAll ${./add-flags.sh} $out/nix-support/add-flags.sh
324       substituteAll ${./add-hardening.sh} $out/nix-support/add-hardening.sh
325       substituteAll ${../wrapper-common/utils.bash} $out/nix-support/utils.bash
326     ''
328     ###
329     ### Ensure consistent LC_VERSION_MIN_MACOSX
330     ###
331     + optionalString stdenv.targetPlatform.isDarwin (
332       let
333         inherit (stdenv.targetPlatform)
334           darwinPlatform darwinSdkVersion
335           darwinMinVersion darwinMinVersionVariable;
336       in ''
337         export darwinPlatform=${darwinPlatform}
338         export darwinMinVersion=${darwinMinVersion}
339         export darwinSdkVersion=${darwinSdkVersion}
340         export darwinMinVersionVariable=${darwinMinVersionVariable}
341         substituteAll ${./add-darwin-ldflags-before.sh} $out/nix-support/add-local-ldflags-before.sh
342       ''
343     )
345     ##
346     ## Code signing on Apple Silicon
347     ##
348     + optionalString (targetPlatform.isDarwin && targetPlatform.isAarch64) ''
349       echo 'source ${postLinkSignHook}' >> $out/nix-support/post-link-hook
351       export signingUtils=${signingUtils}
353       wrap \
354         ${targetPrefix}install_name_tool \
355         ${./darwin-install_name_tool-wrapper.sh} \
356         "${bintools_bin}/bin/${targetPrefix}install_name_tool"
358       wrap \
359         ${targetPrefix}strip ${./darwin-strip-wrapper.sh} \
360         "${bintools_bin}/bin/${targetPrefix}strip"
361     ''
363     ##
364     ## Extra custom steps
365     ##
366     + extraBuildCommands;
368   inherit dynamicLinker;
370   # for substitution in utils.bash
371   expandResponseParams = "${expand-response-params}/bin/expand-response-params";
373   meta =
374     let bintools_ = if bintools != null then bintools else {}; in
375     (if bintools_ ? meta then removeAttrs bintools.meta ["priority"] else {}) //
376     { description =
377         lib.attrByPath ["meta" "description"] "System binary utilities" bintools_
378         + " (wrapper script)";
379       priority = 10;
380   } // optionalAttrs useMacosReexportHack {
381     platforms = lib.platforms.darwin;
382   };