nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at netboot-syslinux-multiplatform 100 lines 4.6 kB view raw
1{ lib 2, stdenv 3, langC 4, langCC 5, langJit 6}: 7 8let 9 enableLibGccOutput = 10 (with stdenv; targetPlatform == hostPlatform) && 11 !langJit && 12 !stdenv.hostPlatform.isDarwin && 13 !stdenv.hostPlatform.isStatic; 14in 15(pkg: pkg.overrideAttrs (previousAttrs: lib.optionalAttrs ((!langC) || langJit || enableLibGccOutput) { 16 outputs = previousAttrs.outputs ++ lib.optionals enableLibGccOutput [ "libgcc" ]; 17 # This is a separate phase because gcc assembles its phase scripts 18 # in bash instead of nix (we should fix that). 19 preFixupPhases = (previousAttrs.preFixupPhases or []) ++ lib.optionals ((!langC) || enableLibGccOutput) [ "preFixupLibGccPhase" ]; 20 preFixupLibGccPhase = 21 # delete extra/unused builds of libgcc_s in non-langC builds 22 # (i.e. libgccjit, gnat, etc) to avoid potential confusion 23 lib.optionalString (!langC) '' 24 rm -f $out/lib/libgcc_s.so* 25 '' 26 27 # TODO(amjoseph): remove the `libgcc_s.so` symlinks below and replace them 28 # with a `-L${gccForLibs.libgcc}/lib` in cc-wrapper's 29 # `$out/nix-support/cc-flags`. See also: 30 # - https://github.com/NixOS/nixpkgs/pull/209870#discussion_r1130614895 31 # - https://github.com/NixOS/nixpkgs/pull/209870#discussion_r1130635982 32 # - https://github.com/NixOS/nixpkgs/commit/404155c6acfa59456aebe6156b22fe385e7dec6f 33 # 34 # move `libgcc_s.so` into its own output, `$libgcc` 35 + lib.optionalString enableLibGccOutput ('' 36 # move libgcc from lib to its own output (libgcc) 37 mkdir -p $libgcc/lib 38 mv $lib/lib/libgcc_s.so $libgcc/lib/ 39 mv $lib/lib/libgcc_s.so.1 $libgcc/lib/ 40 ln -s $libgcc/lib/libgcc_s.so $lib/lib/ 41 ln -s $libgcc/lib/libgcc_s.so.1 $lib/lib/ 42 '' 43 # 44 # Nixpkgs ordinarily turns dynamic linking into pseudo-static linking: 45 # libraries are still loaded dynamically, exactly which copy of each 46 # library is loaded is permanently fixed at compile time (via RUNPATH). 47 # For libgcc_s we must revert to the "impure dynamic linking" style found 48 # in imperative software distributions. We must do this because 49 # `libgcc_s` calls `malloc()` and therefore has a `DT_NEEDED` for `libc`, 50 # which creates two problems: 51 # 52 # 1. A circular package dependency `glibc`<-`libgcc`<-`glibc` 53 # 54 # 2. According to the `-Wl,-rpath` flags added by Nixpkgs' `ld-wrapper`, 55 # the two versions of `glibc` in the cycle above are actually 56 # different packages. The later one is compiled by this `gcc`, but 57 # the earlier one was compiled by the compiler *that compiled* this 58 # `gcc` (usually the bootstrapFiles). In any event, the `glibc` 59 # dynamic loader won't honor that specificity without namespaced 60 # manual loads (`dlmopen()`). Once a `libc` is present in the address 61 # space of a process, that `libc` will be used to satisfy all 62 # `DT_NEEDED`s for `libc`, regardless of `RUNPATH`s. 63 # 64 # So we wipe the RUNPATH using `patchelf --set-rpath ""`. We can't use 65 # `patchelf --remove-rpath`, because at least as of patchelf 0.15.0 it 66 # will leave the old RUNPATH string in the file where the reference 67 # scanner can still find it: 68 # 69 # https://github.com/NixOS/patchelf/issues/453 70 # 71 # Note: we might be using the bootstrapFiles' copy of patchelf, so we have 72 # to keep doing it this way until both the issue is fixed *and* all the 73 # bootstrapFiles are regenerated, on every platform. 74 # 75 # This patchelfing is *not* effectively equivalent to copying 76 # `libgcc_s` into `glibc`'s outpath. There is one minor and one 77 # major difference: 78 # 79 # 1. (Minor): multiple builds of `glibc` (say, with different 80 # overrides or parameters) will all reference a single store 81 # path: 82 # 83 # /nix/store/xxx...xxx-gcc-libgcc/lib/libgcc_s.so.1 84 # 85 # This many-to-one referrer relationship will be visible in the store's 86 # dependency graph, and will be available to `nix-store -q` queries. 87 # Copying `libgcc_s` into each of its referrers would lose that 88 # information. 89 # 90 # 2. (Major): by referencing `libgcc_s.so.1`, rather than copying it, we 91 # are still able to run `nix-store -qd` on it to find out how it got 92 # built! Most importantly, we can see from that deriver which compiler 93 # was used to build it (or if it is part of the unpacked 94 # bootstrap-files). Copying `libgcc_s.so.1` from one outpath to 95 # another eliminates the ability to make these queries. 96 # 97 + '' 98 patchelf --set-rpath "" $libgcc/lib/libgcc_s.so.1 99 ''); 100}))