LLVM stdenvs lack a set of `__atomic_*` routines that compilers
sometimes rely on, making it impossible to build certain C programs in
them. The reason we lack these routines is that we're using neither
compiler-rt's implementation of them (which was disabled by default a
long time ago) nor gcc's implementation (libatomic). See #391740 for a
more detailed explanation and an example of program that cannot be built.
Since no particular preference was expressed as to which approach
should be used to solve this, I'm going with LLVM's implementation
and recommended setup, which seems to be used also in AIX, Fuchsia
and Apple platforms. This consists of enabling a CMake flag,
`COMPILER_RT_BUILD_STANDALONE_LIBATOMIC`, which causes the routines to
be built and shipped in a separate DSO (placing them in a DSO instead
of `builtins.a` is needed for correctness, as it ensures the lock
section is unique in memory).
As with the other builtins, I'm symlinking this DSO to `libatomic.so` so
that downstream packages don't need specific/complicated logic for LLVM.
Other details:
- For static platforms, since no dynamic linking is expected at all, it
should be correct to ship the symbols in `builtins.a`.
So, that's what I'm doing in those cases.
- Since v19, compiler-rt allows using pthread locks rather than ad-hoc
ones for the atomic routines. Since this plays better with
instrumentation, I'm enabling this whenever libc is available.
- It would be nice to put the DSO in a separate output / derivation, so
that the rest of compiler-rt isn't pulled into the runtime closure,
but it isn't high prio since compiler-rt doesn't pull in dependencies
other than libc, libc++ and unwinder.
Fixes: https://github.com/NixOS/nixpkgs/issues/311930
$CPATH is taken to mean the same thing as -I by clang, whereas
$C_INCLUDE_PATH is -isystem. Using $CPATH means tools like clangd will
generate warnings for problems in system headers, which is undesirable.
See llvm/llvm-project#154015
This commit was created by a combination of scripts and tools:
- an ast-grep script to prefix things in meta with `lib.`,
- a modified nixf-diagnose / nixf combination to remove unused `with
lib;`, and
- regular nixfmt.
Co-authored-by: Wolfgang Walther <walther@technowledgy.de>
- add patch from 2 upstream commits that were not backported to llvm_18
and llvm_19:
41eb186fbb
Fixes build failure with gcc15:
```
In file included from /build/mlir-src-18.1.8/mlir/lib/Dialect/Affine/IR/ValueBoundsOpInterfaceImpl.cpp:9:
/build/mlir-src-18.1.8/mlir/include/mlir/Dialect/Affine/IR/ValueBoundsOpInterfaceImpl.h:31:11:
error: 'int64_t' was not declared in this scope
31 | FailureOr<int64_t> fullyComposeAndComputeConstantDelta(Value value1,
| ^~~~~~~
/build/mlir-src-18.1.8/mlir/include/mlir/Dialect/Affine/IR/ValueBoundsOpInterfaceImpl.h:13:1:
note: 'int64_t' is defined in header '<cstdint>'; this is probably
fixable by adding '#include <cstdint>'
12 | #include "mlir/Support/LogicalResult.h"
+++ |+#include <cstdint>
13 |
```
101109fc54
Fixes failure with gcc15:
```
In file included from /build/mlir-src-19.1.7/mlir/lib/Target/SPIRV/Deserialization/Deserialization.cpp:9:
/build/mlir-src-19.1.7/mlir/include/mlir/Target/SPIRV/Deserialization.h:29:51:
error: 'uint32_t' was not declared in this scope
29 | OwningOpRef<spirv::ModuleOp> deserialize(ArrayRef<uint32_t> binary,
| ^~~~~~~~
/build/mlir-src-19.1.7/mlir/include/mlir/Target/SPIRV/Deserialization.h:18:1:
note: 'uint32_t' is defined in header '<cstdint>'; this is probably
fixable by adding '#include <cstdint>'
17 | #include "mlir/Support/LLVM.h"
+++ |+#include <cstdint>
18 |
```
First patch can be applied with `fetchpatch`, but only on llvm_19, because
of changed include line right above.
So use 2 versions of combined patches with 2 commits.
- add patch from upstream commit that was not backported to llvm_18:
bb59f04e7e
Fixes build failure with gcc15:
```
In file included from /build/lldb-src-18.1.8/lldb/source/Utility/AddressableBits.cpp:9:
/build/lldb-src-18.1.8/lldb/include/lldb/Utility/AddressableBits.h:25:27:
error: 'uint32_t' has not been declared
25 | void SetAddressableBits(uint32_t addressing_bits);
| ^~~~~~~~
/build/lldb-src-18.1.8/lldb/include/lldb/Utility/AddressableBits.h:13:1:
note: 'uint32_t' is defined in header '<cstdint>'; this is probably
fixable by adding '#include <cstdint>'
12 | #include "lldb/lldb-forward.h"
+++ |+#include <cstdint>
13 |
```
Cannot use `fetchpatch` because patch does not apply on llvm_18
(no `#include "lldb/lldb-public.h"` line on llvm_18).
- add combined patch from 2 upstream commits that were not backported
to llvm_18:
8f39502b85
Fixes build failure with gcc15:
```
In file included from /build/llvm-src-18.1.8/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp:14:
/build/llvm-src-18.1.8/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h:44:43:
error: 'uint8_t' has not been declared
44 | createAMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI,
| ^~~~~~~
/build/llvm-src-18.1.8/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h:19:1:
note: 'uint8_t' is defined in header '<cstdint>'; this is probably fixable by adding '#include <cstdint>'
18 | #include <memory>
+++ |+#include <cstdint>
19 |
```
7abf44069a
Fixes build failure with gcc15:
```
In file included from /build/llvm-src-18.1.8/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h:19,
from /build/llvm-src-18.1.8/llvm/lib/Target/X86/MCTargetDesc/X86EncodingOptimization.cpp:14:
/build/llvm-src-18.1.8/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h:86:50:
error: 'uint64_t' has not been declared
86 | int MemoryOperand, uint64_t TSFlags);
| ^~~~~~~~
/build/llvm-src-18.1.8/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h:18:1:
note: 'uint64_t' is defined in header '<cstdint>'; this is probably
fixable by adding '#include <cstdint>'
17 | #include <string>
+++ |+#include <cstdint>
18 |
```
Cannot use `fetchpatch` because second patch does not apply on llvm_18,
no `#include "llvm/ADT/SmallVector.h"` line present on llvm_18.
So vendor combined patch from 2 commits.
This is necessary after https://github.com/NixOS/nixpkgs/pull/445095,
which moved libc++ to -cxx-isystem to improve compatibility with build
systems that invoke `clang` to compile C++ code.
This was used in 4b07aeae16 to get
what was actually a *host* LLVM in practice, when the `buildHost`
LLVM package set was included in the `callPackage` scope used for
libraries. It should no longer be necessary and is now quite confusing.