import source from 1.3.40
[external/swig.git] / CCache / ccache.c
1 /*
2   a re-implementation of the compilercache scripts in C
3
4   The idea is based on the shell-script compilercache by Erik Thiele <erikyyy@erikyyy.de>
5
6    Copyright (C) Andrew Tridgell 2002
7    Copyright (C) Martin Pool 2003
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "ccache.h"
25
26 /* verbose mode */
27 int ccache_verbose = 0;
28
29 /* the base cache directory */
30 char *cache_dir = NULL;
31
32 /* the directory for temporary files */
33 static char *temp_dir = NULL;
34
35 /* the debug logfile name, if set */
36 char *cache_logfile = NULL;
37
38 /* the argument list after processing */
39 static ARGS *stripped_args;
40
41 /* the original argument list */
42 static ARGS *orig_args;
43
44 /* the output filename being compiled to */
45 static char *output_file;
46
47 /* the source file */
48 static char *input_file;
49
50 /* the name of the file containing the cached object code */
51 static char *hashname;
52
53 /* the extension of the file after pre-processing */
54 static const char *i_extension;
55
56 /* the name of the temporary pre-processor file */
57 static char *i_tmpfile;
58
59 /* are we compiling a .i or .ii file directly? */
60 static int direct_i_file;
61
62 /* the name of the cpp stderr file */
63 static char *cpp_stderr;
64
65 /* the name of the statistics file */
66 char *stats_file = NULL;
67
68 /* can we safely use the unification hashing backend? */
69 static int enable_unify;
70
71 /* should we strip -c when running the preprocessor only? */
72 static int strip_c_option;
73
74 /* customisation for using the SWIG compiler */
75 static int swig;
76
77 /* a list of supported file extensions, and the equivalent
78    extension for code that has been through the pre-processor
79 */
80 static struct {
81         char *extension;
82         char *i_extension;
83 } extensions[] = {
84         {"c", "i"},
85         {"C", "ii"},
86         {"m", "mi"},
87         {"cc", "ii"},
88         {"CC", "ii"},
89         {"cpp", "ii"},
90         {"CPP", "ii"},
91         {"cxx", "ii"},
92         {"CXX", "ii"},
93         {"c++", "ii"},
94         {"C++", "ii"},
95         {"i", "i"},
96         {"ii", "ii"},
97         {NULL, NULL}};
98
99 /*
100   something went badly wrong - just execute the real compiler
101 */
102 static void failed(void)
103 {
104         char *e;
105
106         /* delete intermediate pre-processor file if needed */
107         if (i_tmpfile) {
108                 if (!direct_i_file) {
109                         unlink(i_tmpfile);
110                 }
111                 free(i_tmpfile);
112                 i_tmpfile = NULL;
113         }
114
115         /* delete the cpp stderr file if necessary */
116         if (cpp_stderr) {
117                 unlink(cpp_stderr);
118                 free(cpp_stderr);
119                 cpp_stderr = NULL;
120         }
121
122         /* strip any local args */
123         args_strip(orig_args, "--ccache-");
124
125         if ((e=getenv("CCACHE_PREFIX"))) {
126                 char *p = find_executable(e, MYNAME);
127                 if (!p) {
128                         cc_log("could not find executable (%s)\n", e);
129                         perror(e);
130                         exit(1);
131                 }
132                 args_add_prefix(orig_args, p);
133         }
134
135         if (ccache_verbose) {
136                 display_execute_args(orig_args->argv);
137         }
138
139         if (swig) {
140                 putenv("CCACHE_OUTFILES");
141         }
142
143 #ifndef _WIN32
144         execv(orig_args->argv[0], orig_args->argv);
145         cc_log("execv returned (%s)!\n", strerror(errno));
146         perror(orig_args->argv[0]);
147         exit(1);
148 #else
149         /* execv on Windows causes the 'non-regular' testcase to fail, so use Win32 API instead */
150         {
151                 PROCESS_INFORMATION pinfo; 
152                 STARTUPINFO sinfo;
153                 BOOL ret; 
154                 DWORD exitcode;
155                 char *args;
156
157                 ZeroMemory(&pinfo, sizeof(PROCESS_INFORMATION));
158                 ZeroMemory(&sinfo, sizeof(STARTUPINFO));
159                 sinfo.cb = sizeof(STARTUPINFO); 
160                 args = argvtos(orig_args->argv);
161                 ret = CreateProcessA(orig_args->argv[0], args, NULL, NULL, TRUE, 0, NULL, NULL,
162                                      &sinfo, &pinfo);
163                 if (!ret) {
164                         exitcode = 1;
165                         cc_log("CreateProcessA failed starting %s\n", orig_args->argv[0]);
166                         perror_win32(orig_args->argv[0]);
167                 } else {
168                         WaitForSingleObject(pinfo.hProcess, INFINITE);
169                         GetExitCodeProcess(pinfo.hProcess, &exitcode);
170                         CloseHandle(pinfo.hProcess);
171                         CloseHandle(pinfo.hThread);
172                 }
173                 free(args);
174                 exit(exitcode);
175         }
176 #endif
177 }
178
179
180 /* return a string to be used to distinguish temporary files 
181    this also tries to cope with NFS by adding the local hostname 
182 */
183 static const char *tmp_string(void)
184 {
185         static char *ret;
186
187         if (!ret) {
188                 char hostname[200];
189                 strcpy(hostname, "unknown");
190 #if HAVE_GETHOSTNAME
191                 gethostname(hostname, sizeof(hostname)-1);
192 #endif
193                 hostname[sizeof(hostname)-1] = 0;
194                 if (asprintf(&ret, "%s.%u", hostname, (unsigned)getpid()) == -1) {
195                         fatal("could not allocate tmp_string");
196                 }
197         }
198
199         return ret;
200 }
201
202 /* update cached file sizes and count helper function for to_cache() */
203 static void to_cache_stats_helper(struct stat *pstat, char *cached_filename, char *tmp_outfiles, int *files_size, int *cached_files_count)
204 {
205 #if ENABLE_ZLIB
206         /* do an extra stat on the cache file for the size statistics */
207         if (stat(cached_filename, pstat) != 0) {
208                 cc_log("failed to stat cache files - %s\n", strerror(errno));
209                 stats_update(STATS_ERROR);
210                 if (tmp_outfiles) {
211                         unlink(tmp_outfiles);
212                 }
213                 failed();
214         }
215 #else
216         (void)cached_filename;
217         (void)tmp_outfiles;
218 #endif
219         (*files_size) += file_size(pstat);
220         (*cached_files_count)++;
221 }
222
223 /* run the real compiler and put the result in cache */
224 static void to_cache(ARGS *args)
225 {
226         char *path_stderr;
227         char *tmp_stdout, *tmp_stderr, *tmp_outfiles;
228         struct stat st1;
229         int status;
230         int cached_files_count = 0;
231         int files_size = 0;
232
233         x_asprintf(&tmp_stdout, "%s/tmp.stdout.%s", temp_dir, tmp_string());
234         x_asprintf(&tmp_stderr, "%s/tmp.stderr.%s", temp_dir, tmp_string());
235         x_asprintf(&tmp_outfiles, "%s/tmp.outfiles.%s", temp_dir, tmp_string());
236
237         if (strip_c_option && !swig) {
238                 args_add(stripped_args, "-c");
239         }
240
241         if (output_file) {
242                 args_add(args, "-o");
243                 args_add(args, output_file);
244         }
245
246         /* Turn off DEPENDENCIES_OUTPUT when running cc1, because
247          * otherwise it will emit a line like
248          *
249          *  tmp.stdout.vexed.732.o: /home/mbp/.ccache/tmp.stdout.vexed.732.i
250          *
251          * unsetenv() is on BSD and Linux but not portable. */
252         putenv("DEPENDENCIES_OUTPUT");
253
254         /* Give SWIG a filename for it to create and populate with a list of files that it generates */
255         if (swig) {
256                 char *ccache_outfiles;
257                 x_asprintf(&ccache_outfiles, "CCACHE_OUTFILES=%s", tmp_outfiles);
258                 unlink(tmp_outfiles);
259                 if (getenv("CCACHE_OUTFILES") || putenv(ccache_outfiles) == -1) {
260                         cc_log("CCACHE_OUTFILES env variable already set or could not be set\n");
261                         stats_update(STATS_ERROR);
262                         failed();
263                 }
264         }
265         
266         if (getenv("CCACHE_CPP2")) {
267                 args_add(args, input_file);
268         } else {
269                 if (swig) {
270                         args_add(args, "-nopreprocess");
271                 }
272                 args_add(args, i_tmpfile);
273         }
274         status = execute(args->argv, tmp_stdout, tmp_stderr);
275         args_pop(args, 3);
276
277         if (stat(tmp_stdout, &st1) != 0 || st1.st_size != 0) {
278                 cc_log("compiler produced stdout for %s\n", input_file);
279                 stats_update(STATS_STDOUT);
280                 unlink(tmp_stdout);
281                 unlink(tmp_stderr);
282                 unlink(tmp_outfiles);
283                 if (!swig) unlink(output_file);
284                 failed();
285         }
286         unlink(tmp_stdout);
287
288         if (status != 0) {
289                 int fd;
290                 cc_log("compile of %s gave status = %d\n", input_file, status);
291                 stats_update(STATS_STATUS);
292
293                 fd = open(tmp_stderr, O_RDONLY | O_BINARY);
294                 if (fd != -1) {
295                         if (cpp_stderr) {
296                                 /* we might have some stderr from cpp */
297                                 int fd2 = open(cpp_stderr, O_RDONLY | O_BINARY);
298                                 if (fd2 != -1) {
299                                         copy_fd(fd2, 2);
300                                         close(fd2);
301                                         unlink(cpp_stderr);
302                                         cpp_stderr = NULL;
303                                 }
304                         }
305
306                         /* we can use a quick method of
307                            getting the failed output */
308                         copy_fd(fd, 2);
309                         close(fd);
310                         unlink(tmp_stderr);
311                         if (i_tmpfile && !direct_i_file) {
312                                 unlink(i_tmpfile);
313                         }
314                         exit(status);
315                 }
316                 
317                 unlink(tmp_stderr);
318                 unlink(tmp_outfiles);
319                 if (!swig) unlink(output_file);
320                 failed();
321         } else {
322                 int hardlink = (getenv("CCACHE_NOCOMPRESS") != 0) && (getenv("CCACHE_HARDLINK") != 0);
323                 if (swig) {
324                         /* read the list of generated files and copy each of them into the cache */
325                         FILE *file;
326                         file = fopen(tmp_outfiles, "r");
327                         if (file) {
328                                 char out_filename[FILENAME_MAX + 1];
329                                 char out_filename_cache[FILENAME_MAX + 1];
330                                 while (fgets(out_filename, FILENAME_MAX, file)) {
331                                         char *linefeed = strchr(out_filename, '\n');
332                                         if (linefeed) {
333                                                 char *potential_cr = linefeed - 1;
334                                                 if (potential_cr >= out_filename && *potential_cr == '\r')
335                                                   *potential_cr = 0;
336                                                 *linefeed = 0;
337
338                                                 if (cached_files_count == 0) {
339                                                         strcpy(out_filename_cache, hashname);
340                                                 } else {
341                                                         sprintf(out_filename_cache, "%s.%d", hashname, cached_files_count);
342                                                 }
343
344                                                 if (commit_to_cache(out_filename, out_filename_cache, hardlink) != 0) {
345                                                         fclose(file);
346                                                         unlink(tmp_outfiles);
347                                                         failed();
348                                                 }
349                                                 to_cache_stats_helper(&st1, out_filename_cache, tmp_outfiles, &files_size, &cached_files_count);
350                                         } else {
351                                                 cached_files_count = 0;
352                                                 break;
353                                         }
354                                 }
355                                 fclose(file);
356                                 if (cached_files_count == 0) {
357                                         cc_log("failed to copy output files to cache - internal error\n");
358                                         stats_update(STATS_ERROR);
359                                         unlink(tmp_outfiles);
360                                         failed();
361                                 }
362
363                                 /* also copy the (uncompressed) file containing the list of generated files into the cache */
364                                 sprintf(out_filename_cache, "%s.outfiles", hashname);
365                                 if (stat(tmp_outfiles, &st1) != 0 ||
366                                         safe_rename(tmp_outfiles, out_filename_cache) != 0) {
367                                         cc_log("failed to copy outfiles file to cache - %s\n", strerror(errno));
368                                         stats_update(STATS_ERROR);
369                                         unlink(tmp_outfiles);
370                                         failed();
371                                 }
372                                 to_cache_stats_helper(&st1, out_filename_cache, tmp_outfiles, &files_size, &cached_files_count);
373                                 unlink(tmp_outfiles);
374                         } else {
375                                 cc_log("failed to open temp outfiles file - %s\n", strerror(errno));
376                                 stats_update(STATS_ERROR);
377                                 failed();
378                         }
379                 } else {
380                         if (commit_to_cache(output_file, hashname, hardlink) != 0) {
381                                 failed();
382                         }
383                         to_cache_stats_helper(&st1, hashname, 0, &files_size, &cached_files_count);
384                 }
385         }
386
387         x_asprintf(&path_stderr, "%s.stderr", hashname);
388
389         if (stat(tmp_stderr, &st1) != 0 ||
390                 move_file(tmp_stderr, path_stderr) != 0) {
391                 cc_log("failed to rename tmp files - %s\n", strerror(errno));
392                 stats_update(STATS_ERROR);
393                 failed();
394         }
395
396         to_cache_stats_helper(&st1, path_stderr, 0, &files_size, &cached_files_count);
397
398         cc_log("Placed %d files for %s into cache\n", cached_files_count, input_file);
399         stats_tocache(files_size, cached_files_count);
400
401         free(tmp_stderr);
402         free(tmp_stdout);
403         free(tmp_outfiles);
404         free(path_stderr);
405 }
406
407 /* find the hash for a command. The hash includes all argument lists,
408    plus the output from running the compiler with -E */
409 static void find_hash(ARGS *args)
410 {
411         int i;
412         char *path_stdout, *path_stderr;
413         char *hash_dir;
414         char *s;
415         struct stat st;
416         int status;
417         int nlevels = 2;
418         char *input_base;
419         char *tmp;
420         
421         if ((s = getenv("CCACHE_NLEVELS"))) {
422                 nlevels = atoi(s);
423                 if (nlevels < 1) nlevels = 1;
424                 if (nlevels > 8) nlevels = 8;
425         }
426
427         hash_start();
428
429         /* when we are doing the unifying tricks we need to include
430            the input file name in the hash to get the warnings right */
431         if (enable_unify || swig) {
432                 hash_string(input_file);
433         }
434
435         if (swig) {
436                 if (output_file) {
437                         hash_string(output_file);
438                 }
439         } else {
440                 /* we have to hash the extension, as a .i file isn't treated the same
441                    by the compiler as a .ii file */
442                 hash_string(i_extension);
443         }
444
445         /* first the arguments */
446         for (i=1;i<args->argc;i++) {
447                 /* some arguments don't contribute to the hash. The
448                    theory is that these arguments will change the
449                    output of -E if they are going to have any effect
450                    at all, or they only affect linking */
451                 if (i < args->argc-1) {
452                         if (strcmp(args->argv[i], "-I") == 0 ||
453                             strcmp(args->argv[i], "-include") == 0 ||
454                             strcmp(args->argv[i], "-L") == 0 ||
455                             strcmp(args->argv[i], "-D") == 0 ||
456                             strcmp(args->argv[i], "-idirafter") == 0 ||
457                             strcmp(args->argv[i], "-isystem") == 0) {
458                                 i++;
459                                 continue;
460                         }
461                 }
462                 if (strncmp(args->argv[i], "-I", 2) == 0 ||
463                     strncmp(args->argv[i], "-L", 2) == 0 ||
464                     strncmp(args->argv[i], "-D", 2) == 0 ||
465                     strncmp(args->argv[i], "-idirafter", 10) == 0 ||
466                     strncmp(args->argv[i], "-isystem", 8) == 0) {
467                         continue;
468                 }
469
470                 if (strncmp(args->argv[i], "--specs=", 8) == 0 &&
471                     stat(args->argv[i]+8, &st) == 0) {
472                         /* if given a explicit specs file, then hash that file, but
473                            don't include the path to it in the hash */
474                         hash_file(args->argv[i]+8);
475                         continue;
476                 }
477
478                 /* all other arguments are included in the hash */
479                 hash_string(args->argv[i]);
480         }
481
482         /* the compiler driver size and date. This is a simple minded way
483            to try and detect compiler upgrades. It is not 100% reliable */
484         if (stat(args->argv[0], &st) != 0) {
485                 cc_log("Couldn't stat the compiler!? (argv[0]='%s')\n", args->argv[0]);
486                 stats_update(STATS_COMPILER);
487                 failed();
488         }
489
490         /* also include the hash of the compiler name - as some compilers
491            use hard links and behave differently depending on the real name */
492         if (st.st_nlink > 1) {
493                 hash_string(str_basename(args->argv[0]));
494         }
495
496         hash_int(st.st_size);
497         hash_int(st.st_mtime);
498
499         /* possibly hash the current working directory */
500         if (getenv("CCACHE_HASHDIR")) {
501                 char *cwd = gnu_getcwd();
502                 if (cwd) {
503                         hash_string(cwd);
504                         free(cwd);
505                 }
506         }
507
508         /* ~/hello.c -> tmp.hello.123.i 
509            limit the basename to 10
510            characters in order to cope with filesystem with small
511            maximum filename length limits */
512         input_base = str_basename(input_file);
513         tmp = strchr(input_base, '.');
514         if (tmp != NULL) {
515                 *tmp = 0;
516         }
517         if (strlen(input_base) > 10) {
518                 input_base[10] = 0;
519         }
520
521         /* now the run */
522         x_asprintf(&path_stdout, "%s/%s.tmp.%s.%s", temp_dir,
523                    input_base, tmp_string(), 
524                    i_extension);
525         x_asprintf(&path_stderr, "%s/tmp.cpp_stderr.%s", temp_dir, tmp_string());
526
527         if (!direct_i_file) {
528                 /* run cpp on the input file to obtain the .i */
529                 args_add(args, "-E");
530                 args_add(args, input_file);
531                 status = execute(args->argv, path_stdout, path_stderr);
532                 args_pop(args, 2);
533         } else {
534                 /* we are compiling a .i or .ii file - that means we
535                    can skip the cpp stage and directly form the
536                    correct i_tmpfile */
537                 path_stdout = x_strdup(input_file);
538                 if (create_empty_file(path_stderr) != 0) {
539                         cc_log("failed to create empty stderr file\n");
540                         stats_update(STATS_ERROR);
541                         failed();
542                 }
543                 status = 0;
544         }
545
546         if (status != 0) {
547                 if (!direct_i_file) {
548                         unlink(path_stdout);
549                 }
550                 unlink(path_stderr);
551                 cc_log("the preprocessor gave %d\n", status);
552                 stats_update(STATS_PREPROCESSOR);
553                 failed();
554         }
555
556         /* if the compilation is with -g then we have to include the whole of the
557            preprocessor output, which means we are sensitive to line number
558            information. Otherwise we can discard line number info, which makes
559            us less sensitive to reformatting changes 
560
561            Note! I have now disabled the unification code by default
562            as it gives the wrong line numbers for warnings. Pity.
563         */
564         if (!enable_unify) {
565                 hash_file(path_stdout);
566         } else {
567                 if (unify_hash(path_stdout) != 0) {
568                         stats_update(STATS_ERROR);
569                         failed();
570                 }
571         }
572         hash_file(path_stderr);
573
574         i_tmpfile = path_stdout;
575
576         if (!getenv("CCACHE_CPP2")) {
577                 /* if we are using the CPP trick then we need to remember this stderr
578                    data and output it just before the main stderr from the compiler
579                    pass */
580                 cpp_stderr = path_stderr;
581         } else {        
582                 unlink(path_stderr);
583                 free(path_stderr);
584         }
585
586         /* we use a N level subdir for the cache path to reduce the impact
587            on filesystems which are slow for large directories
588         */
589         s = hash_result();
590         x_asprintf(&hash_dir, "%s/%c", cache_dir, s[0]);
591         x_asprintf(&stats_file, "%s/stats", hash_dir);
592         for (i=1; i<nlevels; i++) {
593                 char *p;
594                 if (create_dir(hash_dir) != 0) {
595                         cc_log("failed to create %s\n", hash_dir);
596                         stats_update(STATS_ERROR);
597                         failed();
598                 }
599                 x_asprintf(&p, "%s/%c", hash_dir, s[i]);
600                 free(hash_dir);
601                 hash_dir = p;
602         }
603         if (create_dir(hash_dir) != 0) {
604                 cc_log("failed to create %s\n", hash_dir);
605                 stats_update(STATS_ERROR);
606                 failed();
607         }
608         x_asprintf(&hashname, "%s/%s", hash_dir, s+nlevels);
609         free(hash_dir);
610 }
611
612 /* 
613    try to return the compile result from cache. If we can return from
614    cache then this function exits with the correct status code,
615    otherwise it returns */
616 static void from_cache(int first)
617 {
618         int fd_stderr, fd_cpp_stderr;
619         char *stderr_file;
620         struct stat st;
621
622         x_asprintf(&stderr_file, "%s.stderr", hashname);
623         fd_stderr = open(stderr_file, O_RDONLY | O_BINARY);
624         if (fd_stderr == -1) {
625                 /* it isn't in cache ... */
626                 free(stderr_file);
627                 return;
628         }
629
630         /* make sure the output is there too */
631         if (stat(hashname, &st) != 0) {
632                 close(fd_stderr);
633                 unlink(stderr_file);
634                 free(stderr_file);
635                 return;
636         }
637
638         /* the user might be disabling cache hits */
639 #ifndef ENABLE_ZLIB
640         /* if the cache file is compressed we must recache */
641         if ((first && getenv("CCACHE_RECACHE")) ||
642                 test_if_compressed(hashname) == 1)
643 #else
644         if (first && getenv("CCACHE_RECACHE"))
645 #endif
646         {
647                 close(fd_stderr);
648                 unlink(stderr_file);
649                 free(stderr_file);
650                 return;
651         }
652
653         if (first) {
654                 int hardlink;
655                 int passfail = -1;
656
657                 /* update timestamps for LRU cleanup
658                    also gives output_file a sensible mtime when hard-linking (for make) */
659                 x_utimes(stderr_file);
660
661                 hardlink = (getenv("CCACHE_HARDLINK") != 0);
662
663                 if (swig) {
664                         /* read the list of generated files and copy each of them out of the cache */
665                         FILE *file;
666                         char *outfiles;
667                         x_asprintf(&outfiles, "%s.outfiles", hashname);
668                         file = fopen(outfiles, "r");
669                         if (file) {
670                                 char out_filename[FILENAME_MAX + 1];
671                                 char out_filename_cache[FILENAME_MAX + 1];
672                                 int retrieved_files_count = 0;
673                                 x_utimes(outfiles);
674                                 while (fgets(out_filename, FILENAME_MAX, file)) {
675                                         char *linefeed = strchr(out_filename, '\n');
676                                         if (linefeed) {
677                                                 char *potential_cr = linefeed - 1;
678                                                 if (potential_cr >= out_filename && *potential_cr == '\r')
679                                                   *potential_cr = 0;
680                                                 *linefeed = 0;
681
682                                                 if (retrieved_files_count == 0) {
683                                                         strcpy(out_filename_cache, hashname);
684                                                 } else {
685                                                         sprintf(out_filename_cache, "%s.%d", hashname, retrieved_files_count);
686                                                 }
687
688                                                 passfail = retrieve_from_cache(out_filename_cache, out_filename, hardlink);
689                                                 if (passfail == -1) {
690                                                         break;
691                                                 }
692
693                                                 retrieved_files_count++;
694                                         } else {
695                                                 cc_log("failed to copy output files from cache - internal error\n");
696                                                 stats_update(STATS_ERROR);
697                                                 passfail = -1;
698                                                 break;
699                                         }
700                                 }
701                                 if (retrieved_files_count == 0) {
702                                         cc_log("failed to copy output files from cache - internal error\n");
703                                         stats_update(STATS_ERROR);
704                                         passfail = -1;
705                                 }
706                                 fclose(file);
707                         } else {
708                                 cc_log("failed to open cached outfiles file - %s\n", strerror(errno));
709                                 stats_update(STATS_ERROR);
710                         }
711                 } else {
712                         passfail = retrieve_from_cache(hashname, output_file, hardlink);
713                 }
714
715                 free(stderr_file);
716                 if (passfail == -1) {
717                         close(fd_stderr);
718                         unlink(stderr_file);
719                         return;
720                 }
721         }
722
723         /* get rid of the intermediate preprocessor file */
724         if (i_tmpfile) {
725                 if (!direct_i_file) {
726                         unlink(i_tmpfile);
727                 }
728                 free(i_tmpfile);
729                 i_tmpfile = NULL;
730         }
731
732         /* send the cpp stderr, if applicable */
733         fd_cpp_stderr = open(cpp_stderr, O_RDONLY | O_BINARY);
734         if (fd_cpp_stderr != -1) {
735                 copy_fd(fd_cpp_stderr, 2);
736                 close(fd_cpp_stderr);
737                 unlink(cpp_stderr);
738                 free(cpp_stderr);
739                 cpp_stderr = NULL;
740         }
741
742         /* send the stderr */
743         copy_fd(fd_stderr, 2);
744         close(fd_stderr);
745
746         /* and exit with the right status code */
747         if (first) {
748                 cc_log("got cached result for %s\n", input_file);
749                 stats_update(STATS_CACHED);
750         }
751
752         exit(0);
753 }
754
755 /* find the real compiler. We just search the PATH to find a executable of the 
756    same name that isn't a link to ourselves */
757 static void find_compiler(int argc, char **argv)
758 {
759         char *base;
760         char *path;
761
762         orig_args = args_init(argc, argv);
763
764         base = str_basename(argv[0]);
765
766         /* we might be being invoked like "ccache gcc -c foo.c" */
767         if (strcmp(base, MYNAME) == 0) {
768                 args_remove_first(orig_args);
769                 free(base);
770                 if (strchr(argv[1],'/')
771 #ifdef _WIN32
772                     || strchr(argv[1],'\\')
773 #endif
774                     ) {
775                         /* a full path was given */
776                         return;
777                 }
778                 base = str_basename(argv[1]);
779         }
780
781         /* support user override of the compiler */
782         if ((path=getenv("CCACHE_CC"))) {
783                 base = x_strdup(path);
784         }
785
786         orig_args->argv[0] = find_executable(base, MYNAME);
787
788         /* can't find the compiler! */
789         if (!orig_args->argv[0]) {
790                 stats_update(STATS_COMPILER);
791                 cc_log("could not find compiler (%s)\n", base);
792                 perror(base);
793                 exit(1);
794         }
795 }
796
797
798 /* check a filename for C/C++ extension. Return the pre-processor
799    extension */
800 static const char *check_extension(const char *fname, int *direct_i)
801 {
802         int i;
803         const char *p;
804
805         if (direct_i) {
806                 *direct_i = 0;
807         }
808
809         if (swig) return "ii"; /* any file extension is acceptable as input for SWIG */
810
811         p = strrchr(fname, '.');
812         if (!p) return NULL;
813         p++;
814         for (i=0; extensions[i].extension; i++) {
815                 if (strcmp(p, extensions[i].extension) == 0) {
816                         if (direct_i && strcmp(p, extensions[i].i_extension) == 0) {
817                                 *direct_i = 1;
818                         }
819                         p = getenv("CCACHE_EXTENSION");
820                         if (p) return p;
821                         return extensions[i].i_extension;
822                 }
823         }
824         return NULL;
825 }
826
827
828 /* 
829    process the compiler options to form the correct set of options 
830    for obtaining the preprocessor output
831 */
832 static void process_args(int argc, char **argv)
833 {
834         int i;
835         int found_c_opt = 0;
836         int found_S_opt = 0;
837         struct stat st;
838         char *e;
839         /* is gcc being asked to output dependencies? */
840         int generating_dependencies = 0;
841         /* is the dependency makefile name overridden with -MF? */
842         int dependency_filename_specified = 0;
843         /* is the dependency makefile target name specified with -MQ or -MF? */
844         int dependency_target_specified = 0;
845
846
847         stripped_args = args_init(0, NULL);
848
849         args_add(stripped_args, argv[0]);
850
851         /* -c not required for SWIG */
852         if (swig) {
853                 found_c_opt = 1;
854         }
855
856         for (i=1; i<argc; i++) {
857                 /* some options will never work ... */
858                 if (strcmp(argv[i], "-E") == 0) {
859                         failed();
860                 }
861
862                 /* these are too hard */
863                 if (strcmp(argv[i], "-fbranch-probabilities")==0 ||
864                     strcmp(argv[i], "-fprofile-arcs") == 0 ||
865                     strcmp(argv[i], "-ftest-coverage") == 0 ||
866                     strcmp(argv[i], "--coverage") == 0 ||
867                     strcmp(argv[i], "-M") == 0 ||
868                     strcmp(argv[i], "-MM") == 0 ||
869                     strcmp(argv[i], "-x") == 0) {
870                         cc_log("argument %s is unsupported\n", argv[i]);
871                         stats_update(STATS_UNSUPPORTED);
872                         failed();
873                         continue;
874                 }
875
876                 /* we must have -c */
877                 if (strcmp(argv[i], "-c") == 0) {
878                         if (!strip_c_option) {
879                                 args_add(stripped_args, argv[i]);
880                         }
881                         found_c_opt = 1;
882                         continue;
883                 }
884
885                 /* -S changes the default extension */
886                 if (strcmp(argv[i], "-S") == 0) {
887                         args_add(stripped_args, argv[i]);
888                         found_S_opt = 1;
889                         continue;
890                 }
891                 
892                 /* we need to work out where the output was meant to go */
893                 if (strcmp(argv[i], "-o") == 0) {
894                         if (i == argc-1) {
895                                 cc_log("missing argument to %s\n", argv[i]);
896                                 stats_update(STATS_ARGS);
897                                 failed();
898                         }
899                         output_file = argv[i+1];
900                         i++;
901                         continue;
902                 }
903                 
904                 /* alternate form of -o, with no space */
905                 if (!swig) { /* some of SWIG's arguments begin with -o */
906                         if (strncmp(argv[i], "-o", 2) == 0) {
907                                 output_file = &argv[i][2];
908                                 continue;
909                         }
910                 }
911
912                 /* debugging is handled specially, so that we know if we
913                    can strip line number info 
914                 */
915                 if (strncmp(argv[i], "-g", 2) == 0) {
916                         args_add(stripped_args, argv[i]);
917                         if (strcmp(argv[i], "-g0") != 0) {
918                                 enable_unify = 0;
919                         }
920                         continue;
921                 }
922
923                 /* The user knows best: just swallow the next arg */
924                 if (strcmp(argv[i], "--ccache-skip") == 0) {
925                         i++;
926                         if (i == argc) {
927                                 failed();
928                         }
929                         args_add(stripped_args, argv[i]);
930                         continue;
931                 }
932
933                 /* These options require special handling, because they
934                    behave differently with gcc -E, when the output
935                    file is not specified. */
936
937                 if (strcmp(argv[i], "-MD") == 0 || strcmp(argv[i], "-MMD") == 0) {
938                         generating_dependencies = 1;
939                 } else if (strcmp(argv[i], "-MF") == 0) {
940                         dependency_filename_specified = 1;
941                 } else if (strcmp(argv[i], "-MQ") == 0 || strcmp(argv[i], "-MT") == 0) {
942                         dependency_target_specified = 1;
943                 }
944
945                 /* the input file is already preprocessed */
946                 if (swig && strcmp(argv[i], "-nopreprocess") == 0) {
947                         direct_i_file = 1;
948                         continue;
949                 }
950
951                 /* options that take an argument */
952                 {
953                         const char *opts[] = {"-I", "-include", "-imacros", "-iprefix",
954                                               "-iwithprefix", "-iwithprefixbefore",
955                                               "-L", "-D", "-U", "-x", "-MF", 
956                                               "-MT", "-MQ", "-isystem", "-aux-info",
957                                               "--param", "-A", "-Xlinker", "-u",
958                                               "-idirafter", 
959                                               NULL};
960                         int j;
961                         for (j=0;opts[j];j++) {
962                                 if (strcmp(argv[i], opts[j]) == 0) {
963                                         if (i == argc-1) {
964                                                 cc_log("missing argument to %s\n", 
965                                                        argv[i]);
966                                                 stats_update(STATS_ARGS);
967                                                 failed();
968                                         }
969                                                 
970                                         args_add(stripped_args, argv[i]);
971                                         args_add(stripped_args, argv[i+1]);
972                                         i++;
973                                         break;
974                                 }
975                         }
976                         if (opts[j]) continue;
977                 }
978
979                 /* other options */
980                 if (argv[i][0] == '-') {
981                         args_add(stripped_args, argv[i]);
982                         continue;
983                 }
984
985                 /* if an argument isn't a plain file then assume its
986                    an option, not an input file. This allows us to
987                    cope better with unusual compiler options */
988                 if (stat(argv[i], &st) != 0 || !S_ISREG(st.st_mode)) {
989                         args_add(stripped_args, argv[i]);
990                         continue;                       
991                 }
992
993                 if (input_file) {
994                         if (check_extension(argv[i], NULL)) {
995                                 cc_log("multiple input files (%s and %s)\n",
996                                        input_file, argv[i]);
997                                 stats_update(STATS_MULTIPLE);
998                         } else if (!found_c_opt) {
999                                 cc_log("called for link with %s\n", argv[i]);
1000                                 if (strstr(argv[i], "conftest.")) {
1001                                         stats_update(STATS_CONFTEST);
1002                                 } else {
1003                                         stats_update(STATS_LINK);
1004                                 }
1005                         } else {
1006                                 cc_log("non C/C++ file %s\n", argv[i]);
1007                                 stats_update(STATS_NOTC);
1008                         }
1009                         failed();
1010                 }
1011
1012                 input_file = argv[i];
1013         }
1014
1015         if (!input_file) {
1016                 cc_log("No input file found\n");
1017                 stats_update(STATS_NOINPUT);
1018                 failed();
1019         }
1020
1021         if (swig) {
1022                 i_extension = check_extension(input_file, NULL);
1023         } else {
1024                 i_extension = check_extension(input_file, &direct_i_file);
1025         }
1026         if (i_extension == NULL) {
1027                 cc_log("Not a C/C++ file - %s\n", input_file);
1028                 stats_update(STATS_NOTC);
1029                 failed();
1030         }
1031
1032         if (!found_c_opt) {
1033                 cc_log("No -c option found for %s\n", input_file);
1034                 /* I find that having a separate statistic for autoconf tests is useful,
1035                    as they are the dominant form of "called for link" in many cases */
1036                 if (strstr(input_file, "conftest.")) {
1037                         stats_update(STATS_CONFTEST);
1038                 } else {
1039                         stats_update(STATS_LINK);
1040                 }
1041                 failed();
1042         }
1043
1044
1045         /* don't try to second guess the compilers heuristics for stdout handling */
1046         if (output_file && strcmp(output_file, "-") == 0) {
1047                 stats_update(STATS_OUTSTDOUT);
1048                 failed();
1049         }
1050
1051         if (!swig && !output_file) {
1052                 char *p;
1053                 output_file = x_strdup(input_file);
1054                 if ((p = strrchr(output_file, '/'))) {
1055                         output_file = p+1;
1056                 }
1057                 p = strrchr(output_file, '.');
1058                 if (!p || !p[1]) {
1059                         cc_log("badly formed output_file %s\n", output_file);
1060                         stats_update(STATS_ARGS);
1061                         failed();
1062                 }
1063                 p[1] = found_S_opt ? 's' : 'o';
1064                 p[2] = 0;
1065         }
1066
1067         /* If dependencies are generated, configure the preprocessor */
1068
1069         if (generating_dependencies && output_file) {
1070                 if (!dependency_filename_specified) {
1071                         char *default_depfile_name = x_strdup(output_file);
1072                         char *p = strrchr(default_depfile_name, '.');
1073
1074                         if (p) {
1075                                 if (strlen(p) < 2) {
1076                                         cc_log("badly formed dependency file %s\n", output_file);
1077                                         stats_update(STATS_ARGS);
1078                                         failed();
1079                                         return;
1080                                 }
1081                                 *p = 0;
1082                         }
1083                         else  {
1084                                 int len = p - default_depfile_name;
1085                                 
1086                                 p = x_malloc(len + 3);
1087                                 strncpy(default_depfile_name, p, len - 1);
1088                                 free(default_depfile_name);
1089                                 default_depfile_name = p;
1090                         }
1091
1092                         strcat(default_depfile_name, ".d");
1093                         args_add(stripped_args, "-MF");
1094                         args_add(stripped_args, default_depfile_name);
1095                 }
1096
1097                 if (!dependency_target_specified) {
1098                         args_add(stripped_args, "-MT");
1099                         args_add(stripped_args, output_file);
1100                 }
1101         }
1102
1103         /* cope with -o /dev/null */
1104         if (output_file && strcmp(output_file,"/dev/null") != 0 && stat(output_file, &st) == 0 && !S_ISREG(st.st_mode)) {
1105                 cc_log("Not a regular file %s\n", output_file);
1106                 stats_update(STATS_DEVICE);
1107                 failed();
1108         }
1109
1110         if ((e=getenv("CCACHE_PREFIX"))) {
1111                 char *p = find_executable(e, MYNAME);
1112                 if (!p) {
1113                         cc_log("could not find executable (%s)\n", e);
1114                         stats_update(STATS_ENVIRONMMENT);
1115                         perror(e);
1116                         exit(1);
1117                 }
1118                 args_add_prefix(stripped_args, p);
1119         }
1120 }
1121
1122 static void detect_swig()
1123 {
1124         char *basename = str_basename(orig_args->argv[0]);
1125         if (strstr(basename, "swig") || getenv("CCACHE_SWIG")) {
1126                 swig = 1;
1127         }
1128         free(basename);
1129 }
1130
1131 /* the main ccache driver function */
1132 static void ccache(int argc, char *argv[])
1133 {
1134         /* find the real compiler */
1135         find_compiler(argc, argv);
1136
1137         /* use the real compiler if HOME is not set */
1138         if (!cache_dir) {
1139                 cc_log("Unable to determine home directory\n");
1140                 cc_log("ccache is disabled\n");
1141                 failed();
1142         }
1143         
1144         /* we might be disabled */
1145         if (getenv("CCACHE_DISABLE")) {
1146                 cc_log("ccache is disabled\n");
1147                 failed();
1148         }
1149
1150         if (getenv("CCACHE_STRIPC")) {
1151                 strip_c_option = 1;
1152         }
1153
1154         if (getenv("CCACHE_UNIFY")) {
1155                 enable_unify = 1;
1156         }
1157
1158         detect_swig();
1159
1160         /* process argument list, returning a new set of arguments for pre-processing */
1161         process_args(orig_args->argc, orig_args->argv);
1162
1163         /* run with -E to find the hash */
1164         find_hash(stripped_args);
1165
1166         /* if we can return from cache at this point then do */
1167         from_cache(1);
1168
1169         if (getenv("CCACHE_READONLY")) {
1170                 cc_log("read-only set - doing real compile\n");
1171                 failed();
1172         }
1173         
1174         /* run real compiler, sending output to cache */
1175         to_cache(stripped_args);
1176
1177         /* return from cache */
1178         from_cache(0);
1179
1180         /* oh oh! */
1181         cc_log("secondary from_cache failed!\n");
1182         stats_update(STATS_ERROR);
1183         failed();
1184 }
1185
1186
1187 static void usage(void)
1188 {
1189         printf("%s, a compiler cache including support for SWIG. Version %s\n", MYNAME, CCACHE_VERSION);
1190         printf("Copyright Andrew Tridgell, 2002\n\n");
1191         
1192         printf("Usage:\n");
1193         printf("\t" MYNAME " [options]\n");
1194         printf("\t" MYNAME " compiler [compile options]\n");
1195         printf("\tcompiler [compile options]    (via symbolic link)\n");
1196         printf("\nOptions:\n");
1197
1198         printf("-s                      show statistics summary\n");
1199         printf("-z                      zero statistics\n");
1200         printf("-c                      run a cache cleanup\n");
1201         printf("-C                      clear the cache completely\n");
1202         printf("-F <maxfiles>           set maximum files in cache\n");
1203         printf("-M <maxsize>            set maximum size of cache (use G, M or K)\n");
1204         printf("-h                      this help page\n");
1205         printf("-V                      print version number\n");
1206 }
1207
1208 static void check_cache_dir(void)
1209 {
1210         if (!cache_dir) {
1211                 fatal("Unable to determine home directory");
1212         }
1213 }
1214
1215 /* the main program when not doing a compile */
1216 static int ccache_main(int argc, char *argv[])
1217 {
1218         int c;
1219         size_t v;
1220
1221         while ((c = getopt(argc, argv, "hszcCF:M:V")) != -1) {
1222                 switch (c) {
1223                 case 'V':
1224                         printf("%s version %s\n", MYNAME, CCACHE_VERSION);
1225                         printf("Copyright Andrew Tridgell 2002\n");
1226                         printf("Released under the GNU GPL v2 or later\n");
1227                         exit(0);
1228
1229                 case 'h':
1230                         usage();
1231                         exit(0);
1232                         
1233                 case 's':
1234                         check_cache_dir();
1235                         stats_summary();
1236                         break;
1237
1238                 case 'c':
1239                         check_cache_dir();
1240                         cleanup_all(cache_dir);
1241                         printf("Cleaned cache\n");
1242                         break;
1243
1244                 case 'C':
1245                         check_cache_dir();
1246                         wipe_all(cache_dir);
1247                         printf("Cleared cache\n");
1248                         break;
1249
1250                 case 'z':
1251                         check_cache_dir();
1252                         stats_zero();
1253                         printf("Statistics cleared\n");
1254                         break;
1255
1256                 case 'F':
1257                         check_cache_dir();
1258                         v = atoi(optarg);
1259                         if (stats_set_limits(v, -1) == 0) {
1260                                 printf("Set cache file limit to %u\n", (unsigned)v);
1261                         } else {
1262                                 printf("Could not set cache file limit.\n");
1263                                 exit(1);
1264                         }
1265                         break;
1266
1267                 case 'M':
1268                         check_cache_dir();
1269                         v = value_units(optarg);
1270                         if (stats_set_limits(-1, v) == 0) {
1271                                 printf("Set cache size limit to %uk\n", (unsigned)v);
1272                         } else {
1273                                 printf("Could not set cache size limit.\n");
1274                                 exit(1);
1275                         }
1276                         break;
1277
1278                 default:
1279                         usage();
1280                         exit(1);
1281                 }
1282         }
1283
1284         return 0;
1285 }
1286
1287
1288 /* Make a copy of stderr that will not be cached, so things like
1289    distcc can send networking errors to it. */
1290 static void setup_uncached_err(void)
1291 {
1292         char *buf;
1293         int uncached_fd;
1294         
1295         uncached_fd = dup(2);
1296         if (uncached_fd == -1) {
1297                 cc_log("dup(2) failed\n");
1298                 stats_update(STATS_ERROR);
1299                 failed();
1300         }
1301
1302         /* leak a pointer to the environment */
1303         x_asprintf(&buf, "UNCACHED_ERR_FD=%d", uncached_fd);
1304
1305         if (putenv(buf) == -1) {
1306                 cc_log("putenv failed\n");
1307                 stats_update(STATS_ERROR);
1308                 failed();
1309         }
1310 }
1311
1312
1313 int main(int argc, char *argv[])
1314 {
1315         char *p;
1316
1317         cache_dir = getenv("CCACHE_DIR");
1318         if (!cache_dir) {
1319                 const char *home_directory = get_home_directory();
1320                 if (home_directory) {
1321                         x_asprintf(&cache_dir, "%s/.ccache", home_directory);
1322                 }
1323         }
1324
1325         cache_logfile = getenv("CCACHE_LOGFILE");
1326
1327         if (getenv("CCACHE_VERBOSE")) {
1328                 ccache_verbose = 1;
1329         }
1330
1331         setup_uncached_err();
1332         
1333
1334         /* the user might have set CCACHE_UMASK */
1335         p = getenv("CCACHE_UMASK");
1336         if (p) {
1337                 mode_t mask;
1338                 errno = 0;
1339                 mask = strtol(p, NULL, 8);
1340                 if (errno == 0) {
1341                         umask(mask);
1342                 }
1343         }
1344
1345
1346         /* check if we are being invoked as "ccache" */
1347         if (strlen(argv[0]) >= strlen(MYNAME) &&
1348             strcmp(argv[0] + strlen(argv[0]) - strlen(MYNAME), MYNAME) == 0) {
1349                 if (argc < 2) {
1350                         usage();
1351                         exit(1);
1352                 }
1353                 /* if the first argument isn't an option, then assume we are
1354                    being passed a compiler name and options */
1355                 if (argv[1][0] == '-') {
1356                         return ccache_main(argc, argv);
1357                 }
1358         }
1359
1360         /* make sure the cache dir exists */
1361         if (cache_dir && (create_dir(cache_dir) != 0)) {
1362                 fprintf(stderr,"ccache: failed to create %s (%s)\n", 
1363                         cache_dir, strerror(errno));
1364                 exit(1);
1365         }
1366
1367         temp_dir = getenv("CCACHE_TEMPDIR");
1368         if (!temp_dir) {
1369                 x_asprintf(&temp_dir, "%s/temp", cache_dir);
1370                 /* make sure temp dir exists if not supplied by user */
1371                 if (temp_dir && create_dir(temp_dir) != 0) {
1372                         fprintf(stderr,"ccache: failed to create %s (%s)\n", 
1373                                 temp_dir, strerror(errno));
1374                         exit(1);
1375                 }
1376         }
1377
1378         if (!getenv("CCACHE_READONLY")) {
1379                 if (create_cachedirtag(cache_dir) != 0) {
1380                         fprintf(stderr,"ccache: failed to create %s/CACHEDIR.TAG (%s)\n",
1381                                 cache_dir, strerror(errno));
1382                         exit(1);
1383                 }
1384         }
1385
1386         ccache(argc, argv);
1387         return 1;
1388 }