at master 8.8 kB view raw
1{ 2 lib, 3 stdenv, 4 llvm_meta, 5 src ? null, 6 monorepoSrc ? null, 7 runCommand, 8 cmake, 9 ninja, 10 libxml2, 11 libllvm, 12 release_version, 13 version, 14 python3, 15 buildLlvmTools, 16 fixDarwinDylibNames, 17 enableManpages ? false, 18 enableClangToolsExtra ? true, 19 devExtraCmakeFlags ? [ ], 20 replaceVars, 21 getVersionFile, 22 fetchpatch, 23 # for tests 24 libclang, 25}: 26stdenv.mkDerivation ( 27 finalAttrs: 28 { 29 pname = "clang"; 30 inherit version; 31 32 src = 33 if monorepoSrc != null then 34 runCommand "clang-src-${version}" { inherit (monorepoSrc) passthru; } ('' 35 mkdir -p "$out" 36 cp -r ${monorepoSrc}/cmake "$out" 37 cp -r ${monorepoSrc}/clang "$out" 38 ${lib.optionalString enableClangToolsExtra "cp -r ${monorepoSrc}/clang-tools-extra \"$out\""} 39 '') 40 else 41 src; 42 43 sourceRoot = "${finalAttrs.src.name}/clang"; 44 45 patches = [ 46 (getVersionFile "clang/purity.patch") 47 # Remove extraneous ".a" suffix from baremetal clang_rt.builtins when compiling for baremetal. 48 # https://reviews.llvm.org/D51899 49 (getVersionFile "clang/gnu-install-dirs.patch") 50 ] 51 ++ lib.optionals (lib.versionOlder release_version "20") [ 52 # https://github.com/llvm/llvm-project/pull/116476 53 # prevent clang ignoring warnings / errors for unsuppored 54 # options when building & linking a source file with trailing 55 # libraries. eg: `clang -munsupported hello.c -lc` 56 ./clang-unsupported-option.patch 57 ] 58 # Pass the correct path to libllvm 59 ++ [ 60 (replaceVars ./clang-at-least-16-LLVMgold-path.patch { 61 libllvmLibdir = "${libllvm.lib}/lib"; 62 }) 63 ] 64 # Fixes a bunch of lambda-related crashes 65 # https://github.com/llvm/llvm-project/pull/93206 66 ++ lib.optional (lib.versions.major release_version == "18") (fetchpatch { 67 name = "tweak-tryCaptureVariable-for-unevaluated-lambdas.patch"; 68 url = "https://github.com/llvm/llvm-project/commit/3d361b225fe89ce1d8c93639f27d689082bd8dad.patch"; 69 # TreeTransform.h is not affected in LLVM 18. 70 excludes = [ 71 "docs/ReleaseNotes.rst" 72 "lib/Sema/TreeTransform.h" 73 ]; 74 stripLen = 1; 75 hash = "sha256-1NKej08R9SPlbDY/5b0OKUsHjX07i9brR84yXiPwi7E="; 76 }); 77 78 nativeBuildInputs = [ 79 cmake 80 python3 81 ninja 82 ] 83 ++ lib.optionals enableManpages [ 84 python3.pkgs.myst-parser 85 python3.pkgs.sphinx 86 ] 87 ++ lib.optional stdenv.hostPlatform.isDarwin fixDarwinDylibNames; 88 89 buildInputs = [ 90 libxml2 91 libllvm 92 ]; 93 94 cmakeFlags = [ 95 (lib.cmakeFeature "CLANG_INSTALL_PACKAGE_DIR" "${placeholder "dev"}/lib/cmake/clang") 96 (lib.cmakeBool "CLANGD_BUILD_XPC" false) 97 (lib.cmakeBool "LLVM_ENABLE_RTTI" true) 98 (lib.cmakeFeature "LLVM_TABLEGEN_EXE" "${buildLlvmTools.tblgen}/bin/llvm-tblgen") 99 (lib.cmakeFeature "CLANG_TABLEGEN" "${buildLlvmTools.tblgen}/bin/clang-tblgen") 100 ] 101 ++ lib.optionals (lib.versionAtLeast release_version "21") [ 102 (lib.cmakeFeature "CLANG_RESOURCE_DIR" "${placeholder "lib"}/lib/clang/${lib.versions.major release_version}") 103 ] 104 # TODO: Clean up on `staging`. 105 ++ [ 106 (lib.cmakeBool "LLVM_INCLUDE_TESTS" false) 107 ] 108 ++ lib.optionals enableManpages [ 109 (lib.cmakeBool "CLANG_INCLUDE_DOCS" true) 110 (lib.cmakeBool "LLVM_ENABLE_SPHINX" true) 111 (lib.cmakeBool "SPHINX_OUTPUT_MAN" true) 112 (lib.cmakeBool "SPHINX_OUTPUT_HTML" false) 113 (lib.cmakeBool "SPHINX_WARNINGS_AS_ERRORS" false) 114 ] 115 # TODO: Clean up on `staging`. 116 ++ [ 117 # Added in LLVM15: 118 # `clang-tidy-confusable-chars-gen`: https://github.com/llvm/llvm-project/commit/c3574ef739fbfcc59d405985a3a4fa6f4619ecdb 119 # `clang-pseudo-gen`: https://github.com/llvm/llvm-project/commit/cd2292ef824591cc34cc299910a3098545c840c7 120 (lib.cmakeFeature "CLANG_TIDY_CONFUSABLE_CHARS_GEN" "${buildLlvmTools.tblgen}/bin/clang-tidy-confusable-chars-gen") 121 ] 122 ++ lib.optionals (lib.versionOlder release_version "20") [ 123 # clang-pseudo removed in LLVM20: https://github.com/llvm/llvm-project/commit/ed8f78827895050442f544edef2933a60d4a7935 124 (lib.cmakeFeature "CLANG_PSEUDO_GEN" "${buildLlvmTools.tblgen}/bin/clang-pseudo-gen") 125 ] 126 ++ lib.optional (lib.versionAtLeast release_version "20") ( 127 lib.cmakeFeature "LLVM_DIR" "${libllvm.dev}/lib/cmake/llvm" 128 ) 129 ++ devExtraCmakeFlags; 130 131 postPatch = '' 132 # Make sure clang passes the correct location of libLTO to ld64 133 substituteInPlace lib/Driver/ToolChains/Darwin.cpp \ 134 --replace-fail 'StringRef P = llvm::sys::path::parent_path(D.Dir);' 'StringRef P = "${lib.getLib libllvm}";' 135 (cd tools && ln -s ../../clang-tools-extra extra) 136 '' 137 + lib.optionalString stdenv.hostPlatform.isMusl '' 138 sed -i -e 's/lgcc_s/lgcc_eh/' lib/Driver/ToolChains/*.cpp 139 ''; 140 141 outputs = [ 142 "out" 143 "lib" 144 "dev" 145 "python" 146 ]; 147 148 separateDebugInfo = stdenv.buildPlatform.is64bit; # OOMs on 32 bit 149 150 postInstall = '' 151 ln -sv $out/bin/clang $out/bin/cpp 152 '' 153 + (lib.optionalString 154 ((lib.versionAtLeast release_version "19") && !(lib.versionAtLeast release_version "21")) 155 '' 156 mv $out/lib/clang $lib/lib/clang 157 '' 158 ) 159 + '' 160 161 # Move libclang to 'lib' output 162 moveToOutput "lib/libclang.*" "$lib" 163 moveToOutput "lib/libclang-cpp.*" "$lib" 164 mkdir -p $python/bin $python/share/clang/ 165 '' 166 + '' 167 mv $out/bin/{git-clang-format,scan-view} $python/bin 168 if [ -e $out/bin/set-xcode-analyzer ]; then 169 mv $out/bin/set-xcode-analyzer $python/bin 170 fi 171 mv $out/share/clang/*.py $python/share/clang 172 rm $out/bin/c-index-test 173 patchShebangs $python/bin 174 175 mkdir -p $dev/bin 176 '' 177 # TODO(@LunNova): Clean up this rebuild avoidance in staging 178 + lib.optionalString enableClangToolsExtra ( 179 if lib.versionOlder release_version "20" then 180 '' 181 cp bin/{clang-tblgen,clang-tidy-confusable-chars-gen,clang-pseudo-gen} $dev/bin 182 '' 183 else 184 '' 185 cp bin/{clang-tblgen,clang-tidy-confusable-chars-gen} $dev/bin 186 '' 187 ) 188 + lib.optionalString (!enableClangToolsExtra) '' 189 cp bin/clang-tblgen $dev/bin 190 ''; 191 192 env = 193 lib.optionalAttrs (stdenv.buildPlatform != stdenv.hostPlatform && !stdenv.hostPlatform.useLLVM) 194 { 195 # The following warning is triggered with (at least) gcc >= 196 # 12, but appears to occur only for cross compiles. 197 NIX_CFLAGS_COMPILE = "-Wno-maybe-uninitialized"; 198 }; 199 200 passthru = { 201 inherit libllvm; 202 isClang = true; 203 hardeningUnsupportedFlagsByTargetPlatform = 204 targetPlatform: 205 [ "fortify3" ] 206 ++ lib.optional (!targetPlatform.isLinux || !targetPlatform.isx86_64) "shadowstack" 207 ++ lib.optional (!targetPlatform.isAarch64 || !targetPlatform.isLinux) "pacret" 208 ++ lib.optional ( 209 !(targetPlatform.isLinux || targetPlatform.isFreeBSD) 210 || !( 211 targetPlatform.isx86 212 || targetPlatform.isPower64 213 || targetPlatform.isS390x 214 || targetPlatform.isAarch64 215 ) 216 ) "stackclashprotection" 217 ++ lib.optional (!(targetPlatform.isx86_64 || targetPlatform.isAarch64)) "zerocallusedregs" 218 ++ (finalAttrs.passthru.hardeningUnsupportedFlags or [ ]); 219 tests.withoutOptionalFeatures = libclang.override { 220 enableClangToolsExtra = false; 221 }; 222 }; 223 224 requiredSystemFeatures = [ "big-parallel" ]; 225 meta = llvm_meta // { 226 homepage = "https://clang.llvm.org/"; 227 description = "C language family frontend for LLVM"; 228 longDescription = '' 229 The Clang project provides a language front-end and tooling 230 infrastructure for languages in the C language family (C, C++, Objective 231 C/C++, OpenCL, CUDA, and RenderScript) for the LLVM project. 232 It aims to deliver amazingly fast compiles, extremely useful error and 233 warning messages and to provide a platform for building great source 234 level tools. The Clang Static Analyzer and clang-tidy are tools that 235 automatically find bugs in your code, and are great examples of the sort 236 of tools that can be built using the Clang frontend as a library to 237 parse C/C++ code. 238 ''; 239 mainProgram = "clang"; 240 }; 241 } 242 // lib.optionalAttrs enableManpages { 243 pname = "clang-manpages"; 244 245 ninjaFlags = [ "docs-clang-man" ]; 246 247 installPhase = '' 248 mkdir -p $out/share/man/man1 249 # Manually install clang manpage 250 cp docs/man/*.1 $out/share/man/man1/ 251 ''; 252 253 outputs = [ "out" ]; 254 255 doCheck = false; 256 257 meta = llvm_meta // { 258 description = "man page for Clang ${version}"; 259 }; 260 } 261)