Branch data Line data Source code
1 : : /*
2 : : * ccache -- a fast C/C++ compiler cache
3 : : *
4 : : * Copyright (C) 2002-2007 Andrew Tridgell
5 : : * Copyright (C) 2009-2015 Joel Rosdahl
6 : : *
7 : : * This program is free software; you can redistribute it and/or modify it
8 : : * under the terms of the GNU General Public License as published by the Free
9 : : * Software Foundation; either version 3 of the License, or (at your option)
10 : : * any later version.
11 : : *
12 : : * This program is distributed in the hope that it will be useful, but WITHOUT
13 : : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 : : * more details.
16 : : *
17 : : * You should have received a copy of the GNU General Public License along with
18 : : * this program; if not, write to the Free Software Foundation, Inc., 51
19 : : * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 : : */
21 : :
22 : : #include "ccache.h"
23 : : #include "compopt.h"
24 : : #ifdef HAVE_GETOPT_LONG
25 : : #include <getopt.h>
26 : : #else
27 : : #include "getopt_long.h"
28 : : #endif
29 : : #include "hashtable.h"
30 : : #include "hashtable_itr.h"
31 : : #include "hashutil.h"
32 : : #include "language.h"
33 : : #include "manifest.h"
34 : :
35 : : #define STRINGIFY(x) #x
36 : : #define TO_STRING(x) STRINGIFY(x)
37 : :
38 : : static const char VERSION_TEXT[] =
39 : : MYNAME " version %s\n"
40 : : "\n"
41 : : "Copyright (C) 2002-2007 Andrew Tridgell\n"
42 : : "Copyright (C) 2009-2015 Joel Rosdahl\n"
43 : : "\n"
44 : : "This program is free software; you can redistribute it and/or modify it under\n"
45 : : "the terms of the GNU General Public License as published by the Free Software\n"
46 : : "Foundation; either version 3 of the License, or (at your option) any later\n"
47 : : "version.\n";
48 : :
49 : : static const char USAGE_TEXT[] =
50 : : "Usage:\n"
51 : : " " MYNAME " [options]\n"
52 : : " " MYNAME " compiler [compiler options]\n"
53 : : " compiler [compiler options] (via symbolic link)\n"
54 : : "\n"
55 : : "Options:\n"
56 : : " -c, --cleanup delete old files and recalculate size counters\n"
57 : : " (normally not needed as this is done automatically)\n"
58 : : " -C, --clear clear the cache completely (except configuration)\n"
59 : : " -F, --max-files=N set maximum number of files in cache to N (use 0 for\n"
60 : : " no limit)\n"
61 : : " -M, --max-size=SIZE set maximum size of cache to SIZE (use 0 for no\n"
62 : : " limit); available suffixes: k, M, G, T (decimal) and\n"
63 : : " Ki, Mi, Gi, Ti (binary); default suffix: G\n"
64 : : " -o, --set-config=K=V set configuration key K to value V\n"
65 : : " -p, --print-config print current configuration options\n"
66 : : " -s, --show-stats show statistics summary\n"
67 : : " -z, --zero-stats zero statistics counters\n"
68 : : "\n"
69 : : " -h, --help print this help text\n"
70 : : " -V, --version print version and copyright information\n"
71 : : "\n"
72 : : "See also <http://ccache.samba.org>.\n";
73 : :
74 : : /* Global configuration data. */
75 : : struct conf *conf = NULL;
76 : :
77 : : /* Where to write configuration changes. */
78 : : char *primary_config_path = NULL;
79 : :
80 : : /* Secondary, read-only configuration file (if any). */
81 : : char *secondary_config_path = NULL;
82 : :
83 : : /* current working directory taken from $PWD, or getcwd() if $PWD is bad */
84 : : char *current_working_dir = NULL;
85 : :
86 : : /* the original argument list */
87 : : static struct args *orig_args;
88 : :
89 : : /* the source file */
90 : : static char *input_file;
91 : :
92 : : /* The output file being compiled to. */
93 : : static char *output_obj;
94 : :
95 : : /* The path to the dependency file (implicit or specified with -MF). */
96 : : static char *output_dep;
97 : :
98 : : /* The path to the coverage file (implicit when using -ftest-coverage). */
99 : : static char *output_cov;
100 : :
101 : : /* Diagnostic generation information (clang). Contains pathname if not
102 : : NULL. */
103 : : static char *output_dia = NULL;
104 : :
105 : : /* -gsplit-dwarf support: Split dwarf information (GCC 4.8 and
106 : : up). Contains pathname if not NULL. */
107 : : static char *output_dwo = NULL;
108 : :
109 : : /*
110 : : * Name (represented as a struct file_hash) of the file containing the cached
111 : : * object code.
112 : : */
113 : : static struct file_hash *cached_obj_hash;
114 : :
115 : : /*
116 : : * Full path to the file containing the cached object code
117 : : * (cachedir/a/b/cdef[...]-size.o).
118 : : */
119 : : static char *cached_obj;
120 : :
121 : : /*
122 : : * Full path to the file containing the standard error output
123 : : * (cachedir/a/b/cdef[...]-size.stderr).
124 : : */
125 : : static char *cached_stderr;
126 : :
127 : : /*
128 : : * Full path to the file containing the dependency information
129 : : * (cachedir/a/b/cdef[...]-size.d).
130 : : */
131 : : static char *cached_dep;
132 : :
133 : : /*
134 : : * Full path to the file containing the coverage information
135 : : * (cachedir/a/b/cdef[...]-size.gcno).
136 : : */
137 : : static char *cached_cov;
138 : :
139 : : /*
140 : : * Full path to the file containing the diagnostic information (for clang)
141 : : * (cachedir/a/b/cdef[...]-size.dia).
142 : : */
143 : : static char *cached_dia;
144 : :
145 : : /*
146 : : * -gsplit-dwarf support:
147 : : * Full path to the file containing the split dwarf (for GCC 4.8 and
148 : : * above)
149 : : * (cachedir/a/b/cdef[...]-size.dwo).
150 : : *
151 : : * contains NULL if -gsplit-dwarf is not given.
152 : : */
153 : : static char *cached_dwo;
154 : :
155 : : /*
156 : : * -gsplit-dwarf support:
157 : : * using_split_dwarf is true if "-gsplit-dwarf" is given to the
158 : : * compiler (GCC 4.8 and up).
159 : : */
160 : : bool using_split_dwarf = false;
161 : :
162 : : /*
163 : : * Full path to the file containing the manifest
164 : : * (cachedir/a/b/cdef[...]-size.manifest).
165 : : */
166 : : static char *manifest_path;
167 : :
168 : : /*
169 : : * Time of compilation. Used to see if include files have changed after
170 : : * compilation.
171 : : */
172 : : time_t time_of_compilation;
173 : :
174 : : /*
175 : : * Files included by the preprocessor and their hashes/sizes. Key: file path.
176 : : * Value: struct file_hash.
177 : : */
178 : : static struct hashtable *included_files;
179 : :
180 : : /* is gcc being asked to output dependencies? */
181 : : static bool generating_dependencies;
182 : :
183 : : /* is gcc being asked to output coverage? */
184 : : static bool generating_coverage;
185 : :
186 : : /* is gcc being asked to output coverage data (.gcda) at runtime? */
187 : : static bool profile_arcs;
188 : :
189 : : /* name of the custom profile directory (default: object dirname) */
190 : : static char *profile_dir;
191 : :
192 : : /* the name of the temporary pre-processor file */
193 : : static char *i_tmpfile;
194 : :
195 : : /* are we compiling a .i or .ii file directly? */
196 : : static bool direct_i_file;
197 : :
198 : : /* the name of the cpp stderr file */
199 : : static char *cpp_stderr;
200 : :
201 : : /*
202 : : * Full path to the statistics file in the subdirectory where the cached result
203 : : * belongs (<cache_dir>/<x>/stats).
204 : : */
205 : : char *stats_file = NULL;
206 : :
207 : : /* Whether the output is a precompiled header */
208 : : static bool output_is_precompiled_header = false;
209 : :
210 : : /* Profile generation / usage information */
211 : : static char *profile_dir = NULL;
212 : : static bool profile_use = false;
213 : : static bool profile_generate = false;
214 : :
215 : : /*
216 : : * Whether we are using a precompiled header (either via -include, #include or
217 : : * clang's -include-pch or -include-pth).
218 : : */
219 : : static bool using_precompiled_header = false;
220 : :
221 : : /*
222 : : * The .gch/.pch/.pth file used for compilation.
223 : : */
224 : : static char *included_pch_file = NULL;
225 : :
226 : : /* How long (in microseconds) to wait before breaking a stale lock. */
227 : : unsigned lock_staleness_limit = 2000000;
228 : :
229 : : enum fromcache_call_mode {
230 : : FROMCACHE_DIRECT_MODE,
231 : : FROMCACHE_CPP_MODE
232 : : };
233 : :
234 : : struct pending_tmp_file {
235 : : char *path;
236 : : struct pending_tmp_file *next;
237 : : };
238 : :
239 : : /* Temporary files to remove at program exit. */
240 : : static struct pending_tmp_file *pending_tmp_files = NULL;
241 : :
242 : : /*
243 : : * This is a string that identifies the current "version" of the hash sum
244 : : * computed by ccache. If, for any reason, we want to force the hash sum to be
245 : : * different for the same input in a new ccache version, we can just change
246 : : * this string. A typical example would be if the format of one of the files
247 : : * stored in the cache changes in a backwards-incompatible way.
248 : : */
249 : : static const char HASH_PREFIX[] = "3";
250 : :
251 : : static void
252 : 1 : add_prefix(struct args *args)
253 : : {
254 : : char *e;
255 : 1 : char *tok, *saveptr = NULL;
256 : : struct args *prefix;
257 : : int i;
258 : :
259 [ + - ]: 1 : if (str_eq(conf->prefix_command, "")) {
260 : 1 : return;
261 : : }
262 : :
263 : 0 : prefix = args_init(0, NULL);
264 : 0 : e = x_strdup(conf->prefix_command);
265 [ # # ]: 0 : for (tok = strtok_r(e, " ", &saveptr);
266 : : tok;
267 : 0 : tok = strtok_r(NULL, " ", &saveptr)) {
268 : : char *p;
269 : :
270 : 0 : p = find_executable(tok, MYNAME);
271 [ # # ]: 0 : if (!p) {
272 : 0 : fatal("%s: %s", tok, strerror(errno));
273 : : }
274 : :
275 : 0 : args_add(prefix, p);
276 : 0 : free(p);
277 : : }
278 : 0 : free(e);
279 : :
280 : 0 : cc_log("Using command-line prefix %s", conf->prefix_command);
281 [ # # ]: 0 : for (i = prefix->argc; i != 0; i--) {
282 : 0 : args_add_prefix(args, prefix->argv[i-1]);
283 : : }
284 : 1 : args_free(prefix);
285 : : }
286 : :
287 : : /* Something went badly wrong - just execute the real compiler. */
288 : : static void
289 : 0 : failed(void)
290 : : {
291 [ # # ]: 0 : assert(orig_args);
292 : :
293 : 0 : args_strip(orig_args, "--ccache-");
294 : 0 : add_prefix(orig_args);
295 : :
296 : 0 : cc_log("Failed; falling back to running the real compiler");
297 : 0 : cc_log_argv("Executing ", orig_args->argv);
298 : 0 : exitfn_call();
299 : 0 : execv(orig_args->argv[0], orig_args->argv);
300 : 0 : fatal("execv of %s failed: %s", orig_args->argv[0], strerror(errno));
301 : : }
302 : :
303 : : static const char *
304 : 2 : temp_dir()
305 : : {
306 : : static char *path = NULL;
307 [ + + ]: 2 : if (path) {
308 : 1 : return path; /* Memoize */
309 : : }
310 : 1 : path = conf->temporary_dir;
311 [ + - ]: 1 : if (str_eq(path, "")) {
312 : 1 : path = format("%s/tmp", conf->cache_dir);
313 : : }
314 : 2 : return path;
315 : : }
316 : :
317 : : static void
318 : 3 : add_pending_tmp_file(const char *path)
319 : : {
320 : 3 : struct pending_tmp_file *e = x_malloc(sizeof(*e));
321 : 3 : e->path = x_strdup(path);
322 : 3 : e->next = pending_tmp_files;
323 : 3 : pending_tmp_files = e;
324 : 3 : }
325 : :
326 : : static void
327 : 7 : clean_up_pending_tmp_files(void)
328 : : {
329 : 7 : struct pending_tmp_file *p = pending_tmp_files;
330 [ + + ]: 10 : while (p) {
331 : : /* Can't call tmp_unlink here since its cc_log calls aren't signal safe. */
332 : 3 : unlink(p->path);
333 : 3 : p = p->next;
334 : : /* Leak p->path and p here because clean_up_pending_tmp_files needs to be
335 : : * signal safe. */
336 : : }
337 : 7 : }
338 : :
339 : : static void
340 : 0 : signal_handler(int signo)
341 : : {
342 : : (void)signo;
343 : 0 : clean_up_pending_tmp_files();
344 : 0 : }
345 : :
346 : : static void
347 : 1 : clean_up_internal_tempdir(void)
348 : : {
349 : : DIR *dir;
350 : : struct dirent *entry;
351 : : struct stat st;
352 : 1 : time_t now = time(NULL);
353 : :
354 [ + - ][ + - ]: 1 : if (x_stat(conf->cache_dir, &st) != 0 || st.st_mtime + 3600 >= now) {
355 : : /* No cleanup needed. */
356 : 1 : return;
357 : : }
358 : :
359 : 0 : update_mtime(conf->cache_dir);
360 : :
361 : 0 : dir = opendir(temp_dir());
362 [ # # ]: 0 : if (!dir) {
363 : 0 : return;
364 : : }
365 : :
366 [ # # ]: 0 : while ((entry = readdir(dir))) {
367 : : char *path;
368 : :
369 [ # # ][ # # ]: 0 : if (str_eq(entry->d_name, ".") || str_eq(entry->d_name, "..")) {
370 : 0 : continue;
371 : : }
372 : :
373 : 0 : path = format("%s/%s", temp_dir(), entry->d_name);
374 [ # # ][ # # ]: 0 : if (x_lstat(path, &st) == 0 && st.st_mtime + 3600 < now) {
375 : 0 : tmp_unlink(path);
376 : : }
377 : 0 : free(path);
378 : : }
379 : :
380 : 1 : closedir(dir);
381 : : }
382 : :
383 : : static char *
384 : 2 : get_current_working_dir(void)
385 : : {
386 [ + + ]: 2 : if (!current_working_dir) {
387 : 1 : char *cwd = get_cwd();
388 [ + - ]: 1 : if (cwd) {
389 : 1 : current_working_dir = x_realpath(cwd);
390 : 1 : free(cwd);
391 : : }
392 [ - + ]: 1 : if (!current_working_dir) {
393 : 0 : cc_log("Unable to determine current working directory: %s",
394 : : strerror(errno));
395 : 0 : failed();
396 : : }
397 : : }
398 : 2 : return current_working_dir;
399 : : }
400 : :
401 : : /*
402 : : * Transform a name to a full path into the cache directory, creating needed
403 : : * sublevels if needed. Caller frees.
404 : : */
405 : : static char *
406 : 5 : get_path_in_cache(const char *name, const char *suffix)
407 : : {
408 : : unsigned i;
409 : : char *path;
410 : : char *result;
411 : :
412 : 5 : path = x_strdup(conf->cache_dir);
413 [ + + ]: 15 : for (i = 0; i < conf->cache_dir_levels; ++i) {
414 : 10 : char *p = format("%s/%c", path, name[i]);
415 : 10 : free(path);
416 : 10 : path = p;
417 : : }
418 : :
419 : 5 : result = format("%s/%s%s", path, name + conf->cache_dir_levels, suffix);
420 : 5 : free(path);
421 : 5 : return result;
422 : : }
423 : :
424 : : /*
425 : : * This function hashes an include file and stores the path and hash in the
426 : : * global included_files variable. If the include file is a PCH, cpp_hash is
427 : : * also updated. Takes over ownership of path.
428 : : */
429 : : static void
430 : 4 : remember_include_file(char *path, struct mdfour *cpp_hash)
431 : : {
432 : : #ifdef _WIN32
433 : : DWORD attributes;
434 : : #endif
435 : : struct mdfour fhash;
436 : : struct stat st;
437 : 4 : char *source = NULL;
438 : : size_t size;
439 : : bool is_pch;
440 : 4 : size_t path_len = strlen(path);
441 : :
442 [ + - ][ + + ]: 4 : if (path_len >= 2 && (path[0] == '<' && path[path_len - 1] == '>')) {
[ + - ]
443 : : /* Typically <built-in> or <command-line>. */
444 : 2 : goto ignore;
445 : : }
446 : :
447 [ + - ]: 2 : if (str_eq(path, input_file)) {
448 : : /* Don't remember the input file. */
449 : 2 : goto ignore;
450 : : }
451 : :
452 [ # # ]: 0 : if (hashtable_search(included_files, path)) {
453 : : /* Already known include file. */
454 : 0 : goto ignore;
455 : : }
456 : :
457 : : #ifdef _WIN32
458 : : /* stat fails on directories on win32 */
459 : : attributes = GetFileAttributes(path);
460 : : if (attributes != INVALID_FILE_ATTRIBUTES &&
461 : : attributes & FILE_ATTRIBUTE_DIRECTORY)
462 : : goto ignore;
463 : : #endif
464 : :
465 [ # # ]: 0 : if (x_stat(path, &st) != 0) {
466 : 0 : goto failure;
467 : : }
468 [ # # ]: 0 : if (S_ISDIR(st.st_mode)) {
469 : : /* Ignore directory, typically $PWD. */
470 : 0 : goto ignore;
471 : : }
472 [ # # ]: 0 : if (!S_ISREG(st.st_mode)) {
473 : : /* Device, pipe, socket or other strange creature. */
474 : 0 : cc_log("Non-regular include file %s", path);
475 : 0 : goto failure;
476 : : }
477 : :
478 : : /* Let's hash the include file. */
479 [ # # ][ # # ]: 0 : if (!(conf->sloppiness & SLOPPY_INCLUDE_FILE_MTIME)
480 : 0 : && st.st_mtime >= time_of_compilation) {
481 : 0 : cc_log("Include file %s too new", path);
482 : 0 : goto failure;
483 : : }
484 : :
485 [ # # ][ # # ]: 0 : if (!(conf->sloppiness & SLOPPY_INCLUDE_FILE_CTIME)
486 : 0 : && st.st_ctime >= time_of_compilation) {
487 : 0 : cc_log("Include file %s ctime too new", path);
488 : 0 : goto failure;
489 : : }
490 : :
491 : 0 : hash_start(&fhash);
492 : :
493 : 0 : is_pch = is_precompiled_header(path);
494 [ # # ]: 0 : if (is_pch) {
495 : : struct file_hash pch_hash;
496 [ # # ]: 0 : if (!hash_file(&fhash, path)) {
497 : 0 : goto failure;
498 : : }
499 : 0 : hash_result_as_bytes(&fhash, pch_hash.hash);
500 : 0 : pch_hash.size = fhash.totalN;
501 : 0 : hash_delimiter(cpp_hash, "pch_hash");
502 : 0 : hash_buffer(cpp_hash, pch_hash.hash, sizeof(pch_hash.hash));
503 : : }
504 [ # # ]: 0 : if (conf->direct_mode) {
505 : : struct file_hash *h;
506 : :
507 [ # # ]: 0 : if (!is_pch) { /* else: the file has already been hashed. */
508 : : int result;
509 : :
510 [ # # ]: 0 : if (st.st_size > 0) {
511 [ # # ]: 0 : if (!read_file(path, st.st_size, &source, &size)) {
512 : 0 : goto failure;
513 : : }
514 : : } else {
515 : 0 : source = x_strdup("");
516 : 0 : size = 0;
517 : : }
518 : :
519 : 0 : result = hash_source_code_string(conf, &fhash, source, size, path);
520 [ # # ][ # # ]: 0 : if (result & HASH_SOURCE_CODE_ERROR
521 : 0 : || result & HASH_SOURCE_CODE_FOUND_TIME) {
522 : : goto failure;
523 : : }
524 : : }
525 : :
526 : 0 : h = x_malloc(sizeof(*h));
527 : 0 : hash_result_as_bytes(&fhash, h->hash);
528 : 0 : h->size = fhash.totalN;
529 : 0 : hashtable_insert(included_files, path, h);
530 : : } else {
531 : 0 : free(path);
532 : : }
533 : :
534 : 0 : free(source);
535 : 0 : return;
536 : :
537 : : failure:
538 : 0 : cc_log("Disabling direct mode");
539 : 0 : conf->direct_mode = false;
540 : : /* Fall through. */
541 : : ignore:
542 : 4 : free(path);
543 : 4 : free(source);
544 : : }
545 : :
546 : : /*
547 : : * Make a relative path from current working directory to path if path is under
548 : : * the base directory. Takes over ownership of path. Caller frees.
549 : : */
550 : : static char *
551 : 74 : make_relative_path(char *path)
552 : : {
553 : 74 : char *relpath, *canon_path, *path_suffix = NULL;
554 : : struct stat st;
555 : :
556 [ + + ][ + + ]: 74 : if (str_eq(conf->base_dir, "") || !str_startswith(path, conf->base_dir)) {
557 : 73 : return path;
558 : : }
559 : :
560 : : /* x_realpath only works for existing paths, so if path doesn't exist, try
561 : : * dirname(path) and assemble the path afterwards. We only bother to try
562 : : * canonicalizing one of these two paths since a compiler path argument
563 : : * typically only makes sense if path or dirname(path) exists. */
564 [ + - ]: 1 : if (stat(path, &st) != 0) {
565 : : /* path doesn't exist. */
566 : : char *dir, *p;
567 : 1 : dir = dirname(path);
568 [ - + ]: 1 : if (stat(dir, &st) != 0) {
569 : : /* And neither does its parent directory, so no action to take. */
570 : 0 : free(dir);
571 : 0 : return path;
572 : : }
573 : 1 : path_suffix = basename(path);
574 : 1 : p = path;
575 : 1 : path = dirname(path);
576 : 1 : free(p);
577 : : }
578 : :
579 : 1 : canon_path = x_realpath(path);
580 [ + - ]: 1 : if (canon_path) {
581 : 1 : free(path);
582 : 1 : relpath = get_relative_path(get_current_working_dir(), canon_path);
583 : 1 : free(canon_path);
584 [ + - ]: 1 : if (path_suffix) {
585 : 1 : path = format("%s/%s", relpath, path_suffix);
586 : 1 : free(relpath);
587 : 1 : free(path_suffix);
588 : 1 : return path;
589 : : } else {
590 : 0 : return relpath;
591 : : }
592 : : } else {
593 : : /* path doesn't exist, so leave it as it is. */
594 : 0 : free(path_suffix);
595 : 74 : return path;
596 : : }
597 : : }
598 : :
599 : : /*
600 : : * This function reads and hashes a file. While doing this, it also does these
601 : : * things:
602 : : *
603 : : * - Makes include file paths for which the base directory is a prefix relative
604 : : * when computing the hash sum.
605 : : * - Stores the paths and hashes of included files in the global variable
606 : : * included_files.
607 : : */
608 : : static bool
609 : 1 : process_preprocessed_file(struct mdfour *hash, const char *path)
610 : : {
611 : : char *data;
612 : : char *p, *q, *end;
613 : : size_t size;
614 : :
615 [ - + ]: 1 : if (!read_file(path, 0, &data, &size)) {
616 : 0 : return false;
617 : : }
618 : :
619 : 1 : included_files = create_hashtable(1000, hash_from_string, strings_equal);
620 : :
621 : : /* Bytes between p and q are pending to be hashed. */
622 : 1 : end = data + size;
623 : 1 : p = data;
624 : 1 : q = data;
625 [ + + ]: 37 : while (q < end - 7) { /* There must be at least 7 characters (# 1 "x") left
626 : : to potentially find an include file path. */
627 : : /*
628 : : * Check if we look at a line containing the file name of an included file.
629 : : * At least the following formats exist (where N is a positive integer):
630 : : *
631 : : * GCC:
632 : : *
633 : : * # N "file"
634 : : * # N "file" N
635 : : * #pragma GCC pch_preprocess "file"
636 : : *
637 : : * HP's compiler:
638 : : *
639 : : * #line N "file"
640 : : *
641 : : * AIX's compiler:
642 : : *
643 : : * #line N "file"
644 : : * #line N
645 : : *
646 : : * Note that there may be other lines starting with '#' left after
647 : : * preprocessing as well, for instance "# pragma".
648 : : */
649 [ + + ][ + - ]: 40 : if (q[0] == '#'
[ + - ][ - + ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ + + ]
[ + - ]
650 : : /* GCC: */
651 : 12 : && ((q[1] == ' ' && q[2] >= '0' && q[2] <= '9')
652 : : /* GCC precompiled header: */
653 : 0 : || (q[1] == 'p'
654 : 0 : && str_startswith(&q[2], "ragma GCC pch_preprocess "))
655 : : /* HP/AIX: */
656 : 0 : || (q[1] == 'l' && q[2] == 'i' && q[3] == 'n' && q[4] == 'e'
657 : 0 : && q[5] == ' '))
658 : 7 : && (q == data || q[-1] == '\n')) {
659 : : char *path;
660 : :
661 [ + - ][ + + ]: 20 : while (q < end && *q != '"' && *q != '\n') {
[ + - ]
662 : 16 : q++;
663 : : }
664 [ + - ][ - + ]: 4 : if (q < end && *q == '\n') {
665 : : /* A newline before the quotation mark -> no match. */
666 : 0 : continue;
667 : : }
668 : 4 : q++;
669 [ - + ]: 4 : if (q >= end) {
670 : 0 : cc_log("Failed to parse included file path");
671 : 0 : free(data);
672 : 0 : return false;
673 : : }
674 : : /* q points to the beginning of an include file path */
675 : 4 : hash_buffer(hash, p, q - p);
676 : 4 : p = q;
677 [ + - ][ + + ]: 42 : while (q < end && *q != '"') {
678 : 38 : q++;
679 : : }
680 : : /* p and q span the include file path */
681 : 4 : path = x_strndup(p, q - p);
682 : 4 : path = make_relative_path(path);
683 : 4 : hash_string(hash, path);
684 : 4 : remember_include_file(path, hash);
685 : 4 : p = q;
686 : : } else {
687 : 32 : q++;
688 : : }
689 : : }
690 : :
691 : 1 : hash_buffer(hash, p, (end - p));
692 : 1 : free(data);
693 : :
694 : : /* Explicitly check the .gch/.pch/.pth file, Clang does not include any
695 : : * mention of it in the preprocessed output. */
696 [ - + ]: 1 : if (included_pch_file) {
697 : 0 : char *path = x_strdup(included_pch_file);
698 : 0 : path = make_relative_path(path);
699 : 0 : hash_string(hash, path);
700 : 0 : remember_include_file(path, hash);
701 : : }
702 : :
703 : 1 : return true;
704 : : }
705 : :
706 : : /* Copy or link a file to the cache. */
707 : : static void
708 : 1 : put_file_in_cache(const char *source, const char *dest)
709 : : {
710 : : int ret;
711 : : struct stat st;
712 [ - + ][ # # ]: 1 : bool do_link = conf->hard_link && !conf->compression;
713 : :
714 [ - + ]: 1 : if (do_link) {
715 : 0 : x_unlink(dest);
716 : 0 : ret = link(source, dest);
717 : : } else {
718 : 1 : ret = copy_file(source, dest, conf->compression);
719 : : }
720 [ - + ]: 1 : if (ret != 0) {
721 [ # # ]: 0 : cc_log("Failed to %s %s to %s: %s",
722 : : do_link ? "link" : "copy",
723 : : source,
724 : : dest,
725 : : strerror(errno));
726 : 0 : stats_update(STATS_ERROR);
727 : 0 : failed();
728 : : }
729 : 1 : cc_log("Stored in cache: %s -> %s", source, dest);
730 [ - + ]: 1 : if (x_stat(dest, &st) != 0) {
731 : 0 : stats_update(STATS_ERROR);
732 : 0 : failed();
733 : : }
734 : 1 : stats_update_size(file_size(&st), 1);
735 : 1 : }
736 : :
737 : : /* Copy or link a file from the cache. */
738 : : static void
739 : 0 : get_file_from_cache(const char *source, const char *dest)
740 : : {
741 : : int ret;
742 [ # # ][ # # ]: 0 : bool do_link = conf->hard_link && !file_is_compressed(source);
743 : :
744 [ # # ]: 0 : if (do_link) {
745 : 0 : x_unlink(dest);
746 : 0 : ret = link(source, dest);
747 : : } else {
748 : 0 : ret = copy_file(source, dest, 0);
749 : : }
750 : :
751 [ # # ]: 0 : if (ret == -1) {
752 [ # # ]: 0 : if (errno == ENOENT) {
753 : : /* Someone removed the file just before we began copying? */
754 : 0 : cc_log("Cache file %s just disappeared from cache", source);
755 : 0 : stats_update(STATS_MISSING);
756 : : } else {
757 [ # # ]: 0 : cc_log("Failed to %s %s to %s: %s",
758 : : do_link ? "link" : "copy",
759 : : source,
760 : : dest,
761 : : strerror(errno));
762 : 0 : stats_update(STATS_ERROR);
763 : : }
764 : :
765 : : /* If there was trouble getting a file from the cached result, wipe the
766 : : * whole cached result for consistency. */
767 : 0 : x_unlink(cached_stderr);
768 : 0 : x_unlink(cached_obj);
769 : 0 : x_unlink(cached_dep);
770 : 0 : x_unlink(cached_dia);
771 : :
772 : 0 : failed();
773 : : }
774 : :
775 : 0 : cc_log("Created from cache: %s -> %s", source, dest);
776 : 0 : }
777 : :
778 : : /* Send cached stderr, if any, to stderr. */
779 : : static void
780 : 1 : send_cached_stderr(void)
781 : : {
782 : 1 : int fd_stderr = open(cached_stderr, O_RDONLY | O_BINARY);
783 [ + - ]: 1 : if (fd_stderr != -1) {
784 : 1 : copy_fd(fd_stderr, 2);
785 : 1 : close(fd_stderr);
786 : : }
787 : 1 : }
788 : :
789 : : /* Create or update the manifest file. */
790 : 1 : void update_manifest_file(void)
791 : : {
792 : : struct stat st;
793 : 1 : size_t old_size = 0; /* in bytes */
794 : :
795 [ - + ][ # # ]: 1 : if (!conf->direct_mode
[ # # ][ # # ]
796 : 0 : || !included_files
797 : 0 : || conf->read_only
798 : 0 : || conf->read_only_direct) {
799 : 1 : return;
800 : : }
801 : :
802 [ # # ]: 0 : if (stat(manifest_path, &st) == 0) {
803 : 0 : old_size = file_size(&st);
804 : : }
805 [ # # ]: 0 : if (manifest_put(manifest_path, cached_obj_hash, included_files)) {
806 : 0 : cc_log("Added object file hash to %s", manifest_path);
807 : 0 : update_mtime(manifest_path);
808 [ # # ]: 0 : if (x_stat(manifest_path, &st) == 0) {
809 : 0 : stats_update_size(file_size(&st) - old_size, old_size == 0 ? 1 : 0);
810 : : }
811 : : } else {
812 : 1 : cc_log("Failed to add object file hash to %s", manifest_path);
813 : : }
814 : : }
815 : :
816 : : /* run the real compiler and put the result in cache */
817 : : static void
818 : 1 : to_cache(struct args *args)
819 : : {
820 : : char *tmp_stdout, *tmp_stderr, *tmp_aux, *tmp_cov;
821 : 1 : char *tmp_dwo = NULL;
822 : : struct stat st;
823 : : int status, tmp_stdout_fd, tmp_stderr_fd;
824 : : FILE *f;
825 : :
826 : 1 : tmp_stdout = format("%s.tmp.stdout", cached_obj);
827 : 1 : tmp_stdout_fd = create_tmp_fd(&tmp_stdout);
828 : 1 : tmp_stderr = format("%s.tmp.stderr", cached_obj);
829 : 1 : tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
830 : :
831 [ - + ]: 1 : if (generating_coverage) {
832 : : /* gcc has some funny rule about max extension length */
833 [ # # ]: 0 : if (strlen(get_extension(output_obj)) < 6) {
834 : 0 : tmp_aux = remove_extension(output_obj);
835 : : } else {
836 : 0 : tmp_aux = x_strdup(output_obj);
837 : : }
838 : 0 : tmp_cov = format("%s.gcno", tmp_aux);
839 : 0 : free(tmp_aux);
840 : : } else {
841 : 1 : tmp_cov = NULL;
842 : : }
843 : :
844 : : /* GCC (at least 4.8 and 4.9) forms the .dwo file name by removing everything
845 : : * after (and including) the last "." from the object file name and then
846 : : * appending ".dwo".
847 : : */
848 [ - + ]: 1 : if (using_split_dwarf) {
849 : 0 : char *base_name = remove_extension(output_obj);
850 : 0 : tmp_dwo = format("%s.dwo", base_name);
851 : 0 : free(base_name);
852 : : }
853 : :
854 : 1 : args_add(args, "-o");
855 : 1 : args_add(args, output_obj);
856 : :
857 [ - + ]: 1 : if (output_dia) {
858 : 0 : args_add(args, "--serialize-diagnostics");
859 : 0 : args_add(args, output_dia);
860 : : }
861 : :
862 : : /* Turn off DEPENDENCIES_OUTPUT when running cc1, because
863 : : * otherwise it will emit a line like
864 : : *
865 : : * tmp.stdout.vexed.732.o: /home/mbp/.ccache/tmp.stdout.vexed.732.i
866 : : */
867 : 1 : x_unsetenv("DEPENDENCIES_OUTPUT");
868 : :
869 [ - + ]: 1 : if (conf->run_second_cpp) {
870 : 0 : args_add(args, input_file);
871 : : } else {
872 : 1 : args_add(args, i_tmpfile);
873 : : }
874 : :
875 : 1 : cc_log("Running real compiler");
876 : 1 : status = execute(args->argv, tmp_stdout_fd, tmp_stderr_fd);
877 : 1 : args_pop(args, 3);
878 : :
879 [ - + ]: 1 : if (x_stat(tmp_stdout, &st) != 0) {
880 : : /* The stdout file was removed - cleanup in progress? Better bail out. */
881 : 0 : stats_update(STATS_MISSING);
882 : 0 : tmp_unlink(tmp_stdout);
883 : 0 : tmp_unlink(tmp_stderr);
884 [ # # ]: 0 : if (tmp_cov) {
885 : 0 : tmp_unlink(tmp_cov);
886 : : }
887 : 0 : tmp_unlink(tmp_dwo);
888 : 0 : failed();
889 : : }
890 [ - + ]: 1 : if (st.st_size != 0) {
891 : 0 : cc_log("Compiler produced stdout");
892 : 0 : stats_update(STATS_STDOUT);
893 : 0 : tmp_unlink(tmp_stdout);
894 : 0 : tmp_unlink(tmp_stderr);
895 [ # # ]: 0 : if (tmp_cov) {
896 : 0 : tmp_unlink(tmp_cov);
897 : : }
898 : 0 : tmp_unlink(tmp_dwo);
899 : 0 : failed();
900 : : }
901 : 1 : tmp_unlink(tmp_stdout);
902 : :
903 : : /*
904 : : * Merge stderr from the preprocessor (if any) and stderr from the real
905 : : * compiler into tmp_stderr.
906 : : */
907 [ + - ]: 1 : if (cpp_stderr) {
908 : : int fd_cpp_stderr;
909 : : int fd_real_stderr;
910 : : int fd_result;
911 : : char *tmp_stderr2;
912 : :
913 : 1 : tmp_stderr2 = format("%s.2", tmp_stderr);
914 [ - + ]: 1 : if (x_rename(tmp_stderr, tmp_stderr2)) {
915 : 0 : cc_log("Failed to rename %s to %s: %s", tmp_stderr, tmp_stderr2,
916 : : strerror(errno));
917 : 0 : failed();
918 : : }
919 : 1 : fd_cpp_stderr = open(cpp_stderr, O_RDONLY | O_BINARY);
920 [ - + ]: 1 : if (fd_cpp_stderr == -1) {
921 : 0 : cc_log("Failed opening %s: %s", cpp_stderr, strerror(errno));
922 : 0 : failed();
923 : : }
924 : 1 : fd_real_stderr = open(tmp_stderr2, O_RDONLY | O_BINARY);
925 [ - + ]: 1 : if (fd_real_stderr == -1) {
926 : 0 : cc_log("Failed opening %s: %s", tmp_stderr2, strerror(errno));
927 : 0 : failed();
928 : : }
929 : 1 : fd_result = open(tmp_stderr, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
930 [ - + ]: 1 : if (fd_result == -1) {
931 : 0 : cc_log("Failed opening %s: %s", tmp_stderr, strerror(errno));
932 : 0 : failed();
933 : : }
934 : 1 : copy_fd(fd_cpp_stderr, fd_result);
935 : 1 : copy_fd(fd_real_stderr, fd_result);
936 : 1 : close(fd_cpp_stderr);
937 : 1 : close(fd_real_stderr);
938 : 1 : close(fd_result);
939 : 1 : tmp_unlink(tmp_stderr2);
940 : 1 : free(tmp_stderr2);
941 : : }
942 : :
943 [ - + ]: 1 : if (status != 0) {
944 : : int fd;
945 : 0 : cc_log("Compiler gave exit status %d", status);
946 : 0 : stats_update(STATS_STATUS);
947 : :
948 : 0 : fd = open(tmp_stderr, O_RDONLY | O_BINARY);
949 [ # # ]: 0 : if (fd != -1) {
950 : : /* We can output stderr immediately instead of rerunning the compiler. */
951 : 0 : copy_fd(fd, 2);
952 : 0 : close(fd);
953 : 0 : tmp_unlink(tmp_stderr);
954 : :
955 : 0 : x_exit(status);
956 : : }
957 : :
958 : 0 : tmp_unlink(tmp_stderr);
959 [ # # ]: 0 : if (tmp_cov) {
960 : 0 : tmp_unlink(tmp_cov);
961 : : }
962 : 0 : tmp_unlink(tmp_dwo);
963 : :
964 : 0 : failed();
965 : : }
966 : :
967 [ - + ]: 1 : if (stat(output_obj, &st) != 0) {
968 : 0 : cc_log("Compiler didn't produce an object file");
969 : 0 : stats_update(STATS_NOOUTPUT);
970 : 0 : failed();
971 : : }
972 [ - + ]: 1 : if (st.st_size == 0) {
973 : 0 : cc_log("Compiler produced an empty object file");
974 : 0 : stats_update(STATS_EMPTYOUTPUT);
975 : 0 : failed();
976 : : }
977 : :
978 [ - + ]: 1 : if (using_split_dwarf) {
979 [ # # ]: 0 : if (stat(tmp_dwo, &st) != 0) {
980 : 0 : cc_log("Compiler didn't produce a split dwarf file");
981 : 0 : stats_update(STATS_NOOUTPUT);
982 : 0 : failed();
983 : : }
984 [ # # ]: 0 : if (st.st_size == 0) {
985 : 0 : cc_log("Compiler produced an empty split dwarf file");
986 : 0 : stats_update(STATS_EMPTYOUTPUT);
987 : 0 : failed();
988 : : }
989 : : }
990 : :
991 [ - + ]: 1 : if (x_stat(tmp_stderr, &st) != 0) {
992 : 0 : stats_update(STATS_ERROR);
993 : 0 : failed();
994 : : }
995 [ + - ]: 1 : if (st.st_size > 0) {
996 [ - + ][ - + ]: 1 : if (move_uncompressed_file(
997 : : tmp_stderr, cached_stderr,
998 : 1 : conf->compression ? conf->compression_level : 0) != 0) {
999 : 0 : cc_log("Failed to move %s to %s: %s", tmp_stderr, cached_stderr,
1000 : : strerror(errno));
1001 : 0 : stats_update(STATS_ERROR);
1002 : 0 : failed();
1003 : : }
1004 : 1 : cc_log("Stored in cache: %s", cached_stderr);
1005 [ - + ]: 1 : if (!conf->compression
[ # # # # ]
1006 : : /* If the file was compressed, obtain the size again: */
1007 : 0 : || (conf->compression && x_stat(cached_stderr, &st) == 0)) {
1008 : 1 : stats_update_size(file_size(&st), 1);
1009 : : }
1010 : : } else {
1011 : 0 : tmp_unlink(tmp_stderr);
1012 [ # # ]: 0 : if (conf->recache) {
1013 : : /* If recaching, we need to remove any previous .stderr. */
1014 : 0 : x_unlink(cached_stderr);
1015 : : }
1016 : : }
1017 : :
1018 [ - + ]: 1 : if (generating_coverage) {
1019 : : /* gcc won't generate notes if there is no code */
1020 [ # # ][ # # ]: 0 : if (stat(tmp_cov, &st) != 0 && errno == ENOENT) {
1021 : 0 : cc_log("Creating placeholder: %s", cached_cov);
1022 : :
1023 : 0 : f = fopen(cached_cov, "wb");
1024 [ # # ]: 0 : if (!f) {
1025 : 0 : cc_log("Failed to create %s: %s", cached_cov, strerror(errno));
1026 : 0 : stats_update(STATS_ERROR);
1027 : 0 : failed();
1028 : : }
1029 : 0 : fclose(f);
1030 : 0 : stats_update_size(0, 1);
1031 : : } else {
1032 : 0 : put_file_in_cache(tmp_cov, cached_cov);
1033 : : }
1034 : : }
1035 : :
1036 [ - + ]: 1 : if (output_dia) {
1037 [ # # ]: 0 : if (x_stat(output_dia, &st) != 0) {
1038 : 0 : stats_update(STATS_ERROR);
1039 : 0 : failed();
1040 : : }
1041 [ # # ]: 0 : if (st.st_size > 0) {
1042 : 0 : put_file_in_cache(output_dia, cached_dia);
1043 : : }
1044 : : }
1045 : :
1046 : 1 : put_file_in_cache(output_obj, cached_obj);
1047 : :
1048 [ - + ]: 1 : if (using_split_dwarf) {
1049 [ # # ]: 0 : assert(tmp_dwo);
1050 [ # # ]: 0 : assert(cached_dwo);
1051 : 0 : put_file_in_cache(tmp_dwo, cached_dwo);
1052 : : }
1053 : :
1054 [ - + ]: 1 : if (generating_dependencies) {
1055 : 0 : put_file_in_cache(output_dep, cached_dep);
1056 : : }
1057 : 1 : stats_update(STATS_TOCACHE);
1058 : :
1059 : : /* Make sure we have a CACHEDIR.TAG in the cache part of cache_dir. This can
1060 : : * be done almost anywhere, but we might as well do it near the end as we
1061 : : * save the stat call if we exit early.
1062 : : */
1063 : : {
1064 : 1 : char *first_level_dir = dirname(stats_file);
1065 [ - + ]: 1 : if (create_cachedirtag(first_level_dir) != 0) {
1066 : 0 : cc_log("Failed to create %s/CACHEDIR.TAG (%s)\n",
1067 : : first_level_dir, strerror(errno));
1068 : 0 : stats_update(STATS_ERROR);
1069 : 0 : failed();
1070 : : }
1071 : 1 : free(first_level_dir);
1072 : :
1073 : : /* Remove any CACHEDIR.TAG on the cache_dir level where it was located in
1074 : : * previous ccache versions. */
1075 [ - + ]: 1 : if (getpid() % 1000 == 0) {
1076 : 0 : char *path = format("%s/CACHEDIR.TAG", conf->cache_dir);
1077 : 0 : x_unlink(path);
1078 : 0 : free(path);
1079 : : }
1080 : : }
1081 : :
1082 : : /* Everything OK. */
1083 : 1 : send_cached_stderr();
1084 : 1 : update_manifest_file();
1085 : :
1086 : 1 : free(tmp_stderr);
1087 : 1 : free(tmp_stdout);
1088 : 1 : free(tmp_cov);
1089 : 1 : free(tmp_dwo);
1090 : 1 : }
1091 : :
1092 : : /*
1093 : : * Find the object file name by running the compiler in preprocessor mode.
1094 : : * Returns the hash as a heap-allocated hex string.
1095 : : */
1096 : : static struct file_hash *
1097 : 1 : get_object_name_from_cpp(struct args *args, struct mdfour *hash)
1098 : : {
1099 : : char *input_base;
1100 : : char *tmp;
1101 : : char *path_stdout, *path_stderr;
1102 : : int status, path_stderr_fd;
1103 : : struct file_hash *result;
1104 : :
1105 : : /* ~/hello.c -> tmp.hello.123.i
1106 : : limit the basename to 10
1107 : : characters in order to cope with filesystem with small
1108 : : maximum filename length limits */
1109 : 1 : input_base = basename(input_file);
1110 : 1 : tmp = strchr(input_base, '.');
1111 [ + - ]: 1 : if (tmp) {
1112 : 1 : *tmp = 0;
1113 : : }
1114 [ - + ]: 1 : if (strlen(input_base) > 10) {
1115 : 0 : input_base[10] = 0;
1116 : : }
1117 : :
1118 : 1 : path_stderr = format("%s/tmp.cpp_stderr", temp_dir());
1119 : 1 : path_stderr_fd = create_tmp_fd(&path_stderr);
1120 : 1 : add_pending_tmp_file(path_stderr);
1121 : :
1122 : 1 : time_of_compilation = time(NULL);
1123 : :
1124 [ - + ]: 1 : if (direct_i_file) {
1125 : : /* We are compiling a .i or .ii file - that means we can skip the cpp stage
1126 : : * and directly form the correct i_tmpfile. */
1127 : 0 : path_stdout = input_file;
1128 : 0 : status = 0;
1129 : : } else {
1130 : : /* Run cpp on the input file to obtain the .i. */
1131 : : int path_stdout_fd;
1132 : 1 : path_stdout = format("%s/%s.stdout", temp_dir(), input_base);
1133 : 1 : path_stdout_fd = create_tmp_fd(&path_stdout);
1134 : 1 : add_pending_tmp_file(path_stdout);
1135 : :
1136 : 1 : args_add(args, "-E");
1137 : 1 : args_add(args, input_file);
1138 : 1 : cc_log("Running preprocessor");
1139 : 1 : status = execute(args->argv, path_stdout_fd, path_stderr_fd);
1140 : 1 : args_pop(args, 2);
1141 : : }
1142 : :
1143 [ - + ]: 1 : if (status != 0) {
1144 : 0 : cc_log("Preprocessor gave exit status %d", status);
1145 : 0 : stats_update(STATS_PREPROCESSOR);
1146 : 0 : failed();
1147 : : }
1148 : :
1149 [ - + ]: 1 : if (conf->unify) {
1150 : : /* When we are doing the unifying tricks we need to include the input file
1151 : : * name in the hash to get the warnings right. */
1152 : 0 : hash_delimiter(hash, "unifyfilename");
1153 : 0 : hash_string(hash, input_file);
1154 : :
1155 : 0 : hash_delimiter(hash, "unifycpp");
1156 [ # # ]: 0 : if (unify_hash(hash, path_stdout) != 0) {
1157 : 0 : stats_update(STATS_ERROR);
1158 : 0 : cc_log("Failed to unify %s", path_stdout);
1159 : 0 : failed();
1160 : : }
1161 : : } else {
1162 : 1 : hash_delimiter(hash, "cpp");
1163 [ - + ]: 1 : if (!process_preprocessed_file(hash, path_stdout)) {
1164 : 0 : stats_update(STATS_ERROR);
1165 : 0 : failed();
1166 : : }
1167 : : }
1168 : :
1169 : 1 : hash_delimiter(hash, "cppstderr");
1170 [ - + ]: 1 : if (!hash_file(hash, path_stderr)) {
1171 : 0 : fatal("Failed to open %s: %s", path_stderr, strerror(errno));
1172 : : }
1173 : :
1174 [ - + ]: 1 : if (direct_i_file) {
1175 : 0 : i_tmpfile = input_file;
1176 : : } else {
1177 : : /* i_tmpfile needs the proper cpp_extension for the compiler to do its
1178 : : * thing correctly. */
1179 : 1 : i_tmpfile = format("%s.%s", path_stdout, conf->cpp_extension);
1180 : 1 : x_rename(path_stdout, i_tmpfile);
1181 : 1 : add_pending_tmp_file(i_tmpfile);
1182 : : }
1183 : :
1184 [ - + ]: 1 : if (conf->run_second_cpp) {
1185 : 0 : free(path_stderr);
1186 : : } else {
1187 : : /*
1188 : : * If we are using the CPP trick, we need to remember this
1189 : : * stderr data and output it just before the main stderr from
1190 : : * the compiler pass.
1191 : : */
1192 : 1 : cpp_stderr = path_stderr;
1193 : 1 : hash_delimiter(hash, "runsecondcpp");
1194 : 1 : hash_string(hash, "false");
1195 : : }
1196 : :
1197 : 1 : result = x_malloc(sizeof(*result));
1198 : 1 : hash_result_as_bytes(hash, result->hash);
1199 : 1 : result->size = hash->totalN;
1200 : 1 : return result;
1201 : : }
1202 : :
1203 : : static void
1204 : 1 : update_cached_result_globals(struct file_hash *hash)
1205 : : {
1206 : : char *object_name;
1207 : 1 : object_name = format_hash_as_string(hash->hash, hash->size);
1208 : 1 : cached_obj_hash = hash;
1209 : 1 : cached_obj = get_path_in_cache(object_name, ".o");
1210 : 1 : cached_stderr = get_path_in_cache(object_name, ".stderr");
1211 : 1 : cached_dep = get_path_in_cache(object_name, ".d");
1212 : 1 : cached_cov = get_path_in_cache(object_name, ".gcno");
1213 : 1 : cached_dia = get_path_in_cache(object_name, ".dia");
1214 : :
1215 [ - + ]: 1 : if (using_split_dwarf) {
1216 : 0 : cached_dwo = get_path_in_cache(object_name, ".dwo");
1217 : : } else {
1218 : 1 : cached_dwo = NULL;
1219 : : }
1220 : :
1221 : 1 : stats_file = format("%s/%c/stats", conf->cache_dir, object_name[0]);
1222 : 1 : free(object_name);
1223 : 1 : }
1224 : :
1225 : : /*
1226 : : * Hash mtime or content of a file, or the output of a command, according to
1227 : : * the CCACHE_COMPILERCHECK setting.
1228 : : */
1229 : : static void
1230 : 1 : hash_compiler(struct mdfour *hash, struct stat *st, const char *path,
1231 : : bool allow_command)
1232 : : {
1233 [ - + ]: 1 : if (str_eq(conf->compiler_check, "none")) {
1234 : : /* Do nothing. */
1235 [ + - ]: 1 : } else if (str_eq(conf->compiler_check, "mtime")) {
1236 : 1 : hash_delimiter(hash, "cc_mtime");
1237 : 1 : hash_int(hash, st->st_size);
1238 : 1 : hash_int(hash, st->st_mtime);
1239 [ # # ]: 0 : } else if (str_startswith(conf->compiler_check, "string:")) {
1240 : 0 : hash_delimiter(hash, "cc_hash");
1241 : 0 : hash_string(hash, conf->compiler_check + strlen("string:"));
1242 [ # # ][ # # ]: 0 : } else if (str_eq(conf->compiler_check, "content") || !allow_command) {
1243 : 0 : hash_delimiter(hash, "cc_content");
1244 : 0 : hash_file(hash, path);
1245 : : } else { /* command string */
1246 [ # # ]: 0 : if (!hash_multicommand_output(
1247 : 0 : hash, conf->compiler_check, orig_args->argv[0])) {
1248 : 0 : fatal("Failure running compiler check command: %s", conf->compiler_check);
1249 : : }
1250 : : }
1251 : 1 : }
1252 : :
1253 : : /*
1254 : : * Note that these compiler checks are unreliable, so nothing should
1255 : : * hard-depend on them.
1256 : : */
1257 : :
1258 : : static bool
1259 : 0 : compiler_is_clang(struct args *args)
1260 : : {
1261 : 0 : char *name = basename(args->argv[0]);
1262 : 0 : bool is = strstr(name, "clang");
1263 : 0 : free(name);
1264 : 0 : return is;
1265 : : }
1266 : :
1267 : : static bool
1268 : 1 : compiler_is_gcc(struct args *args)
1269 : : {
1270 : 1 : char *name = basename(args->argv[0]);
1271 [ - + ][ # # ]: 1 : bool is = strstr(name, "gcc") || strstr(name, "g++");
1272 : 1 : free(name);
1273 : 1 : return is;
1274 : : }
1275 : :
1276 : : /*
1277 : : * Update a hash sum with information common for the direct and preprocessor
1278 : : * modes.
1279 : : */
1280 : : static void
1281 : 1 : calculate_common_hash(struct args *args, struct mdfour *hash)
1282 : : {
1283 : : struct stat st;
1284 : : char *p;
1285 : 1 : const char *full_path = args->argv[0];
1286 : : #ifdef _WIN32
1287 : : const char *ext;
1288 : : char full_path_win_ext[MAX_PATH + 1] = {0};
1289 : : #endif
1290 : :
1291 : 1 : hash_string(hash, HASH_PREFIX);
1292 : :
1293 : : /*
1294 : : * We have to hash the extension, as a .i file isn't treated the same
1295 : : * by the compiler as a .ii file.
1296 : : */
1297 : 1 : hash_delimiter(hash, "ext");
1298 : 1 : hash_string(hash, conf->cpp_extension);
1299 : :
1300 : : #ifdef _WIN32
1301 : : ext = strrchr(args->argv[0], '.');
1302 : : add_exe_ext_if_no_to_fullpath(full_path_win_ext, MAX_PATH, ext,
1303 : : args->argv[0]);
1304 : : full_path = full_path_win_ext;
1305 : : #endif
1306 : :
1307 [ - + ]: 1 : if (x_stat(full_path, &st) != 0) {
1308 : 0 : stats_update(STATS_COMPILER);
1309 : 0 : failed();
1310 : : }
1311 : :
1312 : : /*
1313 : : * Hash information about the compiler.
1314 : : */
1315 : 1 : hash_compiler(hash, &st, args->argv[0], true);
1316 : :
1317 : : /*
1318 : : * Also hash the compiler name as some compilers use hard links and
1319 : : * behave differently depending on the real name.
1320 : : */
1321 : 1 : hash_delimiter(hash, "cc_name");
1322 : 1 : p = basename(args->argv[0]);
1323 : 1 : hash_string(hash, p);
1324 : 1 : free(p);
1325 : :
1326 : : /* Possibly hash the current working directory. */
1327 [ - + ]: 1 : if (conf->hash_dir) {
1328 : 0 : char *cwd = gnu_getcwd();
1329 [ # # ]: 0 : if (cwd) {
1330 : 0 : hash_delimiter(hash, "cwd");
1331 : 0 : hash_string(hash, cwd);
1332 : 0 : free(cwd);
1333 : : }
1334 : : }
1335 : :
1336 : : /* Possibly hash the coverage data file path. */
1337 [ - + ][ # # ]: 1 : if (generating_coverage && profile_arcs) {
1338 : : char *gcda_path;
1339 : 0 : char *dir = dirname(output_obj);
1340 [ # # ]: 0 : if (profile_dir) {
1341 : 0 : dir = x_strdup(profile_dir);
1342 : : } else {
1343 : 0 : char *real_dir = x_realpath(dir);
1344 : 0 : free(dir);
1345 : 0 : dir = real_dir;
1346 : : }
1347 [ # # ]: 0 : if (dir) {
1348 : 0 : char *base_name = basename(output_obj);
1349 : 0 : p = remove_extension(base_name);
1350 : 0 : free(base_name);
1351 : 0 : gcda_path = format("%s/%s.gcda", dir, p);
1352 : 0 : cc_log("Hashing coverage path %s", gcda_path);
1353 : 0 : free(p);
1354 : 0 : hash_delimiter(hash, "gcda");
1355 : 0 : hash_string(hash, gcda_path);
1356 : 0 : free(dir);
1357 : : }
1358 : : }
1359 : :
1360 [ - + ]: 1 : if (!str_eq(conf->extra_files_to_hash, "")) {
1361 : 0 : char *path, *p, *q, *saveptr = NULL;
1362 : 0 : p = x_strdup(conf->extra_files_to_hash);
1363 : 0 : q = p;
1364 [ # # ]: 0 : while ((path = strtok_r(q, PATH_DELIM, &saveptr))) {
1365 : 0 : cc_log("Hashing extra file %s", path);
1366 : 0 : hash_delimiter(hash, "extrafile");
1367 [ # # ]: 0 : if (!hash_file(hash, path)) {
1368 : 0 : stats_update(STATS_BADEXTRAFILE);
1369 : 0 : failed();
1370 : : }
1371 : 0 : q = NULL;
1372 : : }
1373 : 0 : free(p);
1374 : : }
1375 : :
1376 : : /* Possibly hash GCC_COLORS (for color diagnostics). */
1377 [ + - ]: 1 : if (compiler_is_gcc(args)) {
1378 : 1 : const char *gcc_colors = getenv("GCC_COLORS");
1379 [ - + ]: 1 : if (gcc_colors) {
1380 : 0 : hash_delimiter(hash, "gcccolors");
1381 : 0 : hash_string(hash, gcc_colors);
1382 : : }
1383 : : }
1384 : 1 : }
1385 : :
1386 : : /*
1387 : : * Update a hash sum with information specific to the direct and preprocessor
1388 : : * modes and calculate the object hash. Returns the object hash on success,
1389 : : * otherwise NULL. Caller frees.
1390 : : */
1391 : : static struct file_hash *
1392 : 1 : calculate_object_hash(struct args *args, struct mdfour *hash, int direct_mode)
1393 : : {
1394 : : int i;
1395 : : char *manifest_name;
1396 : : struct stat st;
1397 : : int result;
1398 : 1 : struct file_hash *object_hash = NULL;
1399 : : char *p;
1400 : :
1401 [ - + ]: 1 : if (direct_mode) {
1402 : 0 : hash_delimiter(hash, "manifest version");
1403 : 0 : hash_int(hash, MANIFEST_VERSION);
1404 : : }
1405 : :
1406 : : /* first the arguments */
1407 [ - + ]: 1 : for (i = 1; i < args->argc; i++) {
1408 : : /* -L doesn't affect compilation. */
1409 [ # # ][ # # ]: 0 : if (i < args->argc-1 && str_eq(args->argv[i], "-L")) {
1410 : 0 : i++;
1411 : 0 : continue;
1412 : : }
1413 [ # # ]: 0 : if (str_startswith(args->argv[i], "-L")) {
1414 : 0 : continue;
1415 : : }
1416 : :
1417 : : /* -Wl,... doesn't affect compilation. */
1418 [ # # ]: 0 : if (str_startswith(args->argv[i], "-Wl,")) {
1419 : 0 : continue;
1420 : : }
1421 : :
1422 : : /* The -fdebug-prefix-map option may be used in combination with
1423 : : CCACHE_BASEDIR to reuse results across different directories. Skip it
1424 : : from hashing. */
1425 [ # # ]: 0 : if (str_startswith(args->argv[i], "-fdebug-prefix-map=")) {
1426 : 0 : continue;
1427 : : }
1428 : :
1429 : : /* When using the preprocessor, some arguments don't contribute
1430 : : to the hash. The theory is that these arguments will change
1431 : : the output of -E if they are going to have any effect at
1432 : : all. For precompiled headers this might not be the case. */
1433 [ # # ][ # # ]: 0 : if (!direct_mode && !output_is_precompiled_header
[ # # ]
1434 : : && !using_precompiled_header) {
1435 [ # # ]: 0 : if (compopt_affects_cpp(args->argv[i])) {
1436 : 0 : i++;
1437 : 0 : continue;
1438 : : }
1439 [ # # ]: 0 : if (compopt_short(compopt_affects_cpp, args->argv[i])) {
1440 : 0 : continue;
1441 : : }
1442 : : }
1443 : :
1444 : : /* If we're generating dependencies, we make sure to skip the
1445 : : * filename of the dependency file, since it doesn't impact the
1446 : : * output.
1447 : : */
1448 [ # # ]: 0 : if (generating_dependencies) {
1449 [ # # ]: 0 : if (str_startswith(args->argv[i], "-Wp,")) {
1450 [ # # ][ # # ]: 0 : if (str_startswith(args->argv[i], "-Wp,-MD,")
1451 : 0 : && !strchr(args->argv[i] + 8, ',')) {
1452 : 0 : hash_string_length(hash, args->argv[i], 8);
1453 : 0 : continue;
1454 [ # # ][ # # ]: 0 : } else if (str_startswith(args->argv[i], "-Wp,-MMD,")
1455 : 0 : && !strchr(args->argv[i] + 9, ',')) {
1456 : 0 : hash_string_length(hash, args->argv[i], 9);
1457 : 0 : continue;
1458 : : }
1459 [ # # ]: 0 : } else if (str_startswith(args->argv[i], "-MF")) {
1460 : 0 : bool separate_argument = (strlen(args->argv[i]) == 3);
1461 : :
1462 : : /* In either case, hash the "-MF" part. */
1463 : 0 : hash_string_length(hash, args->argv[i], 3);
1464 : :
1465 [ # # ]: 0 : if (separate_argument) {
1466 : : /* Next argument is dependency name, so
1467 : : * skip it. */
1468 : 0 : i++;
1469 : : }
1470 : 0 : continue;
1471 : : }
1472 : : }
1473 : :
1474 : 0 : p = NULL;
1475 [ # # ]: 0 : if (str_startswith(args->argv[i], "-specs=")) {
1476 : 0 : p = args->argv[i] + 7;
1477 [ # # ]: 0 : } else if (str_startswith(args->argv[i], "--specs=")) {
1478 : 0 : p = args->argv[i] + 8;
1479 : : }
1480 [ # # ][ # # ]: 0 : if (p && x_stat(p, &st) == 0) {
1481 : : /* If given an explicit specs file, then hash that file,
1482 : : but don't include the path to it in the hash. */
1483 : 0 : hash_delimiter(hash, "specs");
1484 : 0 : hash_compiler(hash, &st, p, false);
1485 : 0 : continue;
1486 : : }
1487 : :
1488 [ # # # # ]: 0 : if (str_startswith(args->argv[i], "-fplugin=")
1489 : 0 : && x_stat(args->argv[i] + 9, &st) == 0) {
1490 : 0 : hash_delimiter(hash, "plugin");
1491 : 0 : hash_compiler(hash, &st, args->argv[i] + 9, false);
1492 : 0 : continue;
1493 : : }
1494 : :
1495 [ # # ][ # # ]: 0 : if (str_eq(args->argv[i], "-Xclang")
[ # # ]
[ # # # # ]
1496 : 0 : && i + 3 < args->argc
1497 : 0 : && str_eq(args->argv[i+1], "-load")
1498 : 0 : && str_eq(args->argv[i+2], "-Xclang")
1499 : 0 : && x_stat(args->argv[i+3], &st) == 0) {
1500 : 0 : hash_delimiter(hash, "plugin");
1501 : 0 : hash_compiler(hash, &st, args->argv[i+3], false);
1502 : 0 : continue;
1503 : : }
1504 : :
1505 : : /* All other arguments are included in the hash. */
1506 : 0 : hash_delimiter(hash, "arg");
1507 : 0 : hash_string(hash, args->argv[i]);
1508 : : }
1509 : :
1510 : : /*
1511 : : * For profile generation (-fprofile-arcs, -fprofile-generate):
1512 : : * - hash profile directory
1513 : : * - output to the real file first
1514 : : *
1515 : : * For profile usage (-fprofile-use):
1516 : : * - hash profile data
1517 : : *
1518 : : * -fbranch-probabilities and -fvpt usage is covered by
1519 : : * -fprofile-generate/-fprofile-use.
1520 : : *
1521 : : * The profile directory can be specified as an argument to
1522 : : * -fprofile-generate=, -fprofile-use=, or -fprofile-dir=.
1523 : : */
1524 : :
1525 : : /*
1526 : : * We need to output to the real object first here, otherwise runtime
1527 : : * artifacts will be produced in the wrong place.
1528 : : */
1529 [ - + ]: 1 : if (profile_generate) {
1530 [ # # ]: 0 : if (!profile_dir) {
1531 : 0 : profile_dir = get_cwd();
1532 : : }
1533 : 0 : cc_log("Adding profile directory %s to our hash", profile_dir);
1534 : 0 : hash_delimiter(hash, "-fprofile-dir");
1535 : 0 : hash_string(hash, profile_dir);
1536 : : }
1537 : :
1538 [ - + ]: 1 : if (profile_use) {
1539 : : /* Calculate gcda name */
1540 : : char *gcda_name;
1541 : : char *base_name;
1542 : 0 : base_name = remove_extension(output_obj);
1543 [ # # ]: 0 : if (!profile_dir) {
1544 : 0 : profile_dir = get_cwd();
1545 : : }
1546 : 0 : gcda_name = format("%s/%s.gcda", profile_dir, base_name);
1547 : 0 : cc_log("Adding profile data %s to our hash", gcda_name);
1548 : : /* Add the gcda to our hash */
1549 : 0 : hash_delimiter(hash, "-fprofile-use");
1550 : 0 : hash_file(hash, gcda_name);
1551 : 0 : free(base_name);
1552 : 0 : free(gcda_name);
1553 : : }
1554 : :
1555 [ - + ]: 1 : if (direct_mode) {
1556 : : /* Hash environment variables that affect the preprocessor output. */
1557 : : const char **p;
1558 : : const char *envvars[] = {
1559 : : "CPATH",
1560 : : "C_INCLUDE_PATH",
1561 : : "CPLUS_INCLUDE_PATH",
1562 : : "OBJC_INCLUDE_PATH",
1563 : : "OBJCPLUS_INCLUDE_PATH", /* clang */
1564 : : NULL
1565 : 0 : };
1566 [ # # ]: 0 : for (p = envvars; *p; ++p) {
1567 : 0 : char *v = getenv(*p);
1568 [ # # ]: 0 : if (v) {
1569 : 0 : hash_delimiter(hash, *p);
1570 : 0 : hash_string(hash, v);
1571 : : }
1572 : : }
1573 : :
1574 [ # # ]: 0 : if (!(conf->sloppiness & SLOPPY_FILE_MACRO)) {
1575 : : /*
1576 : : * The source code file or an include file may contain
1577 : : * __FILE__, so make sure that the hash is unique for
1578 : : * the file name.
1579 : : */
1580 : 0 : hash_delimiter(hash, "inputfile");
1581 : 0 : hash_string(hash, input_file);
1582 : : }
1583 : :
1584 : 0 : hash_delimiter(hash, "sourcecode");
1585 : 0 : result = hash_source_code_file(conf, hash, input_file);
1586 [ # # ]: 0 : if (result & HASH_SOURCE_CODE_ERROR) {
1587 : 0 : failed();
1588 : : }
1589 [ # # ]: 0 : if (result & HASH_SOURCE_CODE_FOUND_TIME) {
1590 : 0 : cc_log("Disabling direct mode");
1591 : 0 : conf->direct_mode = false;
1592 : 0 : return NULL;
1593 : : }
1594 : 0 : manifest_name = hash_result(hash);
1595 : 0 : manifest_path = get_path_in_cache(manifest_name, ".manifest");
1596 : 0 : free(manifest_name);
1597 : 0 : cc_log("Looking for object file hash in %s", manifest_path);
1598 : 0 : object_hash = manifest_get(conf, manifest_path);
1599 [ # # ]: 0 : if (object_hash) {
1600 : 0 : cc_log("Got object file hash from manifest");
1601 : : } else {
1602 : 0 : cc_log("Did not find object file hash in manifest");
1603 : : }
1604 : : } else {
1605 : 1 : object_hash = get_object_name_from_cpp(args, hash);
1606 : 1 : cc_log("Got object file hash from preprocessor");
1607 [ - + ]: 1 : if (generating_dependencies) {
1608 : 0 : cc_log("Preprocessor created %s", output_dep);
1609 : : }
1610 : : }
1611 : :
1612 : 1 : return object_hash;
1613 : : }
1614 : :
1615 : : /*
1616 : : * Try to return the compile result from cache. If we can return from cache
1617 : : * then this function exits with the correct status code, otherwise it returns.
1618 : : */
1619 : : static void
1620 : 1 : from_cache(enum fromcache_call_mode mode, bool put_object_in_manifest)
1621 : : {
1622 : : struct stat st;
1623 : 1 : bool produce_dep_file = false;
1624 : :
1625 : : /* the user might be disabling cache hits */
1626 [ - + ]: 1 : if (conf->recache) {
1627 : 0 : return;
1628 : : }
1629 : :
1630 [ + - ]: 1 : if (stat(cached_obj, &st) != 0) {
1631 : 1 : cc_log("Object file %s not in cache", cached_obj);
1632 : 1 : return;
1633 : : }
1634 : :
1635 : : /* Check if the diagnostic file is there. */
1636 [ # # ][ # # ]: 0 : if (output_dia && stat(cached_dia, &st) != 0) {
1637 : 0 : cc_log("Diagnostic file %s not in cache", cached_dia);
1638 : 0 : return;
1639 : : }
1640 : :
1641 : : /*
1642 : : * Occasionally, e.g. on hard reset, our cache ends up as just filesystem
1643 : : * meta-data with no content. Catch an easy case of this.
1644 : : */
1645 [ # # ]: 0 : if (st.st_size == 0) {
1646 : 0 : cc_log("Invalid (empty) object file %s in cache", cached_obj);
1647 : 0 : x_unlink(cached_obj);
1648 : 0 : return;
1649 : : }
1650 : :
1651 [ # # ][ # # ]: 0 : if (using_split_dwarf && !generating_dependencies) {
1652 [ # # ]: 0 : assert(output_dwo);
1653 : : }
1654 [ # # ]: 0 : if (output_dwo) {
1655 [ # # ]: 0 : assert(cached_dwo);
1656 [ # # ]: 0 : if (stat(cached_dwo, &st) != 0) {
1657 : 0 : cc_log("Split dwarf file %s not in cache", cached_dwo);
1658 : 0 : return;
1659 : : }
1660 [ # # ]: 0 : if (st.st_size == 0) {
1661 : 0 : cc_log("Invalid (empty) dwo file %s in cache", cached_dwo);
1662 : 0 : x_unlink(cached_dwo);
1663 : 0 : x_unlink(cached_obj); /* to really invalidate */
1664 : 0 : return;
1665 : : }
1666 : : }
1667 : :
1668 : : /*
1669 : : * (If mode != FROMCACHE_DIRECT_MODE, the dependency file is created by
1670 : : * gcc.)
1671 : : */
1672 [ # # ][ # # ]: 0 : produce_dep_file = generating_dependencies && mode == FROMCACHE_DIRECT_MODE;
1673 : :
1674 : : /* If the dependency file should be in the cache, check that it is. */
1675 [ # # ][ # # ]: 0 : if (produce_dep_file && stat(cached_dep, &st) != 0) {
1676 : 0 : cc_log("Dependency file %s missing in cache", cached_dep);
1677 : 0 : return;
1678 : : }
1679 : :
1680 : : /*
1681 : : * Copy object file from cache. Do so also for FissionDwarf file, cached_dwo,
1682 : : * when -gsplit-dwarf is specified.
1683 : : */
1684 [ # # ]: 0 : if (!str_eq(output_obj, "/dev/null")) {
1685 : 0 : get_file_from_cache(cached_obj, output_obj);
1686 [ # # ]: 0 : if (using_split_dwarf) {
1687 [ # # ]: 0 : assert(output_dwo);
1688 : 0 : get_file_from_cache(cached_dwo, output_dwo);
1689 : : }
1690 : : }
1691 [ # # ]: 0 : if (produce_dep_file) {
1692 : 0 : get_file_from_cache(cached_dep, output_dep);
1693 : : }
1694 [ # # ][ # # ]: 0 : if (generating_coverage && stat(cached_cov, &st) == 0 && st.st_size > 0) {
[ # # ]
1695 : : /* gcc won't generate notes if there is no code */
1696 : 0 : get_file_from_cache(cached_cov, output_cov);
1697 : : }
1698 [ # # ]: 0 : if (output_dia) {
1699 : 0 : get_file_from_cache(cached_dia, output_dia);
1700 : : }
1701 : :
1702 : : /* Update modification timestamps to save files from LRU cleanup.
1703 : : Also gives files a sensible mtime when hard-linking. */
1704 : 0 : update_mtime(cached_obj);
1705 : 0 : update_mtime(cached_stderr);
1706 [ # # ]: 0 : if (produce_dep_file) {
1707 : 0 : update_mtime(cached_dep);
1708 : : }
1709 [ # # ]: 0 : if (generating_coverage) {
1710 : 0 : update_mtime(cached_cov);
1711 : : }
1712 [ # # ]: 0 : if (output_dia) {
1713 : 0 : update_mtime(cached_dia);
1714 : : }
1715 [ # # ]: 0 : if (cached_dwo) {
1716 : 0 : update_mtime(cached_dwo);
1717 : : }
1718 : :
1719 [ # # ][ # # ]: 0 : if (generating_dependencies && mode == FROMCACHE_CPP_MODE) {
1720 : 0 : put_file_in_cache(output_dep, cached_dep);
1721 : : }
1722 : :
1723 : 0 : send_cached_stderr();
1724 : :
1725 [ # # ]: 0 : if (put_object_in_manifest) {
1726 : 0 : update_manifest_file();
1727 : : }
1728 : :
1729 : : /* log the cache hit */
1730 [ # # # ]: 0 : switch (mode) {
1731 : : case FROMCACHE_DIRECT_MODE:
1732 : 0 : cc_log("Succeeded getting cached result");
1733 : 0 : stats_update(STATS_CACHEHIT_DIR);
1734 : 0 : break;
1735 : :
1736 : : case FROMCACHE_CPP_MODE:
1737 : 0 : cc_log("Succeeded getting cached result");
1738 : 0 : stats_update(STATS_CACHEHIT_CPP);
1739 : : break;
1740 : : }
1741 : :
1742 : : /* and exit with the right status code */
1743 : 0 : x_exit(0);
1744 : : }
1745 : :
1746 : : /* find the real compiler. We just search the PATH to find a executable of the
1747 : : same name that isn't a link to ourselves */
1748 : : static void
1749 : 1 : find_compiler(char **argv)
1750 : : {
1751 : : char *base;
1752 : : char *compiler;
1753 : :
1754 : 1 : base = basename(argv[0]);
1755 : :
1756 : : /* we might be being invoked like "ccache gcc -c foo.c" */
1757 [ + - ]: 1 : if (same_executable_name(base, MYNAME)) {
1758 : 1 : args_remove_first(orig_args);
1759 : 1 : free(base);
1760 [ - + ]: 1 : if (is_full_path(orig_args->argv[0])) {
1761 : : /* a full path was given */
1762 : 0 : return;
1763 : : }
1764 : 1 : base = basename(orig_args->argv[0]);
1765 : : }
1766 : :
1767 : : /* support user override of the compiler */
1768 [ - + ]: 1 : if (!str_eq(conf->compiler, "")) {
1769 : 0 : base = conf->compiler;
1770 : : }
1771 : :
1772 : 1 : compiler = find_executable(base, MYNAME);
1773 : :
1774 : : /* can't find the compiler! */
1775 [ - + ]: 1 : if (!compiler) {
1776 : 0 : stats_update(STATS_COMPILER);
1777 : 0 : fatal("Could not find compiler \"%s\" in PATH", base);
1778 : : }
1779 [ - + ]: 1 : if (str_eq(compiler, argv[0])) {
1780 : 0 : fatal("Recursive invocation (the name of the ccache binary must be \"%s\")",
1781 : : MYNAME);
1782 : : }
1783 : 1 : orig_args->argv[0] = compiler;
1784 : : }
1785 : :
1786 : : bool
1787 : 0 : is_precompiled_header(const char *path)
1788 : : {
1789 [ # # # # : 0 : return str_eq(get_extension(path), ".gch")
# # ]
1790 : 0 : || str_eq(get_extension(path), ".pch")
1791 : 0 : || str_eq(get_extension(path), ".pth");
1792 : : }
1793 : :
1794 : : static bool
1795 : 14 : color_output_possible(void)
1796 : : {
1797 : 14 : const char *term_env = getenv("TERM");
1798 [ - + ][ # # ]: 14 : return isatty(STDERR_FILENO) && term_env && strcasecmp(term_env, "DUMB") != 0;
[ # # ]
1799 : : }
1800 : :
1801 : : /*
1802 : : * Process the compiler options into options suitable for passing to the
1803 : : * preprocessor and the real compiler. The preprocessor options don't include
1804 : : * -E; this is added later. Returns true on success, otherwise false.
1805 : : */
1806 : : bool
1807 : 16 : cc_process_args(struct args *args, struct args **preprocessor_args,
1808 : : struct args **compiler_args)
1809 : : {
1810 : : int i;
1811 : 16 : bool found_c_opt = false;
1812 : 16 : bool found_S_opt = false;
1813 : 16 : bool found_arch_opt = false;
1814 : 16 : bool found_pch = false;
1815 : 16 : bool found_fpch_preprocess = false;
1816 : 16 : const char *explicit_language = NULL; /* As specified with -x. */
1817 : : const char *file_language; /* As deduced from file extension. */
1818 : : const char *actual_language; /* Language to actually use. */
1819 : 16 : const char *input_charset = NULL;
1820 : : struct stat st;
1821 : : /* is the dependency makefile name overridden with -MF? */
1822 : 16 : bool dependency_filename_specified = false;
1823 : : /* is the dependency makefile target name specified with -MT or -MQ? */
1824 : 16 : bool dependency_target_specified = false;
1825 : : struct args *expanded_args, *stripped_args, *dep_args, *cpp_args;
1826 : : int argc;
1827 : : char **argv;
1828 : 16 : bool result = true;
1829 : 16 : bool found_color_diagnostics = false;
1830 : :
1831 : 16 : expanded_args = args_copy(args);
1832 : 16 : stripped_args = args_init(0, NULL);
1833 : 16 : dep_args = args_init(0, NULL);
1834 : 16 : cpp_args = args_init(0, NULL);
1835 : :
1836 : 16 : argc = expanded_args->argc;
1837 : 16 : argv = expanded_args->argv;
1838 : :
1839 : 16 : args_add(stripped_args, argv[0]);
1840 : :
1841 [ + + ]: 128 : for (i = 1; i < argc; i++) {
1842 : : /* The user knows best: just swallow the next arg */
1843 [ - + ]: 114 : if (str_eq(argv[i], "--ccache-skip")) {
1844 : 0 : i++;
1845 [ # # ]: 0 : if (i == argc) {
1846 : 0 : cc_log("--ccache-skip lacks an argument");
1847 : 0 : result = false;
1848 : 0 : goto out;
1849 : : }
1850 : 0 : args_add(stripped_args, argv[i]);
1851 : 0 : continue;
1852 : : }
1853 : :
1854 : : /* Special case for -E. */
1855 [ + + ]: 114 : if (str_eq(argv[i], "-E")) {
1856 : 1 : stats_update(STATS_PREPROCESSING);
1857 : 1 : result = false;
1858 : 1 : goto out;
1859 : : }
1860 : :
1861 : : /* Handle "@file" argument. */
1862 [ + - ][ - + ]: 113 : if (str_startswith(argv[i], "@") || str_startswith(argv[i], "-@")) {
1863 : 0 : char *argpath = argv[i] + 1;
1864 : : struct args *file_args;
1865 : :
1866 [ # # ]: 0 : if (argpath[-1] == '-') {
1867 : 0 : ++argpath;
1868 : : }
1869 : 0 : file_args = args_init_from_gcc_atfile(argpath);
1870 [ # # ]: 0 : if (!file_args) {
1871 : 0 : cc_log("Couldn't read arg file %s", argpath);
1872 : 0 : stats_update(STATS_ARGS);
1873 : 0 : result = false;
1874 : 0 : goto out;
1875 : : }
1876 : :
1877 : 0 : args_insert(expanded_args, i, file_args, true);
1878 : 0 : argc = expanded_args->argc;
1879 : 0 : argv = expanded_args->argv;
1880 : 0 : i--;
1881 : 0 : continue;
1882 : : }
1883 : :
1884 : : /* These are always too hard. */
1885 [ + + ][ - + ]: 113 : if (compopt_too_hard(argv[i])
1886 : 112 : || str_startswith(argv[i], "-fdump-")) {
1887 : 1 : cc_log("Compiler option %s is unsupported", argv[i]);
1888 : 1 : stats_update(STATS_UNSUPPORTED);
1889 : 1 : result = false;
1890 : 1 : goto out;
1891 : : }
1892 : :
1893 : : /* These are too hard in direct mode. */
1894 [ + + ]: 112 : if (conf->direct_mode) {
1895 [ - + ]: 110 : if (compopt_too_hard_for_direct_mode(argv[i])) {
1896 : 0 : cc_log("Unsupported compiler option for direct mode: %s", argv[i]);
1897 : 0 : conf->direct_mode = false;
1898 : : }
1899 : : }
1900 : :
1901 : : /* Multiple -arch options are too hard. */
1902 [ - + ]: 112 : if (str_eq(argv[i], "-arch")) {
1903 [ # # ]: 0 : if (found_arch_opt) {
1904 : 0 : cc_log("More than one -arch compiler option is unsupported");
1905 : 0 : stats_update(STATS_UNSUPPORTED);
1906 : 0 : result = false;
1907 : 0 : goto out;
1908 : : } else {
1909 : 0 : found_arch_opt = true;
1910 : : }
1911 : : }
1912 : :
1913 [ + - ][ + - ]: 112 : if (str_eq(argv[i], "-fpch-preprocess")
[ - + ]
1914 : 112 : || str_eq(argv[i], "-emit-pch")
1915 : 112 : || str_eq(argv[i], "-emit-pth")) {
1916 : 0 : found_fpch_preprocess = true;
1917 : : }
1918 : :
1919 : : /* we must have -c */
1920 [ + + ]: 112 : if (str_eq(argv[i], "-c")) {
1921 : 16 : found_c_opt = true;
1922 : 16 : continue;
1923 : : }
1924 : :
1925 : : /* -S changes the default extension */
1926 [ - + ]: 96 : if (str_eq(argv[i], "-S")) {
1927 : 0 : args_add(stripped_args, argv[i]);
1928 : 0 : found_S_opt = true;
1929 : 0 : continue;
1930 : : }
1931 : :
1932 : : /*
1933 : : * Special handling for -x: remember the last specified language before the
1934 : : * input file and strip all -x options from the arguments.
1935 : : */
1936 [ - + ]: 96 : if (str_eq(argv[i], "-x")) {
1937 [ # # ]: 0 : if (i == argc-1) {
1938 : 0 : cc_log("Missing argument to %s", argv[i]);
1939 : 0 : stats_update(STATS_ARGS);
1940 : 0 : result = false;
1941 : 0 : goto out;
1942 : : }
1943 [ # # ]: 0 : if (!input_file) {
1944 : 0 : explicit_language = argv[i+1];
1945 : : }
1946 : 0 : i++;
1947 : 0 : continue;
1948 : : }
1949 [ - + ]: 96 : if (str_startswith(argv[i], "-x")) {
1950 [ # # ]: 0 : if (!input_file) {
1951 : 0 : explicit_language = &argv[i][2];
1952 : : }
1953 : 0 : continue;
1954 : : }
1955 : :
1956 : : /* we need to work out where the output was meant to go */
1957 [ + + ]: 96 : if (str_eq(argv[i], "-o")) {
1958 [ - + ]: 6 : if (i == argc-1) {
1959 : 0 : cc_log("Missing argument to %s", argv[i]);
1960 : 0 : stats_update(STATS_ARGS);
1961 : 0 : result = false;
1962 : 0 : goto out;
1963 : : }
1964 : 6 : output_obj = make_relative_path(x_strdup(argv[i+1]));
1965 : 6 : i++;
1966 : 6 : continue;
1967 : : }
1968 : :
1969 : : /* alternate form of -o, with no space */
1970 [ - + ]: 90 : if (str_startswith(argv[i], "-o")) {
1971 : 0 : output_obj = make_relative_path(x_strdup(&argv[i][2]));
1972 : 0 : continue;
1973 : : }
1974 : :
1975 [ - + ]: 90 : if (str_eq(argv[i], "-gsplit-dwarf")) {
1976 : 0 : cc_log("Enabling caching of dwarf files since -gsplit-dwarf is used");
1977 : 0 : using_split_dwarf = true;
1978 : 0 : args_add(stripped_args, argv[i]);
1979 : 0 : continue;
1980 : : }
1981 : :
1982 : : /* debugging is handled specially, so that we know if we
1983 : : can strip line number info
1984 : : */
1985 [ - + ]: 90 : if (str_startswith(argv[i], "-g")) {
1986 : 0 : args_add(stripped_args, argv[i]);
1987 [ # # ][ # # ]: 0 : if (conf->unify && !str_eq(argv[i], "-g0")) {
1988 : 0 : cc_log("%s used; disabling unify mode", argv[i]);
1989 : 0 : conf->unify = false;
1990 : : }
1991 [ # # ]: 0 : if (str_eq(argv[i], "-g3")) {
1992 : : /*
1993 : : * Fix for bug 7190 ("commandline macros (-D)
1994 : : * have non-zero lineno when using -g3").
1995 : : */
1996 : 0 : cc_log("%s used; not compiling preprocessed code", argv[i]);
1997 : 0 : conf->run_second_cpp = true;
1998 : : }
1999 : 0 : continue;
2000 : : }
2001 : :
2002 : : /* These options require special handling, because they
2003 : : behave differently with gcc -E, when the output
2004 : : file is not specified. */
2005 [ + + ][ + + ]: 90 : if (str_eq(argv[i], "-MD") || str_eq(argv[i], "-MMD")) {
2006 : 12 : generating_dependencies = true;
2007 : 12 : args_add(dep_args, argv[i]);
2008 : 12 : continue;
2009 : : }
2010 [ + + ]: 78 : if (str_startswith(argv[i], "-MF")) {
2011 : : char *arg;
2012 : 10 : bool separate_argument = (strlen(argv[i]) == 3);
2013 : 10 : dependency_filename_specified = true;
2014 : 10 : free(output_dep);
2015 [ + + ]: 10 : if (separate_argument) {
2016 : : /* -MF arg */
2017 [ - + ]: 2 : if (i >= argc - 1) {
2018 : 0 : cc_log("Missing argument to %s", argv[i]);
2019 : 0 : stats_update(STATS_ARGS);
2020 : 0 : result = false;
2021 : 0 : goto out;
2022 : : }
2023 : 2 : arg = argv[i + 1];
2024 : 2 : i++;
2025 : : } else {
2026 : : /* -MFarg */
2027 : 8 : arg = &argv[i][3];
2028 : : }
2029 : 10 : output_dep = make_relative_path(x_strdup(arg));
2030 : : /* Keep the format of the args the same */
2031 [ + + ]: 10 : if (separate_argument) {
2032 : 2 : args_add(dep_args, "-MF");
2033 : 2 : args_add(dep_args, output_dep);
2034 : : } else {
2035 : 8 : char *option = format("-MF%s", output_dep);
2036 : 8 : args_add(dep_args, option);
2037 : 8 : free(option);
2038 : : }
2039 : 10 : continue;
2040 : : }
2041 [ + + ][ + + ]: 68 : if (str_startswith(argv[i], "-MQ") || str_startswith(argv[i], "-MT")) {
2042 : : char *relpath;
2043 : 20 : dependency_target_specified = true;
2044 [ + + ]: 20 : if (strlen(argv[i]) == 3) {
2045 : : /* -MQ arg or -MT arg */
2046 [ - + ]: 14 : if (i >= argc - 1) {
2047 : 0 : cc_log("Missing argument to %s", argv[i]);
2048 : 0 : stats_update(STATS_ARGS);
2049 : 0 : result = false;
2050 : 0 : goto out;
2051 : : }
2052 : 14 : args_add(dep_args, argv[i]);
2053 : 14 : relpath = make_relative_path(x_strdup(argv[i + 1]));
2054 : 14 : args_add(dep_args, relpath);
2055 : 14 : free(relpath);
2056 : 14 : i++;
2057 : : } else {
2058 : : char *arg_opt;
2059 : : char *option;
2060 : 6 : arg_opt = x_strndup(argv[i], 3);
2061 : 6 : relpath = make_relative_path(x_strdup(argv[i] + 3));
2062 : 6 : option = format("%s%s", arg_opt, relpath);
2063 : 6 : args_add(dep_args, option);
2064 : 6 : free(arg_opt);
2065 : 6 : free(relpath);
2066 : 6 : free(option);
2067 : : }
2068 : 20 : continue;
2069 : : }
2070 [ - + ]: 48 : if (str_eq(argv[i], "-fprofile-arcs")) {
2071 : 0 : profile_arcs = true;
2072 : 0 : args_add(stripped_args, argv[i]);
2073 : 0 : continue;
2074 : : }
2075 [ - + ]: 48 : if (str_eq(argv[i], "-ftest-coverage")) {
2076 : 0 : generating_coverage = true;
2077 : 0 : args_add(stripped_args, argv[i]);
2078 : 0 : continue;
2079 : : }
2080 [ - + ]: 48 : if (str_eq(argv[i], "--coverage")) { /* = -fprofile-arcs -ftest-coverage */
2081 : 0 : profile_arcs = true;
2082 : 0 : generating_coverage = true;
2083 : 0 : args_add(stripped_args, argv[i]);
2084 : 0 : continue;
2085 : : }
2086 [ - + ]: 48 : if (str_startswith(argv[i], "-fprofile-dir=")) {
2087 : 0 : profile_dir = x_strdup(argv[i] + 14);
2088 : 0 : args_add(stripped_args, argv[i]);
2089 : 0 : continue;
2090 : : }
2091 [ + + ]: 48 : if (str_startswith(argv[i], "--sysroot=")) {
2092 : 1 : char *relpath = make_relative_path(x_strdup(argv[i] + 10));
2093 : 1 : char *option = format("--sysroot=%s", relpath);
2094 : 1 : args_add(stripped_args, option);
2095 : 1 : free(relpath);
2096 : 1 : free(option);
2097 : 1 : continue;
2098 : : }
2099 [ + + ]: 47 : if (str_startswith(argv[i], "-Wp,")) {
2100 [ + - ][ - + ]: 4 : if (str_eq(argv[i], "-Wp,-P") || strstr(argv[i], ",-P,")) {
2101 : : /* -P removes preprocessor information in such a way that the object
2102 : : * file from compiling the preprocessed file will not be equal to the
2103 : : * object file produced when compiling without ccache. */
2104 : 0 : cc_log("Too hard option -Wp,-P detected");
2105 : 0 : stats_update(STATS_UNSUPPORTED);
2106 : 0 : failed();
2107 [ + + ][ + - ]: 4 : } else if (str_startswith(argv[i], "-Wp,-MD,")
2108 : 2 : && !strchr(argv[i] + 8, ',')) {
2109 : 2 : generating_dependencies = true;
2110 : 2 : dependency_filename_specified = true;
2111 : 2 : free(output_dep);
2112 : 2 : output_dep = make_relative_path(x_strdup(argv[i] + 8));
2113 : 2 : args_add(dep_args, argv[i]);
2114 : 2 : continue;
2115 [ + - ][ + - ]: 2 : } else if (str_startswith(argv[i], "-Wp,-MMD,")
2116 : 2 : && !strchr(argv[i] + 9, ',')) {
2117 : 2 : generating_dependencies = true;
2118 : 2 : dependency_filename_specified = true;
2119 : 2 : free(output_dep);
2120 : 2 : output_dep = make_relative_path(x_strdup(argv[i] + 9));
2121 : 2 : args_add(dep_args, argv[i]);
2122 : 2 : continue;
2123 [ # # ]: 0 : } else if (conf->direct_mode) {
2124 : : /*
2125 : : * -Wp, can be used to pass too hard options to
2126 : : * the preprocessor. Hence, disable direct
2127 : : * mode.
2128 : : */
2129 : 0 : cc_log("Unsupported compiler option for direct mode: %s", argv[i]);
2130 : 0 : conf->direct_mode = false;
2131 : : }
2132 : : }
2133 [ + + ]: 43 : if (str_eq(argv[i], "-MP")) {
2134 : 6 : args_add(dep_args, argv[i]);
2135 : 6 : continue;
2136 : : }
2137 : :
2138 : : /* Input charset needs to be handled specially. */
2139 [ - + ]: 37 : if (str_startswith(argv[i], "-finput-charset=")) {
2140 : 0 : input_charset = argv[i];
2141 : 0 : continue;
2142 : : }
2143 : :
2144 [ - + ]: 37 : if (str_eq(argv[i], "--serialize-diagnostics")) {
2145 [ # # ]: 0 : if (i >= argc - 1) {
2146 : 0 : cc_log("Missing argument to %s", argv[i]);
2147 : 0 : stats_update(STATS_ARGS);
2148 : 0 : result = false;
2149 : 0 : goto out;
2150 : : }
2151 : 0 : output_dia = make_relative_path(x_strdup(argv[i+1]));
2152 : 0 : i++;
2153 : 0 : continue;
2154 : : }
2155 : :
2156 [ + + ]: 37 : if (str_startswith(argv[i], "-fprofile-")) {
2157 : 2 : const char *arg_profile_dir = strchr(argv[i], '=');
2158 : 2 : char *arg = x_strdup(argv[i]);
2159 : 2 : bool supported_profile_option = false;
2160 : :
2161 [ + - ]: 2 : if (arg_profile_dir) {
2162 : 2 : char *option = x_strndup(argv[i], arg_profile_dir - argv[i]);
2163 : : char *dir;
2164 : :
2165 : : /* Convert to absolute path. */
2166 : 2 : dir = x_realpath(arg_profile_dir + 1);
2167 [ + + ]: 2 : if (!dir) {
2168 : : /* Directory doesn't exist. */
2169 : 1 : dir = x_strdup(arg_profile_dir + 1);
2170 : : }
2171 : :
2172 : : /* We can get a better hit rate by using the real path here. */
2173 : 2 : free(arg);
2174 : 2 : arg = format("%s=%s", option, dir);
2175 : 2 : cc_log("Rewriting %s to %s", argv[i], arg);
2176 : 2 : free(option);
2177 : 2 : free(dir);
2178 : : }
2179 : :
2180 [ - + ][ # # ]: 2 : if (str_startswith(argv[i], "-fprofile-generate")
2181 : 0 : || str_eq(argv[i], "-fprofile-arcs")) {
2182 : 2 : profile_generate = true;
2183 : 2 : supported_profile_option = true;
2184 [ # # ][ # # ]: 0 : } else if (str_startswith(argv[i], "-fprofile-use")
2185 : 0 : || str_eq(argv[i], "-fbranch-probabilities")) {
2186 : 0 : profile_use = true;
2187 : 0 : supported_profile_option = true;
2188 [ # # ]: 0 : } else if (str_eq(argv[i], "-fprofile-dir")) {
2189 : 0 : supported_profile_option = true;
2190 : : }
2191 : :
2192 [ + - ]: 2 : if (supported_profile_option) {
2193 : 2 : args_add(stripped_args, arg);
2194 : 2 : free(arg);
2195 : :
2196 : : /*
2197 : : * If the profile directory has already been set, give up... Hard to
2198 : : * know what the user means, and what the compiler will do.
2199 : : */
2200 [ + - ][ - + ]: 2 : if (arg_profile_dir && profile_dir) {
2201 : 0 : cc_log("Profile directory already set; giving up");
2202 : 0 : result = false;
2203 : 0 : goto out;
2204 [ + - ]: 2 : } else if (arg_profile_dir) {
2205 : 2 : cc_log("Setting profile directory to %s", profile_dir);
2206 : 2 : profile_dir = x_strdup(arg_profile_dir);
2207 : : }
2208 : 2 : continue;
2209 : : }
2210 : 0 : cc_log("Unknown profile option: %s", argv[i]);
2211 : 0 : free(arg);
2212 : : }
2213 : :
2214 [ + - ][ + - ]: 35 : if (str_eq(argv[i], "-fcolor-diagnostics")
[ + - ][ + - ]
[ + - ][ - + ]
2215 : 35 : || str_eq(argv[i], "-fno-color-diagnostics")
2216 : 35 : || str_eq(argv[i], "-fdiagnostics-color")
2217 : 35 : || str_eq(argv[i], "-fdiagnostics-color=always")
2218 : 35 : || str_eq(argv[i], "-fno-diagnostics-color")
2219 : 35 : || str_eq(argv[i], "-fdiagnostics-color=never")) {
2220 : 0 : args_add(stripped_args, argv[i]);
2221 : 0 : found_color_diagnostics = true;
2222 : 0 : continue;
2223 : : }
2224 [ - + ]: 35 : if (str_eq(argv[i], "-fdiagnostics-color=auto")) {
2225 [ # # ]: 0 : if (color_output_possible()) {
2226 : : /* Output is redirected, so color output must be forced. */
2227 : 0 : args_add(stripped_args, "-fdiagnostics-color=always");
2228 : 0 : cc_log("Automatically forcing colors");
2229 : : } else {
2230 : 0 : args_add(stripped_args, argv[i]);
2231 : : }
2232 : 0 : found_color_diagnostics = true;
2233 : 0 : continue;
2234 : : }
2235 : :
2236 : : /*
2237 : : * Options taking an argument that we may want to rewrite to relative paths
2238 : : * to get better hit rate. A secondary effect is that paths in the standard
2239 : : * error output produced by the compiler will be normalized.
2240 : : */
2241 [ + + ]: 35 : if (compopt_takes_path(argv[i])) {
2242 : : char *relpath;
2243 : 11 : char *pch_file = NULL;
2244 [ - + ]: 11 : if (i == argc-1) {
2245 : 0 : cc_log("Missing argument to %s", argv[i]);
2246 : 0 : stats_update(STATS_ARGS);
2247 : 0 : result = false;
2248 : 0 : goto out;
2249 : : }
2250 : :
2251 : 11 : relpath = make_relative_path(x_strdup(argv[i+1]));
2252 [ + - ]: 11 : if (compopt_affects_cpp(argv[i])) {
2253 : 11 : args_add(cpp_args, argv[i]);
2254 : 11 : args_add(cpp_args, relpath);
2255 : : } else {
2256 : 0 : args_add(stripped_args, argv[i]);
2257 : 0 : args_add(stripped_args, relpath);
2258 : : }
2259 : :
2260 : : /* Try to be smart about detecting precompiled headers */
2261 [ + + ][ - + ]: 12 : if (str_eq(argv[i], "-include-pch")
2262 : 10 : || str_eq(argv[i], "-include-pth")) {
2263 [ - + ]: 1 : if (stat(argv[i+1], &st) == 0) {
2264 : 0 : cc_log("Detected use of precompiled header: %s", argv[i+1]);
2265 : 0 : found_pch = true;
2266 : 0 : pch_file = x_strdup(argv[i+1]);
2267 : : }
2268 : : } else {
2269 : 10 : char *gchpath = format("%s.gch", argv[i+1]);
2270 [ - + ]: 10 : if (stat(gchpath, &st) == 0) {
2271 : 0 : cc_log("Detected use of precompiled header: %s", gchpath);
2272 : 0 : found_pch = true;
2273 : 0 : pch_file = x_strdup(gchpath);
2274 : : } else {
2275 : 10 : char *pchpath = format("%s.pch", argv[i+1]);
2276 [ - + ]: 10 : if (stat(pchpath, &st) == 0) {
2277 : 0 : cc_log("Detected use of precompiled header: %s", pchpath);
2278 : 0 : found_pch = true;
2279 : 0 : pch_file = x_strdup(pchpath);
2280 : : } else {
2281 : : /* clang may use pretokenized headers */
2282 : 10 : char *pthpath = format("%s.pth", argv[i+1]);
2283 [ - + ]: 10 : if (stat(pthpath, &st) == 0) {
2284 : 0 : cc_log("Detected use of pretokenized header: %s", pthpath);
2285 : 0 : found_pch = true;
2286 : 0 : pch_file = x_strdup(pthpath);
2287 : : }
2288 : 10 : free(pthpath);
2289 : : }
2290 : 10 : free(pchpath);
2291 : : }
2292 : 10 : free(gchpath);
2293 : : }
2294 : :
2295 [ - + ]: 11 : if (pch_file) {
2296 [ # # ]: 0 : if (included_pch_file) {
2297 : 0 : cc_log("Multiple precompiled headers used: %s and %s\n",
2298 : : included_pch_file, pch_file);
2299 : 0 : stats_update(STATS_ARGS);
2300 : 0 : result = false;
2301 : 0 : goto out;
2302 : : }
2303 : 0 : included_pch_file = pch_file;
2304 : : }
2305 : :
2306 : 11 : free(relpath);
2307 : 11 : i++;
2308 : 11 : continue;
2309 : : }
2310 : :
2311 : : /* Same as above but options with concatenated argument. */
2312 [ + + ]: 24 : if (compopt_short(compopt_takes_path, argv[i])) {
2313 : : char *relpath;
2314 : : char *option;
2315 : 2 : relpath = make_relative_path(x_strdup(argv[i] + 2));
2316 : 2 : option = format("-%c%s", argv[i][1], relpath);
2317 : :
2318 [ + - ]: 2 : if (compopt_short(compopt_affects_cpp, argv[i])) {
2319 : 2 : args_add(cpp_args, option);
2320 : : } else {
2321 : 0 : args_add(stripped_args, option);
2322 : : }
2323 : :
2324 : 2 : free(relpath);
2325 : 2 : free(option);
2326 : 2 : continue;
2327 : : }
2328 : :
2329 : : /* options that take an argument */
2330 [ - + ]: 22 : if (compopt_takes_arg(argv[i])) {
2331 [ # # ]: 0 : if (i == argc-1) {
2332 : 0 : cc_log("Missing argument to %s", argv[i]);
2333 : 0 : stats_update(STATS_ARGS);
2334 : 0 : result = false;
2335 : 0 : goto out;
2336 : : }
2337 : :
2338 [ # # ]: 0 : if (compopt_affects_cpp(argv[i])) {
2339 : 0 : args_add(cpp_args, argv[i]);
2340 : 0 : args_add(cpp_args, argv[i+1]);
2341 : : } else {
2342 : 0 : args_add(stripped_args, argv[i]);
2343 : 0 : args_add(stripped_args, argv[i+1]);
2344 : : }
2345 : :
2346 : 0 : i++;
2347 : 0 : continue;
2348 : : }
2349 : :
2350 : : /* other options */
2351 [ + + ]: 22 : if (argv[i][0] == '-') {
2352 [ + + ][ + - ]: 12 : if (compopt_affects_cpp(argv[i])
2353 : 3 : || compopt_prefix_affects_cpp(argv[i])) {
2354 : 6 : args_add(cpp_args, argv[i]);
2355 : : } else {
2356 : 0 : args_add(stripped_args, argv[i]);
2357 : : }
2358 : 6 : continue;
2359 : : }
2360 : :
2361 : : /* if an argument isn't a plain file then assume its
2362 : : an option, not an input file. This allows us to
2363 : : cope better with unusual compiler options */
2364 [ + - ][ - + ]: 16 : if (stat(argv[i], &st) != 0 || !S_ISREG(st.st_mode)) {
2365 : 0 : cc_log("%s is not a regular file, not considering as input file",
2366 : 0 : argv[i]);
2367 : 0 : args_add(stripped_args, argv[i]);
2368 : 0 : continue;
2369 : : }
2370 : :
2371 [ - + ]: 16 : if (input_file) {
2372 [ # # ]: 0 : if (language_for_file(argv[i])) {
2373 : 0 : cc_log("Multiple input files: %s and %s", input_file, argv[i]);
2374 : 0 : stats_update(STATS_MULTIPLE);
2375 [ # # ]: 0 : } else if (!found_c_opt) {
2376 : 0 : cc_log("Called for link with %s", argv[i]);
2377 [ # # ]: 0 : if (strstr(argv[i], "conftest.")) {
2378 : 0 : stats_update(STATS_CONFTEST);
2379 : : } else {
2380 : 0 : stats_update(STATS_LINK);
2381 : : }
2382 : : } else {
2383 : 0 : cc_log("Unsupported source extension: %s", argv[i]);
2384 : 0 : stats_update(STATS_SOURCELANG);
2385 : : }
2386 : 0 : result = false;
2387 : 0 : goto out;
2388 : : }
2389 : :
2390 : : /* The source code file path gets put into the notes */
2391 [ - + ]: 16 : if (generating_coverage) {
2392 : 0 : input_file = x_strdup(argv[i]);
2393 : 0 : continue;
2394 : : }
2395 : :
2396 : : /* Rewrite to relative to increase hit rate. */
2397 : 16 : input_file = make_relative_path(x_strdup(argv[i]));
2398 : : } /* for */
2399 : :
2400 [ - + ]: 14 : if (found_S_opt) {
2401 : : /* Even if -gsplit-dwarf is given, the .dwo file is not generated when -S
2402 : : * is also given.
2403 : : */
2404 : 0 : using_split_dwarf = false;
2405 : 0 : cc_log("Disabling caching of dwarf files since -S is used");
2406 : : }
2407 : :
2408 [ - + ]: 14 : if (!input_file) {
2409 : 0 : cc_log("No input file found");
2410 : 0 : stats_update(STATS_NOINPUT);
2411 : 0 : result = false;
2412 : 0 : goto out;
2413 : : }
2414 : :
2415 [ + - ][ - + ]: 14 : if (found_pch || found_fpch_preprocess) {
2416 : 0 : using_precompiled_header = true;
2417 [ # # ]: 0 : if (!(conf->sloppiness & SLOPPY_TIME_MACROS)) {
2418 : 0 : cc_log("You have to specify \"time_macros\" sloppiness when using"
2419 : : " precompiled headers to get direct hits");
2420 : 0 : cc_log("Disabling direct mode");
2421 : 0 : stats_update(STATS_CANTUSEPCH);
2422 : 0 : result = false;
2423 : 0 : goto out;
2424 : : }
2425 : : }
2426 : :
2427 [ - + ][ # # ]: 14 : if (explicit_language && str_eq(explicit_language, "none")) {
2428 : 0 : explicit_language = NULL;
2429 : : }
2430 : 14 : file_language = language_for_file(input_file);
2431 [ - + ]: 14 : if (explicit_language) {
2432 [ # # ]: 0 : if (!language_is_supported(explicit_language)) {
2433 : 0 : cc_log("Unsupported language: %s", explicit_language);
2434 : 0 : stats_update(STATS_SOURCELANG);
2435 : 0 : result = false;
2436 : 0 : goto out;
2437 : : }
2438 : 0 : actual_language = explicit_language;
2439 : : } else {
2440 : 14 : actual_language = file_language;
2441 : : }
2442 : :
2443 : 14 : output_is_precompiled_header =
2444 [ + - ][ - + ]: 14 : actual_language && strstr(actual_language, "-header");
2445 : :
2446 [ - + ][ # # ]: 14 : if (output_is_precompiled_header
2447 : 0 : && !(conf->sloppiness & SLOPPY_PCH_DEFINES)) {
2448 : 0 : cc_log("You have to specify \"pch_defines,time_macros\" sloppiness when"
2449 : : " creating precompiled headers");
2450 : 0 : stats_update(STATS_CANTUSEPCH);
2451 : 0 : result = false;
2452 : 0 : goto out;
2453 : : }
2454 : :
2455 [ - + ]: 14 : if (!found_c_opt) {
2456 [ # # ]: 0 : if (output_is_precompiled_header) {
2457 : 0 : args_add(stripped_args, "-c");
2458 : : } else {
2459 : 0 : cc_log("No -c option found");
2460 : : /* I find that having a separate statistic for autoconf tests is useful,
2461 : : as they are the dominant form of "called for link" in many cases */
2462 [ # # ]: 0 : if (strstr(input_file, "conftest.")) {
2463 : 0 : stats_update(STATS_CONFTEST);
2464 : : } else {
2465 : 0 : stats_update(STATS_LINK);
2466 : : }
2467 : 0 : result = false;
2468 : 0 : goto out;
2469 : : }
2470 : : }
2471 : :
2472 [ - + ]: 14 : if (!actual_language) {
2473 : 0 : cc_log("Unsupported source extension: %s", input_file);
2474 : 0 : stats_update(STATS_SOURCELANG);
2475 : 0 : result = false;
2476 : 0 : goto out;
2477 : : }
2478 : :
2479 : 14 : direct_i_file = language_is_preprocessed(actual_language);
2480 : :
2481 [ - + ]: 14 : if (output_is_precompiled_header) {
2482 : : /* It doesn't work to create the .gch from preprocessed source. */
2483 : 0 : cc_log("Creating precompiled header; not compiling preprocessed code");
2484 : 0 : conf->run_second_cpp = true;
2485 : : }
2486 : :
2487 [ + - ]: 14 : if (str_eq(conf->cpp_extension, "")) {
2488 : 14 : const char *p_language = p_language_for_language(actual_language);
2489 : 14 : free(conf->cpp_extension);
2490 : 14 : conf->cpp_extension = x_strdup(extension_for_language(p_language) + 1);
2491 : : }
2492 : :
2493 : : /* don't try to second guess the compilers heuristics for stdout handling */
2494 [ + + ][ - + ]: 14 : if (output_obj && str_eq(output_obj, "-")) {
2495 : 0 : stats_update(STATS_OUTSTDOUT);
2496 : 0 : cc_log("Output file is -");
2497 : 0 : result = false;
2498 : 0 : goto out;
2499 : : }
2500 : :
2501 [ + + ]: 14 : if (!output_obj) {
2502 [ - + ]: 8 : if (output_is_precompiled_header) {
2503 : 0 : output_obj = format("%s.gch", input_file);
2504 : : } else {
2505 : : char *p;
2506 : 8 : output_obj = basename(input_file);
2507 : 8 : p = strrchr(output_obj, '.');
2508 [ + - ][ - + ]: 8 : if (!p || !p[1]) {
2509 : 0 : cc_log("Badly formed object filename");
2510 : 0 : stats_update(STATS_ARGS);
2511 : 0 : result = false;
2512 : 0 : goto out;
2513 : : }
2514 [ - + ]: 8 : p[1] = found_S_opt ? 's' : 'o';
2515 : 8 : p[2] = 0;
2516 : : }
2517 : : }
2518 : :
2519 [ - + ]: 14 : if (using_split_dwarf) {
2520 : : char *p;
2521 : 0 : p = strrchr(output_obj, '.');
2522 [ # # ][ # # ]: 0 : if (!p || !p[1]) {
2523 : 0 : cc_log("Badly formed object filename");
2524 : 0 : stats_update(STATS_ARGS);
2525 : 0 : result = false;
2526 : 0 : goto out;
2527 : : }
2528 : : {
2529 : 0 : char *base_name = remove_extension(output_obj);
2530 : 0 : output_dwo = format("%s.dwo", base_name);
2531 : 0 : free(base_name);
2532 : : }
2533 : : }
2534 : :
2535 : : /* cope with -o /dev/null */
2536 [ + - - + ]: 28 : if (!str_eq(output_obj,"/dev/null")
[ # # ]
2537 : : && stat(output_obj, &st) == 0
2538 : 14 : && !S_ISREG(st.st_mode)) {
2539 : 0 : cc_log("Not a regular file: %s", output_obj);
2540 : 0 : stats_update(STATS_DEVICE);
2541 : 0 : result = false;
2542 : 0 : goto out;
2543 : : }
2544 : :
2545 : : /*
2546 : : * Some options shouldn't be passed to the real compiler when it compiles
2547 : : * preprocessed code:
2548 : : *
2549 : : * -finput-charset=XXX (otherwise conversion happens twice)
2550 : : * -x XXX (otherwise the wrong language is selected)
2551 : : */
2552 [ - + ]: 14 : if (input_charset) {
2553 : 0 : args_add(cpp_args, input_charset);
2554 : : }
2555 [ - + ]: 14 : if (found_pch) {
2556 : 0 : args_add(cpp_args, "-fpch-preprocess");
2557 : : }
2558 [ - + ]: 14 : if (explicit_language) {
2559 : 0 : args_add(cpp_args, "-x");
2560 : 0 : args_add(cpp_args, explicit_language);
2561 : : }
2562 : :
2563 : : /*
2564 : : * Since output is redirected, compilers will not color their output by
2565 : : * default, so force it explicitly if it would be otherwise done.
2566 : : */
2567 [ + - ][ - + ]: 14 : if (!found_color_diagnostics && color_output_possible()) {
2568 [ # # ]: 0 : if (compiler_is_clang(args)) {
2569 : 0 : args_add(stripped_args, "-fcolor-diagnostics");
2570 : 0 : cc_log("Automatically enabling colors");
2571 [ # # ]: 0 : } else if (compiler_is_gcc(args)) {
2572 : : /*
2573 : : * GCC has it since 4.9, but that'd require detecting what GCC version is
2574 : : * used for the actual compile. However it requires also GCC_COLORS to be
2575 : : * set (and not empty), so use that for detecting if GCC would use
2576 : : * colors.
2577 : : */
2578 [ # # ][ # # ]: 0 : if (getenv("GCC_COLORS") && getenv("GCC_COLORS")[0] != '\0') {
2579 : 0 : args_add(stripped_args, "-fdiagnostics-color");
2580 : 0 : cc_log("Automatically enabling colors");
2581 : : }
2582 : : }
2583 : : }
2584 : :
2585 : : /*
2586 : : * Add flags for dependency generation only to the preprocessor command line.
2587 : : */
2588 [ + + ]: 14 : if (generating_dependencies) {
2589 [ - + ]: 10 : if (!dependency_filename_specified) {
2590 : : char *default_depfile_name;
2591 : : char *base_name;
2592 : :
2593 : 0 : base_name = remove_extension(output_obj);
2594 : 0 : default_depfile_name = format("%s.d", base_name);
2595 : 0 : free(base_name);
2596 : 0 : args_add(dep_args, "-MF");
2597 : 0 : args_add(dep_args, default_depfile_name);
2598 : 0 : output_dep = make_relative_path(x_strdup(default_depfile_name));
2599 : : }
2600 : :
2601 [ - + ]: 10 : if (!dependency_target_specified) {
2602 : 0 : args_add(dep_args, "-MQ");
2603 : 0 : args_add(dep_args, output_obj);
2604 : : }
2605 : : }
2606 [ - + ]: 14 : if (generating_coverage) {
2607 : : char *default_covfile_name;
2608 : : char *base_name;
2609 : :
2610 : 0 : base_name = remove_extension(output_obj);
2611 : 0 : default_covfile_name = format("%s.gcno", base_name);
2612 : 0 : free(base_name);
2613 : 0 : output_cov = make_relative_path(x_strdup(default_covfile_name));
2614 : : }
2615 : :
2616 : 14 : *compiler_args = args_copy(stripped_args);
2617 [ - + ]: 14 : if (conf->run_second_cpp) {
2618 : 0 : args_extend(*compiler_args, cpp_args);
2619 : : } else {
2620 [ - + ]: 14 : if (explicit_language) {
2621 : : /*
2622 : : * Workaround for a bug in Apple's patched distcc -- it doesn't properly
2623 : : * reset the language specified with -x, so if -x is given, we have to
2624 : : * specify the preprocessed language explicitly.
2625 : : */
2626 : 0 : args_add(*compiler_args, "-x");
2627 : 0 : args_add(*compiler_args, p_language_for_language(explicit_language));
2628 : : }
2629 : : }
2630 : :
2631 [ + - ]: 14 : if (found_c_opt) {
2632 : 14 : args_add(*compiler_args, "-c");
2633 : : }
2634 : :
2635 : : /*
2636 : : * Only pass dependency arguments to the preprocesor since Intel's C++
2637 : : * compiler doesn't produce a correct .d file when compiling preprocessed
2638 : : * source.
2639 : : */
2640 : 14 : args_extend(cpp_args, dep_args);
2641 : :
2642 : 14 : *preprocessor_args = args_copy(stripped_args);
2643 : 14 : args_extend(*preprocessor_args, cpp_args);
2644 : :
2645 : : out:
2646 : 16 : args_free(expanded_args);
2647 : 16 : args_free(stripped_args);
2648 : 16 : args_free(dep_args);
2649 : 16 : args_free(cpp_args);
2650 : 16 : return result;
2651 : : }
2652 : :
2653 : : static void
2654 : 0 : create_initial_config_file(struct conf *conf, const char *path)
2655 : : {
2656 : : unsigned max_files;
2657 : : uint64_t max_size;
2658 : : char *stats_dir;
2659 : : FILE *f;
2660 : : struct stat st;
2661 : :
2662 [ # # ]: 0 : if (create_parent_dirs(path) != 0) {
2663 : 0 : return;
2664 : : }
2665 : :
2666 : 0 : stats_dir = format("%s/0", conf->cache_dir);
2667 [ # # ]: 0 : if (stat(stats_dir, &st) == 0) {
2668 : 0 : stats_get_obsolete_limits(stats_dir, &max_files, &max_size);
2669 : : /* STATS_MAXFILES and STATS_MAXSIZE was stored for each top directory. */
2670 : 0 : max_files *= 16;
2671 : 0 : max_size *= 16;
2672 : : } else {
2673 : 0 : max_files = 0;
2674 : 0 : max_size = conf->max_size;
2675 : : }
2676 : 0 : free(stats_dir);
2677 : :
2678 : 0 : f = fopen(path, "w");
2679 [ # # ]: 0 : if (!f) {
2680 : 0 : return;
2681 : : }
2682 [ # # ]: 0 : if (max_files != 0) {
2683 : 0 : fprintf(f, "max_files = %u\n", max_files);
2684 : 0 : conf->max_files = max_files;
2685 : : }
2686 [ # # ]: 0 : if (max_size != 0) {
2687 : 0 : char *size = format_parsable_size_with_suffix(max_size);
2688 : 0 : fprintf(f, "max_size = %s\n", size);
2689 : 0 : free(size);
2690 : 0 : conf->max_size = max_size;
2691 : : }
2692 : 0 : fclose(f);
2693 : : }
2694 : :
2695 : : /*
2696 : : * Read config file(s), populate variables, create configuration file in cache
2697 : : * directory if missing, etc.
2698 : : */
2699 : : static void
2700 : 7 : initialize(void)
2701 : : {
2702 : : char *errmsg;
2703 : : char *p;
2704 : : struct stat st;
2705 : 7 : bool should_create_initial_config = false;
2706 : :
2707 : 7 : conf_free(conf);
2708 : 7 : conf = conf_create();
2709 : :
2710 : 7 : p = getenv("CCACHE_CONFIGPATH");
2711 [ + - ]: 7 : if (p) {
2712 : 7 : primary_config_path = x_strdup(p);
2713 : : } else {
2714 : 0 : secondary_config_path = format("%s/ccache.conf", TO_STRING(SYSCONFDIR));
2715 [ # # ]: 0 : if (!conf_read(conf, secondary_config_path, &errmsg)) {
2716 [ # # ]: 0 : if (stat(secondary_config_path, &st) == 0) {
2717 : 0 : fatal("%s", errmsg);
2718 : : }
2719 : : /* Missing config file in SYSCONFDIR is OK. */
2720 : 0 : free(errmsg);
2721 : : }
2722 : :
2723 [ # # ]: 0 : if (str_eq(conf->cache_dir, "")) {
2724 : 0 : fatal("configuration setting \"cache_dir\" must not be the empty string");
2725 : : }
2726 [ # # ]: 0 : if ((p = getenv("CCACHE_DIR"))) {
2727 : 0 : free(conf->cache_dir);
2728 : 0 : conf->cache_dir = strdup(p);
2729 : : }
2730 [ # # ]: 0 : if (str_eq(conf->cache_dir, "")) {
2731 : 0 : fatal("CCACHE_DIR must not be the empty string");
2732 : : }
2733 : :
2734 : 0 : primary_config_path = format("%s/ccache.conf", conf->cache_dir);
2735 : : }
2736 : :
2737 [ - + ]: 7 : if (!conf_read(conf, primary_config_path, &errmsg)) {
2738 [ # # ]: 0 : if (stat(primary_config_path, &st) == 0) {
2739 : 0 : fatal("%s", errmsg);
2740 : : }
2741 : 0 : should_create_initial_config = true;
2742 : : }
2743 : :
2744 [ - + ]: 7 : if (!conf_update_from_environment(conf, &errmsg)) {
2745 : 0 : fatal("%s", errmsg);
2746 : : }
2747 : :
2748 [ - + ]: 7 : if (conf->disable) {
2749 : 0 : should_create_initial_config = false;
2750 : : }
2751 : :
2752 [ - + ]: 7 : if (should_create_initial_config) {
2753 : 0 : create_initial_config_file(conf, primary_config_path);
2754 : : }
2755 : :
2756 : 7 : exitfn_init();
2757 : 7 : exitfn_add_nullary(stats_flush);
2758 : 7 : exitfn_add_nullary(clean_up_pending_tmp_files);
2759 : :
2760 : 7 : cc_log("=== CCACHE %s STARTED =========================================",
2761 : : CCACHE_VERSION);
2762 : :
2763 [ - + ]: 7 : if (conf->umask != UINT_MAX) {
2764 : 0 : umask(conf->umask);
2765 : : }
2766 : 7 : }
2767 : :
2768 : : /* Reset the global state. Used by the test suite. */
2769 : : void
2770 : 88 : cc_reset(void)
2771 : : {
2772 : 88 : conf_free(conf); conf = NULL;
2773 : 88 : free(primary_config_path); primary_config_path = NULL;
2774 : 88 : free(secondary_config_path); secondary_config_path = NULL;
2775 : 88 : free(current_working_dir); current_working_dir = NULL;
2776 : 88 : free(profile_dir); profile_dir = NULL;
2777 : 88 : free(included_pch_file); included_pch_file = NULL;
2778 : 88 : args_free(orig_args); orig_args = NULL;
2779 : 88 : free(input_file); input_file = NULL;
2780 : 88 : free(output_obj); output_obj = NULL;
2781 : 88 : free(output_dwo); output_dwo = NULL;
2782 : 88 : free(output_dep); output_dep = NULL;
2783 : 88 : free(output_cov); output_cov = NULL;
2784 : 88 : free(output_dia); output_dia = NULL;
2785 : 88 : free(cached_obj_hash); cached_obj_hash = NULL;
2786 : 88 : free(cached_obj); cached_obj = NULL;
2787 : 88 : free(cached_dwo); cached_dwo = NULL;
2788 : 88 : free(cached_stderr); cached_stderr = NULL;
2789 : 88 : free(cached_dep); cached_dep = NULL;
2790 : 88 : free(cached_cov); cached_cov = NULL;
2791 : 88 : free(cached_dia); cached_dia = NULL;
2792 : 88 : free(manifest_path); manifest_path = NULL;
2793 : 88 : time_of_compilation = 0;
2794 [ - + ]: 88 : if (included_files) {
2795 : 0 : hashtable_destroy(included_files, 1); included_files = NULL;
2796 : : }
2797 : 88 : generating_dependencies = false;
2798 : 88 : generating_coverage = false;
2799 : 88 : profile_arcs = false;
2800 : 88 : free(profile_dir); profile_dir = NULL;
2801 : 88 : i_tmpfile = NULL;
2802 : 88 : direct_i_file = false;
2803 : 88 : free(cpp_stderr); cpp_stderr = NULL;
2804 : 88 : free(stats_file); stats_file = NULL;
2805 : 88 : output_is_precompiled_header = false;
2806 : :
2807 : 88 : conf = conf_create();
2808 : 88 : using_split_dwarf = false;
2809 : 88 : }
2810 : :
2811 : : /* Make a copy of stderr that will not be cached, so things like
2812 : : distcc can send networking errors to it. */
2813 : : static void
2814 : 1 : setup_uncached_err(void)
2815 : : {
2816 : : char *buf;
2817 : : int uncached_fd;
2818 : :
2819 : 1 : uncached_fd = dup(2);
2820 [ - + ]: 1 : if (uncached_fd == -1) {
2821 : 0 : cc_log("dup(2) failed: %s", strerror(errno));
2822 : 0 : failed();
2823 : : }
2824 : :
2825 : : /* leak a pointer to the environment */
2826 : 1 : buf = format("UNCACHED_ERR_FD=%d", uncached_fd);
2827 : :
2828 [ - + ]: 1 : if (putenv(buf) == -1) {
2829 : 0 : cc_log("putenv failed: %s", strerror(errno));
2830 : 0 : failed();
2831 : : }
2832 : 1 : }
2833 : :
2834 : : static void
2835 : 27 : configuration_logger(const char *descr, const char *origin, void *context)
2836 : : {
2837 : : (void)context;
2838 : 27 : cc_bulklog("Config: (%s) %s", origin, descr);
2839 : 27 : }
2840 : :
2841 : : /* the main ccache driver function */
2842 : : static void
2843 : 1 : ccache(int argc, char *argv[])
2844 : : {
2845 : 1 : bool put_object_in_manifest = false;
2846 : : struct file_hash *object_hash;
2847 : 1 : struct file_hash *object_hash_from_manifest = NULL;
2848 : : struct mdfour common_hash;
2849 : : struct mdfour direct_hash;
2850 : : struct mdfour cpp_hash;
2851 : :
2852 : : /* Arguments (except -E) to send to the preprocessor. */
2853 : : struct args *preprocessor_args;
2854 : :
2855 : : /* Arguments to send to the real compiler. */
2856 : : struct args *compiler_args;
2857 : :
2858 : 1 : orig_args = args_init(argc, argv);
2859 : :
2860 : 1 : initialize();
2861 : 1 : find_compiler(argv);
2862 : :
2863 : : #ifndef _WIN32
2864 : 1 : signal(SIGHUP, signal_handler);
2865 : : #endif
2866 : 1 : signal(SIGINT, signal_handler);
2867 : 1 : signal(SIGTERM, signal_handler);
2868 : :
2869 [ + - ]: 1 : if (str_eq(conf->temporary_dir, "")) {
2870 : 1 : clean_up_internal_tempdir();
2871 : : }
2872 : :
2873 [ + - ]: 1 : if (!str_eq(conf->log_file, "")) {
2874 : 1 : conf_print_items(conf, configuration_logger, NULL);
2875 : : }
2876 : :
2877 [ - + ]: 1 : if (conf->disable) {
2878 : 0 : cc_log("ccache is disabled");
2879 : 0 : failed();
2880 : : }
2881 : :
2882 : 1 : setup_uncached_err();
2883 : :
2884 : 1 : cc_log_argv("Command line: ", argv);
2885 : 1 : cc_log("Hostname: %s", get_hostname());
2886 : 1 : cc_log("Working directory: %s", get_current_working_dir());
2887 : :
2888 [ - + ]: 1 : if (conf->unify) {
2889 : 0 : cc_log("Direct mode disabled because unify mode is enabled");
2890 : 0 : conf->direct_mode = false;
2891 : : }
2892 : :
2893 [ - + ]: 1 : if (!cc_process_args(orig_args, &preprocessor_args, &compiler_args)) {
2894 : 0 : failed();
2895 : : }
2896 : :
2897 : 1 : cc_log("Source file: %s", input_file);
2898 [ - + ]: 1 : if (generating_dependencies) {
2899 : 0 : cc_log("Dependency file: %s", output_dep);
2900 : : }
2901 [ - + ]: 1 : if (generating_coverage) {
2902 : 0 : cc_log("Coverage file: %s", output_cov);
2903 : : }
2904 [ - + ]: 1 : if (output_dia) {
2905 : 0 : cc_log("Diagnostic file: %s", output_dia);
2906 : : }
2907 : :
2908 [ - + ]: 1 : if (using_split_dwarf ) {
2909 [ # # ]: 0 : if (!generating_dependencies) {
2910 [ # # ]: 0 : assert(output_dwo);
2911 : : }
2912 : : } else {
2913 [ - + ]: 1 : assert(!output_dwo);
2914 : : }
2915 : :
2916 [ - + ]: 1 : if (output_dwo) {
2917 : 0 : cc_log("Split dwarf file: %s", output_dwo);
2918 : : }
2919 : :
2920 : 1 : cc_log("Object file: %s", output_obj);
2921 : :
2922 : 1 : hash_start(&common_hash);
2923 : 1 : calculate_common_hash(preprocessor_args, &common_hash);
2924 : :
2925 : : /* try to find the hash using the manifest */
2926 : 1 : direct_hash = common_hash;
2927 [ - + ]: 1 : if (conf->direct_mode) {
2928 : 0 : cc_log("Trying direct lookup");
2929 : 0 : object_hash = calculate_object_hash(preprocessor_args, &direct_hash, 1);
2930 [ # # ]: 0 : if (object_hash) {
2931 : 0 : update_cached_result_globals(object_hash);
2932 : :
2933 : : /*
2934 : : * If we can return from cache at this point then do
2935 : : * so.
2936 : : */
2937 : 0 : from_cache(FROMCACHE_DIRECT_MODE, 0);
2938 : :
2939 : : /*
2940 : : * Wasn't able to return from cache at this point.
2941 : : * However, the object was already found in manifest,
2942 : : * so don't readd it later.
2943 : : */
2944 : 0 : put_object_in_manifest = false;
2945 : :
2946 : 0 : object_hash_from_manifest = object_hash;
2947 : : } else {
2948 : : /* Add object to manifest later. */
2949 : 0 : put_object_in_manifest = true;
2950 : : }
2951 : : }
2952 : :
2953 [ - + ]: 1 : if (conf->read_only_direct) {
2954 : 0 : cc_log("Read-only direct mode; running real compiler");
2955 : 0 : failed();
2956 : : }
2957 : :
2958 : : /*
2959 : : * Find the hash using the preprocessed output. Also updates
2960 : : * included_files.
2961 : : */
2962 : 1 : cpp_hash = common_hash;
2963 : 1 : object_hash = calculate_object_hash(preprocessor_args, &cpp_hash, 0);
2964 [ - + ]: 1 : if (!object_hash) {
2965 : 0 : fatal("internal error: object hash from cpp returned NULL");
2966 : : }
2967 : 1 : update_cached_result_globals(object_hash);
2968 : :
2969 [ - + # # ]: 1 : if (object_hash_from_manifest
2970 : 0 : && !file_hashes_equal(object_hash_from_manifest, object_hash)) {
2971 : : /*
2972 : : * The hash from manifest differs from the hash of the
2973 : : * preprocessor output. This could be because:
2974 : : *
2975 : : * - The preprocessor produces different output for the same
2976 : : * input (not likely).
2977 : : * - There's a bug in ccache (maybe incorrect handling of
2978 : : * compiler arguments).
2979 : : * - The user has used a different CCACHE_BASEDIR (most
2980 : : * likely).
2981 : : *
2982 : : * The best thing here would probably be to remove the hash
2983 : : * entry from the manifest. For now, we use a simpler method:
2984 : : * just remove the manifest file.
2985 : : */
2986 : 0 : cc_log("Hash from manifest doesn't match preprocessor output");
2987 : 0 : cc_log("Likely reason: different CCACHE_BASEDIRs used");
2988 : 0 : cc_log("Removing manifest as a safety measure");
2989 : 0 : x_unlink(manifest_path);
2990 : :
2991 : 0 : put_object_in_manifest = true;
2992 : : }
2993 : :
2994 : : /* if we can return from cache at this point then do */
2995 : 1 : from_cache(FROMCACHE_CPP_MODE, put_object_in_manifest);
2996 : :
2997 [ - + ]: 1 : if (conf->read_only) {
2998 : 0 : cc_log("Read-only mode; running real compiler");
2999 : 0 : failed();
3000 : : }
3001 : :
3002 : 1 : add_prefix(compiler_args);
3003 : :
3004 : : /* run real compiler, sending output to cache */
3005 : 1 : to_cache(compiler_args);
3006 : :
3007 : 1 : x_exit(0);
3008 : : }
3009 : :
3010 : : static void
3011 : 0 : configuration_printer(const char *descr, const char *origin, void *context)
3012 : : {
3013 [ # # ]: 0 : assert(context);
3014 : 0 : fprintf(context, "(%s) %s\n", origin, descr);
3015 : 0 : }
3016 : :
3017 : : /* the main program when not doing a compile */
3018 : : static int
3019 : 6 : ccache_main_options(int argc, char *argv[])
3020 : : {
3021 : : int c;
3022 : : char *errmsg;
3023 : :
3024 : : enum longopts {
3025 : : DUMP_MANIFEST
3026 : : };
3027 : : static const struct option options[] = {
3028 : : {"cleanup", no_argument, 0, 'c'},
3029 : : {"clear", no_argument, 0, 'C'},
3030 : : {"dump-manifest", required_argument, 0, DUMP_MANIFEST},
3031 : : {"help", no_argument, 0, 'h'},
3032 : : {"max-files", required_argument, 0, 'F'},
3033 : : {"max-size", required_argument, 0, 'M'},
3034 : : {"set-config", required_argument, 0, 'o'},
3035 : : {"print-config", no_argument, 0, 'p'},
3036 : : {"show-stats", no_argument, 0, 's'},
3037 : : {"version", no_argument, 0, 'V'},
3038 : : {"zero-stats", no_argument, 0, 'z'},
3039 : : {0, 0, 0, 0}
3040 : : };
3041 : :
3042 [ + + ]: 12 : while ((c = getopt_long(argc, argv, "cChF:M:o:psVz", options, NULL)) != -1) {
3043 [ - - - - : 6 : switch (c) {
- - - - +
- - - ]
3044 : : case DUMP_MANIFEST:
3045 : 0 : manifest_dump(optarg, stdout);
3046 : 0 : break;
3047 : :
3048 : : case 'c': /* --cleanup */
3049 : 0 : initialize();
3050 : 0 : cleanup_all(conf);
3051 : 0 : printf("Cleaned cache\n");
3052 : 0 : break;
3053 : :
3054 : : case 'C': /* --clear */
3055 : 0 : initialize();
3056 : 0 : wipe_all(conf);
3057 : 0 : printf("Cleared cache\n");
3058 : 0 : break;
3059 : :
3060 : : case 'h': /* --help */
3061 : 0 : fputs(USAGE_TEXT, stdout);
3062 : 0 : x_exit(0);
3063 : :
3064 : : case 'F': /* --max-files */
3065 : : {
3066 : : unsigned files;
3067 : 0 : initialize();
3068 : 0 : files = atoi(optarg);
3069 [ # # ]: 0 : if (conf_set_value_in_file(primary_config_path, "max_files", optarg,
3070 : : &errmsg)) {
3071 [ # # ]: 0 : if (files == 0) {
3072 : 0 : printf("Unset cache file limit\n");
3073 : : } else {
3074 : 0 : printf("Set cache file limit to %u\n", files);
3075 : : }
3076 : : } else {
3077 : 0 : fatal("could not set cache file limit: %s", errmsg);
3078 : : }
3079 : : }
3080 : 0 : break;
3081 : :
3082 : : case 'M': /* --max-size */
3083 : : {
3084 : : uint64_t size;
3085 : 0 : initialize();
3086 [ # # ]: 0 : if (!parse_size_with_suffix(optarg, &size)) {
3087 : 0 : fatal("invalid size: %s", optarg);
3088 : : }
3089 [ # # ]: 0 : if (conf_set_value_in_file(primary_config_path, "max_size", optarg,
3090 : : &errmsg)) {
3091 [ # # ]: 0 : if (size == 0) {
3092 : 0 : printf("Unset cache size limit\n");
3093 : : } else {
3094 : 0 : char *s = format_human_readable_size(size);
3095 : 0 : printf("Set cache size limit to %s\n", s);
3096 : 0 : free(s);
3097 : : }
3098 : : } else {
3099 : 0 : fatal("could not set cache size limit: %s", errmsg);
3100 : : }
3101 : : }
3102 : 0 : break;
3103 : :
3104 : : case 'o': /* --set-config */
3105 : : {
3106 : : char *errmsg, *key, *value, *p;
3107 : 0 : initialize();
3108 : 0 : p = strchr(optarg, '=');
3109 [ # # ]: 0 : if (!p) {
3110 : 0 : fatal("missing equal sign in \"%s\"", optarg);
3111 : : }
3112 : 0 : key = x_strndup(optarg, p - optarg);
3113 : 0 : value = p + 1;
3114 [ # # ]: 0 : if (!conf_set_value_in_file(primary_config_path, key, value, &errmsg)) {
3115 : 0 : fatal("%s", errmsg);
3116 : : }
3117 : 0 : free(key);
3118 : : }
3119 : 0 : break;
3120 : :
3121 : : case 'p': /* --print-config */
3122 : 0 : initialize();
3123 : 0 : conf_print_items(conf, configuration_printer, stdout);
3124 : 0 : break;
3125 : :
3126 : : case 's': /* --show-stats */
3127 : 6 : initialize();
3128 : 6 : stats_summary(conf);
3129 : 6 : break;
3130 : :
3131 : : case 'V': /* --version */
3132 : 0 : fprintf(stdout, VERSION_TEXT, CCACHE_VERSION);
3133 : 0 : x_exit(0);
3134 : :
3135 : : case 'z': /* --zero-stats */
3136 : 0 : initialize();
3137 : 0 : stats_zero();
3138 : 0 : printf("Statistics cleared\n");
3139 : 0 : break;
3140 : :
3141 : : default:
3142 : 0 : fputs(USAGE_TEXT, stderr);
3143 : 0 : x_exit(1);
3144 : : }
3145 : : }
3146 : :
3147 : 6 : return 0;
3148 : : }
3149 : :
3150 : : int
3151 : 7 : ccache_main(int argc, char *argv[])
3152 : : {
3153 : : /* check if we are being invoked as "ccache" */
3154 : 7 : char *program_name = basename(argv[0]);
3155 [ + - ]: 7 : if (same_executable_name(program_name, MYNAME)) {
3156 [ - + ]: 7 : if (argc < 2) {
3157 : 0 : fputs(USAGE_TEXT, stderr);
3158 : 0 : x_exit(1);
3159 : : }
3160 : : /* if the first argument isn't an option, then assume we are
3161 : : being passed a compiler name and options */
3162 [ + + ]: 7 : if (argv[1][0] == '-') {
3163 : 6 : return ccache_main_options(argc, argv);
3164 : : }
3165 : : }
3166 : 1 : free(program_name);
3167 : :
3168 : 1 : ccache(argc, argv);
3169 : 6 : return 1;
3170 : : }
|