1let
2 withGold = platform: platform.isElf && !platform.isRiscV && !platform.isLoongArch64;
3in
4
5{ stdenv
6, autoreconfHook
7, autoconf269, automake, libtool
8, bison
9, buildPackages
10, fetchFromGitHub
11, fetchurl
12, flex
13, gettext
14, lib
15, noSysDirs
16, perl
17, substitute
18, zlib
19
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
25}:
26
27# WARN: configure silently disables ld.gold if it's unsupported, so we need to
28# make sure that intent matches result ourselves.
29assert enableGold -> withGold stdenv.targetPlatform;
30assert enableGoldDefault -> enableGold;
31
32
33let
34 inherit (stdenv) buildPlatform hostPlatform targetPlatform;
35
36 version = "2.41";
37
38 srcs = {
39 normal = fetchurl {
40 url = "mirror://gnu/binutils/binutils-${version}.tar.bz2";
41 hash = "sha256-pMS+wFL3uDcAJOYDieGUN38/SLVmGEGOpRBn9nqqsws=";
42 };
43 vc4-none = fetchFromGitHub {
44 owner = "itszor";
45 repo = "binutils-vc4";
46 rev = "708acc851880dbeda1dd18aca4fd0a95b2573b36";
47 sha256 = "1kdrz6fki55lm15rwwamn74fnqpy0zlafsida2zymk76n3656c63";
48 };
49 };
50
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}-";
54in
55
56stdenv.mkDerivation (finalAttrs: {
57 pname = targetPrefix + "binutils";
58 inherit version;
59
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}
63 or srcs.normal;
64
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.
68 patches = [
69 # Upstream patch to fix llvm testsuite failure when loading powerpc
70 # objects:
71 # https://sourceware.org/PR30794
72 ./gold-powerpc-for-llvm.patch
73
74 # Make binutils output deterministic by default.
75 ./deterministic.patch
76
77
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
82
83 # Required for newer macos versions
84 ./0001-libtool.m4-update-macos-version-detection-block.patch
85
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
91 # cross-compiling.
92 ./always-search-rpath.patch
93
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
98 ]
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
105 ;
106
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
114 # cross-binutils.
115 ++ lib.optionals (targetPlatform == hostPlatform) [ "lib" ];
116
117 strictDeps = true;
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 = [
123 bison
124 perl
125 ]
126 ++ lib.optionals targetPlatform.isiOS [ autoreconfHook ]
127 ++ lib.optionals buildPlatform.isDarwin [ autoconf269 automake gettext libtool ]
128 ++ lib.optionals targetPlatform.isVc4 [ flex ]
129 ;
130
131 buildInputs = [ zlib gettext ];
132
133 inherit noSysDirs;
134
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}
141 autoconf
142 popd
143 done
144 '') + ''
145 # Clear the default library search path.
146 if test "$noSysDirs" = "1"; then
147 echo 'NATIVE_LIB_DIRS=' >> ld/configure.tgt
148 fi
149
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 |'
154 done
155
156 # autoreconfHook is not included for all targets.
157 # Call it here explicitly as well.
158 ${finalAttrs.postAutoreconf}
159 '';
160
161 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
167 touch gas/doc/as.1
168 touch gas/doc/as.info
169 '';
170
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";
177
178 hardeningDisable = [ "format" "pie" ];
179
180 configurePlatforms = [ "build" "host" "target" ];
181
182 configureFlags = [
183 "--enable-64-bit-bfd"
184 "--with-system-zlib"
185
186 "--enable-deterministic-archives"
187 "--disable-werror"
188 "--enable-fix-loongson2f-nop"
189
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.
193 "--enable-new-dtags"
194
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}"
203
204 # Unconditionally disable:
205 # - musl target needs porting: https://sourceware.org/PR29477
206 "--disable-gprofng"
207
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.
211 "--with-lib-path=:"
212 ]
213 ++ lib.optionals withAllTargets [ "--enable-targets=all" ]
214 ++ lib.optionals enableGold [
215 "--enable-gold${lib.optionalString enableGoldDefault "=default"}"
216 "--enable-plugins"
217 ] ++ (if enableShared
218 then [ "--enable-shared" "--disable-static" ]
219 else [ "--disable-shared" "--enable-static" ])
220 ;
221
222 # Fails
223 doCheck = false;
224
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;
227
228 # INFO: Otherwise it fails with:
229 # `./sanity.sh: line 36: $out/bin/size: not found`
230 doInstallCheck = (buildPlatform == hostPlatform) && (hostPlatform == targetPlatform);
231
232 enableParallelBuilding = true;
233
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/
243 '';
244
245 passthru = {
246 inherit targetPrefix;
247 hasGold = enableGold;
248 isGNU = true;
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;
254 };
255
256 meta = with lib; {
257 description = "Tools for manipulating binaries (linker, assembler, etc.)";
258 longDescription = ''
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.
263 '';
264 homepage = "https://www.gnu.org/software/binutils/";
265 license = licenses.gpl3Plus;
266 maintainers = with maintainers; [ ericson2314 lovesegfault ];
267 platforms = platforms.unix;
268
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.
271 priority = 10;
272 };
273})