~ubuntu-branches/debian/stretch/ccache/stretch

« back to all changes in this revision

Viewing changes to ccache.c

  • Committer: Bazaar Package Importer
  • Author(s): Joel Rosdahl
  • Date: 2010-12-02 21:05:17 UTC
  • mfrom: (5.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20101202210517-ji5owl2qa3s5c1rg
New upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 */
21
21
 
22
22
#include "ccache.h"
 
23
#include "compopt.h"
 
24
#ifdef HAVE_GETOPT_LONG
 
25
#include <getopt.h>
 
26
#else
23
27
#include "getopt_long.h"
 
28
#endif
24
29
#include "hashtable.h"
25
30
#include "hashtable_itr.h"
26
31
#include "hashutil.h"
 
32
#include "language.h"
27
33
#include "manifest.h"
28
34
 
29
 
#include <sys/types.h>
30
 
#include <sys/stat.h>
31
 
#include <sys/mman.h>
32
 
#include <errno.h>
33
 
#include <fcntl.h>
34
 
#include <stdlib.h>
35
 
#include <stdio.h>
36
 
#include <string.h>
37
 
#include <time.h>
38
 
#include <unistd.h>
39
 
 
40
35
static const char VERSION_TEXT[] =
41
 
"ccache version %s\n"
 
36
MYNAME " version %s\n"
42
37
"\n"
43
38
"Copyright (C) 2002-2007 Andrew Tridgell\n"
44
39
"Copyright (C) 2009-2010 Joel Rosdahl\n"
50
45
 
51
46
static const char USAGE_TEXT[] =
52
47
"Usage:\n"
53
 
"    ccache [options]\n"
54
 
"    ccache compiler [compiler options]\n"
 
48
"    " MYNAME " [options]\n"
 
49
"    " MYNAME " compiler [compiler options]\n"
55
50
"    compiler [compiler options]          (via symbolic link)\n"
56
51
"\n"
57
52
"Options:\n"
87
82
static char *base_dir;
88
83
 
89
84
/* the original argument list */
90
 
static ARGS *orig_args;
 
85
static struct args *orig_args;
91
86
 
92
87
/* the source file */
93
88
static char *input_file;
144
139
static struct hashtable *included_files;
145
140
 
146
141
/* is gcc being asked to output dependencies? */
147
 
static int generating_dependencies;
 
142
static bool generating_dependencies;
148
143
 
149
144
/* the extension of the file (without dot) after pre-processing */
150
145
static const char *i_extension;
153
148
static char *i_tmpfile;
154
149
 
155
150
/* are we compiling a .i or .ii file directly? */
156
 
static int direct_i_file;
 
151
static bool direct_i_file;
157
152
 
158
153
/* the name of the cpp stderr file */
159
154
static char *cpp_stderr;
165
160
char *stats_file = NULL;
166
161
 
167
162
/* can we safely use the unification hashing backend? */
168
 
static int enable_unify;
 
163
static bool enable_unify;
169
164
 
170
165
/* should we use the direct mode? */
171
 
static int enable_direct = 1;
 
166
static bool enable_direct = true;
172
167
 
173
168
/*
174
169
 * Whether to enable compression of files stored in the cache. (Manifest files
175
170
 * are always compressed.)
176
171
 */
177
 
static int enable_compression = 0;
 
172
static bool enable_compression = false;
178
173
 
179
174
/* number of levels (1 <= nlevels <= 8) */
180
175
static int nlevels = 2;
183
178
 * Whether we should use the optimization of passing the already existing
184
179
 * preprocessed source code to the compiler.
185
180
 */
186
 
static int compile_preprocessed_source_code;
187
 
 
188
 
/*
189
 
 * Supported file extensions and corresponding languages (as in parameter to
190
 
 * the -x option).
191
 
 */
192
 
static const struct {
193
 
        const char *extension;
194
 
        const char *language;
195
 
} extensions[] = {
196
 
        /* Preprocessed: */
197
 
        {".i",   "cpp-output"},
198
 
        {".ii",  "c++-cpp-output"},
199
 
        {".mi",  "objc-cpp-output"},
200
 
        {".mii", "objc++-cpp-output"},
201
 
        /* Other: */
202
 
        {".c",   "c"},
203
 
        {".C",   "c++"},
204
 
        {".cc",  "c++"},
205
 
        {".CC",  "c++"},
206
 
        {".cpp", "c++"},
207
 
        {".CPP", "c++"},
208
 
        {".cxx", "c++"},
209
 
        {".CXX", "c++"},
210
 
        {".c++", "c++"},
211
 
        {".C++", "c++"},
212
 
        {".m",   "objective-c"},
213
 
        {".M",   "objective-c++"},
214
 
        {".mm",  "objective-c++"},
215
 
        {NULL,  NULL}};
216
 
 
217
 
/*
218
 
 * Supported languages and corresponding preprocessed languages.
219
 
 */
220
 
static const struct {
221
 
        const char *language;
222
 
        const char *p_language;
223
 
} languages[] = {
224
 
        {"c",                 "cpp-output"},
225
 
        {"cpp-output",        "cpp-output"},
226
 
        {"c++",               "c++-cpp-output"},
227
 
        {"c++-cpp-output",    "c++-cpp-output"},
228
 
        {"objective-c",       "objc-cpp-output"},
229
 
        {"objc-cpp-output",   "objc-cpp-output"},
230
 
        {"objective-c++",     "objc++-cpp-output"},
231
 
        {"objc++-cpp-output", "objc++-cpp-output"},
232
 
        {NULL,  NULL}};
 
181
static bool compile_preprocessed_source_code;
 
182
 
 
183
/* Whether the output is a precompiled header */
 
184
static bool output_is_precompiled_header = false;
 
185
 
 
186
/*
 
187
 * Whether we are using a precompiled header (either via -include or #include).
 
188
 */
 
189
static bool using_precompiled_header = false;
 
190
 
 
191
/* How long (in microseconds) to wait before breaking a stale lock. */
 
192
unsigned lock_staleness_limit = 2000000;
233
193
 
234
194
enum fromcache_call_mode {
235
195
        FROMCACHE_DIRECT_MODE,
246
206
 */
247
207
static const char HASH_PREFIX[] = "3";
248
208
 
249
 
/*
250
 
  something went badly wrong - just execute the real compiler
251
 
*/
252
 
static void failed(void)
 
209
/* Something went badly wrong - just execute the real compiler. */
 
210
static void
 
211
failed(void)
253
212
{
254
213
        char *e;
255
214
 
256
 
        /* delete intermediate pre-processor file if needed */
257
 
        if (i_tmpfile) {
258
 
                if (!direct_i_file) {
259
 
                        unlink(i_tmpfile);
260
 
                }
261
 
                free(i_tmpfile);
262
 
                i_tmpfile = NULL;
263
 
        }
264
 
 
265
 
        /* delete the cpp stderr file if necessary */
266
 
        if (cpp_stderr) {
267
 
                unlink(cpp_stderr);
268
 
                free(cpp_stderr);
269
 
                cpp_stderr = NULL;
270
 
        }
271
 
 
272
215
        /* strip any local args */
273
216
        args_strip(orig_args, "--ccache-");
274
217
 
275
 
        if ((e=getenv("CCACHE_PREFIX"))) {
 
218
        if ((e = getenv("CCACHE_PREFIX"))) {
276
219
                char *p = find_executable(e, MYNAME);
277
220
                if (!p) {
278
 
                        perror(e);
279
 
                        exit(1);
 
221
                        fatal("%s: %s", e, strerror(errno));
280
222
                }
281
223
                args_add_prefix(orig_args, p);
282
224
        }
283
225
 
284
226
        cc_log("Failed; falling back to running the real compiler");
285
 
        cc_log_executed_command(orig_args->argv);
 
227
        cc_log_argv("Executing ", orig_args->argv);
 
228
        exitfn_call();
286
229
        execv(orig_args->argv[0], orig_args->argv);
287
 
        cc_log("execv returned (%s)!", strerror(errno));
288
 
        perror(orig_args->argv[0]);
289
 
        exit(1);
 
230
        fatal("%s: execv returned (%s)", orig_args->argv[0], strerror(errno));
 
231
}
 
232
 
 
233
static void
 
234
clean_up_tmp_files()
 
235
{
 
236
        /* delete intermediate pre-processor file if needed */
 
237
        if (i_tmpfile) {
 
238
                if (!direct_i_file) {
 
239
                        tmp_unlink(i_tmpfile);
 
240
                }
 
241
                free(i_tmpfile);
 
242
                i_tmpfile = NULL;
 
243
        }
 
244
 
 
245
        /* delete the cpp stderr file if necessary */
 
246
        if (cpp_stderr) {
 
247
                tmp_unlink(cpp_stderr);
 
248
                free(cpp_stderr);
 
249
                cpp_stderr = NULL;
 
250
        }
290
251
}
291
252
 
292
253
/*
293
254
 * Transform a name to a full path into the cache directory, creating needed
294
255
 * sublevels if needed. Caller frees.
295
256
 */
296
 
static char *get_path_in_cache(const char *name, const char *suffix)
 
257
static char *
 
258
get_path_in_cache(const char *name, const char *suffix)
297
259
{
298
260
        int i;
299
261
        char *path;
301
263
 
302
264
        path = x_strdup(cache_dir);
303
265
        for (i = 0; i < nlevels; ++i) {
304
 
                char *p;
305
 
                x_asprintf(&p, "%s/%c", path, name[i]);
 
266
                char *p = format("%s/%c", path, name[i]);
306
267
                free(path);
307
268
                path = p;
308
269
                if (create_dir(path) != 0) {
310
271
                        failed();
311
272
                }
312
273
        }
313
 
        x_asprintf(&result, "%s/%s%s", path, name + nlevels, suffix);
 
274
        result = format("%s/%s%s", path, name + nlevels, suffix);
314
275
        free(path);
315
276
        return result;
316
277
}
317
278
 
318
279
/*
319
280
 * This function hashes an include file and stores the path and hash in the
320
 
 * global included_files variable. Takes over ownership of path.
 
281
 * global included_files variable. If the include file is a PCH, cpp_hash is
 
282
 * also updated. Takes over ownership of path.
321
283
 */
322
 
static void remember_include_file(char *path, size_t path_len)
 
284
static void
 
285
remember_include_file(char *path, size_t path_len, struct mdfour *cpp_hash)
323
286
{
324
 
        struct file_hash *h;
325
287
        struct mdfour fhash;
326
288
        struct stat st;
327
 
        int fd = -1;
328
 
        char *data = (char *)-1;
329
 
        char *source;
 
289
        char *source = NULL;
 
290
        size_t size;
330
291
        int result;
331
 
 
332
 
        if (!included_files) {
333
 
                goto ignore;
334
 
        }
 
292
        bool is_pch;
335
293
 
336
294
        if (path_len >= 2 && (path[0] == '<' && path[path_len - 1] == '>')) {
337
295
                /* Typically <built-in> or <command-line>. */
338
296
                goto ignore;
339
297
        }
340
298
 
341
 
        if (strcmp(path, input_file) == 0) {
 
299
        if (str_eq(path, input_file)) {
342
300
                /* Don't remember the input file. */
343
301
                goto ignore;
344
302
        }
348
306
                goto ignore;
349
307
        }
350
308
 
351
 
        /* Let's hash the include file. */
352
 
        fd = open(path, O_RDONLY|O_BINARY);
353
 
        if (fd == -1) {
354
 
                cc_log("Failed to open include file %s", path);
355
 
                goto failure;
356
 
        }
357
 
        if (fstat(fd, &st) != 0) {
358
 
                cc_log("Failed to fstat include file %s", path);
 
309
        if (stat(path, &st) != 0) {
 
310
                cc_log("Failed to stat include file %s", path);
359
311
                goto failure;
360
312
        }
361
313
        if (S_ISDIR(st.st_mode)) {
362
314
                /* Ignore directory, typically $PWD. */
363
315
                goto ignore;
364
316
        }
 
317
        if (!S_ISREG(st.st_mode)) {
 
318
                /* Device, pipe, socket or other strange creature. */
 
319
                cc_log("Non-regular include file %s", path);
 
320
                goto failure;
 
321
        }
 
322
 
 
323
        /* Let's hash the include file. */
365
324
        if (!(sloppiness & SLOPPY_INCLUDE_FILE_MTIME)
366
325
            && st.st_mtime >= time_of_compilation) {
367
326
                cc_log("Include file %s too new", path);
368
327
                goto failure;
369
328
        }
370
 
        if (st.st_size > 0) {
371
 
                data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
372
 
                if (data == (char *)-1) {
373
 
                        cc_log("Failed to mmap %s", path);
 
329
 
 
330
        hash_start(&fhash);
 
331
 
 
332
        is_pch = is_precompiled_header(path);
 
333
        if (is_pch) {
 
334
                struct file_hash pch_hash;
 
335
                if (!hash_file(&fhash, path)) {
374
336
                        goto failure;
375
337
                }
376
 
                source = data;
 
338
                hash_result_as_bytes(&fhash, pch_hash.hash);
 
339
                pch_hash.size = fhash.totalN;
 
340
                hash_delimiter(cpp_hash, "pch_hash");
 
341
                hash_buffer(cpp_hash, pch_hash.hash, sizeof(pch_hash.hash));
 
342
        }
 
343
        if (enable_direct) {
 
344
                struct file_hash *h;
 
345
 
 
346
                if (!is_pch) { /* else: the file has already been hashed. */
 
347
                        if (st.st_size > 0) {
 
348
                                if (!read_file(path, st.st_size, &source, &size)) {
 
349
                                        goto failure;
 
350
                                }
 
351
                        } else {
 
352
                                source = x_strdup("");
 
353
                                size = 0;
 
354
                        }
 
355
 
 
356
                        result = hash_source_code_string(&fhash, source, size, path);
 
357
                        if (result & HASH_SOURCE_CODE_ERROR
 
358
                            || result & HASH_SOURCE_CODE_FOUND_TIME) {
 
359
                                goto failure;
 
360
                        }
 
361
                }
 
362
 
 
363
                h = x_malloc(sizeof(*h));
 
364
                hash_result_as_bytes(&fhash, h->hash);
 
365
                h->size = fhash.totalN;
 
366
                hashtable_insert(included_files, path, h);
377
367
        } else {
378
 
                source = "";
379
 
        }
380
 
        close(fd);
381
 
 
382
 
        hash_start(&fhash);
383
 
        result = hash_source_code_string(&fhash, source, st.st_size, path);
384
 
        if (result & HASH_SOURCE_CODE_ERROR
385
 
            || result & HASH_SOURCE_CODE_FOUND_TIME) {
386
 
                goto failure;
387
 
        }
388
 
 
389
 
        h = x_malloc(sizeof(*h));
390
 
        hash_result_as_bytes(&fhash, h->hash);
391
 
        h->size = fhash.totalN;
392
 
        hashtable_insert(included_files, path, h);
393
 
        munmap(data, st.st_size);
 
368
                free(path);
 
369
        }
 
370
 
 
371
        free(source);
394
372
        return;
395
373
 
396
374
failure:
397
375
        cc_log("Disabling direct mode");
398
 
        enable_direct = 0;
 
376
        enable_direct = false;
399
377
        /* Fall through. */
400
378
ignore:
401
379
        free(path);
402
 
        if (data != (char *)-1) {
403
 
                munmap(data, st.st_size);
404
 
        }
405
 
        if (fd != -1) {
406
 
                close(fd);
407
 
        }
 
380
        free(source);
408
381
}
409
382
 
410
383
/*
411
384
 * Make a relative path from CCACHE_BASEDIR to path. Takes over ownership of
412
385
 * path. Caller frees.
413
386
 */
414
 
static char *make_relative_path(char *path)
 
387
static char *
 
388
make_relative_path(char *path)
415
389
{
416
390
        char *relpath;
417
391
 
418
 
        if (!base_dir || strncmp(path, base_dir, strlen(base_dir)) != 0) {
 
392
        if (!base_dir || !str_startswith(path, base_dir)) {
419
393
                return path;
420
394
        }
421
395
 
433
407
 * - Stores the paths and hashes of included files in the global variable
434
408
 *   included_files.
435
409
 */
436
 
static int process_preprocessed_file(struct mdfour *hash, const char *path)
 
410
static bool
 
411
process_preprocessed_file(struct mdfour *hash, const char *path)
437
412
{
438
 
        int fd;
439
413
        char *data;
440
414
        char *p, *q, *end;
441
 
        off_t size;
442
 
        struct stat st;
443
 
 
444
 
        fd = open(path, O_RDONLY);
445
 
        if (fd == -1) {
446
 
                cc_log("Failed to open %s", path);
447
 
                return 0;
448
 
        }
449
 
        if (fstat(fd, &st) != 0) {
450
 
                cc_log("Failed to fstat %s", path);
451
 
                return 0;
452
 
        }
453
 
        size = st.st_size;
454
 
        data = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
455
 
        close(fd);
456
 
        if (data == (void *)-1) {
457
 
                cc_log("Failed to mmap %s", path);
458
 
                return 0;
459
 
        }
460
 
 
461
 
        if (enable_direct) {
462
 
                included_files = create_hashtable(1000, hash_from_string,
463
 
                                                  strings_equal);
464
 
        }
 
415
        size_t size;
 
416
 
 
417
        if (!read_file(path, 0, &data, &size)) {
 
418
                return false;
 
419
        }
 
420
 
 
421
        included_files = create_hashtable(1000, hash_from_string, strings_equal);
465
422
 
466
423
        /* Bytes between p and q are pending to be hashed. */
467
424
        end = data + size;
477
434
                 *
478
435
                 *   # N "file"
479
436
                 *   # N "file" N
 
437
                 *   #pragma GCC pch_preprocess "file"
480
438
                 *
481
439
                 * HP's compiler:
482
440
                 *
483
441
                 *   #line N "file"
484
442
                 *
 
443
                 * AIX's compiler:
 
444
                 *
 
445
                 *   #line N "file"
 
446
                 *   #line N
 
447
                 *
485
448
                 * Note that there may be other lines starting with '#' left after
486
449
                 * preprocessing as well, for instance "#    pragma".
487
450
                 */
488
451
                if (q[0] == '#'
489
452
                        /* GCC: */
490
453
                    && ((q[1] == ' ' && q[2] >= '0' && q[2] <= '9')
491
 
                        /* HP: */
 
454
                        /* GCC precompiled header: */
 
455
                        || (q[1] == 'p'
 
456
                            && str_startswith(&q[2], "ragma GCC pch_preprocess "))
 
457
                        /* HP/AIX: */
492
458
                        || (q[1] == 'l' && q[2] == 'i' && q[3] == 'n' && q[4] == 'e'
493
459
                            && q[5] == ' '))
494
460
                    && (q == data || q[-1] == '\n')) {
495
461
                        char *path;
496
462
 
497
 
                        while (q < end && *q != '"') {
 
463
                        while (q < end && *q != '"' && *q != '\n') {
498
464
                                q++;
499
465
                        }
 
466
                        if (q < end && *q == '\n') {
 
467
                                /* A newline before the quotation mark -> no match. */
 
468
                                continue;
 
469
                        }
500
470
                        q++;
501
471
                        if (q >= end) {
502
472
                                cc_log("Failed to parse included file path");
503
 
                                munmap(data, size);
504
 
                                return 0;
 
473
                                free(data);
 
474
                                return false;
505
475
                        }
506
476
                        /* q points to the beginning of an include file path */
507
477
                        hash_buffer(hash, p, q - p);
513
483
                        path = x_strndup(p, q - p);
514
484
                        path = make_relative_path(path);
515
485
                        hash_string(hash, path);
516
 
                        if (enable_direct) {
517
 
                                remember_include_file(path, q - p);
518
 
                        } else {
519
 
                                free(path);
520
 
                        }
 
486
                        remember_include_file(path, q - p, hash);
521
487
                        p = q;
522
488
                } else {
523
489
                        q++;
525
491
        }
526
492
 
527
493
        hash_buffer(hash, p, (end - p));
528
 
        munmap(data, size);
529
 
        return 1;
530
 
}
531
 
 
532
 
/*
533
 
 * Guess the language of a file based on its extension. Returns NULL if the
534
 
 * extension is unknown.
535
 
 */
536
 
static const char *
537
 
language_for_file(const char *fname)
538
 
{
539
 
        int i;
540
 
        const char *p;
541
 
 
542
 
        p = get_extension(fname);
543
 
        for (i = 0; extensions[i].extension; i++) {
544
 
                if (strcmp(p, extensions[i].extension) == 0) {
545
 
                        return extensions[i].language;
546
 
                }
547
 
        }
548
 
        return NULL;
549
 
}
550
 
 
551
 
/*
552
 
 * Return the preprocessed language for a given language, or NULL if unknown.
553
 
 */
554
 
static const char *
555
 
p_language_for_language(const char *language)
556
 
{
557
 
        int i;
558
 
 
559
 
        if (!language) {
560
 
                return NULL;
561
 
        }
562
 
        for (i = 0; languages[i].language; ++i) {
563
 
                if (strcmp(language, languages[i].language) == 0) {
564
 
                        return languages[i].p_language;
565
 
                }
566
 
        }
567
 
        return NULL;
568
 
}
569
 
 
570
 
/*
571
 
 * Return the default file extension (including dot) for a language, or NULL if
572
 
 * unknown.
573
 
 */
574
 
static const char *
575
 
extension_for_language(const char *language)
576
 
{
577
 
        int i;
578
 
 
579
 
        if (!language) {
580
 
                return NULL;
581
 
        }
582
 
        for (i = 0; extensions[i].extension; i++) {
583
 
                if (strcmp(language, extensions[i].language) == 0) {
584
 
                        return extensions[i].extension;
585
 
                }
586
 
        }
587
 
        return NULL;
588
 
}
589
 
 
590
 
static int
591
 
language_is_supported(const char *language)
592
 
{
593
 
        return p_language_for_language(language) != NULL;
594
 
}
595
 
 
596
 
static int
597
 
language_is_preprocessed(const char *language)
598
 
{
599
 
        return strcmp(language, p_language_for_language(language)) == 0;
 
494
        free(data);
 
495
        return true;
600
496
}
601
497
 
602
498
/* run the real compiler and put the result in cache */
603
 
static void to_cache(ARGS *args)
 
499
static void
 
500
to_cache(struct args *args)
604
501
{
605
502
        char *tmp_stdout, *tmp_stderr, *tmp_obj;
606
503
        struct stat st;
608
505
        size_t added_bytes = 0;
609
506
        unsigned added_files = 0;
610
507
 
611
 
        x_asprintf(&tmp_stdout, "%s.tmp.stdout.%s", cached_obj, tmp_string());
612
 
        x_asprintf(&tmp_stderr, "%s.tmp.stderr.%s", cached_obj, tmp_string());
613
 
        x_asprintf(&tmp_obj, "%s.tmp.%s", cached_obj, tmp_string());
 
508
        tmp_stdout = format("%s.tmp.stdout.%s", cached_obj, tmp_string());
 
509
        tmp_stderr = format("%s.tmp.stderr.%s", cached_obj, tmp_string());
 
510
        tmp_obj = format("%s.tmp.%s", cached_obj, tmp_string());
614
511
 
615
512
        args_add(args, "-o");
616
513
        args_add(args, tmp_obj);
636
533
        if (stat(tmp_stdout, &st) != 0 || st.st_size != 0) {
637
534
                cc_log("Compiler produced stdout");
638
535
                stats_update(STATS_STDOUT);
639
 
                unlink(tmp_stdout);
640
 
                unlink(tmp_stderr);
641
 
                unlink(tmp_obj);
 
536
                tmp_unlink(tmp_stdout);
 
537
                tmp_unlink(tmp_stderr);
 
538
                tmp_unlink(tmp_obj);
642
539
                failed();
643
540
        }
644
 
        unlink(tmp_stdout);
 
541
        tmp_unlink(tmp_stdout);
645
542
 
646
543
        /*
647
544
         * Merge stderr from the preprocessor (if any) and stderr from the real
651
548
                int fd_cpp_stderr;
652
549
                int fd_real_stderr;
653
550
                int fd_result;
 
551
                char *tmp_stderr2;
654
552
 
 
553
                tmp_stderr2 = format("%s.tmp.stderr2.%s", cached_obj, tmp_string());
 
554
                if (x_rename(tmp_stderr, tmp_stderr2)) {
 
555
                        cc_log("Failed to rename %s to %s", tmp_stderr, tmp_stderr2);
 
556
                        failed();
 
557
                }
655
558
                fd_cpp_stderr = open(cpp_stderr, O_RDONLY | O_BINARY);
656
559
                if (fd_cpp_stderr == -1) {
657
560
                        cc_log("Failed opening %s", cpp_stderr);
658
561
                        failed();
659
562
                }
660
 
                fd_real_stderr = open(tmp_stderr, O_RDONLY | O_BINARY);
 
563
                fd_real_stderr = open(tmp_stderr2, O_RDONLY | O_BINARY);
661
564
                if (fd_real_stderr == -1) {
662
 
                        cc_log("Failed opening %s", tmp_stderr);
 
565
                        cc_log("Failed opening %s", tmp_stderr2);
663
566
                        failed();
664
567
                }
665
 
                unlink(tmp_stderr);
666
 
                fd_result = open(tmp_stderr,
667
 
                                 O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
668
 
                                 0666);
 
568
                fd_result = open(tmp_stderr, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
669
569
                if (fd_result == -1) {
670
570
                        cc_log("Failed opening %s", tmp_stderr);
671
571
                        failed();
675
575
                close(fd_cpp_stderr);
676
576
                close(fd_real_stderr);
677
577
                close(fd_result);
678
 
                unlink(cpp_stderr);
679
 
                free(cpp_stderr);
680
 
                cpp_stderr = NULL;
 
578
                tmp_unlink(tmp_stderr2);
 
579
                free(tmp_stderr2);
681
580
        }
682
581
 
683
582
        if (status != 0) {
687
586
 
688
587
                fd = open(tmp_stderr, O_RDONLY | O_BINARY);
689
588
                if (fd != -1) {
690
 
                        if (strcmp(output_obj, "/dev/null") == 0
 
589
                        if (str_eq(output_obj, "/dev/null")
691
590
                            || (access(tmp_obj, R_OK) == 0
692
591
                                && move_file(tmp_obj, output_obj, 0) == 0)
693
592
                            || errno == ENOENT) {
694
 
                                /* we can use a quick method of
695
 
                                   getting the failed output */
 
593
                                /* we can use a quick method of getting the failed output */
696
594
                                copy_fd(fd, 2);
697
595
                                close(fd);
698
 
                                unlink(tmp_stderr);
699
 
                                if (i_tmpfile && !direct_i_file) {
700
 
                                        unlink(i_tmpfile);
701
 
                                }
 
596
                                tmp_unlink(tmp_stderr);
702
597
                                exit(status);
703
598
                        }
704
599
                }
705
600
 
706
 
                unlink(tmp_stderr);
707
 
                unlink(tmp_obj);
 
601
                tmp_unlink(tmp_stderr);
 
602
                tmp_unlink(tmp_obj);
708
603
                failed();
709
604
        }
710
605
 
727
622
        if (st.st_size > 0) {
728
623
                if (move_uncompressed_file(tmp_stderr, cached_stderr,
729
624
                                           enable_compression) != 0) {
730
 
                        cc_log("Failed to move %s to %s",
731
 
                               tmp_stderr, cached_stderr);
 
625
                        cc_log("Failed to move %s to %s", tmp_stderr, cached_stderr);
732
626
                        stats_update(STATS_ERROR);
733
627
                        failed();
734
628
                }
739
633
                added_bytes += file_size(&st);
740
634
                added_files += 1;
741
635
        } else {
742
 
                unlink(tmp_stderr);
 
636
                tmp_unlink(tmp_stderr);
743
637
        }
744
638
        if (move_uncompressed_file(tmp_obj, cached_obj, enable_compression) != 0) {
745
639
                cc_log("Failed to move %s to %s", tmp_obj, cached_obj);
774
668
 * Returns the hash as a heap-allocated hex string.
775
669
 */
776
670
static struct file_hash *
777
 
get_object_name_from_cpp(ARGS *args, struct mdfour *hash)
 
671
get_object_name_from_cpp(struct args *args, struct mdfour *hash)
778
672
{
779
673
        char *input_base;
780
674
        char *tmp;
796
690
        }
797
691
 
798
692
        /* now the run */
799
 
        x_asprintf(&path_stdout, "%s/%s.tmp.%s.%s", temp_dir,
800
 
                   input_base, tmp_string(), i_extension);
801
 
        x_asprintf(&path_stderr, "%s/tmp.cpp_stderr.%s", temp_dir,
802
 
                   tmp_string());
 
693
        path_stdout = format("%s/%s.tmp.%s.%s",
 
694
                             temp_dir, input_base, tmp_string(), i_extension);
 
695
        path_stderr = format("%s/tmp.cpp_stderr.%s", temp_dir, tmp_string());
803
696
 
804
697
        time_of_compilation = time(NULL);
805
698
 
824
717
 
825
718
        if (status != 0) {
826
719
                if (!direct_i_file) {
827
 
                        unlink(path_stdout);
 
720
                        tmp_unlink(path_stdout);
828
721
                }
829
 
                unlink(path_stderr);
 
722
                tmp_unlink(path_stderr);
830
723
                cc_log("Preprocessor gave exit status %d", status);
831
724
                stats_update(STATS_PREPROCESSOR);
832
725
                failed();
843
736
                hash_delimiter(hash, "unifycpp");
844
737
                if (unify_hash(hash, path_stdout) != 0) {
845
738
                        stats_update(STATS_ERROR);
846
 
                        unlink(path_stderr);
 
739
                        tmp_unlink(path_stderr);
847
740
                        cc_log("Failed to unify %s", path_stdout);
848
741
                        failed();
849
742
                }
851
744
                hash_delimiter(hash, "cpp");
852
745
                if (!process_preprocessed_file(hash, path_stdout)) {
853
746
                        stats_update(STATS_ERROR);
854
 
                        unlink(path_stderr);
 
747
                        tmp_unlink(path_stderr);
855
748
                        failed();
856
749
                }
857
750
        }
871
764
                 */
872
765
                cpp_stderr = path_stderr;
873
766
        } else {
874
 
                unlink(path_stderr);
 
767
                tmp_unlink(path_stderr);
875
768
                free(path_stderr);
876
769
        }
877
770
 
881
774
        return result;
882
775
}
883
776
 
884
 
static void update_cached_result_globals(struct file_hash *hash)
 
777
static void
 
778
update_cached_result_globals(struct file_hash *hash)
885
779
{
886
780
        char *object_name;
887
781
 
890
784
        cached_obj = get_path_in_cache(object_name, ".o");
891
785
        cached_stderr = get_path_in_cache(object_name, ".stderr");
892
786
        cached_dep = get_path_in_cache(object_name, ".d");
893
 
        x_asprintf(&stats_file, "%s/%c/stats", cache_dir, object_name[0]);
 
787
        stats_file = format("%s/%c/stats", cache_dir, object_name[0]);
894
788
        free(object_name);
895
789
}
896
790
 
898
792
 * Update a hash sum with information common for the direct and preprocessor
899
793
 * modes.
900
794
 */
901
 
static void calculate_common_hash(ARGS *args, struct mdfour *hash)
 
795
static void
 
796
calculate_common_hash(struct args *args, struct mdfour *hash)
902
797
{
903
798
        struct stat st;
904
799
        const char *compilercheck;
926
821
        if (!compilercheck) {
927
822
                compilercheck = "mtime";
928
823
        }
929
 
        if (strcmp(compilercheck, "none") == 0) {
 
824
        if (str_eq(compilercheck, "none")) {
930
825
                /* Do nothing. */
931
 
        } else if (strcmp(compilercheck, "content") == 0) {
 
826
        } else if (str_eq(compilercheck, "content")) {
932
827
                hash_delimiter(hash, "cc_content");
933
828
                hash_file(hash, args->argv[0]);
934
 
        } else { /* mtime */
 
829
        } else if (str_eq(compilercheck, "mtime")) {
935
830
                hash_delimiter(hash, "cc_mtime");
936
831
                hash_int(hash, st.st_size);
937
832
                hash_int(hash, st.st_mtime);
 
833
        } else { /* command string */
 
834
                if (!hash_multicommand_output(hash, compilercheck, orig_args->argv[0])) {
 
835
                        fatal("Failure running compiler check command: %s", compilercheck);
 
836
                }
938
837
        }
939
838
 
940
839
        /*
956
855
 
957
856
        p = getenv("CCACHE_EXTRAFILES");
958
857
        if (p) {
959
 
                char *path, *q;
 
858
                char *path, *q, *saveptr = NULL;
960
859
                p = x_strdup(p);
961
860
                q = p;
962
 
                while ((path = strtok(q, ":"))) {
 
861
                while ((path = strtok_r(q, PATH_DELIM, &saveptr))) {
963
862
                        cc_log("Hashing extra file %s", path);
964
863
                        hash_delimiter(hash, "extrafile");
965
864
                        if (!hash_file(hash, path)) {
977
876
 * modes and calculate the object hash. Returns the object hash on success,
978
877
 * otherwise NULL. Caller frees.
979
878
 */
980
 
static struct file_hash *calculate_object_hash(
981
 
        ARGS *args, struct mdfour *hash, int direct_mode)
 
879
static struct file_hash *
 
880
calculate_object_hash(struct args *args, struct mdfour *hash, int direct_mode)
982
881
{
983
882
        int i;
984
883
        char *manifest_name;
987
886
        struct file_hash *object_hash = NULL;
988
887
 
989
888
        /* first the arguments */
990
 
        for (i=1;i<args->argc;i++) {
 
889
        for (i = 1; i < args->argc; i++) {
991
890
                /* -L doesn't affect compilation. */
992
 
                if (i < args->argc-1 && strcmp(args->argv[i], "-L") == 0) {
 
891
                if (i < args->argc-1 && str_eq(args->argv[i], "-L")) {
993
892
                        i++;
994
893
                        continue;
995
894
                }
996
 
                if (strncmp(args->argv[i], "-L", 2) == 0) {
 
895
                if (str_startswith(args->argv[i], "-L")) {
997
896
                        continue;
998
897
                }
999
898
 
1000
899
                /* When using the preprocessor, some arguments don't contribute
1001
900
                   to the hash. The theory is that these arguments will change
1002
901
                   the output of -E if they are going to have any effect at
1003
 
                   all. */
1004
 
                if (!direct_mode) {
1005
 
                        if (i < args->argc-1) {
1006
 
                                if (strcmp(args->argv[i], "-D") == 0 ||
1007
 
                                    strcmp(args->argv[i], "-I") == 0 ||
1008
 
                                    strcmp(args->argv[i], "-U") == 0 ||
1009
 
                                    strcmp(args->argv[i], "-idirafter") == 0 ||
1010
 
                                    strcmp(args->argv[i], "-imacros") == 0 ||
1011
 
                                    strcmp(args->argv[i], "-imultilib") == 0 ||
1012
 
                                    strcmp(args->argv[i], "-include") == 0 ||
1013
 
                                    strcmp(args->argv[i], "-iprefix") == 0 ||
1014
 
                                    strcmp(args->argv[i], "-iquote") == 0 ||
1015
 
                                    strcmp(args->argv[i], "-isysroot") == 0 ||
1016
 
                                    strcmp(args->argv[i], "-isystem") == 0 ||
1017
 
                                    strcmp(args->argv[i], "-iwithprefix") == 0 ||
1018
 
                                    strcmp(args->argv[i], "-iwithprefixbefore") == 0 ||
1019
 
                                    strcmp(args->argv[i], "-nostdinc") == 0 ||
1020
 
                                    strcmp(args->argv[i], "-nostdinc++") == 0) {
1021
 
                                        /* Skip from hash. */
1022
 
                                        i++;
1023
 
                                        continue;
1024
 
                                }
 
902
                   all. For precompiled headers this might not be the case. */
 
903
                if (!direct_mode && !output_is_precompiled_header
 
904
                    && !using_precompiled_header) {
 
905
                        if (compopt_affects_cpp(args->argv[i])) {
 
906
                                i++;
 
907
                                continue;
1025
908
                        }
1026
 
                        if (strncmp(args->argv[i], "-D", 2) == 0 ||
1027
 
                            strncmp(args->argv[i], "-I", 2) == 0 ||
1028
 
                            strncmp(args->argv[i], "-U", 2) == 0) {
1029
 
                                /* Skip from hash. */
 
909
                        if (compopt_short(compopt_affects_cpp, args->argv[i])) {
1030
910
                                continue;
1031
911
                        }
1032
912
                }
1033
913
 
1034
 
                if (strncmp(args->argv[i], "--specs=", 8) == 0 &&
 
914
                if (str_startswith(args->argv[i], "--specs=") &&
1035
915
                    stat(args->argv[i] + 8, &st) == 0) {
1036
916
                        /* If given a explicit specs file, then hash that file,
1037
917
                           but don't include the path to it in the hash. */
1065
945
                }
1066
946
                if (result & HASH_SOURCE_CODE_FOUND_TIME) {
1067
947
                        cc_log("Disabling direct mode");
1068
 
                        enable_direct = 0;
 
948
                        enable_direct = false;
1069
949
                        return NULL;
1070
950
                }
1071
951
                manifest_name = hash_result(hash);
1072
952
                manifest_path = get_path_in_cache(manifest_name, ".manifest");
1073
953
                free(manifest_name);
1074
 
                cc_log("Looking for object file hash in %s",
1075
 
                       manifest_path);
 
954
                cc_log("Looking for object file hash in %s", manifest_path);
1076
955
                object_hash = manifest_get(manifest_path);
1077
956
                if (object_hash) {
1078
957
                        cc_log("Got object file hash from manifest");
1091
970
}
1092
971
 
1093
972
/*
1094
 
   try to return the compile result from cache. If we can return from
1095
 
   cache then this function exits with the correct status code,
1096
 
   otherwise it returns */
1097
 
static void from_cache(enum fromcache_call_mode mode, int put_object_in_manifest)
 
973
 * Try to return the compile result from cache. If we can return from cache
 
974
 * then this function exits with the correct status code, otherwise it returns.
 
975
 */
 
976
static void
 
977
from_cache(enum fromcache_call_mode mode, bool put_object_in_manifest)
1098
978
{
1099
979
        int fd_stderr;
1100
980
        int ret;
1101
981
        struct stat st;
1102
 
        int produce_dep_file;
 
982
        bool produce_dep_file;
1103
983
 
1104
984
        /* the user might be disabling cache hits */
1105
985
        if (mode != FROMCACHE_COMPILED_MODE && getenv("CCACHE_RECACHE")) {
1116
996
         * (If mode != FROMCACHE_DIRECT_MODE, the dependency file is created by
1117
997
         * gcc.)
1118
998
         */
1119
 
        produce_dep_file = \
1120
 
                generating_dependencies && mode == FROMCACHE_DIRECT_MODE;
 
999
        produce_dep_file = generating_dependencies && mode == FROMCACHE_DIRECT_MODE;
1121
1000
 
1122
1001
        /* If the dependency file should be in the cache, check that it is. */
1123
1002
        if (produce_dep_file && stat(cached_dep, &st) != 0) {
1125
1004
                return;
1126
1005
        }
1127
1006
 
1128
 
        if (strcmp(output_obj, "/dev/null") == 0) {
 
1007
        if (str_eq(output_obj, "/dev/null")) {
1129
1008
                ret = 0;
1130
1009
        } else {
1131
 
                unlink(output_obj);
 
1010
                x_unlink(output_obj);
1132
1011
                /* only make a hardlink if the cache file is uncompressed */
1133
 
                if (getenv("CCACHE_HARDLINK") &&
1134
 
                    test_if_compressed(cached_obj) == 0) {
 
1012
                if (getenv("CCACHE_HARDLINK") && !file_is_compressed(cached_obj)) {
1135
1013
                        ret = link(cached_obj, output_obj);
1136
1014
                } else {
1137
1015
                        ret = copy_file(cached_obj, output_obj, 0);
1141
1019
        if (ret == -1) {
1142
1020
                if (errno == ENOENT) {
1143
1021
                        /* Someone removed the file just before we began copying? */
1144
 
                        cc_log("Object file %s just disappeared from cache",
1145
 
                               cached_obj);
 
1022
                        cc_log("Object file %s just disappeared from cache", cached_obj);
1146
1023
                        stats_update(STATS_MISSING);
1147
1024
                } else {
1148
1025
                        cc_log("Failed to copy/link %s to %s (%s)",
1150
1027
                        stats_update(STATS_ERROR);
1151
1028
                        failed();
1152
1029
                }
1153
 
                unlink(output_obj);
1154
 
                unlink(cached_stderr);
1155
 
                unlink(cached_obj);
1156
 
                unlink(cached_dep);
 
1030
                x_unlink(output_obj);
 
1031
                x_unlink(cached_stderr);
 
1032
                x_unlink(cached_obj);
 
1033
                x_unlink(cached_dep);
1157
1034
                return;
1158
1035
        } else {
1159
1036
                cc_log("Created %s from %s", output_obj, cached_obj);
1160
1037
        }
1161
1038
 
1162
1039
        if (produce_dep_file) {
1163
 
                unlink(output_dep);
 
1040
                x_unlink(output_dep);
1164
1041
                /* only make a hardlink if the cache file is uncompressed */
1165
 
                if (getenv("CCACHE_HARDLINK") &&
1166
 
                    test_if_compressed(cached_dep) == 0) {
 
1042
                if (getenv("CCACHE_HARDLINK") && !file_is_compressed(cached_dep)) {
1167
1043
                        ret = link(cached_dep, output_dep);
1168
1044
                } else {
1169
1045
                        ret = copy_file(cached_dep, output_dep, 0);
1174
1050
                                 * Someone removed the file just before we
1175
1051
                                 * began copying?
1176
1052
                                 */
1177
 
                                cc_log("Dependency file %s just disappeared"
1178
 
                                       " from cache", output_obj);
 
1053
                                cc_log("Dependency file %s just disappeared from cache", output_obj);
1179
1054
                                stats_update(STATS_MISSING);
1180
1055
                        } else {
1181
1056
                                cc_log("Failed to copy/link %s to %s (%s)",
1184
1059
                                stats_update(STATS_ERROR);
1185
1060
                                failed();
1186
1061
                        }
1187
 
                        unlink(output_obj);
1188
 
                        unlink(output_dep);
1189
 
                        unlink(cached_stderr);
1190
 
                        unlink(cached_obj);
1191
 
                        unlink(cached_dep);
 
1062
                        x_unlink(output_obj);
 
1063
                        x_unlink(output_dep);
 
1064
                        x_unlink(cached_stderr);
 
1065
                        x_unlink(cached_obj);
 
1066
                        x_unlink(cached_dep);
1192
1067
                        return;
1193
1068
                } else {
1194
1069
                        cc_log("Created %s from %s", output_dep, cached_dep);
1216
1091
                }
1217
1092
        }
1218
1093
 
1219
 
        /* get rid of the intermediate preprocessor file */
1220
 
        if (i_tmpfile) {
1221
 
                if (!direct_i_file) {
1222
 
                        unlink(i_tmpfile);
1223
 
                }
1224
 
                free(i_tmpfile);
1225
 
                i_tmpfile = NULL;
1226
 
        }
1227
 
 
1228
 
        /* Delete the cpp stderr file if necessary. */
1229
 
        if (cpp_stderr) {
1230
 
                unlink(cpp_stderr);
1231
 
                free(cpp_stderr);
1232
 
                cpp_stderr = NULL;
1233
 
        }
1234
 
 
1235
1094
        /* Send the stderr, if any. */
1236
1095
        fd_stderr = open(cached_stderr, O_RDONLY | O_BINARY);
1237
1096
        if (fd_stderr != -1) {
1253
1112
                        cc_log("Added object file hash to %s", manifest_path);
1254
1113
                        update_mtime(manifest_path);
1255
1114
                        stat(manifest_path, &st);
1256
 
                        stats_update_size(
1257
 
                                STATS_NONE,
1258
 
                                (file_size(&st) - old_size) / 1024,
1259
 
                                old_size == 0 ? 1 : 0);
 
1115
                        stats_update_size(STATS_NONE,
 
1116
                                          (file_size(&st) - old_size) / 1024,
 
1117
                                          old_size == 0 ? 1 : 0);
1260
1118
                } else {
1261
1119
                        cc_log("Failed to add object file hash to %s", manifest_path);
1262
1120
                }
1285
1143
 
1286
1144
/* find the real compiler. We just search the PATH to find a executable of the
1287
1145
   same name that isn't a link to ourselves */
1288
 
static void find_compiler(int argc, char **argv)
 
1146
static void
 
1147
find_compiler(int argc, char **argv)
1289
1148
{
1290
1149
        char *base;
1291
1150
        char *path;
1296
1155
        base = basename(argv[0]);
1297
1156
 
1298
1157
        /* we might be being invoked like "ccache gcc -c foo.c" */
1299
 
        if (strcmp(base, MYNAME) == 0) {
 
1158
        if (same_executable_name(base, MYNAME)) {
1300
1159
                args_remove_first(orig_args);
1301
1160
                free(base);
1302
 
                if (strchr(argv[1],'/')) {
 
1161
                if (is_full_path(argv[1])) {
1303
1162
                        /* a full path was given */
1304
1163
                        return;
1305
1164
                }
1307
1166
        }
1308
1167
 
1309
1168
        /* support user override of the compiler */
1310
 
        if ((path=getenv("CCACHE_CC"))) {
 
1169
        if ((path = getenv("CCACHE_CC"))) {
1311
1170
                base = x_strdup(path);
1312
1171
        }
1313
1172
 
1318
1177
                stats_update(STATS_COMPILER);
1319
1178
                fatal("Could not find compiler \"%s\" in PATH", base);
1320
1179
        }
1321
 
        if (strcmp(compiler, argv[0]) == 0) {
1322
 
                fatal("Recursive invocation (the name of the ccache binary"
1323
 
                      " must be \"%s\")", MYNAME);
 
1180
        if (str_eq(compiler, argv[0])) {
 
1181
                fatal("Recursive invocation (the name of the ccache binary must be \"%s\")",
 
1182
                      MYNAME);
1324
1183
        }
1325
1184
        orig_args->argv[0] = compiler;
1326
1185
}
1327
1186
 
 
1187
bool
 
1188
is_precompiled_header(const char *path)
 
1189
{
 
1190
        return str_eq(get_extension(path), ".gch");
 
1191
}
 
1192
 
1328
1193
/*
1329
 
   process the compiler options to form the correct set of options
1330
 
   for obtaining the preprocessor output
1331
 
*/
1332
 
static void process_args(int argc, char **argv, ARGS **preprocessor_args,
1333
 
                         ARGS **compiler_args)
 
1194
 * Process the compiler options into options suitable for passing to the
 
1195
 * preprocessor and the real compiler. The preprocessor options don't include
 
1196
 * -E; this is added later. Returns true on success, otherwise false.
 
1197
 */
 
1198
bool
 
1199
cc_process_args(struct args *orig_args, struct args **preprocessor_args,
 
1200
                struct args **compiler_args)
1334
1201
{
1335
1202
        int i;
1336
 
        int found_c_opt = 0;
1337
 
        int found_S_opt = 0;
1338
 
        int found_arch_opt = 0;
 
1203
        bool found_c_opt = false;
 
1204
        bool found_S_opt = false;
 
1205
        bool found_arch_opt = false;
 
1206
        bool found_pch = false;
 
1207
        bool found_fpch_preprocess = false;
1339
1208
        const char *explicit_language = NULL; /* As specified with -x. */
1340
1209
        const char *file_language;            /* As deduced from file extension. */
1341
1210
        const char *actual_language;          /* Language to actually use. */
1342
1211
        const char *input_charset = NULL;
1343
1212
        struct stat st;
1344
1213
        /* is the dependency makefile name overridden with -MF? */
1345
 
        int dependency_filename_specified = 0;
 
1214
        bool dependency_filename_specified = false;
1346
1215
        /* is the dependency makefile target name specified with -MT or -MQ? */
1347
 
        int dependency_target_specified = 0;
1348
 
        ARGS *stripped_args;
 
1216
        bool dependency_target_specified = false;
 
1217
        struct args *stripped_args = NULL, *dep_args = NULL;
 
1218
        int argc = orig_args->argc;
 
1219
        char **argv = orig_args->argv;
 
1220
        bool result = true;
1349
1221
 
1350
1222
        stripped_args = args_init(0, NULL);
 
1223
        dep_args = args_init(0, NULL);
1351
1224
 
1352
1225
        args_add(stripped_args, argv[0]);
1353
1226
 
1354
 
        for (i=1; i<argc; i++) {
1355
 
                /* some options will never work ... */
1356
 
                if (strcmp(argv[i], "-E") == 0) {
1357
 
                        cc_log("Compiler option -E is unsupported");
1358
 
                        stats_update(STATS_UNSUPPORTED);
1359
 
                        failed();
 
1227
        for (i = 1; i < argc; i++) {
 
1228
                /* The user knows best: just swallow the next arg */
 
1229
                if (str_eq(argv[i], "--ccache-skip")) {
 
1230
                        i++;
 
1231
                        if (i == argc) {
 
1232
                                cc_log("--ccache-skip lacks an argument");
 
1233
                                result = false;
 
1234
                                goto out;
 
1235
                        }
 
1236
                        args_add(stripped_args, argv[i]);
 
1237
                        continue;
1360
1238
                }
1361
1239
 
1362
 
                /* these are too hard */
1363
 
                if (strncmp(argv[i], "@", 1) == 0 ||
1364
 
                    strcmp(argv[i], "--coverage") == 0 ||
1365
 
                    strcmp(argv[i], "-M") == 0 ||
1366
 
                    strcmp(argv[i], "-MM") == 0 ||
1367
 
                    strcmp(argv[i], "-fbranch-probabilities") == 0 ||
1368
 
                    strcmp(argv[i], "-fprofile-arcs") == 0 ||
1369
 
                    strcmp(argv[i], "-fprofile-generate") == 0 ||
1370
 
                    strcmp(argv[i], "-fprofile-use") == 0 ||
1371
 
                    strcmp(argv[i], "-frepo") == 0 ||
1372
 
                    strcmp(argv[i], "-ftest-coverage") == 0 ||
1373
 
                    strcmp(argv[i], "-save-temps") == 0) {
 
1240
                /* These are always too hard. */
 
1241
                if (compopt_too_hard(argv[i])
 
1242
                    || str_startswith(argv[i], "@")
 
1243
                    || str_startswith(argv[i], "-fdump-")) {
1374
1244
                        cc_log("Compiler option %s is unsupported", argv[i]);
1375
1245
                        stats_update(STATS_UNSUPPORTED);
1376
 
                        failed();
1377
 
                        continue;
 
1246
                        result = false;
 
1247
                        goto out;
1378
1248
                }
1379
1249
 
1380
1250
                /* These are too hard in direct mode. */
1381
1251
                if (enable_direct) {
1382
 
                        if (strcmp(argv[i], "-Xpreprocessor") == 0) {
1383
 
                                cc_log("Unsupported compiler option for direct"
1384
 
                                       " mode: %s", argv[i]);
1385
 
                                enable_direct = 0;
 
1252
                        if (compopt_too_hard_for_direct_mode(argv[i])) {
 
1253
                                cc_log("Unsupported compiler option for direct mode: %s", argv[i]);
 
1254
                                enable_direct = false;
1386
1255
                        }
1387
1256
                }
1388
1257
 
1389
1258
                /* Multiple -arch options are too hard. */
1390
 
                if (strcmp(argv[i], "-arch") == 0) {
 
1259
                if (str_eq(argv[i], "-arch")) {
1391
1260
                        if (found_arch_opt) {
1392
 
                                cc_log("More than one -arch compiler option"
1393
 
                                       " is unsupported");
 
1261
                                cc_log("More than one -arch compiler option is unsupported");
1394
1262
                                stats_update(STATS_UNSUPPORTED);
1395
 
                                failed();
 
1263
                                result = false;
 
1264
                                goto out;
1396
1265
                        } else {
1397
 
                                found_arch_opt = 1;
 
1266
                                found_arch_opt = true;
1398
1267
                        }
1399
1268
                }
1400
1269
 
 
1270
                if (str_eq(argv[i], "-fpch-preprocess")) {
 
1271
                        found_fpch_preprocess = true;
 
1272
                }
 
1273
 
1401
1274
                /* we must have -c */
1402
 
                if (strcmp(argv[i], "-c") == 0) {
 
1275
                if (str_eq(argv[i], "-c")) {
1403
1276
                        args_add(stripped_args, argv[i]);
1404
 
                        found_c_opt = 1;
 
1277
                        found_c_opt = true;
1405
1278
                        continue;
1406
1279
                }
1407
1280
 
1408
1281
                /* -S changes the default extension */
1409
 
                if (strcmp(argv[i], "-S") == 0) {
 
1282
                if (str_eq(argv[i], "-S")) {
1410
1283
                        args_add(stripped_args, argv[i]);
1411
 
                        found_S_opt = 1;
 
1284
                        found_S_opt = true;
1412
1285
                        continue;
1413
1286
                }
1414
1287
 
1416
1289
                 * Special handling for -x: remember the last specified language before the
1417
1290
                 * input file and strip all -x options from the arguments.
1418
1291
                 */
1419
 
                if (strcmp(argv[i], "-x") == 0) {
 
1292
                if (str_eq(argv[i], "-x")) {
1420
1293
                        if (i == argc-1) {
1421
1294
                                cc_log("Missing argument to %s", argv[i]);
1422
1295
                                stats_update(STATS_ARGS);
1423
 
                                failed();
 
1296
                                result = false;
 
1297
                                goto out;
1424
1298
                        }
1425
1299
                        if (!input_file) {
1426
1300
                                explicit_language = argv[i+1];
1428
1302
                        i++;
1429
1303
                        continue;
1430
1304
                }
1431
 
                if (strncmp(argv[i], "-x", 2) == 0) {
 
1305
                if (str_startswith(argv[i], "-x")) {
1432
1306
                        if (!input_file) {
1433
1307
                                explicit_language = &argv[i][2];
1434
1308
                        }
1436
1310
                }
1437
1311
 
1438
1312
                /* we need to work out where the output was meant to go */
1439
 
                if (strcmp(argv[i], "-o") == 0) {
 
1313
                if (str_eq(argv[i], "-o")) {
1440
1314
                        if (i == argc-1) {
1441
1315
                                cc_log("Missing argument to %s", argv[i]);
1442
1316
                                stats_update(STATS_ARGS);
1443
 
                                failed();
 
1317
                                result = false;
 
1318
                                goto out;
1444
1319
                        }
1445
1320
                        output_obj = argv[i+1];
1446
1321
                        i++;
1448
1323
                }
1449
1324
 
1450
1325
                /* alternate form of -o, with no space */
1451
 
                if (strncmp(argv[i], "-o", 2) == 0) {
 
1326
                if (str_startswith(argv[i], "-o")) {
1452
1327
                        output_obj = &argv[i][2];
1453
1328
                        continue;
1454
1329
                }
1456
1331
                /* debugging is handled specially, so that we know if we
1457
1332
                   can strip line number info
1458
1333
                */
1459
 
                if (strncmp(argv[i], "-g", 2) == 0) {
 
1334
                if (str_startswith(argv[i], "-g")) {
1460
1335
                        args_add(stripped_args, argv[i]);
1461
 
                        if (enable_unify && strcmp(argv[i], "-g0") != 0) {
1462
 
                                cc_log("%s used; disabling unify mode",
1463
 
                                       argv[i]);
1464
 
                                enable_unify = 0;
 
1336
                        if (enable_unify && !str_eq(argv[i], "-g0")) {
 
1337
                                cc_log("%s used; disabling unify mode", argv[i]);
 
1338
                                enable_unify = false;
1465
1339
                        }
1466
 
                        if (strcmp(argv[i], "-g3") == 0) {
 
1340
                        if (str_eq(argv[i], "-g3")) {
1467
1341
                                /*
1468
1342
                                 * Fix for bug 7190 ("commandline macros (-D)
1469
1343
                                 * have non-zero lineno when using -g3").
1470
1344
                                 */
1471
 
                                cc_log("%s used; not compiling preprocessed"
1472
 
                                       " code", argv[i]);
1473
 
                                compile_preprocessed_source_code = 0;
1474
 
                        }
1475
 
                        continue;
1476
 
                }
1477
 
 
1478
 
                /* The user knows best: just swallow the next arg */
1479
 
                if (strcmp(argv[i], "--ccache-skip") == 0) {
1480
 
                        i++;
1481
 
                        if (i == argc) {
1482
 
                                cc_log("--ccache-skip lacks an argument");
1483
 
                                failed();
1484
 
                        }
1485
 
                        args_add(stripped_args, argv[i]);
 
1345
                                cc_log("%s used; not compiling preprocessed code", argv[i]);
 
1346
                                compile_preprocessed_source_code = false;
 
1347
                        }
1486
1348
                        continue;
1487
1349
                }
1488
1350
 
1489
1351
                /* These options require special handling, because they
1490
1352
                   behave differently with gcc -E, when the output
1491
1353
                   file is not specified. */
1492
 
                if (strcmp(argv[i], "-MD") == 0
1493
 
                    || strcmp(argv[i], "-MMD") == 0) {
1494
 
                        generating_dependencies = 1;
 
1354
                if (str_eq(argv[i], "-MD") || str_eq(argv[i], "-MMD")) {
 
1355
                        generating_dependencies = true;
 
1356
                        args_add(dep_args, argv[i]);
 
1357
                        continue;
1495
1358
                }
1496
1359
                if (i < argc - 1) {
1497
 
                        if (strcmp(argv[i], "-MF") == 0) {
1498
 
                                dependency_filename_specified = 1;
1499
 
                                output_dep = make_relative_path(
1500
 
                                        x_strdup(argv[i + 1]));
1501
 
                        } else if (strcmp(argv[i], "-MQ") == 0
1502
 
                                   || strcmp(argv[i], "-MT") == 0) {
1503
 
                                dependency_target_specified = 1;
 
1360
                        if (str_startswith(argv[i], "-MF")) {
 
1361
                                char *arg;
 
1362
                                dependency_filename_specified = true;
 
1363
                                free(output_dep);
 
1364
                                args_add(dep_args, argv[i]);
 
1365
                                if (strlen(argv[i]) == 3) {
 
1366
                                        /* -MF arg */
 
1367
                                        arg = argv[i + 1];
 
1368
                                        args_add(dep_args, argv[i + 1]);
 
1369
                                        i++;
 
1370
                                } else {
 
1371
                                        /* -MFarg */
 
1372
                                        arg = &argv[i][3];
 
1373
                                }
 
1374
                                output_dep = make_relative_path(x_strdup(arg));
 
1375
                                continue;
 
1376
                        } else if (str_startswith(argv[i], "-MQ")
 
1377
                                   || str_startswith(argv[i], "-MT")) {
 
1378
                                dependency_target_specified = true;
 
1379
                                args_add(dep_args, argv[i]);
 
1380
                                if (strlen(argv[i]) == 3) {
 
1381
                                        /* -MQ arg or -MT arg */
 
1382
                                        args_add(dep_args, argv[i + 1]);
 
1383
                                        i++;
 
1384
                                }
 
1385
                                continue;
1504
1386
                        }
1505
1387
                }
1506
 
 
1507
 
                if (strncmp(argv[i], "-Wp,", 4) == 0) {
1508
 
                        if (strncmp(argv[i], "-Wp,-MD,", 8) == 0
1509
 
                            && !strchr(argv[i] + 8, ',')) {
1510
 
                                generating_dependencies = 1;
1511
 
                                dependency_filename_specified = 1;
1512
 
                                output_dep = make_relative_path(
1513
 
                                        x_strdup(argv[i] + 8));
1514
 
                        } else if (strncmp(argv[i], "-Wp,-MMD,", 9) == 0
1515
 
                            && !strchr(argv[i] + 9, ',')) {
1516
 
                                generating_dependencies = 1;
1517
 
                                dependency_filename_specified = 1;
1518
 
                                output_dep = make_relative_path(
1519
 
                                        x_strdup(argv[i] + 9));
 
1388
                if (str_startswith(argv[i], "-Wp,")) {
 
1389
                        if (str_startswith(argv[i], "-Wp,-MD,") && !strchr(argv[i] + 8, ',')) {
 
1390
                                generating_dependencies = true;
 
1391
                                dependency_filename_specified = true;
 
1392
                                free(output_dep);
 
1393
                                output_dep = make_relative_path(x_strdup(argv[i] + 8));
 
1394
                                args_add(dep_args, argv[i]);
 
1395
                                continue;
 
1396
                        } else if (str_startswith(argv[i], "-Wp,-MMD,")
 
1397
                                   && !strchr(argv[i] + 9, ',')) {
 
1398
                                generating_dependencies = true;
 
1399
                                dependency_filename_specified = true;
 
1400
                                free(output_dep);
 
1401
                                output_dep = make_relative_path(x_strdup(argv[i] + 9));
 
1402
                                args_add(dep_args, argv[i]);
 
1403
                                continue;
1520
1404
                        } else if (enable_direct) {
1521
1405
                                /*
1522
1406
                                 * -Wp, can be used to pass too hard options to
1523
1407
                                 * the preprocessor. Hence, disable direct
1524
1408
                                 * mode.
1525
1409
                                 */
1526
 
                                cc_log("Unsupported compiler option for direct mode: %s",
1527
 
                                       argv[i]);
1528
 
                                enable_direct = 0;
 
1410
                                cc_log("Unsupported compiler option for direct mode: %s", argv[i]);
 
1411
                                enable_direct = false;
1529
1412
                        }
1530
1413
                }
 
1414
                if (str_eq(argv[i], "-MP")) {
 
1415
                        args_add(dep_args, argv[i]);
 
1416
                        continue;
 
1417
                }
1531
1418
 
1532
1419
                /* Input charset needs to be handled specially. */
1533
 
                if (strncmp(argv[i], "-finput-charset=", 16) == 0) {
 
1420
                if (str_startswith(argv[i], "-finput-charset=")) {
1534
1421
                        input_charset = argv[i];
1535
1422
                        continue;
1536
1423
                }
1541
1428
                 * is that paths in the standard error output produced by the
1542
1429
                 * compiler will be normalized.
1543
1430
                 */
1544
 
                {
1545
 
                        const char *opts[] = {
1546
 
                                "-I", "-idirafter", "-imacros", "-include",
1547
 
                                "-iprefix", "-isystem", NULL
1548
 
                        };
1549
 
                        int j;
 
1431
                if (compopt_takes_path(argv[i])) {
1550
1432
                        char *relpath;
1551
 
                        for (j = 0; opts[j]; j++) {
1552
 
                                if (strcmp(argv[i], opts[j]) == 0) {
1553
 
                                        if (i == argc-1) {
1554
 
                                                cc_log("Missing argument to %s",
1555
 
                                                       argv[i]);
1556
 
                                                stats_update(STATS_ARGS);
1557
 
                                                failed();
1558
 
                                        }
1559
 
 
1560
 
                                        args_add(stripped_args, argv[i]);
1561
 
                                        relpath = make_relative_path(x_strdup(argv[i+1]));
1562
 
                                        args_add(stripped_args, relpath);
1563
 
                                        free(relpath);
1564
 
                                        i++;
1565
 
                                        break;
1566
 
                                }
1567
 
                        }
1568
 
                        if (opts[j]) {
1569
 
                                continue;
1570
 
                        }
 
1433
                        char *pchpath;
 
1434
                        if (i == argc-1) {
 
1435
                                cc_log("Missing argument to %s", argv[i]);
 
1436
                                stats_update(STATS_ARGS);
 
1437
                                result = false;
 
1438
                                goto out;
 
1439
                        }
 
1440
 
 
1441
                        args_add(stripped_args, argv[i]);
 
1442
                        relpath = make_relative_path(x_strdup(argv[i+1]));
 
1443
                        args_add(stripped_args, relpath);
 
1444
 
 
1445
                        /* Try to be smart about detecting precompiled headers */
 
1446
                        pchpath = format("%s.gch", argv[i+1]);
 
1447
                        if (stat(pchpath, &st) == 0) {
 
1448
                                cc_log("Detected use of precompiled header: %s", pchpath);
 
1449
                                found_pch = true;
 
1450
                        }
 
1451
 
 
1452
                        free(pchpath);
 
1453
                        free(relpath);
 
1454
                        i++;
 
1455
                        continue;
1571
1456
                }
1572
1457
 
1573
1458
                /* Same as above but options with concatenated argument. */
1574
 
                {
1575
 
                        const char *opts[] = {"-I", NULL};
1576
 
                        int j;
 
1459
                if (compopt_short(compopt_takes_path, argv[i])) {
1577
1460
                        char *relpath;
1578
1461
                        char *option;
1579
 
                        for (j = 0; opts[j]; j++) {
1580
 
                                if (strncmp(argv[i], opts[j], strlen(opts[j])) == 0) {
1581
 
                                        relpath = make_relative_path(
1582
 
                                                x_strdup(argv[i] + strlen(opts[j])));
1583
 
                                        x_asprintf(&option, "%s%s", opts[j], relpath);
1584
 
                                        args_add(stripped_args, option);
1585
 
                                        free(relpath);
1586
 
                                        free(option);
1587
 
                                        break;
1588
 
                                }
1589
 
                        }
1590
 
                        if (opts[j]) {
1591
 
                                continue;
1592
 
                        }
 
1462
                        relpath = make_relative_path(x_strdup(argv[i] + 2));
 
1463
                        option = format("-%c%s", argv[i][1], relpath);
 
1464
                        args_add(stripped_args, option);
 
1465
                        free(relpath);
 
1466
                        free(option);
 
1467
                        continue;
1593
1468
                }
1594
1469
 
1595
1470
                /* options that take an argument */
1596
 
                {
1597
 
                        const char *opts[] = {
1598
 
                                "--param",
1599
 
                                "-A",
1600
 
                                "-D",
1601
 
                                "-G",
1602
 
                                "-L",
1603
 
                                "-MF",
1604
 
                                "-MQ",
1605
 
                                "-MT",
1606
 
                                "-U",
1607
 
                                "-V",
1608
 
                                "-Xassembler",
1609
 
                                "-Xlinker",
1610
 
                                "-aux-info",
1611
 
                                "-b",
1612
 
                                "-iwithprefix",
1613
 
                                "-iwithprefixbefore",
1614
 
                                "-u",
1615
 
                                NULL
1616
 
                        };
1617
 
                        int j;
1618
 
                        for (j = 0; opts[j]; j++) {
1619
 
                                if (strcmp(argv[i], opts[j]) == 0) {
1620
 
                                        if (i == argc-1) {
1621
 
                                                cc_log("Missing argument to %s",
1622
 
                                                       argv[i]);
1623
 
                                                stats_update(STATS_ARGS);
1624
 
                                                failed();
1625
 
                                        }
1626
 
 
1627
 
                                        args_add(stripped_args, argv[i]);
1628
 
                                        args_add(stripped_args, argv[i+1]);
1629
 
                                        i++;
1630
 
                                        break;
1631
 
                                }
 
1471
                if (compopt_takes_arg(argv[i])) {
 
1472
                        if (i == argc-1) {
 
1473
                                cc_log("Missing argument to %s", argv[i]);
 
1474
                                stats_update(STATS_ARGS);
 
1475
                                result = false;
 
1476
                                goto out;
1632
1477
                        }
1633
 
                        if (opts[j]) continue;
 
1478
                        args_add(stripped_args, argv[i]);
 
1479
                        args_add(stripped_args, argv[i+1]);
 
1480
                        i++;
 
1481
                        continue;
1634
1482
                }
1635
1483
 
1636
1484
                /* other options */
1651
1499
 
1652
1500
                if (input_file) {
1653
1501
                        if (language_for_file(argv[i])) {
1654
 
                                cc_log("Multiple input files: %s and %s",
1655
 
                                       input_file, argv[i]);
 
1502
                                cc_log("Multiple input files: %s and %s", input_file, argv[i]);
1656
1503
                                stats_update(STATS_MULTIPLE);
1657
1504
                        } else if (!found_c_opt) {
1658
1505
                                cc_log("Called for link with %s", argv[i]);
1665
1512
                                cc_log("Unsupported source extension: %s", argv[i]);
1666
1513
                                stats_update(STATS_SOURCELANG);
1667
1514
                        }
1668
 
                        failed();
 
1515
                        result = false;
 
1516
                        goto out;
1669
1517
                }
1670
1518
 
1671
1519
                /* Rewrite to relative to increase hit rate. */
1675
1523
        if (!input_file) {
1676
1524
                cc_log("No input file found");
1677
1525
                stats_update(STATS_NOINPUT);
1678
 
                failed();
 
1526
                result = false;
 
1527
                goto out;
1679
1528
        }
1680
1529
 
1681
 
        if (!found_c_opt) {
1682
 
                cc_log("No -c option found");
1683
 
                /* I find that having a separate statistic for autoconf tests is useful,
1684
 
                   as they are the dominant form of "called for link" in many cases */
1685
 
                if (strstr(input_file, "conftest.")) {
1686
 
                        stats_update(STATS_CONFTEST);
1687
 
                } else {
1688
 
                        stats_update(STATS_LINK);
 
1530
        if (found_pch || found_fpch_preprocess) {
 
1531
                using_precompiled_header = true;
 
1532
                if (!(sloppiness & SLOPPY_TIME_MACROS)) {
 
1533
                        cc_log("You have to specify \"time_macros\" sloppiness when using"
 
1534
                               " precompiled headers to get direct hits");
 
1535
                        cc_log("Disabling direct mode");
 
1536
                        stats_update(STATS_CANTUSEPCH);
 
1537
                        result = false;
 
1538
                        goto out;
1689
1539
                }
1690
 
                failed();
1691
1540
        }
1692
1541
 
1693
 
        if (explicit_language && strcmp(explicit_language, "none") == 0) {
 
1542
        if (explicit_language && str_eq(explicit_language, "none")) {
1694
1543
                explicit_language = NULL;
1695
1544
        }
1696
1545
        file_language = language_for_file(input_file);
1698
1547
                if (!language_is_supported(explicit_language)) {
1699
1548
                        cc_log("Unsupported language: %s", explicit_language);
1700
1549
                        stats_update(STATS_SOURCELANG);
1701
 
                        failed();
 
1550
                        result = false;
 
1551
                        goto out;
1702
1552
                }
1703
1553
                actual_language = explicit_language;
1704
1554
        } else {
1705
1555
                actual_language = file_language;
1706
1556
        }
 
1557
 
 
1558
        output_is_precompiled_header =
 
1559
                actual_language && strstr(actual_language, "-header") != NULL;
 
1560
 
 
1561
        if (!found_c_opt && !output_is_precompiled_header) {
 
1562
                cc_log("No -c option found");
 
1563
                /* I find that having a separate statistic for autoconf tests is useful,
 
1564
                   as they are the dominant form of "called for link" in many cases */
 
1565
                if (strstr(input_file, "conftest.")) {
 
1566
                        stats_update(STATS_CONFTEST);
 
1567
                } else {
 
1568
                        stats_update(STATS_LINK);
 
1569
                }
 
1570
                result = false;
 
1571
                goto out;
 
1572
        }
 
1573
 
1707
1574
        if (!actual_language) {
1708
1575
                cc_log("Unsupported source extension: %s", input_file);
1709
1576
                stats_update(STATS_SOURCELANG);
1710
 
                failed();
 
1577
                result = false;
 
1578
                goto out;
1711
1579
        }
 
1580
 
1712
1581
        direct_i_file = language_is_preprocessed(actual_language);
1713
1582
 
 
1583
        if (output_is_precompiled_header) {
 
1584
                /* It doesn't work to create the .gch from preprocessed source. */
 
1585
                cc_log("Creating precompiled header; not compiling preprocessed code");
 
1586
                compile_preprocessed_source_code = false;
 
1587
        }
 
1588
 
1714
1589
        i_extension = getenv("CCACHE_EXTENSION");
1715
1590
        if (!i_extension) {
1716
1591
                const char *p_language = p_language_for_language(actual_language);
1718
1593
        }
1719
1594
 
1720
1595
        /* don't try to second guess the compilers heuristics for stdout handling */
1721
 
        if (output_obj && strcmp(output_obj, "-") == 0) {
 
1596
        if (output_obj && str_eq(output_obj, "-")) {
1722
1597
                stats_update(STATS_OUTSTDOUT);
1723
1598
                cc_log("Output file is -");
1724
 
                failed();
 
1599
                result = false;
 
1600
                goto out;
1725
1601
        }
1726
1602
 
1727
1603
        if (!output_obj) {
1728
 
                char *p;
1729
 
                output_obj = x_strdup(input_file);
1730
 
                if ((p = strrchr(output_obj, '/'))) {
1731
 
                        output_obj = p+1;
1732
 
                }
1733
 
                p = strrchr(output_obj, '.');
1734
 
                if (!p || !p[1]) {
1735
 
                        cc_log("Badly formed object filename");
1736
 
                        stats_update(STATS_ARGS);
1737
 
                        failed();
1738
 
                }
1739
 
                p[1] = found_S_opt ? 's' : 'o';
1740
 
                p[2] = 0;
1741
 
        }
1742
 
 
1743
 
        /* If dependencies are generated, configure the preprocessor */
1744
 
 
1745
 
        if (generating_dependencies) {
1746
 
                if (!dependency_filename_specified) {
1747
 
                        char *default_depfile_name;
1748
 
                        char *base_name;
1749
 
 
1750
 
                        base_name = remove_extension(output_obj);
1751
 
                        x_asprintf(&default_depfile_name, "%s.d", base_name);
1752
 
                        free(base_name);
1753
 
                        args_add(stripped_args, "-MF");
1754
 
                        args_add(stripped_args, default_depfile_name);
1755
 
                        output_dep = make_relative_path(
1756
 
                                x_strdup(default_depfile_name));
1757
 
                }
1758
 
 
1759
 
                if (!dependency_target_specified) {
1760
 
                        args_add(stripped_args, "-MT");
1761
 
                        args_add(stripped_args, output_obj);
 
1604
                if (output_is_precompiled_header) {
 
1605
                        output_obj = format("%s.gch", input_file);
 
1606
                } else {
 
1607
                        char *p;
 
1608
                        output_obj = x_strdup(input_file);
 
1609
                        if ((p = strrchr(output_obj, '/'))) {
 
1610
                                output_obj = p+1;
 
1611
                        }
 
1612
                        p = strrchr(output_obj, '.');
 
1613
                        if (!p || !p[1]) {
 
1614
                                cc_log("Badly formed object filename");
 
1615
                                stats_update(STATS_ARGS);
 
1616
                                result = false;
 
1617
                                goto out;
 
1618
                        }
 
1619
                        p[1] = found_S_opt ? 's' : 'o';
 
1620
                        p[2] = 0;
1762
1621
                }
1763
1622
        }
1764
1623
 
1765
1624
        /* cope with -o /dev/null */
1766
 
        if (strcmp(output_obj,"/dev/null") != 0
 
1625
        if (!str_eq(output_obj,"/dev/null")
1767
1626
            && stat(output_obj, &st) == 0
1768
1627
            && !S_ISREG(st.st_mode)) {
1769
1628
                cc_log("Not a regular file: %s", output_obj);
1770
1629
                stats_update(STATS_DEVICE);
1771
 
                failed();
 
1630
                result = false;
 
1631
                goto out;
1772
1632
        }
1773
1633
 
1774
1634
        /*
1782
1642
        if (input_charset) {
1783
1643
                args_add(*preprocessor_args, input_charset);
1784
1644
        }
 
1645
        if (found_pch) {
 
1646
                args_add(*preprocessor_args, "-fpch-preprocess");
 
1647
        }
1785
1648
        if (explicit_language) {
1786
1649
                args_add(*preprocessor_args, "-x");
1787
1650
                args_add(*preprocessor_args, explicit_language);
1788
1651
        }
 
1652
 
 
1653
        /*
 
1654
         * Add flags for dependency generation only to the preprocessor command line.
 
1655
         */
 
1656
        if (generating_dependencies) {
 
1657
                if (!dependency_filename_specified) {
 
1658
                        char *default_depfile_name;
 
1659
                        char *base_name;
 
1660
 
 
1661
                        base_name = remove_extension(output_obj);
 
1662
                        default_depfile_name = format("%s.d", base_name);
 
1663
                        free(base_name);
 
1664
                        args_add(dep_args, "-MF");
 
1665
                        args_add(dep_args, default_depfile_name);
 
1666
                        output_dep = make_relative_path(x_strdup(default_depfile_name));
 
1667
                }
 
1668
 
 
1669
                if (!dependency_target_specified) {
 
1670
                        args_add(dep_args, "-MT");
 
1671
                        args_add(dep_args, output_obj);
 
1672
                }
 
1673
        }
 
1674
 
1789
1675
        if (compile_preprocessed_source_code) {
1790
1676
                *compiler_args = args_copy(stripped_args);
1791
1677
                if (explicit_language) {
1800
1686
        } else {
1801
1687
                *compiler_args = args_copy(*preprocessor_args);
1802
1688
        }
 
1689
 
 
1690
        /*
 
1691
         * Only pass dependency arguments to the preprocesor since Intel's C++
 
1692
         * compiler doesn't produce a correct .d file when compiling preprocessed
 
1693
         * source.
 
1694
         */
 
1695
        args_extend(*preprocessor_args, dep_args);
 
1696
 
 
1697
out:
1803
1698
        args_free(stripped_args);
1804
 
}
1805
 
 
1806
 
static unsigned parse_sloppiness(char *p)
 
1699
        args_free(dep_args);
 
1700
        return result;
 
1701
}
 
1702
 
 
1703
/* Reset the global state. Used by the test suite. */
 
1704
void
 
1705
cc_reset(void)
 
1706
{
 
1707
        free(current_working_dir); current_working_dir = NULL;
 
1708
        free(cache_dir); cache_dir = NULL;
 
1709
        cache_logfile = NULL;
 
1710
        base_dir = NULL;
 
1711
        args_free(orig_args); orig_args = NULL;
 
1712
        free(input_file); input_file = NULL;
 
1713
        output_obj = NULL;
 
1714
        free(output_dep); output_dep = NULL;
 
1715
        free(cached_obj_hash); cached_obj_hash = NULL;
 
1716
        free(cached_obj); cached_obj = NULL;
 
1717
        free(cached_stderr); cached_stderr = NULL;
 
1718
        free(cached_dep); cached_dep = NULL;
 
1719
        free(manifest_path); manifest_path = NULL;
 
1720
        time_of_compilation = 0;
 
1721
        sloppiness = false;
 
1722
        if (included_files) {
 
1723
                hashtable_destroy(included_files, 1); included_files = NULL;
 
1724
        }
 
1725
        generating_dependencies = false;
 
1726
        i_extension = NULL;
 
1727
        i_tmpfile = NULL;
 
1728
        direct_i_file = false;
 
1729
        free(cpp_stderr); cpp_stderr = NULL;
 
1730
        free(stats_file); stats_file = NULL;
 
1731
        enable_unify = false;
 
1732
        enable_direct = true;
 
1733
        enable_compression = false;
 
1734
        nlevels = 2;
 
1735
        compile_preprocessed_source_code = false;
 
1736
        output_is_precompiled_header = false;
 
1737
}
 
1738
 
 
1739
static unsigned
 
1740
parse_sloppiness(char *p)
1807
1741
{
1808
1742
        unsigned result = 0;
1809
 
        char *word, *q;
 
1743
        char *word, *q, *saveptr = NULL;
1810
1744
 
1811
1745
        if (!p) {
1812
1746
                return result;
1813
1747
        }
1814
1748
        p = x_strdup(p);
1815
1749
        q = p;
1816
 
        while ((word = strtok(q, ", "))) {
1817
 
                if (strcmp(word, "file_macro") == 0) {
 
1750
        while ((word = strtok_r(q, ", ", &saveptr))) {
 
1751
                if (str_eq(word, "file_macro")) {
1818
1752
                        cc_log("Being sloppy about __FILE__");
1819
1753
                        result |= SLOPPY_FILE_MACRO;
1820
1754
                }
1821
 
                if (strcmp(word, "include_file_mtime") == 0) {
 
1755
                if (str_eq(word, "include_file_mtime")) {
1822
1756
                        cc_log("Being sloppy about include file mtime");
1823
1757
                        result |= SLOPPY_INCLUDE_FILE_MTIME;
1824
1758
                }
1825
 
                if (strcmp(word, "time_macros") == 0) {
 
1759
                if (str_eq(word, "time_macros")) {
1826
1760
                        cc_log("Being sloppy about __DATE__ and __TIME__");
1827
1761
                        result |= SLOPPY_TIME_MACROS;
1828
1762
                }
1833
1767
}
1834
1768
 
1835
1769
/* the main ccache driver function */
1836
 
static void ccache(int argc, char *argv[])
 
1770
static void
 
1771
ccache(int argc, char *argv[])
1837
1772
{
1838
 
        int put_object_in_manifest = 0;
 
1773
        bool put_object_in_manifest = false;
1839
1774
        struct file_hash *object_hash;
1840
1775
        struct file_hash *object_hash_from_manifest = NULL;
1841
1776
        char *env;
1844
1779
        struct mdfour cpp_hash;
1845
1780
 
1846
1781
        /* Arguments (except -E) to send to the preprocessor. */
1847
 
        ARGS *preprocessor_args;
 
1782
        struct args *preprocessor_args;
1848
1783
 
1849
1784
        /* Arguments to send to the real compiler. */
1850
 
        ARGS *compiler_args;
 
1785
        struct args *compiler_args;
1851
1786
 
1852
1787
        find_compiler(argc, argv);
1853
1788
 
1867
1802
 
1868
1803
        if (getenv("CCACHE_UNIFY")) {
1869
1804
                cc_log("Unify mode disabled");
1870
 
                enable_unify = 1;
 
1805
                enable_unify = true;
1871
1806
        }
1872
1807
 
1873
1808
        if (getenv("CCACHE_NODIRECT") || enable_unify) {
1874
1809
                cc_log("Direct mode disabled");
1875
 
                enable_direct = 0;
 
1810
                enable_direct = false;
1876
1811
        }
1877
1812
 
1878
1813
        if (getenv("CCACHE_COMPRESS")) {
1879
1814
                cc_log("Compression enabled");
1880
 
                enable_compression = 1;
 
1815
                enable_compression = true;
1881
1816
        }
1882
1817
 
1883
1818
        if ((env = getenv("CCACHE_NLEVELS"))) {
1886
1821
                if (nlevels > 8) nlevels = 8;
1887
1822
        }
1888
1823
 
1889
 
        /*
1890
 
         * Process argument list, returning a new set of arguments to pass to
1891
 
         * the preprocessor and the real compiler.
1892
 
         */
1893
 
        process_args(orig_args->argc, orig_args->argv, &preprocessor_args,
1894
 
                     &compiler_args);
 
1824
        if (!cc_process_args(orig_args, &preprocessor_args, &compiler_args)) {
 
1825
                failed();
 
1826
        }
1895
1827
 
1896
1828
        cc_log("Source file: %s", input_file);
1897
1829
        if (generating_dependencies) {
1906
1838
        direct_hash = common_hash;
1907
1839
        if (enable_direct) {
1908
1840
                cc_log("Trying direct lookup");
1909
 
                object_hash = calculate_object_hash(
1910
 
                        preprocessor_args, &direct_hash, 1);
 
1841
                object_hash = calculate_object_hash(preprocessor_args, &direct_hash, 1);
1911
1842
                if (object_hash) {
1912
1843
                        update_cached_result_globals(object_hash);
1913
1844
 
1922
1853
                         * However, the object was already found in manifest,
1923
1854
                         * so don't readd it later.
1924
1855
                         */
1925
 
                        put_object_in_manifest = 0;
 
1856
                        put_object_in_manifest = false;
1926
1857
 
1927
1858
                        object_hash_from_manifest = object_hash;
1928
1859
                } else {
1929
1860
                        /* Add object to manifest later. */
1930
 
                        put_object_in_manifest = 1;
 
1861
                        put_object_in_manifest = true;
1931
1862
                }
1932
1863
        }
1933
1864
 
1963
1894
                cc_log("Hash from manifest doesn't match preprocessor output");
1964
1895
                cc_log("Likely reason: different CCACHE_BASEDIRs used");
1965
1896
                cc_log("Removing manifest as a safety measure");
1966
 
                unlink(manifest_path);
 
1897
                x_unlink(manifest_path);
1967
1898
 
1968
 
                put_object_in_manifest = 1;
 
1899
                put_object_in_manifest = true;
1969
1900
        }
1970
1901
 
1971
1902
        /* if we can return from cache at this point then do */
1980
1911
        if (env) {
1981
1912
                char *p = find_executable(env, MYNAME);
1982
1913
                if (!p) {
1983
 
                        perror(env);
1984
 
                        exit(1);
 
1914
                        fatal("%s: %s", env, strerror(errno));
1985
1915
                }
1986
1916
                cc_log("Using command-line prefix %s", env);
1987
1917
                args_add_prefix(compiler_args, p);
1999
1929
        failed();
2000
1930
}
2001
1931
 
2002
 
static void check_cache_dir(void)
 
1932
static void
 
1933
check_cache_dir(void)
2003
1934
{
2004
1935
        if (!cache_dir) {
2005
1936
                fatal("Unable to determine cache directory");
2007
1938
}
2008
1939
 
2009
1940
/* the main program when not doing a compile */
2010
 
static int ccache_main(int argc, char *argv[])
 
1941
static int
 
1942
ccache_main_options(int argc, char *argv[])
2011
1943
{
2012
1944
        int c;
2013
1945
        size_t v;
2014
1946
 
2015
 
        static const struct option long_options[] = {
 
1947
        static const struct option options[] = {
2016
1948
                {"show-stats", no_argument,       0, 's'},
2017
1949
                {"zero-stats", no_argument,       0, 'z'},
2018
1950
                {"cleanup",    no_argument,       0, 'c'},
2023
1955
                {"version",    no_argument,       0, 'V'},
2024
1956
                {0, 0, 0, 0}
2025
1957
        };
2026
 
        int option_index = 0;
2027
1958
 
2028
 
        while ((c = getopt_long(argc, argv, "hszcCF:M:V", long_options, &option_index)) != -1) {
 
1959
        while ((c = getopt_long(argc, argv, "hszcCF:M:V", options, NULL)) != -1) {
2029
1960
                switch (c) {
2030
1961
                case 'V':
2031
1962
                        fprintf(stdout, VERSION_TEXT, CCACHE_VERSION);
2081
2012
                                        printf("Unset cache size limit\n");
2082
2013
                                } else {
2083
2014
                                        char *s = format_size(v);
2084
 
                                        printf("Set cache size limit to %s\n",
2085
 
                                               s);
 
2015
                                        printf("Set cache size limit to %s\n", s);
2086
2016
                                        free(s);
2087
2017
                                }
2088
2018
                        } else {
2103
2033
 
2104
2034
/* Make a copy of stderr that will not be cached, so things like
2105
2035
   distcc can send networking errors to it. */
2106
 
static void setup_uncached_err(void)
 
2036
static void
 
2037
setup_uncached_err(void)
2107
2038
{
2108
2039
        char *buf;
2109
2040
        int uncached_fd;
2115
2046
        }
2116
2047
 
2117
2048
        /* leak a pointer to the environment */
2118
 
        x_asprintf(&buf, "UNCACHED_ERR_FD=%d", uncached_fd);
 
2049
        buf = format("UNCACHED_ERR_FD=%d", uncached_fd);
2119
2050
 
2120
2051
        if (putenv(buf) == -1) {
2121
2052
                cc_log("putenv failed");
2123
2054
        }
2124
2055
}
2125
2056
 
2126
 
 
2127
 
int main(int argc, char *argv[])
 
2057
int
 
2058
ccache_main(int argc, char *argv[])
2128
2059
{
2129
2060
        char *p;
2130
2061
        char *program_name;
2131
2062
 
 
2063
        exitfn_init();
 
2064
        exitfn_add_nullary(stats_flush);
 
2065
        exitfn_add_nullary(clean_up_tmp_files);
 
2066
 
2132
2067
        /* check for logging early so cc_log messages start working ASAP */
2133
2068
        cache_logfile = getenv("CCACHE_LOGFILE");
2134
2069
        cc_log("=== CCACHE STARTED =========================================");
2146
2081
 
2147
2082
        current_working_dir = get_cwd();
2148
2083
        cache_dir = getenv("CCACHE_DIR");
2149
 
        if (!cache_dir) {
 
2084
        if (cache_dir) {
 
2085
                cache_dir = x_strdup(cache_dir);
 
2086
        } else {
2150
2087
                const char *home_directory = get_home_directory();
2151
2088
                if (home_directory) {
2152
 
                        x_asprintf(&cache_dir, "%s/.ccache", home_directory);
 
2089
                        cache_dir = format("%s/.ccache", home_directory);
2153
2090
                }
2154
2091
        }
2155
2092
 
2156
2093
        /* check if we are being invoked as "ccache" */
2157
2094
        program_name = basename(argv[0]);
2158
 
        if (strcmp(program_name, MYNAME) == 0) {
 
2095
        if (same_executable_name(program_name, MYNAME)) {
2159
2096
                if (argc < 2) {
2160
2097
                        fputs(USAGE_TEXT, stderr);
2161
2098
                        exit(1);
2163
2100
                /* if the first argument isn't an option, then assume we are
2164
2101
                   being passed a compiler name and options */
2165
2102
                if (argv[1][0] == '-') {
2166
 
                        return ccache_main(argc, argv);
 
2103
                        return ccache_main_options(argc, argv);
2167
2104
                }
2168
2105
        }
2169
2106
        free(program_name);
2172
2109
 
2173
2110
        temp_dir = getenv("CCACHE_TEMPDIR");
2174
2111
        if (!temp_dir) {
2175
 
                x_asprintf(&temp_dir, "%s/tmp", cache_dir);
 
2112
                temp_dir = format("%s/tmp", cache_dir);
2176
2113
        }
2177
2114
 
2178
2115
        base_dir = getenv("CCACHE_BASEDIR");
2187
2124
 
2188
2125
        /* make sure the cache dir exists */
2189
2126
        if (create_dir(cache_dir) != 0) {
2190
 
                fprintf(stderr,"ccache: failed to create %s (%s)\n",
2191
 
                        cache_dir, strerror(errno));
 
2127
                fprintf(stderr,
 
2128
                        "ccache: failed to create %s (%s)\n",
 
2129
                        cache_dir, strerror(errno));
2192
2130
                exit(1);
2193
2131
        }
2194
2132
 
2195
2133
        /* make sure the temp dir exists */
2196
2134
        if (create_dir(temp_dir) != 0) {
2197
 
                fprintf(stderr,"ccache: failed to create %s (%s)\n",
2198
 
                        temp_dir, strerror(errno));
 
2135
                fprintf(stderr,
 
2136
                        "ccache: failed to create %s (%s)\n",
 
2137
                        temp_dir, strerror(errno));
2199
2138
                exit(1);
2200
2139
        }
2201
2140
 
2202
2141
        if (!getenv("CCACHE_READONLY")) {
2203
2142
                if (create_cachedirtag(cache_dir) != 0) {
2204
 
                        fprintf(stderr,"ccache: failed to create %s/CACHEDIR.TAG (%s)\n",
2205
 
                                cache_dir, strerror(errno));
 
2143
                        fprintf(stderr,
 
2144
                                "ccache: failed to create %s/CACHEDIR.TAG (%s)\n",
 
2145
                                cache_dir, strerror(errno));
2206
2146
                        exit(1);
2207
2147
                }
2208
2148
        }