2 withGold = platform: platform.isElf && !platform.isRiscV && !platform.isLoongArch64;
7 , autoconf269, automake, libtool
20 , enableGold ? withGold stdenv.targetPlatform
21 , enableGoldDefault ? false
22 , enableShared ? !stdenv.hostPlatform.isStatic
23 # WARN: Enabling all targets increases output size to a multiple.
24 , withAllTargets ? false
27 # WARN: configure silently disables ld.gold if it's unsupported, so we need to
28 # make sure that intent matches result ourselves.
29 assert enableGold -> withGold stdenv.targetPlatform;
30 assert enableGoldDefault -> enableGold;
34 inherit (stdenv) buildPlatform hostPlatform targetPlatform;
40 url = "mirror://gnu/binutils/binutils-${version}.tar.bz2";
41 hash = "sha256-pMS+wFL3uDcAJOYDieGUN38/SLVmGEGOpRBn9nqqsws=";
43 vc4-none = fetchFromGitHub {
45 repo = "binutils-vc4";
46 rev = "708acc851880dbeda1dd18aca4fd0a95b2573b36";
47 sha256 = "1kdrz6fki55lm15rwwamn74fnqpy0zlafsida2zymk76n3656c63";
51 #INFO: The targetPrefix prepended to binary names to allow multiple binuntils
52 # on the PATH to both be usable.
53 targetPrefix = lib.optionalString (targetPlatform != hostPlatform) "${targetPlatform.config}-";
56 stdenv.mkDerivation (finalAttrs: {
57 pname = targetPrefix + "binutils";
60 # HACK: Ensure that we preserve source from bootstrap binutils to not rebuild LLVM
61 src = stdenv.__bootPackages.binutils-unwrapped.src
62 or srcs.${targetPlatform.system}
65 # WARN: this package is used for bootstrapping fetchurl, and thus cannot use
66 # fetchpatch! All mutable patches (generated by GitHub or cgit) that are
67 # needed here should be included directly in Nixpkgs as files.
69 # Upstream patch to fix llvm testsuite failure when loading powerpc
71 # https://sourceware.org/PR30794
72 ./gold-powerpc-for-llvm.patch
74 # Make binutils output deterministic by default.
78 # Breaks nm BSD flag detection, heeds an upstream fix:
79 # https://sourceware.org/PR29547
80 ./0001-Revert-libtool.m4-fix-the-NM-nm-over-here-B-option-w.patch
81 ./0001-Revert-libtool.m4-fix-nm-BSD-flag-detection.patch
83 # Required for newer macos versions
84 ./0001-libtool.m4-update-macos-version-detection-block.patch
86 # For some reason bfd ld doesn't search DT_RPATH when cross-compiling. It's
87 # not clear why this behavior was decided upon but it has the unfortunate
88 # consequence that the linker will fail to find transitive dependencies of
89 # shared objects when cross-compiling. Consequently, we are forced to
90 # override this behavior, forcing ld to search DT_RPATH even when
92 ./always-search-rpath.patch
94 # Avoid `lib -> out -> lib` reference. Normally `bfd-plugins` does
95 # not need to know binutils' BINDIR at all. It's an absolute path
96 # where libraries are stored.
97 ./plugins-no-BINDIR.patch
99 ++ lib.optional targetPlatform.isiOS ./support-ios.patch
100 # Adds AVR-specific options to "size" for compatibility with Atmel's downstream distribution
101 # Patch from arch-community
102 # https://github.com/archlinux/svntogit-community/blob/c8d53dd1734df7ab15931f7fad0c9acb8386904c/trunk/avr-size.patch
103 ++ lib.optional targetPlatform.isAvr ./avr-size.patch
104 ++ lib.optional stdenv.targetPlatform.isWindows ./windres-locate-gcc.patch
107 outputs = [ "out" "info" "man" "dev" ]
108 # Ideally we would like to always install 'lib' into a separate
109 # target. Unfortunately cross-compiled binutils installs libraries
110 # across both `$lib/lib/` and `$out/$target/lib` with a reference
111 # from $out to $lib. Probably a binutils bug: all libraries should go
112 # to $lib as binutils does not build target libraries. Let's make our
113 # life slightly simpler by installing everything into $out for
115 ++ lib.optionals (targetPlatform == hostPlatform) [ "lib" ];
118 depsBuildBuild = [ buildPackages.stdenv.cc ];
119 # texinfo was removed here in https://github.com/NixOS/nixpkgs/pull/210132
120 # to reduce rebuilds during stdenv bootstrap. Please don't add it back without
121 # checking the impact there first.
122 nativeBuildInputs = [
126 ++ lib.optionals targetPlatform.isiOS [ autoreconfHook ]
127 ++ lib.optionals buildPlatform.isDarwin [ autoconf269 automake gettext libtool ]
128 ++ lib.optionals targetPlatform.isVc4 [ flex ]
131 buildInputs = [ zlib gettext ];
135 preConfigure = (lib.optionalString buildPlatform.isDarwin ''
136 for i in */configure.ac; do
137 pushd "$(dirname "$i")"
138 echo "Running autoreconf in $PWD"
139 # autoreconf doesn't work, don't know why
140 # autoreconf ''${autoreconfFlags:---install --force --verbose}
145 # Clear the default library search path.
146 if test "$noSysDirs" = "1"; then
147 echo 'NATIVE_LIB_DIRS=' >> ld/configure.tgt
150 # Use symlinks instead of hard links to save space ("strip" in the
151 # fixup phase strips each hard link separately).
152 for i in binutils/Makefile.in gas/Makefile.in ld/Makefile.in gold/Makefile.in; do
153 sed -i "$i" -e 's|ln |ln -s |'
156 # autoreconfHook is not included for all targets.
157 # Call it here explicitly as well.
158 ${finalAttrs.postAutoreconf}
162 # As we regenerated configure build system tries hard to use
163 # texinfo to regenerate manuals. Let's avoid the dependency
164 # on texinfo in bootstrap path and keep manuals unmodified.
165 touch gas/doc/.dirstamp
166 touch gas/doc/asconfig.texi
168 touch gas/doc/as.info
171 # As binutils takes part in the stdenv building, we don't want references
172 # to the bootstrap-tools libgcc (as uses to happen on arm/mips)
173 env.NIX_CFLAGS_COMPILE =
174 if hostPlatform.isDarwin
175 then "-Wno-string-plus-int -Wno-deprecated-declarations"
176 else "-static-libgcc";
178 hardeningDisable = [ "format" "pie" ];
180 configurePlatforms = [ "build" "host" "target" ];
183 "--enable-64-bit-bfd"
186 "--enable-deterministic-archives"
188 "--enable-fix-loongson2f-nop"
190 # Turn on --enable-new-dtags by default to make the linker set
191 # RUNPATH instead of RPATH on binaries. This is important because
192 # RUNPATH can be overridden using LD_LIBRARY_PATH at runtime.
195 # force target prefix. Some versions of binutils will make it empty if
196 # `--host` and `--target` are too close, even if Nixpkgs thinks the
197 # platforms are different (e.g. because not all the info makes the
198 # `config`). Other versions of binutils will always prefix if `--target` is
199 # passed, even if `--host` and `--target` are the same. The easiest thing
200 # for us to do is not leave it to chance, and force the program prefix to be
201 # what we want it to be.
202 "--program-prefix=${targetPrefix}"
204 # Unconditionally disable:
205 # - musl target needs porting: https://sourceware.org/PR29477
208 # By default binutils searches $libdir for libraries. This brings in
209 # libbfd and libopcodes into a default visibility. Drop default lib
210 # path to force users to declare their use of these libraries.
213 ++ lib.optionals withAllTargets [ "--enable-targets=all" ]
214 ++ lib.optionals enableGold [
215 "--enable-gold${lib.optionalString enableGoldDefault "=default"}"
217 ] ++ (if enableShared
218 then [ "--enable-shared" "--disable-static" ]
219 else [ "--disable-shared" "--enable-static" ])
225 # Break dependency on pkgsBuildBuild.gcc when building a cross-binutils
226 stripDebugList = if stdenv.hostPlatform != stdenv.targetPlatform then "bin lib ${stdenv.hostPlatform.config}" else null;
228 # INFO: Otherwise it fails with:
229 # `./sanity.sh: line 36: $out/bin/size: not found`
230 doInstallCheck = (buildPlatform == hostPlatform) && (hostPlatform == targetPlatform);
232 enableParallelBuilding = true;
234 # For the same reason we don't split "lib" output we undo the $target/
235 # prefix for installed headers and libraries we link:
236 # $out/$host/$target/lib/* to $out/lib/
237 # $out/$host/$target/include/* to $dev/include/*
238 # TODO(trofi): fix installation paths upstream so we could remove this
239 # code and have "lib" output unconditionally.
240 postInstall = lib.optionalString (hostPlatform.config != targetPlatform.config) ''
241 ln -s $out/${hostPlatform.config}/${targetPlatform.config}/lib/* $out/lib/
242 ln -s $out/${hostPlatform.config}/${targetPlatform.config}/include/* $dev/include/
246 inherit targetPrefix;
247 hasGold = enableGold;
249 # Having --enable-plugins is not enough, system has to support
250 # dlopen() or equivalent. See config/plugins.m4 and configure.ac
251 # (around PLUGINS) for cases that support or not support plugins.
252 # No platform specific filters yet here.
253 hasPluginAPI = enableGold;
257 description = "Tools for manipulating binaries (linker, assembler, etc.)";
259 The GNU Binutils are a collection of binary tools. The main
260 ones are `ld' (the GNU linker) and `as' (the GNU assembler).
261 They also include the BFD (Binary File Descriptor) library,
262 `gprof', `nm', `strip', etc.
264 homepage = "https://www.gnu.org/software/binutils/";
265 license = licenses.gpl3Plus;
266 maintainers = with maintainers; [ ericson2314 lovesegfault ];
267 platforms = platforms.unix;
269 # INFO: Give binutils a lower priority than gcc-wrapper to prevent a
270 # collision due to the ld/as wrappers/symlinks in the latter.