1{
2 lib,
3 stdenv,
4 llvm_meta,
5 src ? null,
6 monorepoSrc ? null,
7 version,
8 release_version,
9 runCommand,
10 python3,
11 python3Packages,
12 patches ? [ ],
13 cmake,
14 ninja,
15 isFullBuild ? true,
16 linuxHeaders,
17}:
18let
19 pname = "libc";
20
21 src' = runCommand "${pname}-src-${version}" { } (
22 ''
23 mkdir -p "$out"
24 cp -r ${monorepoSrc}/cmake "$out"
25 cp -r ${monorepoSrc}/runtimes "$out"
26 cp -r ${monorepoSrc}/llvm "$out"
27 cp -r ${monorepoSrc}/compiler-rt "$out"
28 cp -r ${monorepoSrc}/${pname} "$out"
29 ''
30 + lib.optionalString (lib.versionAtLeast release_version "21") ''
31 cp -r ${monorepoSrc}/third-party "$out"
32 ''
33 );
34in
35stdenv.mkDerivation (finalAttrs: {
36 inherit pname version patches;
37
38 src = src';
39
40 sourceRoot = "${finalAttrs.src.name}/runtimes";
41
42 nativeBuildInputs = [
43 cmake
44 python3
45 ninja
46 ]
47 ++ (lib.optional isFullBuild python3Packages.pyyaml);
48
49 buildInputs = lib.optional isFullBuild linuxHeaders;
50
51 outputs = [ "out" ] ++ (lib.optional isFullBuild "dev");
52
53 postUnpack = lib.optionalString isFullBuild ''
54 chmod +w $sourceRoot/../$pname/utils/hdrgen
55 patchShebangs $sourceRoot/../$pname/utils/hdrgen/main.py
56 chmod +x $sourceRoot/../$pname/utils/hdrgen/main.py
57 '';
58
59 prePatch = ''
60 cd ../${finalAttrs.pname}
61 chmod -R u+w ../
62 '';
63
64 postPatch = ''
65 cd ../runtimes
66 '';
67
68 postInstall =
69 lib.optionalString (!isFullBuild) ''
70 substituteAll ${./libc-shim.tpl} $out/lib/libc.so
71 ''
72 # LLVM libc doesn't recognize static vs dynamic yet.
73 # Treat LLVM libc as a static libc, requires this symlink until upstream fixes it.
74 + lib.optionalString (isFullBuild && stdenv.hostPlatform.isLinux) ''
75 ln $out/lib/crt1.o $out/lib/Scrt1.o
76 '';
77
78 libc = if (!isFullBuild) then stdenv.cc.libc else null;
79
80 cmakeFlags = [
81 (lib.cmakeBool "LLVM_LIBC_FULL_BUILD" isFullBuild)
82 (lib.cmakeFeature "LLVM_ENABLE_RUNTIMES" "libc;compiler-rt")
83 # Tests requires the host to have a libc.
84 (lib.cmakeBool "LLVM_INCLUDE_TESTS" (stdenv.cc.libc != null))
85 ]
86 ++ lib.optionals (isFullBuild && stdenv.cc.libc == null) [
87 # CMake runs a check to see if the compiler works.
88 # This includes including headers which requires a libc.
89 # Skip these checks because a libc cannot be used when one doesn't exist.
90 (lib.cmakeBool "CMAKE_C_COMPILER_WORKS" true)
91 (lib.cmakeBool "CMAKE_CXX_COMPILER_WORKS" true)
92 ];
93
94 # For the update script:
95 passthru = {
96 monorepoSrc = monorepoSrc;
97 inherit isFullBuild;
98 };
99
100 meta = llvm_meta // {
101 broken = stdenv.hostPlatform.isDarwin;
102 homepage = "https://libc.llvm.org/";
103 description = "Standard C library for LLVM";
104 };
105})