nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 runCommand,
5 writeText,
6 clang-unwrapped,
7 clang,
8 libcxxClang,
9 llvm_meta,
10 # enableLibcxx will use the c++ headers from clang instead of gcc.
11 # This shouldn't have any effect on platforms that use clang as the default compiler already.
12 enableLibcxx ? false,
13}:
14
15stdenv.mkDerivation (finalAttrs: {
16 pname = "clang-tools";
17 version = lib.getVersion clang-unwrapped;
18 dontUnpack = true;
19 clang = if enableLibcxx then libcxxClang else clang;
20
21 installPhase = ''
22 runHook preInstall
23
24 mkdir -p $out/bin
25
26 for toolPath in ${clang-unwrapped}/bin/clangd ${clang-unwrapped}/bin/clang-*; do
27 toolName=$(basename "$toolPath")
28
29 # Compilers have their own derivations, no need to include them here
30 if [[ $toolName == "clang-cl" || $toolName == "clang-cpp" || $toolName =~ ^clang\-[0-9]+$ ]]; then
31 continue
32 fi
33
34 cp $toolPath $out/bin/$toolName-unwrapped
35 substituteAll ${./wrapper} $out/bin/$toolName
36 chmod +x $out/bin/$toolName
37 done
38
39 # clangd etc. find standard header files by looking at the directory the
40 # tool is located in and appending `../lib` to the search path. Since we
41 # are copying the binaries, they expect to find `$out/lib` present right
42 # within this derivation, containing `stddef.h` and so on.
43 #
44 # Note that using `ln -s` instead of `cp` in the loop above wouldn't avoid
45 # this problem, since it's `clang-unwrapped` which separates libs into a
46 # different output in the first place - here we are merely "merging" the
47 # directories back together, as expected by the tools.
48 ln -s ${clang-unwrapped.lib}/lib $out/lib
49
50 runHook postInstall
51 '';
52
53 passthru.tests.smokeOk =
54 let
55 src = writeText "main.cpp" ''
56 #include <iostream>
57
58 int main() {
59 std::cout << "Hi!";
60 }
61 '';
62
63 in
64 runCommand "clang-tools-test-smoke-ok" { } ''
65 ${finalAttrs.finalPackage}/bin/clangd --check=${src}
66 touch $out
67 '';
68
69 passthru.tests.smokeErr =
70 let
71 src = writeText "main.cpp" ''
72 #include <iostream>
73
74 int main() {
75 std::cout << "Hi!";
76 }
77 '';
78
79 in
80 runCommand "clang-tools-test-smoke-err" { } ''
81 (${finalAttrs.finalPackage}/bin/clangd --query-driver='**' --check=${src} 2>&1 || true) \
82 | grep 'use of undeclared identifier'
83
84 touch $out
85 '';
86
87 meta = llvm_meta // {
88 description = "Standalone command line tools for C++ development";
89 maintainers = with lib.maintainers; [ patryk27 ];
90 };
91})