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