diff --git a/lib/systems/default.nix b/lib/systems/default.nix index 00f7f3523aa4..ec0106a13dac 100644 --- a/lib/systems/default.nix +++ b/lib/systems/default.nix @@ -102,6 +102,7 @@ let else if final.isMusl then "musl" else if final.isUClibc then "uclibc" else if final.isAndroid then "bionic" + else if final.isLLVMLibc then "llvm" else if final.isLinux /* default */ then "glibc" else if final.isFreeBSD then "fblibc" else if final.isOpenBSD then "oblibc" diff --git a/lib/systems/inspect.nix b/lib/systems/inspect.nix index ebc7ab366876..de4df13cd811 100644 --- a/lib/systems/inspect.nix +++ b/lib/systems/inspect.nix @@ -113,6 +113,7 @@ rec { isGnu = with abis; map (a: { abi = a; }) [ gnuabi64 gnuabin32 gnu gnueabi gnueabihf gnuabielfv1 gnuabielfv2 ]; isMusl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf muslabin32 muslabi64 ]; isUClibc = with abis; map (a: { abi = a; }) [ uclibc uclibceabi uclibceabihf ]; + isLLVMLibc = [ { abi = abis.llvm; } ]; isEfi = [ { cpu = { family = "arm"; version = "6"; }; } diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix index fa3cc02647ae..e3e6ef16c6b0 100644 --- a/lib/systems/parse.nix +++ b/lib/systems/parse.nix @@ -416,6 +416,9 @@ rec { uclibceabihf = { float = "hard"; }; uclibc = {}; + # LLVM libc + llvm = {}; + unknown = {}; }; diff --git a/pkgs/development/compilers/llvm/common/default.nix b/pkgs/development/compilers/llvm/common/default.nix index c9886052d632..27e7e05e4d1c 100644 --- a/pkgs/development/compilers/llvm/common/default.nix +++ b/pkgs/development/compilers/llvm/common/default.nix @@ -1075,135 +1075,148 @@ let relative = "compiler-rt"; }); in - { - compiler-rt-libc = callPackage ./compiler-rt ( - let - # temp rename to avoid infinite recursion + ( + { + compiler-rt-libc = callPackage ./compiler-rt ( + let + # temp rename to avoid infinite recursion + stdenv = + # Darwin needs to use a bootstrap stdenv to avoid an infinite recursion when cross-compiling. + if args.stdenv.hostPlatform.isDarwin then + overrideCC darwin.bootstrapStdenv buildLlvmTools.clangWithLibcAndBasicRtAndLibcxx + else if args.stdenv.hostPlatform.useLLVM or false then + overrideCC args.stdenv buildLlvmTools.clangWithLibcAndBasicRtAndLibcxx + else + args.stdenv; + in + { + patches = compiler-rtPatches; + inherit stdenv; + } + // lib.optionalAttrs (stdenv.hostPlatform.useLLVM or false) { + libxcrypt = (libxcrypt.override { inherit stdenv; }).overrideAttrs (old: { + configureFlags = old.configureFlags ++ [ "--disable-symvers" ]; + }); + } + ); + + compiler-rt-no-libc = callPackage ./compiler-rt { + patches = compiler-rtPatches; + doFakeLibgcc = stdenv.hostPlatform.useLLVM or false; stdenv = # Darwin needs to use a bootstrap stdenv to avoid an infinite recursion when cross-compiling. - if args.stdenv.hostPlatform.isDarwin then - overrideCC darwin.bootstrapStdenv buildLlvmTools.clangWithLibcAndBasicRtAndLibcxx - else if args.stdenv.hostPlatform.useLLVM or false then - overrideCC args.stdenv buildLlvmTools.clangWithLibcAndBasicRtAndLibcxx + if stdenv.hostPlatform.isDarwin then + overrideCC darwin.bootstrapStdenv buildLlvmTools.clangNoLibcNoRt else - args.stdenv; - in - { - patches = compiler-rtPatches; - inherit stdenv; - } - // lib.optionalAttrs (stdenv.hostPlatform.useLLVM or false) { - libxcrypt = (libxcrypt.override { inherit stdenv; }).overrideAttrs (old: { - configureFlags = old.configureFlags ++ [ "--disable-symvers" ]; - }); - } - ); + overrideCC stdenv buildLlvmTools.clangNoLibcNoRt; + }; - compiler-rt-no-libc = callPackage ./compiler-rt { - patches = compiler-rtPatches; - doFakeLibgcc = stdenv.hostPlatform.useLLVM or false; - stdenv = - # Darwin needs to use a bootstrap stdenv to avoid an infinite recursion when cross-compiling. - if stdenv.hostPlatform.isDarwin then - overrideCC darwin.bootstrapStdenv buildLlvmTools.clangNoLibcNoRt + compiler-rt = + if + stdenv.hostPlatform.libc == null + # Building the with-libc compiler-rt and WASM doesn't yet work, + # because wasilibc doesn't provide some expected things. See + # compiler-rt's file for further details. + || stdenv.hostPlatform.isWasm + # Failing `#include ` in + # `lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp` + # sanitizers, not sure where to get it. + || stdenv.hostPlatform.isFreeBSD + then + libraries.compiler-rt-no-libc else - overrideCC stdenv buildLlvmTools.clangNoLibcNoRt; - }; + libraries.compiler-rt-libc; - compiler-rt = - if - stdenv.hostPlatform.libc == null - # Building the with-libc compiler-rt and WASM doesn't yet work, - # because wasilibc doesn't provide some expected things. See - # compiler-rt's file for further details. - || stdenv.hostPlatform.isWasm - # Failing `#include ` in - # `lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp` - # sanitizers, not sure where to get it. - || stdenv.hostPlatform.isFreeBSD - then - libraries.compiler-rt-no-libc - else - libraries.compiler-rt-libc; + stdenv = overrideCC stdenv buildLlvmTools.clang; - stdenv = overrideCC stdenv buildLlvmTools.clang; + libcxxStdenv = overrideCC stdenv buildLlvmTools.libcxxClang; - libcxxStdenv = overrideCC stdenv buildLlvmTools.libcxxClang; - - libcxx = callPackage ./libcxx ( - { - patches = lib.optionals (lib.versionOlder metadata.release_version "16") ( - lib.optional (lib.versions.major metadata.release_version == "15") - # See: - # - https://reviews.llvm.org/D133566 - # - https://github.com/NixOS/nixpkgs/issues/214524#issuecomment-1429146432 - # !!! Drop in LLVM 16+ - ( - fetchpatch { - url = "https://github.com/llvm/llvm-project/commit/57c7bb3ec89565c68f858d316504668f9d214d59.patch"; - hash = "sha256-B07vHmSjy5BhhkGSj3e1E0XmMv5/9+mvC/k70Z29VwY="; - } - ) - ++ [ - (substitute { - src = ./libcxxabi/wasm.patch; + libcxx = callPackage ./libcxx ( + { + patches = lib.optionals (lib.versionOlder metadata.release_version "16") ( + lib.optional (lib.versions.major metadata.release_version == "15") + # See: + # - https://reviews.llvm.org/D133566 + # - https://github.com/NixOS/nixpkgs/issues/214524#issuecomment-1429146432 + # !!! Drop in LLVM 16+ + ( + fetchpatch { + url = "https://github.com/llvm/llvm-project/commit/57c7bb3ec89565c68f858d316504668f9d214d59.patch"; + hash = "sha256-B07vHmSjy5BhhkGSj3e1E0XmMv5/9+mvC/k70Z29VwY="; + } + ) + ++ [ + (substitute { + src = ./libcxxabi/wasm.patch; + substitutions = [ + "--replace-fail" + "/cmake/" + "/llvm/cmake/" + ]; + }) + ] + ++ lib.optional stdenv.hostPlatform.isMusl (substitute { + src = ./libcxx/libcxx-0001-musl-hacks.patch; substitutions = [ "--replace-fail" - "/cmake/" - "/llvm/cmake/" + "/include/" + "/libcxx/include/" ]; }) - ] - ++ lib.optional stdenv.hostPlatform.isMusl (substitute { - src = ./libcxx/libcxx-0001-musl-hacks.patch; - substitutions = [ - "--replace-fail" - "/include/" - "/libcxx/include/" - ]; - }) - ); - stdenv = - if stdenv.hostPlatform.isDarwin then - overrideCC darwin.bootstrapStdenv buildLlvmTools.clangWithLibcAndBasicRt - else - overrideCC stdenv buildLlvmTools.clangWithLibcAndBasicRt; - } - // lib.optionalAttrs (lib.versionOlder metadata.release_version "14") { - # TODO: remove this, causes LLVM 13 packages rebuild. - inherit (metadata) monorepoSrc; # Preserve bug during #307211 refactor. - } - ); - - libunwind = callPackage ./libunwind { - patches = lib.optional (lib.versionOlder metadata.release_version "17") ( - metadata.getVersionFile "libunwind/gnu-install-dirs.patch" + ); + stdenv = + if stdenv.hostPlatform.isDarwin then + overrideCC darwin.bootstrapStdenv buildLlvmTools.clangWithLibcAndBasicRt + else + overrideCC stdenv buildLlvmTools.clangWithLibcAndBasicRt; + } + // lib.optionalAttrs (lib.versionOlder metadata.release_version "14") { + # TODO: remove this, causes LLVM 13 packages rebuild. + inherit (metadata) monorepoSrc; # Preserve bug during #307211 refactor. + } ); - stdenv = overrideCC stdenv buildLlvmTools.clangWithLibcAndBasicRt; - }; - openmp = callPackage ./openmp { - patches = - lib.optional ( - lib.versionAtLeast metadata.release_version "15" && lib.versionOlder metadata.release_version "19" - ) (metadata.getVersionFile "openmp/fix-find-tool.patch") - ++ lib.optional ( - lib.versionAtLeast metadata.release_version "14" && lib.versionOlder metadata.release_version "18" - ) (metadata.getVersionFile "openmp/gnu-install-dirs.patch") - ++ lib.optional (lib.versionAtLeast metadata.release_version "14") ( - metadata.getVersionFile "openmp/run-lit-directly.patch" - ) - ++ - lib.optional (lib.versionOlder metadata.release_version "14") - # Fix cross. - ( - fetchpatch { - url = "https://github.com/llvm/llvm-project/commit/5e2358c781b85a18d1463fd924d2741d4ae5e42e.patch"; - hash = "sha256-UxIlAifXnexF/MaraPW0Ut6q+sf3e7y1fMdEv1q103A="; - } - ); - }; - } + libunwind = callPackage ./libunwind { + patches = lib.optional (lib.versionOlder metadata.release_version "17") ( + metadata.getVersionFile "libunwind/gnu-install-dirs.patch" + ); + stdenv = overrideCC stdenv buildLlvmTools.clangWithLibcAndBasicRt; + }; + + openmp = callPackage ./openmp { + patches = + lib.optional ( + lib.versionAtLeast metadata.release_version "15" && lib.versionOlder metadata.release_version "19" + ) (metadata.getVersionFile "openmp/fix-find-tool.patch") + ++ lib.optional ( + lib.versionAtLeast metadata.release_version "14" && lib.versionOlder metadata.release_version "18" + ) (metadata.getVersionFile "openmp/gnu-install-dirs.patch") + ++ lib.optional (lib.versionAtLeast metadata.release_version "14") ( + metadata.getVersionFile "openmp/run-lit-directly.patch" + ) + ++ + lib.optional (lib.versionOlder metadata.release_version "14") + # Fix cross. + ( + fetchpatch { + url = "https://github.com/llvm/llvm-project/commit/5e2358c781b85a18d1463fd924d2741d4ae5e42e.patch"; + hash = "sha256-UxIlAifXnexF/MaraPW0Ut6q+sf3e7y1fMdEv1q103A="; + } + ); + }; + } + // lib.optionalAttrs (lib.versionAtLeast metadata.release_version "20") { + libc-overlay = callPackage ./libc { + isFullBuild = false; + }; + + libc-full = callPackage ./libc { + isFullBuild = true; + }; + + libc = if stdenv.targetPlatform.libc == "llvm" then libraries.libc-full else libraries.libc-overlay; + } + ) ); noExtend = extensible: lib.attrsets.removeAttrs extensible [ "extend" ]; diff --git a/pkgs/development/compilers/llvm/common/libc/default.nix b/pkgs/development/compilers/llvm/common/libc/default.nix new file mode 100644 index 000000000000..eecae81bb433 --- /dev/null +++ b/pkgs/development/compilers/llvm/common/libc/default.nix @@ -0,0 +1,95 @@ +{ + lib, + stdenv, + llvm_meta, + src ? null, + monorepoSrc ? null, + version, + release_version, + runCommand, + python3, + python3Packages, + patches ? [ ], + cmake, + ninja, + isFullBuild ? true, + linuxHeaders, +}: +let + pname = "libc"; + + src' = runCommand "${pname}-src-${version}" { } ('' + mkdir -p "$out" + cp -r ${monorepoSrc}/cmake "$out" + cp -r ${monorepoSrc}/runtimes "$out" + cp -r ${monorepoSrc}/llvm "$out" + cp -r ${monorepoSrc}/${pname} "$out" + ''); + + stdenv' = + if stdenv.cc.isClang then + stdenv.override { + cc = stdenv.cc.override { + nixSupport = stdenv.cc.nixSupport // { + cc-cflags = lib.remove "-lunwind" stdenv.cc.nixSupport.cc-cflags; + }; + }; + } + else + stdenv; +in +stdenv'.mkDerivation (finalAttrs: { + inherit pname version patches; + + src = src'; + + sourceRoot = "${finalAttrs.src.name}/runtimes"; + + nativeBuildInputs = + [ + cmake + python3 + ] + ++ (lib.optional (lib.versionAtLeast release_version "15") ninja) + ++ (lib.optional isFullBuild python3Packages.pyyaml); + + buildInputs = lib.optional isFullBuild linuxHeaders; + + outputs = [ "out" ] ++ (lib.optional isFullBuild "dev"); + + postUnpack = lib.optionalString isFullBuild '' + patchShebangs $sourceRoot/../$pname/hdrgen/yaml_to_classes.py + chmod +x $sourceRoot/../$pname/hdrgen/yaml_to_classes.py + ''; + + prePatch = '' + cd ../${finalAttrs.pname} + chmod -R u+w ../ + ''; + + postPatch = '' + cd ../runtimes + ''; + + postInstall = lib.optionalString (!isFullBuild) '' + substituteAll ${./libc-shim.so} $out/lib/libc.so + ''; + + libc = if (!isFullBuild) then stdenv.cc.libc else null; + + cmakeFlags = [ + (lib.cmakeBool "LLVM_LIBC_FULL_BUILD" isFullBuild) + (lib.cmakeFeature "LLVM_ENABLE_RUNTIMES" "libc") + ]; + + # For the update script: + passthru = { + monorepoSrc = monorepoSrc; + inherit isFullBuild; + }; + + meta = llvm_meta // { + homepage = "https://libc.llvm.org/"; + description = "Standard C library for LLVM"; + }; +}) diff --git a/pkgs/development/compilers/llvm/common/libc/libc-shim.so b/pkgs/development/compilers/llvm/common/libc/libc-shim.so new file mode 100644 index 000000000000..f3beea87680d --- /dev/null +++ b/pkgs/development/compilers/llvm/common/libc/libc-shim.so @@ -0,0 +1 @@ +GROUP (@libc@ @out@/lib/libllvmlibc.a) diff --git a/pkgs/development/compilers/llvm/default.nix b/pkgs/development/compilers/llvm/default.nix index 569c0e2dd0d0..ee60db1e08a6 100644 --- a/pkgs/development/compilers/llvm/default.nix +++ b/pkgs/development/compilers/llvm/default.nix @@ -31,9 +31,9 @@ let "18.1.8".officialRelease.sha256 = "sha256-iiZKMRo/WxJaBXct9GdAcAT3cz9d9pnAcO1mmR6oPNE="; "19.1.6".officialRelease.sha256 = "sha256-LD4nIjZTSZJtbgW6tZopbTF5Mq0Tenj2gbuPXhtOeUI="; "20.0.0-git".gitRelease = { - rev = "eb5cda480d2ad81230b2aa3e134e2b603ff90a1c"; - rev-version = "20.0.0-unstable-2024-11-26"; - sha256 = "sha256-8VbQINEZZqAIF4egMaNPd3/W3E3QmOXMl7WToftrebg="; + rev = "1ef5b987a464611a60e873650726b5e02fda0feb"; + rev-version = "20.0.0-unstable-2024-12-17"; + sha256 = "sha256-QCY9z9h3z5gPvwq6bNzAB5xFFStwOCfKh4VnWInhxU4="; }; } // llvmVersions; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index c616d6aba7d3..a21f709c36bf 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -9017,6 +9017,9 @@ with pkgs; else if name == "nblibc" then targetPackages.netbsd.libc or netbsd.libc else if name == "wasilibc" then targetPackages.wasilibc or wasilibc else if name == "relibc" then targetPackages.relibc or relibc + else if name == "llvm" then + # Use llvmPackages_git until LLVM 20 is the default. + targetPackages.llvmPackages_git.libc or llvmPackages_git.libc else throw "Unknown libc ${name}"; libcCross = diff --git a/pkgs/top-level/release-attrpaths-superset.nix b/pkgs/top-level/release-attrpaths-superset.nix index 9a89062bd174..c306a64be585 100644 --- a/pkgs/top-level/release-attrpaths-superset.nix +++ b/pkgs/top-level/release-attrpaths-superset.nix @@ -50,6 +50,7 @@ let # cross packagesets pkgsLLVM = true; + pkgsLLVMLibc = true; pkgsMusl = true; pkgsStatic = true; pkgsCross = true; diff --git a/pkgs/top-level/release.nix b/pkgs/top-level/release.nix index 78bdf1491125..97e64f73c510 100644 --- a/pkgs/top-level/release.nix +++ b/pkgs/top-level/release.nix @@ -345,6 +345,7 @@ let agdaPackages = packagePlatforms pkgs.agdaPackages; pkgsLLVM.stdenv = [ "x86_64-linux" "aarch64-linux" ]; + pkgsLLVMLibc.stdenv = [ "x86_64-linux" "aarch64-linux" ]; pkgsArocc.stdenv = [ "x86_64-linux" "aarch64-linux" ]; pkgsZig.stdenv = [ "x86_64-linux" "aarch64-linux" ]; pkgsMusl.stdenv = [ "x86_64-linux" "aarch64-linux" ]; diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix index 1cedd8dd1845..64bc2308f6da 100644 --- a/pkgs/top-level/stage.nix +++ b/pkgs/top-level/stage.nix @@ -98,6 +98,10 @@ let or lib.systems.parse.abis.musl; }); + makeLLVMParsedPlatform = parsed: + (parsed // { + abi = lib.systems.parse.abis.llvm; + }); stdenvAdapters = self: super: let @@ -207,6 +211,19 @@ let }; }; + pkgsLLVMLibc = nixpkgsFun { + overlays = [ (self': super': { + pkgsLLVMLibc = super'; + })] ++ overlays; + # Bootstrap a cross stdenv using LLVM libc. + # This is currently not possible when compiling natively, + # so we don't need to check hostPlatform != buildPlatform. + crossSystem = stdenv.hostPlatform // { + config = lib.systems.parse.tripleFromSystem (makeLLVMParsedPlatform stdenv.hostPlatform.parsed); + libc = "llvm"; + }; + }; + pkgsArocc = nixpkgsFun { overlays = [ (self': super': {