Files
nixpkgs/pkgs/development/compilers/llvm/common/compiler-rt/default.nix
Vladimír Čunát 75568a3200 llvmPackages_22.compiler-rt: improve conditional precision
In case of 22 the upstream commit is
9b722024f1
(which reaches tags 22.1.5+, by github.com UI)

Practical issue solved by this is most pkgsRocm based on 22.0.0:
https://hydra.nixos.org/build/339955996/nixlog/3/tail
2026-07-31 13:22:46 +02:00

326 lines
14 KiB
Nix
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
lib,
stdenv,
llvm_meta,
release_version,
version,
src ? null,
monorepoSrc ? null,
runCommand,
cmake,
ninja,
python3,
jq,
libcxx,
linuxHeaders,
freebsd,
# Some platforms have switched to using compiler-rt, but still want a
# libgcc.a for ABI compat purposes. The use case would be old code that
# expects to link `-lgcc` but doesn't care exactly what its contents
# are, so long as it provides some builtins.
doFakeLibgcc ? stdenv.hostPlatform.isFreeBSD,
# Whether to build the set of __atomic_* routines that would typically
# be provided by libatomic in gcc environments.
withAtomics ?
stdenv.hostPlatform.useLLVM
&& ((stdenv.cc.libc != null) || !stdenv.hostPlatform.hasSharedLibraries),
# If withAtomics is enabled, setting this to true ships those routines
# in a separate DSO (aliased as libatomic to match gcc's) rather than
# making them part of builtins.a. Unless no dynamic linking is used at
# all, this is the correct setup as it ensures the locks are unique in
# memory.
withAtomicsLib ? stdenv.hostPlatform.hasSharedLibraries,
# If withAtomics is enabled, this selects the pthreads-based
# implementation of the routines instead of the implementation
# using ad-hoc mutexes (which doesn't depend on libc at all).
# Use of pthreads helps code play better with sanitizers.
withAtomicsPthread ? lib.versionAtLeast release_version "19" && stdenv.cc.libc != null,
# In recent releases, the compiler-rt build seems to produce
# many `libclang_rt*` libraries, but not a single unified
# `libcompiler_rt` library, at least under certain configurations. Some
# platforms still expect this, however, so we symlink one into place.
forceLinkCompilerRt ? stdenv.hostPlatform.isOpenBSD,
devExtraCmakeFlags ? [ ],
getVersionFile,
fetchpatch,
}:
let
useLLVM = stdenv.hostPlatform.useLLVM or false;
bareMetal = stdenv.hostPlatform.parsed.kernel.name == "none";
haveLibc = stdenv.cc.libc != null;
# TODO: Make this account for GCC having libstdcxx, which will help
# use clean up the `cmakeFlags` rats nest below.
haveLibcxx = stdenv.cc.libcxx != null;
isDarwinStatic = stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isStatic;
inherit (stdenv.hostPlatform) isMusl isAarch64 isWindows;
noSanitizers = !haveLibc || bareMetal || isMusl || isDarwinStatic || isWindows;
in
stdenv.mkDerivation (finalAttrs: {
pname = "compiler-rt${lib.optionalString haveLibc "-libc"}";
inherit version;
src =
if monorepoSrc != null then
runCommand "compiler-rt-src-${version}" { inherit (monorepoSrc) passthru; } (
''
mkdir -p "$out"
cp -r ${monorepoSrc}/cmake "$out"
''
+ lib.optionalString (lib.versionAtLeast release_version "21") ''
cp -r ${monorepoSrc}/third-party "$out"
''
+ ''
cp -r ${monorepoSrc}/compiler-rt "$out"
cp -r ${monorepoSrc}/llvm "$out"
''
)
else
src;
sourceRoot = "${finalAttrs.src.name}/compiler-rt";
patches = [
(getVersionFile "compiler-rt/X86-support-extension.patch") # Add support for i486 i586 i686 by reusing i386 config
# ld-wrapper dislikes `-rpath-link //nix/store`, so we normalize away the
# extra `/`.
(getVersionFile "compiler-rt/normalize-var.patch")
# Fix build on armv6l
./armv6-no-ldrexd-strexd.patch
# See: https://github.com/NixOS/nixpkgs/pull/186575
./darwin-plistbuddy-workaround.patch
]
++ [
(getVersionFile "compiler-rt/armv6-scudo-libatomic.patch")
]
++ lib.optional (lib.versions.major release_version == "19") (fetchpatch {
url = "https://github.com/llvm/llvm-project/pull/99837/commits/14ae0a660a38e1feb151928a14f35ff0f4487351.patch";
hash = "sha256-JykABCaNNhYhZQxCvKiBn54DZ5ZguksgCHnpdwWF2no=";
relative = "compiler-rt";
})
++ lib.optional (lib.strings.versionOlder (lib.versions.major release_version) "20") (fetchpatch {
url = "https://github.com/llvm/llvm-project/commit/59978b21ad9c65276ee8e14f26759691b8a65763.patch";
hash = "sha256-ys5SMLfO3Ay9nCX9GV5yRCQ6pLsseFu/ZY6Xd6OL4p0=";
relative = "compiler-rt";
})
# Linux removed `linux/scc.h`, which breaks building compiler-rt. Upstream LLVM has fixed it in LLVM 22 and 23.
++ lib.optional (lib.strings.versionOlder version "22.1.5") (fetchpatch {
url = "https://github.com/llvm/llvm-project/commit/3dc4fd6dd41100f051a63642f449b16324389c96.patch?full_index=1";
hash = "sha256-Av6CN95XjdUagIKh3AAjD0UK8r01fDz0cD0BLjZ70dg=";
relative = "compiler-rt";
});
nativeBuildInputs = [
cmake
python3
ninja
]
++ lib.optionals stdenv.hostPlatform.isDarwin [ jq ];
buildInputs =
lib.optional (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isRiscV) linuxHeaders
++ lib.optional (stdenv.hostPlatform.isFreeBSD) freebsd.include;
env = {
NIX_CFLAGS_COMPILE = toString (
[
"-DSCUDO_DEFAULT_OPTIONS=delete_size_mismatch=false:dealloc_type_mismatch=false"
]
++ lib.optionals (!haveLibc) [
# The compiler got stricter about this, and there is a usellvm patch below
# which patches out the assert include causing an implicit definition of
# assert. It would be nicer to understand why compiler-rt thinks it should
# be able to #include <assert.h> in the first place; perhaps it's in the
# wrong, or perhaps there is a way to provide an assert.h.
"-Wno-error=implicit-function-declaration"
]
);
# Work around clangs trying to invoke unprefixed-ld on Darwin when `-target` is passed.
NIX_CFLAGS_LINK = lib.optionalString (stdenv.hostPlatform.isDarwin) "--ld-path=${stdenv.cc.bintools}/bin/${stdenv.cc.targetPrefix}ld";
};
cmakeFlags = [
(lib.cmakeBool "COMPILER_RT_DEFAULT_TARGET_ONLY" true)
(lib.cmakeFeature "CMAKE_C_COMPILER_TARGET" stdenv.hostPlatform.config)
(lib.cmakeFeature "CMAKE_ASM_COMPILER_TARGET" stdenv.hostPlatform.config)
]
++ lib.optionals (useLLVM && haveLibc && stdenv.cc.libcxx == libcxx) [
(lib.cmakeFeature "SANITIZER_CXX_ABI" "libcxxabi")
(lib.cmakeFeature "SANITIZER_CXX_ABI_LIBNAME" "libcxxabi")
(lib.cmakeBool "COMPILER_RT_USE_BUILTINS_LIBRARY" true)
]
++ lib.optionals (useLLVM && haveLibc) [
(lib.cmakeBool "COMPILER_RT_BUILD_SANITIZERS" true)
(lib.cmakeBool "COMPILER_RT_BUILD_PROFILE" true)
]
++ lib.optionals noSanitizers [
(lib.cmakeBool "COMPILER_RT_BUILD_SANITIZERS" false)
]
++ lib.optionals ((useLLVM && !haveLibcxx) || !haveLibc || bareMetal || isMusl || isDarwinStatic) [
(lib.cmakeBool "COMPILER_RT_BUILD_XRAY" false)
(lib.cmakeBool "COMPILER_RT_BUILD_LIBFUZZER" false)
(lib.cmakeBool "COMPILER_RT_BUILD_MEMPROF" false)
(lib.cmakeBool "COMPILER_RT_BUILD_ORC" false) # may be possible to build with musl if necessary
]
++ lib.optionals (!haveLibc || bareMetal) [
(lib.cmakeBool "COMPILER_RT_BUILD_PROFILE" false)
(lib.cmakeBool "CMAKE_C_COMPILER_WORKS" true)
(lib.cmakeBool "COMPILER_RT_BAREMETAL_BUILD" true)
(lib.cmakeFeature "CMAKE_SIZEOF_VOID_P" (toString (stdenv.hostPlatform.parsed.cpu.bits / 8)))
]
++ lib.optionals (!haveLibc || bareMetal || isDarwinStatic) [
(lib.cmakeBool "CMAKE_CXX_COMPILER_WORKS" true)
]
++ lib.optionals (!haveLibc) [
(lib.cmakeFeature "CMAKE_C_FLAGS" "-nodefaultlibs")
]
++ lib.optionals useLLVM [
(lib.cmakeBool "COMPILER_RT_BUILD_BUILTINS" true)
#https://stackoverflow.com/questions/53633705/cmake-the-c-compiler-is-not-able-to-compile-a-simple-test-program
(lib.cmakeFeature "CMAKE_TRY_COMPILE_TARGET_TYPE" "STATIC_LIBRARY")
]
++ lib.optionals bareMetal [
(lib.cmakeFeature "COMPILER_RT_OS_DIR" "baremetal")
]
++ lib.optionals (stdenv.hostPlatform.isDarwin) (
[
(lib.cmakeFeature "CMAKE_LIPO" "${lib.getBin stdenv.cc.bintools.bintools}/bin/${stdenv.cc.targetPrefix}lipo")
]
++ lib.optionals (!haveLibcxx) [
# Darwin fails to detect that the compiler supports the `-g` flag when there is no libc++ during the
# compiler-rt bootstrap, which prevents compiler-rt from building. The `-g` flag is required by the
# Darwin support, so force it to be enabled during the first stage of the compiler-rt bootstrap.
(lib.cmakeBool "COMPILER_RT_HAS_G_FLAG" true)
]
++ [
(lib.cmakeFeature "DARWIN_osx_ARCHS" stdenv.hostPlatform.darwinArch)
(lib.cmakeFeature "DARWIN_osx_BUILTIN_ARCHS" stdenv.hostPlatform.darwinArch)
(lib.cmakeFeature "SANITIZER_MIN_OSX_VERSION" stdenv.hostPlatform.darwinMinVersion)
# `COMPILER_RT_DEFAULT_TARGET_ONLY` does not apply to Darwin:
# https://github.com/llvm/llvm-project/blob/27ef42bec80b6c010b7b3729ed0528619521a690/compiler-rt/cmake/base-config-ix.cmake#L153
(lib.cmakeBool "COMPILER_RT_ENABLE_IOS" false)
]
)
++ lib.optionals (noSanitizers && lib.versionAtLeast release_version "19") [
(lib.cmakeBool "COMPILER_RT_BUILD_CTX_PROFILE" false)
]
++
lib.optional (stdenv.hostPlatform.isAarch64 && !haveLibc)
# Fixes https://github.com/NixOS/nixpkgs/issues/393603
(lib.cmakeBool "COMPILER_RT_DISABLE_AARCH64_FMV" true)
++ lib.optionals withAtomics [
(lib.cmakeBool "COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN" (!withAtomicsLib))
(lib.cmakeBool "COMPILER_RT_BUILD_STANDALONE_LIBATOMIC" withAtomicsLib)
(lib.cmakeBool "COMPILER_RT_LIBATOMIC_USE_PTHREAD" withAtomicsPthread)
]
++ devExtraCmakeFlags;
outputs = [
"out"
"dev"
];
postPatch =
lib.optionalString (!stdenv.hostPlatform.isDarwin) ''
substituteInPlace cmake/builtin-config-ix.cmake \
--replace-fail 'set(X86 i386)' 'set(X86 i386 i486 i586 i686)'
''
+ lib.optionalString (!haveLibc) (
(lib.optionalString (lib.versions.major release_version == "18") ''
substituteInPlace lib/builtins/aarch64/sme-libc-routines.c \
--replace-fail "<stdlib.h>" "<stddef.h>"
'')
+ ''
substituteInPlace lib/builtins/int_util.c \
--replace-fail "#include <stdlib.h>" ""
''
+ (lib.optionalString (!stdenv.hostPlatform.isFreeBSD)
# On FreeBSD, assert/static_assert are macros and allowing them to be implicitly declared causes link errors.
# see description above for why we're nuking assert.h normally but that doesn't work here.
# instead, we add the freebsd.include dependency explicitly
''
substituteInPlace lib/builtins/clear_cache.c \
--replace-fail "#include <assert.h>" ""
substituteInPlace lib/builtins/cpu_model/x86.c \
--replace-fail "#include <assert.h>" ""
''
)
)
+
lib.optionalString (lib.versionAtLeast release_version "19")
# codesign in sigtool doesn't support the various options used by the build
# and is present in the bootstrap-tools. Removing find_program prevents the
# build from trying to use it and failing.
''
substituteInPlace cmake/Modules/AddCompilerRT.cmake \
--replace-fail 'find_program(CODESIGN codesign)' ""
'';
preConfigure = lib.optionalString stdenv.hostPlatform.isDarwin ''
cmakeFlagsArray+=(
"-DDARWIN_macosx_CACHED_SYSROOT=$SDKROOT"
"-DDARWIN_macosx_OVERRIDE_SDK_VERSION=$(jq -r .Version "$SDKROOT/SDKSettings.json")"
)
'';
# Hack around weird upstream RPATH bug
postInstall =
lib.optionalString (stdenv.hostPlatform.isDarwin) ''
ln -s "$out/lib"/*/* "$out/lib"
''
+ lib.optionalString (useLLVM && stdenv.hostPlatform.isLinux) ''
ln -s $out/lib/*/clang_rt.crtbegin-*.o $out/lib/crtbegin.o
ln -s $out/lib/*/clang_rt.crtend-*.o $out/lib/crtend.o
# Note the history of crt{begin,end}S in previous versions of llvm in nixpkg:
# The presence of crtbegin_shared has been added and removed; it's possible
# people have added/removed it to get it working on their platforms.
# Try each in turn for now.
ln -s $out/lib/*/clang_rt.crtbegin-*.o $out/lib/crtbeginS.o
ln -s $out/lib/*/clang_rt.crtend-*.o $out/lib/crtendS.o
ln -s $out/lib/*/clang_rt.crtbegin_shared-*.o $out/lib/crtbeginS.o
ln -s $out/lib/*/clang_rt.crtend_shared-*.o $out/lib/crtendS.o
''
+ lib.optionalString doFakeLibgcc ''
ln -s $out/lib/*/libclang_rt.builtins-*.a $out/lib/libgcc.a
''
+ lib.optionalString forceLinkCompilerRt ''
ln -s $out/lib/*/libclang_rt.builtins-*.a $out/lib/libcompiler_rt.a
''
+ lib.optionalString (withAtomics && withAtomicsLib) ''
ln -s $out/lib/*/libclang_rt.atomic-*.so $out/lib/libatomic.so
# create a link with the original soname as well, so it's found at runtime
ln -s $out/lib/*/libclang_rt.atomic-*.so $out/lib/
'';
meta = llvm_meta // {
homepage = "https://compiler-rt.llvm.org/";
description = "Compiler runtime libraries";
longDescription = ''
The compiler-rt project provides highly tuned implementations of the
low-level code generator support routines like "__fixunsdfdi" and other
calls generated when a target doesn't have a short sequence of native
instructions to implement a core IR operation. It also provides
implementations of run-time libraries for dynamic testing tools such as
AddressSanitizer, ThreadSanitizer, MemorySanitizer, and DataFlowSanitizer.
'';
# "All of the code in the compiler-rt project is dual licensed under the MIT
# license and the UIUC License (a BSD-like license)":
license = with lib.licenses; [
mit
ncsa
];
broken =
# compiler-rt requires a Clang stdenv on 32-bit RISC-V:
# https://reviews.llvm.org/D43106#1019077
(stdenv.hostPlatform.isRiscV32 && !stdenv.cc.isClang)
# emutls wants `<pthread.h>` which isn't available (without experimental WASM threads proposal).
# `enable_execute_stack.c` Also doesn't sound like something WASM would support.
|| (stdenv.hostPlatform.isWasm && haveLibc);
};
})