nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 385 lines 13 kB view raw
1let 2 withGold = platform: platform.isElf && !platform.isRiscV && !platform.isLoongArch64; 3in 4 5{ 6 stdenv, 7 autoconf269, 8 automake, 9 libtool, 10 bison, 11 buildPackages, 12 fetchurl, 13 gettext, 14 lib, 15 noSysDirs, 16 perl, 17 runCommand, 18 zlib, 19 20 enableGold ? withGold stdenv.targetPlatform, 21 enableGoldDefault ? false, 22 # shared lib linking fails on cygwin due to multiple definitions 23 # https://cygwin.com/cgit/cygwin-packages/binutils/blame/binutils.cygport 24 enableShared ? (!stdenv.hostPlatform.isStatic && !stdenv.hostPlatform.isCygwin), 25 # WARN: Enabling all targets increases output size to a multiple. 26 withAllTargets ? false, 27}: 28 29# WARN: configure silently disables ld.gold if it's unsupported, so we need to 30# make sure that intent matches result ourselves. 31assert enableGold -> withGold stdenv.targetPlatform; 32assert enableGoldDefault -> enableGold; 33 34let 35 inherit (stdenv) buildPlatform hostPlatform targetPlatform; 36 37 version = "2.44"; 38 39 #INFO: The targetPrefix prepended to binary names to allow multiple binuntils 40 # on the PATH to both be usable. 41 targetPrefix = lib.optionalString (targetPlatform != hostPlatform) "${targetPlatform.config}-"; 42 43 # gas is disabled for some targets via noconfigdirs in configure. 44 targetHasGas = !stdenv.targetPlatform.isDarwin; 45 46 # gas isn't multi-target, even with --enable-targets=all, so we do 47 # separate builds of just gas for each target. 48 # 49 # There's no way to do this exhaustively, so feel free to add 50 # additional targets here as required. 51 allGasTargets = 52 allGasTargets' 53 ++ lib.optional ( 54 targetHasGas && !lib.elem targetPlatform.config allGasTargets' 55 ) targetPlatform.config; 56 allGasTargets' = [ 57 "aarch64-unknown-linux-gnu" 58 "alpha-unknown-linux-gnu" 59 "arm-unknown-linux-gnu" 60 "avr-unknown-linux-gnu" 61 "cris-unknown-linux-gnu" 62 "hppa-unknown-linux-gnu" 63 "i686-unknown-linux-gnu" 64 "ia64-unknown-linux-gnu" 65 "m68k-unknown-linux-gnu" 66 "mips-unknown-linux-gnu" 67 "mips64-unknown-linux-gnu" 68 "msp430-unknown-linux-gnu" 69 "powerpc-unknown-linux-gnu" 70 "powerpc64-unknown-linux-gnu" 71 "s390-unknown-linux-gnu" 72 "sparc-unknown-linux-gnu" 73 "vax-unknown-linux-gnu" 74 "x86_64-unknown-linux-gnu" 75 "xscale-unknown-linux-gnu" 76 ]; 77in 78 79stdenv.mkDerivation (finalAttrs: { 80 pname = targetPrefix + "binutils"; 81 inherit version; 82 83 src = fetchurl { 84 url = "mirror://gnu/binutils/binutils-with-gold-${version}.tar.bz2"; 85 hash = "sha256-NHM+pJXMDlDnDbTliQ3sKKxB8OFMShZeac8n+5moxMg="; 86 }; 87 88 # WARN: this package is used for bootstrapping fetchurl, and thus cannot use 89 # fetchpatch! All mutable patches (generated by GitHub or cgit) that are 90 # needed here should be included directly in Nixpkgs as files. 91 patches = [ 92 # Make binutils output deterministic by default. 93 ./deterministic.patch 94 95 # Breaks nm BSD flag detection, heeds an upstream fix: 96 # https://sourceware.org/PR29547 97 ./0001-Revert-libtool.m4-fix-the-NM-nm-over-here-B-option-w.patch 98 ./0001-Revert-libtool.m4-fix-nm-BSD-flag-detection.patch 99 100 # For some reason bfd ld doesn't search DT_RPATH when cross-compiling. It's 101 # not clear why this behavior was decided upon but it has the unfortunate 102 # consequence that the linker will fail to find transitive dependencies of 103 # shared objects when cross-compiling. Consequently, we are forced to 104 # override this behavior, forcing ld to search DT_RPATH even when 105 # cross-compiling. 106 ./always-search-rpath.patch 107 108 # Avoid `lib -> out -> lib` reference. Normally `bfd-plugins` does 109 # not need to know binutils' BINDIR at all. It's an absolute path 110 # where libraries are stored. 111 ./plugins-no-BINDIR.patch 112 113 # ld64 needs `-undefined dynamic_lookup` to link `libctf-nobfd.dylib`, but the Darwin 114 # version detection in `libtool.m4` fails to detect the Darwin version correctly. 115 ./0001-libtool.m4-update-macos-version-detection-block.patch 116 117 # Adds AVR-specific options to "size" for compatibility with Atmel's downstream distribution 118 # Patch from arch-community 119 # https://github.com/archlinux/svntogit-community/blob/c8d53dd1734df7ab15931f7fad0c9acb8386904c/trunk/avr-size.patch 120 ./avr-size.patch 121 122 ./windres-locate-gcc.patch 123 124 # Backported against CVE patched in the 2.45 series. See: 125 # https://nvd.nist.gov/vuln/detail/CVE-2025-5244 126 ./CVE-2025-5244.diff 127 128 # Backported against CVE patched in the 2.45 series. See: 129 # https://nvd.nist.gov/vuln/detail/CVE-2025-5245 130 ./CVE-2025-5245.diff 131 ]; 132 133 outputs = [ 134 "out" 135 "info" 136 "man" 137 "dev" 138 ] 139 # Ideally we would like to always install 'lib' into a separate 140 # target. Unfortunately cross-compiled binutils installs libraries 141 # across both `$lib/lib/` and `$out/$target/lib` with a reference 142 # from $out to $lib. Probably a binutils bug: all libraries should go 143 # to $lib as binutils does not build target libraries. Let's make our 144 # life slightly simpler by installing everything into $out for 145 # cross-binutils. 146 ++ lib.optionals (targetPlatform == hostPlatform) [ "lib" ]; 147 148 strictDeps = true; 149 depsBuildBuild = [ buildPackages.stdenv.cc ]; 150 # texinfo was removed here in https://github.com/NixOS/nixpkgs/pull/210132 151 # to reduce rebuilds during stdenv bootstrap. Please don't add it back without 152 # checking the impact there first. 153 nativeBuildInputs = [ 154 bison 155 perl 156 ] 157 ++ lib.optionals buildPlatform.isDarwin [ 158 autoconf269 159 automake 160 gettext 161 libtool 162 ]; 163 164 buildInputs = [ 165 zlib 166 gettext 167 ]; 168 169 inherit noSysDirs; 170 171 preConfigure = 172 (lib.optionalString buildPlatform.isDarwin '' 173 for i in */configure.ac; do 174 pushd "$(dirname "$i")" 175 echo "Running autoreconf in $PWD" 176 # autoreconf doesn't work, don't know why 177 # autoreconf ''${autoreconfFlags:---install --force --verbose} 178 autoconf 179 popd 180 done 181 '') 182 + '' 183 # Clear the default library search path. 184 if test "$noSysDirs" = "1"; then 185 echo 'NATIVE_LIB_DIRS=' >> ld/configure.tgt 186 fi 187 188 # Use symlinks instead of hard links to save space ("strip" in the 189 # fixup phase strips each hard link separately). 190 for i in binutils/Makefile.in gas/Makefile.in ld/Makefile.in gold/Makefile.in; do 191 sed -i "$i" -e 's|ln |ln -s |' 192 done 193 194 configureScript="$PWD/configure" 195 mkdir $NIX_BUILD_TOP/build 196 cd $NIX_BUILD_TOP/build 197 ''; 198 199 # As binutils takes part in the stdenv building, we don't want references 200 # to the bootstrap-tools libgcc (as uses to happen on arm/mips) 201 # 202 # for FreeBSD it's more complicated. With -static-libgcc, configure 203 # thinks that limits.h does not exist and the build fails for not finding 204 # LONG_MIN. The configure test itself succeeds but the compiler issues a 205 # warning about -static-libgcc being unused. 206 env.NIX_CFLAGS_COMPILE = 207 if (hostPlatform.isDarwin || hostPlatform.isFreeBSD) then 208 "-Wno-string-plus-int -Wno-deprecated-declarations" 209 else 210 "-static-libgcc"; 211 212 hardeningDisable = [ 213 "format" 214 ]; 215 216 configurePlatforms = [ 217 "build" 218 "host" 219 "target" 220 ]; 221 222 configureFlags = [ 223 "--enable-64-bit-bfd" 224 "--with-system-zlib" 225 226 "--enable-deterministic-archives" 227 "--disable-werror" 228 "--enable-fix-loongson2f-nop" 229 230 # Turn on --enable-new-dtags by default to make the linker set 231 # RUNPATH instead of RPATH on binaries. This is important because 232 # RUNPATH can be overridden using LD_LIBRARY_PATH at runtime. 233 "--enable-new-dtags" 234 235 # force target prefix. Some versions of binutils will make it empty if 236 # `--host` and `--target` are too close, even if Nixpkgs thinks the 237 # platforms are different (e.g. because not all the info makes the 238 # `config`). Other versions of binutils will always prefix if `--target` is 239 # passed, even if `--host` and `--target` are the same. The easiest thing 240 # for us to do is not leave it to chance, and force the program prefix to be 241 # what we want it to be. 242 "--program-prefix=${targetPrefix}" 243 244 # Unconditionally disable: 245 # - musl target needs porting: https://sourceware.org/PR29477 246 "--disable-gprofng" 247 248 # By default binutils searches $libdir for libraries. This brings in 249 # libbfd and libopcodes into a default visibility. Drop default lib 250 # path to force users to declare their use of these libraries. 251 "--with-lib-path=:" 252 ] 253 ++ lib.optionals withAllTargets [ 254 "--enable-targets=all" 255 # gas will be built separately for each target. 256 "--disable-gas" 257 ] 258 ++ lib.optionals enableGold [ 259 "--enable-gold${lib.optionalString enableGoldDefault "=default"}" 260 "--enable-plugins" 261 ] 262 ++ ( 263 if enableShared then 264 [ 265 "--enable-shared" 266 "--disable-static" 267 ] 268 else 269 [ 270 "--disable-shared" 271 "--enable-static" 272 ] 273 ) 274 ++ (lib.optionals (stdenv.cc.bintools.isLLVM && lib.versionAtLeast stdenv.cc.bintools.version "17") 275 [ 276 # lld17+ passes `--no-undefined-version` by default and makes this a hard 277 # error; libctf.ver version script references symbols that aren't present. 278 # 279 # This is fixed upstream and can be removed with the future release of 2.43. 280 # For now we allow this with `--undefined-version`: 281 "LDFLAGS=-Wl,--undefined-version" 282 ] 283 ); 284 285 postConfigure = lib.optionalString withAllTargets '' 286 for target in ${lib.escapeShellArgs allGasTargets}; do 287 mkdir "$NIX_BUILD_TOP/build-$target" 288 env -C "$NIX_BUILD_TOP/build-$target" \ 289 "$configureScript" $configureFlags "''${configureFlagsArray[@]}" \ 290 --enable-gas --program-prefix "$target-" --target "$target" 291 done 292 ''; 293 294 makeFlags = [ 295 # As we regenerated configure build system tries hard to use 296 # texinfo to regenerate manuals. Let's avoid the dependency 297 # on texinfo in bootstrap path and keep manuals unmodified. 298 "MAKEINFO=true" 299 ]; 300 301 postBuild = lib.optionalString withAllTargets '' 302 for target in ${lib.escapeShellArgs allGasTargets}; do 303 make -C "$NIX_BUILD_TOP/build-$target" -j"$NIX_BUILD_CORES" \ 304 $makeFlags "''${makeFlagsArray[@]}" $buildFlags "''${buildFlagsArray[@]}" \ 305 TARGET-gas=as-new all-gas 306 done 307 ''; 308 309 # Fails 310 doCheck = false; 311 312 # Break dependency on pkgsBuildBuild.gcc when building a cross-binutils 313 stripDebugList = 314 if stdenv.hostPlatform != stdenv.targetPlatform then 315 "bin lib ${stdenv.hostPlatform.config}" 316 else 317 null; 318 319 # INFO: Otherwise it fails with: 320 # `./sanity.sh: line 36: $out/bin/size: not found` 321 doInstallCheck = (buildPlatform == hostPlatform) && (hostPlatform == targetPlatform); 322 323 enableParallelBuilding = true; 324 325 # For the same reason we don't split "lib" output we undo the $target/ 326 # prefix for installed headers and libraries we link: 327 # $out/$host/$target/lib/* to $out/lib/ 328 # $out/$host/$target/include/* to $dev/include/* 329 # TODO(trofi): fix installation paths upstream so we could remove this 330 # code and have "lib" output unconditionally. 331 postInstall = 332 lib.optionalString (hostPlatform.config != targetPlatform.config) '' 333 ln -s $out/${hostPlatform.config}/${targetPlatform.config}/lib/* $out/lib/ 334 ln -s $out/${hostPlatform.config}/${targetPlatform.config}/include/* $dev/include/ 335 '' 336 + lib.optionalString withAllTargets '' 337 for target in ${lib.escapeShellArgs allGasTargets}; do 338 make -C "$NIX_BUILD_TOP/build-$target/gas" -j"$NIX_BUILD_CORES" \ 339 $makeFlags "''${makeFlagsArray[@]}" $installFlags "''${installFlagsArray[@]}" \ 340 install-exec-bindir 341 done 342 '' 343 + lib.optionalString (withAllTargets && targetHasGas) '' 344 ln -s $out/bin/${stdenv.targetPlatform.config}-as $out/bin/as 345 ''; 346 347 passthru = { 348 inherit targetPrefix; 349 hasGold = enableGold; 350 isGNU = true; 351 352 # The plugin API is not a function of any targets. Expose it separately, 353 # currently only used by LLVM for enabling BFD to do LTO with LLVM bitcode. 354 # (Tar will exit with an error if there are no matches). 355 plugin-api-header = runCommand "libbfd-plugin-api-header" { } '' 356 mkdir -p $out 357 tar --directory=$out \ 358 --extract \ 359 --file=${finalAttrs.src} \ 360 --strip-components=1 \ 361 --wildcards '*'/include/plugin-api.h 362 ''; 363 }; 364 365 meta = { 366 description = "Tools for manipulating binaries (linker, assembler, etc.)"; 367 longDescription = '' 368 The GNU Binutils are a collection of binary tools. The main 369 ones are `ld' (the GNU linker) and `as' (the GNU assembler). 370 They also include the BFD (Binary File Descriptor) library, 371 `gprof', `nm', `strip', etc. 372 ''; 373 homepage = "https://www.gnu.org/software/binutils/"; 374 license = lib.licenses.gpl3Plus; 375 maintainers = with lib.maintainers; [ 376 ericson2314 377 lovesegfault 378 ]; 379 platforms = lib.platforms.unix; 380 381 # INFO: Give binutils a lower priority than gcc-wrapper to prevent a 382 # collision due to the ld/as wrappers/symlinks in the latter. 383 priority = 10; 384 }; 385})