Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1let
2 withGold = platform: platform.parsed.kernel.execFormat.name == "elf" && !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, enableShared ? !stdenv.hostPlatform.isStatic
22 # WARN: Enabling all targets increases output size to a multiple.
23, withAllTargets ? false
24}:
25
26# WARN: configure silently disables ld.gold if it's unsupported, so we need to
27# make sure that intent matches result ourselves.
28assert enableGold -> withGold stdenv.targetPlatform;
29
30
31let
32 inherit (stdenv) buildPlatform hostPlatform targetPlatform;
33
34 version = "2.40";
35
36 srcs = {
37 normal = fetchurl {
38 url = "mirror://gnu/binutils/binutils-${version}.tar.bz2";
39 hash = "sha256-+CmOsVOks30RLpRapcsoUAQLzyaj6mW1pxXIOv4F5Io=";
40 };
41 vc4-none = fetchFromGitHub {
42 owner = "itszor";
43 repo = "binutils-vc4";
44 rev = "708acc851880dbeda1dd18aca4fd0a95b2573b36";
45 sha256 = "1kdrz6fki55lm15rwwamn74fnqpy0zlafsida2zymk76n3656c63";
46 };
47 };
48
49 #INFO: The targetPrefix prepended to binary names to allow multiple binuntils
50 # on the PATH to both be usable.
51 targetPrefix = lib.optionalString (targetPlatform != hostPlatform) "${targetPlatform.config}-";
52in
53
54stdenv.mkDerivation (finalAttrs: {
55 pname = targetPrefix + "binutils";
56 inherit version;
57
58 # HACK: Ensure that we preserve source from bootstrap binutils to not rebuild LLVM
59 src = stdenv.__bootPackages.binutils-unwrapped.src
60 or srcs.${targetPlatform.system}
61 or srcs.normal;
62
63 # WARN: this package is used for bootstrapping fetchurl, and thus cannot use
64 # fetchpatch! All mutable patches (generated by GitHub or cgit) that are
65 # needed here should be included directly in Nixpkgs as files.
66 patches = [
67 # Make binutils output deterministic by default.
68 ./deterministic.patch
69
70
71 # Breaks nm BSD flag detection, heeds an upstream fix:
72 # https://sourceware.org/PR29547
73 ./0001-Revert-libtool.m4-fix-the-NM-nm-over-here-B-option-w.patch
74 ./0001-Revert-libtool.m4-fix-nm-BSD-flag-detection.patch
75
76 # Required for newer macos versions
77 ./0001-libtool.m4-update-macos-version-detection-block.patch
78
79 # For some reason bfd ld doesn't search DT_RPATH when cross-compiling. It's
80 # not clear why this behavior was decided upon but it has the unfortunate
81 # consequence that the linker will fail to find transitive dependencies of
82 # shared objects when cross-compiling. Consequently, we are forced to
83 # override this behavior, forcing ld to search DT_RPATH even when
84 # cross-compiling.
85 ./always-search-rpath.patch
86
87 # Avoid `lib -> out -> lib` reference. Normally `bfd-plugins` does
88 # not need to know binutils' BINDIR at all. It's an absolute path
89 # where libraries are stored.
90 ./plugins-no-BINDIR.patch
91
92 # CVE-2023-1972 fix to bfd/elf.c from:
93 # https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=c22d38baefc5a7a1e1f5cdc9dbb556b1f0ec5c57
94 ./CVE-2023-1972.patch
95 ]
96 ++ lib.optional targetPlatform.isiOS ./support-ios.patch
97 # Adds AVR-specific options to "size" for compatibility with Atmel's downstream distribution
98 # Patch from arch-community
99 # https://github.com/archlinux/svntogit-community/blob/c8d53dd1734df7ab15931f7fad0c9acb8386904c/trunk/avr-size.patch
100 ++ lib.optional targetPlatform.isAvr ./avr-size.patch
101 ++ lib.optional stdenv.targetPlatform.isWindows ./windres-locate-gcc.patch
102 ++ lib.optional stdenv.targetPlatform.isMips64n64
103 # this patch is from debian:
104 # https://sources.debian.org/data/main/b/binutils/2.38-3/debian/patches/mips64-default-n64.diff
105 (if stdenv.targetPlatform.isMusl
106 then substitute { src = ./mips64-default-n64.patch; replacements = [ "--replace" "gnuabi64" "muslabi64" ]; }
107 else ./mips64-default-n64.patch)
108 # This patch fixes a bug in 2.40 on MinGW, which breaks DXVK when cross-building from Darwin.
109 # See https://sourceware.org/bugzilla/show_bug.cgi?id=30079
110 ++ lib.optional stdenv.targetPlatform.isMinGW ./mingw-abort-fix.patch
111 ;
112
113 outputs = [ "out" "info" "man" "dev" ]
114 # Ideally we would like to always install 'lib' into a separate
115 # target. Unfortunately cross-compiled binutils installs libraries
116 # across both `$lib/lib/` and `$out/$target/lib` with a reference
117 # from $out to $lib. Probably a binutils bug: all libraries should go
118 # to $lib as binutils does not build target libraries. Let's make our
119 # life slightly simpler by installing everything into $out for
120 # cross-binutils.
121 ++ lib.optionals (targetPlatform == hostPlatform) [ "lib" ];
122
123 strictDeps = true;
124 depsBuildBuild = [ buildPackages.stdenv.cc ];
125 # texinfo was removed here in https://github.com/NixOS/nixpkgs/pull/210132
126 # to reduce rebuilds during stdenv bootstrap. Please don't add it back without
127 # checking the impact there first.
128 nativeBuildInputs = [
129 bison
130 perl
131 ]
132 ++ lib.optionals targetPlatform.isiOS [ autoreconfHook ]
133 ++ lib.optionals buildPlatform.isDarwin [ autoconf269 automake gettext libtool ]
134 ++ lib.optionals targetPlatform.isVc4 [ flex ]
135 ;
136
137 buildInputs = [ zlib gettext ];
138
139 inherit noSysDirs;
140
141 preConfigure = (lib.optionalString buildPlatform.isDarwin ''
142 for i in */configure.ac; do
143 pushd "$(dirname "$i")"
144 echo "Running autoreconf in $PWD"
145 # autoreconf doesn't work, don't know why
146 # autoreconf ''${autoreconfFlags:---install --force --verbose}
147 autoconf
148 popd
149 done
150 '') + ''
151 # Clear the default library search path.
152 if test "$noSysDirs" = "1"; then
153 echo 'NATIVE_LIB_DIRS=' >> ld/configure.tgt
154 fi
155
156 # Use symlinks instead of hard links to save space ("strip" in the
157 # fixup phase strips each hard link separately).
158 for i in binutils/Makefile.in gas/Makefile.in ld/Makefile.in gold/Makefile.in; do
159 sed -i "$i" -e 's|ln |ln -s |'
160 done
161
162 # autoreconfHook is not included for all targets.
163 # Call it here explicitly as well.
164 ${finalAttrs.postAutoreconf}
165 '';
166
167 postAutoreconf = ''
168 # As we regenerated configure build system tries hard to use
169 # texinfo to regenerate manuals. Let's avoid the dependency
170 # on texinfo in bootstrap path and keep manuals unmodified.
171 touch gas/doc/.dirstamp
172 touch gas/doc/asconfig.texi
173 touch gas/doc/as.1
174 touch gas/doc/as.info
175 '';
176
177 # As binutils takes part in the stdenv building, we don't want references
178 # to the bootstrap-tools libgcc (as uses to happen on arm/mips)
179 env.NIX_CFLAGS_COMPILE =
180 if hostPlatform.isDarwin
181 then "-Wno-string-plus-int -Wno-deprecated-declarations"
182 else "-static-libgcc";
183
184 hardeningDisable = [ "format" "pie" ];
185
186 configurePlatforms = [ "build" "host" "target" ];
187
188 configureFlags = [
189 "--enable-64-bit-bfd"
190 "--with-system-zlib"
191
192 "--enable-deterministic-archives"
193 "--disable-werror"
194 "--enable-fix-loongson2f-nop"
195
196 # Turn on --enable-new-dtags by default to make the linker set
197 # RUNPATH instead of RPATH on binaries. This is important because
198 # RUNPATH can be overridden using LD_LIBRARY_PATH at runtime.
199 "--enable-new-dtags"
200
201 # force target prefix. Some versions of binutils will make it empty if
202 # `--host` and `--target` are too close, even if Nixpkgs thinks the
203 # platforms are different (e.g. because not all the info makes the
204 # `config`). Other versions of binutils will always prefix if `--target` is
205 # passed, even if `--host` and `--target` are the same. The easiest thing
206 # for us to do is not leave it to chance, and force the program prefix to be
207 # what we want it to be.
208 "--program-prefix=${targetPrefix}"
209
210 # Unconditionally disable:
211 # - musl target needs porting: https://sourceware.org/PR29477
212 "--disable-gprofng"
213
214 # By default binutils searches $libdir for libraries. This brings in
215 # libbfd and libopcodes into a default visibility. Drop default lib
216 # path to force users to declare their use of these libraries.
217 "--with-lib-path=:"
218 ]
219 ++ lib.optionals withAllTargets [ "--enable-targets=all" ]
220 ++ lib.optionals enableGold [ "--enable-gold" "--enable-plugins" ]
221 ++ (if enableShared
222 then [ "--enable-shared" "--disable-static" ]
223 else [ "--disable-shared" "--enable-static" ])
224 ;
225
226 # Fails
227 doCheck = false;
228
229 # Break dependency on pkgsBuildBuild.gcc when building a cross-binutils
230 stripDebugList = if stdenv.hostPlatform != stdenv.targetPlatform then "bin lib ${stdenv.hostPlatform.config}" else null;
231
232 # INFO: Otherwise it fails with:
233 # `./sanity.sh: line 36: $out/bin/size: not found`
234 doInstallCheck = (buildPlatform == hostPlatform) && (hostPlatform == targetPlatform);
235
236 enableParallelBuilding = true;
237
238 # For the same reason we don't split "lib" output we undo the $target/
239 # prefix for installed headers and libraries we link:
240 # $out/$host/$target/lib/* to $out/lib/
241 # $out/$host/$target/include/* to $dev/include/*
242 # TODO(trofi): fix installation paths upstream so we could remove this
243 # code and have "lib" output unconditionally.
244 postInstall = lib.optionalString (hostPlatform.config != targetPlatform.config) ''
245 ln -s $out/${hostPlatform.config}/${targetPlatform.config}/lib/* $out/lib/
246 ln -s $out/${hostPlatform.config}/${targetPlatform.config}/include/* $dev/include/
247 '';
248
249 passthru = {
250 inherit targetPrefix;
251 hasGold = enableGold;
252 isGNU = true;
253 # Having --enable-plugins is not enough, system has to support
254 # dlopen() or equivalent. See config/plugins.m4 and configure.ac
255 # (around PLUGINS) for cases that support or not support plugins.
256 # No platform specific filters yet here.
257 hasPluginAPI = enableGold;
258 };
259
260 meta = with lib; {
261 description = "Tools for manipulating binaries (linker, assembler, etc.)";
262 longDescription = ''
263 The GNU Binutils are a collection of binary tools. The main
264 ones are `ld' (the GNU linker) and `as' (the GNU assembler).
265 They also include the BFD (Binary File Descriptor) library,
266 `gprof', `nm', `strip', etc.
267 '';
268 homepage = "https://www.gnu.org/software/binutils/";
269 license = licenses.gpl3Plus;
270 maintainers = with maintainers; [ ericson2314 lovesegfault ];
271 platforms = platforms.unix;
272
273 # INFO: Give binutils a lower priority than gcc-wrapper to prevent a
274 # collision due to the ld/as wrappers/symlinks in the latter.
275 priority = 10;
276 };
277})