nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 180 lines 8.0 kB view raw
1{ 2 lib, 3 stdenv, 4 version, 5 langC, 6 langCC, 7 langJit, 8 enableShared, 9 targetPlatform, 10 hostPlatform, 11 withoutTargetLibc, 12 libcCross, 13}: 14 15assert !stdenv.targetPlatform.hasSharedLibraries -> !enableShared; 16 17drv: 18lib.pipe drv 19 20 ( 21 [ 22 23 ( 24 pkg: 25 pkg.overrideAttrs ( 26 previousAttrs: 27 lib.optionalAttrs 28 ( 29 (!lib.systems.equals targetPlatform hostPlatform) 30 && (enableShared || targetPlatform.isMinGW) 31 && withoutTargetLibc 32 ) 33 { 34 makeFlags = [ 35 "all-gcc" 36 "all-target-libgcc" 37 ]; 38 installTargets = "install-gcc install-target-libgcc"; 39 } 40 ) 41 ) 42 43 ] 44 ++ ( 45 let 46 targetPlatformSlash = 47 if lib.systems.equals hostPlatform targetPlatform then "" else "${targetPlatform.config}/"; 48 49 # If we are building a cross-compiler and the target libc provided 50 # to us at build time has a libgcc, use that instead of building a 51 # new one. This avoids having two separate (but identical) libgcc 52 # outpaths in the closure of most packages, which can be confusing. 53 useLibgccFromTargetLibc = libcCross != null && libcCross ? passthru.libgcc; 54 55 enableLibGccOutput = 56 # $libgcc logic is currently hardcoded for .so 57 !stdenv.hostPlatform.isPE 58 && !stdenv.targetPlatform.isPE 59 && !langJit 60 && !stdenv.hostPlatform.isDarwin 61 && enableShared 62 && !useLibgccFromTargetLibc; 63 64 # For some reason libgcc_s.so has major-version "2" on m68k but 65 # "1" everywhere else. Might be worth changing this to "*". 66 libgcc_s-version-major = if targetPlatform.isM68k then "2" else "1"; 67 68 in 69 [ 70 71 ( 72 pkg: 73 pkg.overrideAttrs ( 74 previousAttrs: 75 lib.optionalAttrs useLibgccFromTargetLibc { 76 passthru = (previousAttrs.passthru or { }) // { 77 inherit (libcCross) libgcc; 78 }; 79 } 80 ) 81 ) 82 83 ( 84 pkg: 85 pkg.overrideAttrs ( 86 previousAttrs: 87 lib.optionalAttrs ((!langC) || langJit || enableLibGccOutput) { 88 outputs = previousAttrs.outputs ++ lib.optionals enableLibGccOutput [ "libgcc" ]; 89 # This is a separate phase because gcc assembles its phase scripts 90 # in bash instead of nix (we should fix that). 91 preFixupPhases = 92 (previousAttrs.preFixupPhases or [ ]) 93 ++ lib.optionals ((!langC) || enableLibGccOutput) [ "preFixupLibGccPhase" ]; 94 preFixupLibGccPhase = 95 # delete extra/unused builds of libgcc_s in non-langC builds 96 # (i.e. libgccjit, gnat, etc) to avoid potential confusion 97 lib.optionalString (!langC) '' 98 rm -f $out/lib/libgcc_s.so* 99 '' 100 101 # move `libgcc_s.so` into its own output, `$libgcc` 102 # We maintain $libgcc/lib/$target/ structure to make sure target 103 # strip runs over libgcc_s.so and remove debug references to headers: 104 # https://github.com/NixOS/nixpkgs/issues/316114 105 + lib.optionalString enableLibGccOutput ( 106 '' 107 # move libgcc from lib to its own output (libgcc) 108 mkdir -p $libgcc/${targetPlatformSlash}lib 109 mv $lib/${targetPlatformSlash}lib/libgcc_s.so $libgcc/${targetPlatformSlash}lib/ 110 mv $lib/${targetPlatformSlash}lib/libgcc_s.so.${libgcc_s-version-major} $libgcc/${targetPlatformSlash}lib/ 111 ln -s $libgcc/${targetPlatformSlash}lib/libgcc_s.so $lib/${targetPlatformSlash}lib/ 112 ln -s $libgcc/${targetPlatformSlash}lib/libgcc_s.so.${libgcc_s-version-major} $lib/${targetPlatformSlash}lib/ 113 '' 114 + lib.optionalString (targetPlatformSlash != "") '' 115 ln -s ${targetPlatformSlash}lib $libgcc/lib 116 '' 117 # 118 # Nixpkgs ordinarily turns dynamic linking into pseudo-static linking: 119 # libraries are still loaded dynamically, exactly which copy of each 120 # library is loaded is permanently fixed at compile time (via RUNPATH). 121 # For libgcc_s we must revert to the "impure dynamic linking" style found 122 # in imperative software distributions. We must do this because 123 # `libgcc_s` calls `malloc()` and therefore has a `DT_NEEDED` for `libc`, 124 # which creates two problems: 125 # 126 # 1. A circular package dependency `glibc`<-`libgcc`<-`glibc` 127 # 128 # 2. According to the `-Wl,-rpath` flags added by Nixpkgs' `ld-wrapper`, 129 # the two versions of `glibc` in the cycle above are actually 130 # different packages. The later one is compiled by this `gcc`, but 131 # the earlier one was compiled by the compiler *that compiled* this 132 # `gcc` (usually the bootstrapFiles). In any event, the `glibc` 133 # dynamic loader won't honor that specificity without namespaced 134 # manual loads (`dlmopen()`). Once a `libc` is present in the address 135 # space of a process, that `libc` will be used to satisfy all 136 # `DT_NEEDED`s for `libc`, regardless of `RUNPATH`s. 137 # 138 # So we wipe the RUNPATH using `patchelf --set-rpath ""`. We can't use 139 # `patchelf --remove-rpath`, because at least as of patchelf 0.15.0 it 140 # will leave the old RUNPATH string in the file where the reference 141 # scanner can still find it: 142 # 143 # https://github.com/NixOS/patchelf/issues/453 144 # 145 # Note: we might be using the bootstrapFiles' copy of patchelf, so we have 146 # to keep doing it this way until both the issue is fixed *and* all the 147 # bootstrapFiles are regenerated, on every platform. 148 # 149 # This patchelfing is *not* effectively equivalent to copying 150 # `libgcc_s` into `glibc`'s outpath. There is one minor and one 151 # major difference: 152 # 153 # 1. (Minor): multiple builds of `glibc` (say, with different 154 # overrides or parameters) will all reference a single store 155 # path: 156 # 157 # /nix/store/xxx...xxx-gcc-libgcc/lib/libgcc_s.so.1 158 # 159 # This many-to-one referrer relationship will be visible in the store's 160 # dependency graph, and will be available to `nix-store -q` queries. 161 # Copying `libgcc_s` into each of its referrers would lose that 162 # information. 163 # 164 # 2. (Major): by referencing `libgcc_s.so.1`, rather than copying it, we 165 # are still able to run `nix-store -qd` on it to find out how it got 166 # built! Most importantly, we can see from that deriver which compiler 167 # was used to build it (or if it is part of the unpacked 168 # bootstrap-files). Copying `libgcc_s.so.1` from one outpath to 169 # another eliminates the ability to make these queries. 170 # 171 + '' 172 patchelf --set-rpath "" $libgcc/lib/libgcc_s.so.${libgcc_s-version-major} 173 '' 174 ); 175 } 176 ) 177 ) 178 ] 179 ) 180 )