Operations like `nix eval --file '<nixpkgs>' hello.name` are supposed
to be lazy in the sense that they shouldn't cause any derivations to
be instantiated. However, this was not the case anymore, e.g.
$ time nix eval --file '<nixpkgs>' hello.name -vvvvvvv 2>&1 | grep -c 'copying.*to the store\|^instantiated'
1145
real 0m0.359s
In fact, even evaluating `lib.version` triggers 1145 paths to be
copied to the store. (Why `lib` causes a bunch of derivations to be
evaluated is another issue...)
The reason for this is that cc-wrapper has assertions like
assert libc_bin == bintools.libc_bin
which which Nix implements by comparing their outPaths. Computing an
outPath calls derivationStrict, causing the .drv closure of the
bootstrap libc to be written to the store. Since these asserts ran
whenever a cc-wrapper derivation was forced to WHNF (which the stdenv
bootstrap stage assertions do on every evaluation of the Nixpkgs top
level), merely evaluating e.g. 'hello.name' wrote over a thousand .drv
files.
Now the asserts are (arbitrarily) moved under `unpackPhase`, which is
only forced when the derivation is actually instantiated, so
evaluating metadata attributes stays free of store writes:
$ time nix eval --file '<nixpkgs>' hello.name -vvvvvvv 2>&1 | grep -c 'copying.*to the store\|^instantiated'
0
real 0m0.113s
Assisted-by: Claude Fable 5 <noreply@anthropic.com>
TLSDESC is a more performant way of doing TLS, since it has a custom
calling convention that does not require the caller (of what's usually
__tls_get_addr) to spill clobbered registers and assumes that the callee
preserves all registers.
This adds corresponding plumbing in the machineFlags in the cc-wrapper
that includes version gates for compilers. TLSDESC needs to be supported
by the bintools and libc, so I've only enabled it for architectures that
our packaged glibc, musl, GNU binutils support (x86, x86_64).
We package a lot of LLVM versions and support for -mtls-dialect in the
Clang driver has only landed in LLVM 19, so a version check is added
there too.
Ideally we'd set the default at GCC build-time, but LLVM lacks such an
option, so we'd have to keep it in the compiler wrapper for now.
Gentoo is already building with it by default [1], as is Fedora [2].
In glibc < 2.40 [3] there existed a bug with not all registers being
preserved, but it has since been resolved. x86 support has existed
since basically forever with LLVM adding support in LLVM >= 19.1.
LoongArch support has been added recently too, but it's only available
since musl 1.2.6 while we are stuck at 1.2.5 for now, so I haven't dug
deeper. Aarch64 uses TLSDESC by default already.
The support status on non-Linux is a bit unclear, so these defaults are
scoped only to linux targets.
Sadly RISC-V support is still cooking apparently [4].
See: https://maskray.me/blog/2021-02-14-all-about-thread-local-storage
See: https://groups.google.com/g/x86-64-abi/c/0tjmaQx6nZ0
[1]: https://github.com/gentoo/gentoo/commit/46191b478ebcb6bc6831627526da44f04dfcd1be
[2]: https://src.fedoraproject.org/rpms/gcc/c/8f8d2ea9c326784bce044ff86547107611dda338?branch=rawhide
[3]: https://sourceware.org/bugzilla/show_bug.cgi?id=31372
[4]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/494
Inline optionalAttrs for Go passthru attrs and fallback_sdk.
Replace mapAttrs+optionalString for Darwin env vars with direct
optionalString calls, eliminating intermediate attrset and // merge.
Build on the initial LLVM Flang wrapper work by exposing the needed clang passthru and teaching cc-wrapper about flang-specific flag handling.
Co-authored-by: stove <stove@rivosinc.com>
Co-authored-by: acture <acture@gmail.com>
Co-authored-by: Emily <hello@emily.moe>
Co-authored-by: Philip Taron <philip.taron@gmail.com>
The libc++ headers are expected to be found in the sysroot when `clang`
is invoked for C++ code.
Always making them available improves compatibility with build systems
like Bazel and SwiftPM, which try to compile C++ code with `clang`.
as with glibcxxassertions, we don't yet have a nice mechanism
for deferring support decisions to the c++ library in use, so
for now at least enabling this hardening flag will cause
_LIBCPP_HARDENING_MODE to be defined on all compilers
All hardening options have identical spelling to their names except the
`stack-clash-protection`. As a result just copying it to `hardeningDisable`
from the warning log does not work. Let's fix the discrepancy.
go1: warning: command-line option '-Wformat=1' is valid for C/C++/ObjC/ObjC++ but not for Go
go1: warning: command-line option '-Wformat-security' is valid for C/C++/ObjC/ObjC++ but not for Go
go1: warning: '-Werror=' argument '-Werror=format-security' is not valid for Go
no platforms "unsupported" because we don't have a nice
mechanism for determining a platform's c++ lib and the flag
should be harmlessly ignored by a other c++ libs
GDC 11 was the last version that could bootstrap without a D compiler,
and GDC don’t offer their own binaries any more. GCC 11 is now
end‐of‐life and being removed (as is GCC 12, even).
It’s possible that we could use another distribution’s binary
packages to bootstrap this, or go via our DMD package (it’s
apparently not possible to bootstrap GDC with LDC, but I’m not sure
about DMD), but as nobody has worked on it in the three years since
GCC 12 came out, it seems like interest is limited, and it’s more
of a yak shave than I’m up for right now.
A full from‐source bootstrap chain would of course be nice, but is
more the realm of the minimal bootstrap work than something we’d
want to keep GCC 11 around in the main package set indefinitely for.
Without the change both `s390` and `s390x` `glibc` builds fail as
https://hydra.nixos.org/build/303208799:
In file included from ../sysdeps/s390/utf16-utf32-z9.c:501,
from ../sysdeps/s390/multiarch/utf16-utf32-z9.c:20:
../iconv/loop.c: In function '__from_utf16_loop_vx_cu':
../iconv/loop.c:274:1: error: %r11 cannot be used in 'asm' here
274 | }
| ^
Disable the `-fno-omit-frame-pointer` for now.
Because we're building things separately, we don't need the fancy
lib/... namespacing tricks that GCC normally does to squeeze itself in
the FHS. We can just use the normal autotools libdir and include dir,
and the nixpkgs infra will sort everything out.
Where possible I submitted patches to the mailing list, and fetched
those. The ones I am vendoring are the residuals which I don't think are
ready for upstreaming yet. (I can imagine a further reworking upstream
such that we wouldn't need our own patches of that sort, but it would be
good to get the first crop merged first before discussing that.)
Clang cannot handle the gnuabielfv{1,2} ABI specification in the triplet properly. It used to parse it as just "gnu", disregarding the ABI version in it and defaulting to ELFv1. Now, it completely fails to parse such target triplet:
> clang: error: version 'abielfv1' in target triple 'powerpc64-unknown-linux-gnuabielfv1' is invalid
So when it comes time to passing the target triplet to Clang, handle this support deficiency:
1. If the triplet ends in gnuabielfv*, shorten it to just gnu. This makes it get parsed properly.
2. After the above, re-add the ABI via the separate -mabi option. This makes it use the correct ABI for the platform.