1{
2 lib,
3 stdenv,
4 fetchFromGitHub,
5 replaceVars,
6 binutils,
7 asciidoctor,
8 cmake,
9 perl,
10 fmt,
11 hiredis,
12 xxHash,
13 zstd,
14 bashInteractive,
15 doctest,
16 xcodebuild,
17 makeWrapper,
18 ctestCheckHook,
19 writableTmpDirAsHomeHook,
20 nix-update-script,
21}:
22
23stdenv.mkDerivation (finalAttrs: {
24 pname = "ccache";
25 version = "4.11.3";
26
27 src = fetchFromGitHub {
28 owner = "ccache";
29 repo = "ccache";
30 tag = "v${finalAttrs.version}";
31 # `git archive` replaces `$Format:%H %D$` in cmake/CcacheVersion.cmake
32 # we need to replace it with something reproducible
33 # see https://github.com/NixOS/nixpkgs/pull/316524
34 postFetch = ''
35 sed -i -E \
36 's/version_info "([0-9a-f]{40}) .*(tag: v[^,]+).*"/version_info "\1 \2"/g w match' \
37 $out/cmake/CcacheVersion.cmake
38 if [ -s match ]; then
39 rm match
40 else # pattern didn't match
41 exit 1
42 fi
43 '';
44 hash = "sha256-w41e73Zh5HhYhgLPtaaSiJ48BklBNtnK9S859tol5wc=";
45 };
46
47 outputs = [
48 "out"
49 "man"
50 ];
51
52 patches = [
53 # When building for Darwin, test/run uses dwarfdump, whereas on
54 # Linux it uses objdump. We don't have dwarfdump packaged for
55 # Darwin, so this patch updates the test to also use objdump on
56 # Darwin.
57 # Additionally, when cross compiling, the correct target prefix
58 # needs to be set.
59 (replaceVars ./fix-objdump-path.patch {
60 objdump = "${binutils.bintools}/bin/${binutils.targetPrefix}objdump";
61 })
62 ];
63
64 strictDeps = true;
65
66 nativeBuildInputs = [
67 asciidoctor
68 cmake
69 perl
70 ];
71
72 buildInputs = [
73 fmt
74 hiredis
75 xxHash
76 zstd
77 ];
78
79 cmakeFlags = lib.optional (!finalAttrs.finalPackage.doCheck) "-DENABLE_TESTING=OFF";
80
81 doCheck = true;
82
83 nativeCheckInputs = [
84 # test/run requires the compgen function which is available in
85 # bashInteractive, but not bash.
86 bashInteractive
87 ctestCheckHook
88 writableTmpDirAsHomeHook
89 ]
90 ++ lib.optional stdenv.hostPlatform.isDarwin xcodebuild;
91
92 checkInputs = [
93 doctest
94 ];
95
96 disabledTests = [
97 "test.trim_dir" # flaky on hydra (possibly filesystem-specific?)
98 "test.fileclone" # flaky on hydra, also seems to fail on zfs
99 ]
100 ++ lib.optionals stdenv.hostPlatform.isDarwin [
101 "test.basedir"
102 "test.multi_arch"
103 "test.nocpp2"
104 ];
105
106 passthru = {
107 # A derivation that provides gcc and g++ commands, but that
108 # will end up calling ccache for the given cacheDir
109 links =
110 { unwrappedCC, extraConfig }:
111 stdenv.mkDerivation {
112 pname = "ccache-links";
113 inherit (finalAttrs) version;
114 passthru = {
115 isClang = unwrappedCC.isClang or false;
116 isGNU = unwrappedCC.isGNU or false;
117 isCcache = true;
118 };
119 lib = lib.getLib unwrappedCC;
120 nativeBuildInputs = [ makeWrapper ];
121 # Unwrapped clang does not have a targetPrefix because it is multi-target
122 # target is decided with argv0.
123 buildCommand =
124 let
125 targetPrefix =
126 if unwrappedCC.isClang or false then
127 ""
128 else
129 (lib.optionalString (
130 unwrappedCC ? targetConfig && unwrappedCC.targetConfig != null && unwrappedCC.targetConfig != ""
131 ) "${unwrappedCC.targetConfig}-");
132 in
133 ''
134 mkdir -p $out/bin
135
136 wrap() {
137 local cname="${targetPrefix}$1"
138 if [ -x "${unwrappedCC}/bin/$cname" ]; then
139 makeWrapper ${finalAttrs.finalPackage}/bin/ccache $out/bin/$cname \
140 --run ${lib.escapeShellArg extraConfig} \
141 --add-flags ${unwrappedCC}/bin/$cname
142 fi
143 }
144
145 wrap cc
146 wrap c++
147 wrap gcc
148 wrap g++
149 wrap clang
150 wrap clang++
151
152 for executable in $(ls ${unwrappedCC}/bin); do
153 if [ ! -x "$out/bin/$executable" ]; then
154 ln -s ${unwrappedCC}/bin/$executable $out/bin/$executable
155 fi
156 done
157 for file in $(ls ${unwrappedCC} | grep -vw bin); do
158 ln -s ${unwrappedCC}/$file $out/$file
159 done
160 '';
161 };
162
163 updateScript = nix-update-script { };
164 };
165
166 meta = with lib; {
167 description = "Compiler cache for fast recompilation of C/C++ code";
168 homepage = "https://ccache.dev";
169 downloadPage = "https://ccache.dev/download.html";
170 changelog = "https://ccache.dev/releasenotes.html#_ccache_${
171 builtins.replaceStrings [ "." ] [ "_" ] finalAttrs.version
172 }";
173 license = licenses.gpl3Plus;
174 maintainers = with maintainers; [
175 kira-bruneau
176 r-burns
177 ];
178 platforms = platforms.unix;
179 mainProgram = "ccache";
180 };
181})