Having all 3 of binutils, libbfd, libopcodes in one directory eases
copying of the whole directory when we need to hold back old version of
the whole of binutils or of it's pieces.
Before the change 'postFixup' was breaking binaries as it deleted `libctf.so`'s
dependency without fixing the links (https://hydra.nixos.org/build/173957444):
objdump:
symbol lookup error: ...-binutils-2.38/lib/libctf.so.0: undefined symbol: htab_eq_string
Instead of tying binutils and libbfd together let's stop replacing the
libraries and use local copies. They are not mechanically interchangeable.
Ideally binutils' upstream build system should allow linking external
`libbfd`/`libopcodes`/`libctf` but we are not there yet.
Upstream binutils is missing sensible defaults for a few flags
(notably linker personality) when cross-compiling to
mips64el-*-*abi64.
Most of the time this isn't an issue because packages that invoke the
linker directly detect the flags from gcc's behavior (for example,
libtool does this) and gcc has good code for detecting the right
defaults. However some do not; notably nix, itself lacks this.
Presumably Debian is working on upstreaming this, and has more clout
than we do. I propose we carry their patch in the meantime. The
patch is conditioned on stdenv.targetPlatform.isMips64n64 in order to
avoid mass-rebuilds.
Closes#164835.
Otherwise the patch application fails as:
applying patch /nix/store/y0l0144l12q7jpq4jv735shgxv8ygxwh-build-components-separately.patch
1 out of 3 hunks FAILED -- saving rejects to file opcodes/Makefile.am.rej
1 out of 2 hunks FAILED -- saving rejects to file opcodes/configure.ac.rej
1 out of 2 hunks FAILED -- saving rejects to file opcodes/configure.ac.rej
ld.gold is “A new, faster, ELF only linker”. Thus we only should pass
the configure flag --with-gold if our target platform will actually
support gold (in which case binutil's configure script silently
disables it).
With this change, not only will configureFlags represent the actual
configuration more closely, but we can also expose if the binutils
derivation contains ld.gold via a passthru attr. Specifically this
means that:
nix-repl> pkgsCross.mingwW64.stdenv.cc.bintools.bintools.hasGold
false
The intended way to use this is to check
`stdenv.cc.bintools.bintools or false` which returns accurate results
regardless of the actual linker derivation.
TODO: maybe also add hasGold to binutils wrapper as it also symlinks
ld.gold in?
Backport patch from 2.36 so that gold can succeed in linking programs without complaining
unknown program property type 0xc0008002 in .note.gnu.property section
Should fix: https://github.com/NixOS/nixpkgs/issues/134190
The binutils build system checks by itself if it is building a cross
toolchain or not and prepends or omits a targetPrefix accordingly. This
means that we can always pass target via configureTargets.
However the binutils build system and our bintools wrapper disagree over
whether we are building a cross toolchain or not sometimes since cross
compilation can be relatively subtle in nixpkgs. For example every use
of crossOverlays will make nixpkgs build a cross toolchain even though
localSystem == crossSystem. The cross infrastructure is also used to
build native binaries with a different stdenv (musl instead of glibc,
clang instead of gcc). In all of these cases stdenv.hostPlatform.config
== stdenv.targetPlatform.config, causing binutils to not prepend a
target prefix. At the same time stdenv.hostPlatform !=
stdenv.targetPlatform causing the bintools wrapper to expect a target
prefix, thus building an incomplete set of bintools. This is why
currently pkgsCross.gnu64 and pkgsCross.musl64 aren't working.
The solution is quite simple however: If we detect that we are building
a cross toolchain in the binutils-unwrapped expression, we force the
targetPrefix with --programprefix and fulfill the expectations of the
bintools wrapper at the same time.
Tested (on x86_64-linux):
* pkgsCross.musl64.hello
* pkgsCross.aarch64-multiplatform.hello
* pkgs.hello
Still not working is pkgsCross.gnu64, since
x86_64-unknown-linux-gnu-stage-final-gcc gets confused about targets
now, so bootstrapping the stdenv fails. Since this wasn't working
previously anyways, it's proably fine to fix this separately.
Instead of always supplying flags, apply the flags as defaults. Use
clang's native flags instead of lifting the linker flags from binutils
with `-Wl,`.
If a project is using clang to drive linking, make clang do the right
thing with MACOSX_DEPLOYMENT_TARGET. This can be overridden by command
line arguments. This will cause modern clang to pass
`-platform_version 10.12 0.0.0`, since it doesn't know about the SDK
settings. Older versions of clang will pass down `-macos_version_min`
flags with no sdk version.
At the linker layer, apply a default value for anything left
ambiguous. If nothing is specified, pass a full
`-platform_version`. If only `-macos_version_min` is specified, then
lock down the sdk_version explicitly with `-sdk_version`. If a min
version and sdk version is passed, do nothing.
We can use use `stdenv.hostPlatform.isStatic` instead, and move the
logic per package. The least opionated benefit of this is that it makes
it much easier to replace packages with modified ones, as there is no
longer any issue of overlay order.
CC @FRidh @matthewbauer