]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
avoid a 2nd cpp run by compiling the pre-processed output on a cache
authorAndrew Tridgell <tridge@samba.org>
Sun, 7 Apr 2002 13:20:53 +0000 (15:20 +0200)
committerAndrew Tridgell <tridge@samba.org>
Sun, 7 Apr 2002 13:20:53 +0000 (15:20 +0200)
miss

this lowers the overhead in the case of a cache miss to just about
zero!

ccache.1
ccache.c
ccache.h
ccache.yo
web/ccache-man.html

index eacc9735c2a03239960fbc71f84d1f2bbcc8ba54..8ee4b1c48791140047408535afcc11cd7974b18b 100644 (file)
--- a/ccache.1
+++ b/ccache.1
@@ -134,6 +134,16 @@ If you set the environment variable
 CCACHE_DISABLE then ccache will just call the real compiler,
 bypassing the cache completely\&.
 .IP 
+.IP "\fBCCACHE_CPP2\fP" 
+If you set the environment variable CCACHE_CPP2
+then ccache will not use the optimisation of avoiding the 2nd call to
+the pre-processor by compiling the pre-processed output that was used
+for finding the hash in the case of a cache miss\&. This is primarily a
+debugging option, although it is possible that some unusual compilers
+will have problems with the intermediate filename extensions used in
+this optimisation, in which case this option could allow ccache to be
+used\&.
+.IP 
 .IP "\fBCCACHE_NOSTATS\fP" 
 If you set the environment variable
 CCACHE_NOSTATS then ccache will not update the statistics files on
@@ -250,6 +260,17 @@ compiling rsync I get:
 .fi 
  
 
+.PP 
+.SH "CREDITS" 
+.PP 
+Thanks to the following people for their contributions to ccache
+.IP o 
+Erik Thiele for the original compilercache script
+.IP o 
+Luciano Rocha for the idea of compiling the pre-processor output
+to avoid a 2nd cpp pass
+.IP o 
+Paul Russell for many suggestions and the debian packaging
 .PP 
 .SH "AUTHOR" 
 .PP 
index 6f50cac7f6941eb1027df284fce823e0e3a05184..94559aba64acb4f8d9648c7a89c11cba25e9c020 100644 (file)
--- a/ccache.c
+++ b/ccache.c
 
 #include "ccache.h"
 
+/* the base cache directory */
 char *cache_dir = NULL;
+
+/* the debug logfile name, if set */
 char *cache_logfile = NULL;
+
+/* the argument list after processing */
 static ARGS *stripped_args;
+
+/* the original argument list */
 static ARGS *orig_args;
+
+/* the output filename being compiled to */
 static char *output_file;
+
+/* the source file */
 static char *input_file;
+
+/* the name of the file containing the cached object code */
 static char *hashname;
+
+/* the extension of the file after pre-processing */
+static char *i_extension;
+
+/* the name of the temporary pre-processor file */
+static char *i_tmpfile;
+
+/* the name of the statistics file */
 char *stats_file = NULL;
+
+/* did we find a -g option? */
 static int found_debug;
 
+/* a list of supported file extensions, and the equivalent
+   extension for code that has been through the pre-processor
+*/
+static struct {
+       char *extension;
+       char *i_extension;
+} extensions[] = {
+       {"c", "i"},
+       {"C", "ii"},
+       {"m", "mi"},
+       {"cc", "ii"},
+       {"CC", "ii"},
+       {"cpp", "ii"},
+       {"CPP", "ii"},
+       {"cxx", "ii"},
+       {"CXX", "ii"},
+       {NULL, NULL}};
+
 /*
   something went badly wrong - just execute the real compiler
 */
 static void failed(void)
 {
+       /* delete intermediate pre-processor file if needed */
+       if (i_tmpfile) {
+               unlink(i_tmpfile);
+               free(i_tmpfile);
+               i_tmpfile = NULL;
+       }
        execv(orig_args->argv[0], orig_args->argv);
        cc_log("execv returned (%s)!\n", strerror(errno));
        perror(orig_args->argv[0]);
@@ -57,8 +104,14 @@ static void to_cache(ARGS *args)
 
        args_add(args, "-o");
        args_add(args, tmp_hashname);
+       
+       if (getenv("CCACHE_CPP2")) {
+               args_add(args, input_file);
+       } else {
+               args_add(args, i_tmpfile);
+       }
        status = execute(args->argv, tmp_stdout, tmp_stderr);
-       args_pop(args, 2);
+       args_pop(args, 3);
 
        if (stat(tmp_stdout, &st1) != 0 || st1.st_size != 0) {
                cc_log("compiler produced stdout for %s\n", output_file);
@@ -136,9 +189,6 @@ static void find_hash(ARGS *args)
                   theory is that these arguments will change the
                   output of -E if they are going to have any effect
                   at all, or they only affect linking */
-               if (strcmp(args->argv[i], input_file) == 0) {
-                       continue;
-               }
                if (i < args->argc-1) {
                        if (strcmp(args->argv[i], "-I") == 0 ||
                            strcmp(args->argv[i], "-include") == 0 ||
@@ -169,12 +219,14 @@ static void find_hash(ARGS *args)
        hash_int(st.st_mtime);
 
        /* now the run */
-       x_asprintf(&path_stdout, "%s/tmp.stdout.%d", cache_dir, getpid());
+       x_asprintf(&path_stdout, "%s/tmp.stdout.%d.%s", cache_dir, getpid(), 
+                  i_extension);
        x_asprintf(&path_stderr, "%s/tmp.stderr.%d", cache_dir, getpid());
 
        args_add(args, "-E");
+       args_add(args, input_file);
        status = execute(args->argv, path_stdout, path_stderr);
-       args_pop(args, 1);
+       args_pop(args, 2);
 
        if (status != 0) {
                unlink(path_stdout);
@@ -198,9 +250,8 @@ static void find_hash(ARGS *args)
        }
        hash_file(path_stderr);
 
-       unlink(path_stdout);
+       i_tmpfile = path_stdout;
        unlink(path_stderr);
-       free(path_stdout);
        free(path_stderr);
 
        /* we use a N level subdir for the cache path to reduce the impact
@@ -288,6 +339,13 @@ static void from_cache(int first)
                utime(output_file, NULL);
        }
 
+       /* get rid of the intermediate preprocessor file */
+       if (i_tmpfile) {
+               unlink(i_tmpfile);
+               free(i_tmpfile);
+               i_tmpfile = NULL;
+       }
+
        /* send the stderr */
        copy_fd(fd_stderr, 2);
        close(fd_stderr);
@@ -383,20 +441,22 @@ static void find_compiler(int argc, char **argv)
 }
 
 
-/* check a filename for C/C++ extension */
-static int check_extension(const char *fname)
+/* check a filename for C/C++ extension. Return the pre-processor
+   extension */
+static char *check_extension(const char *fname)
 {
-       char *extensions[] = {"c", "C", "m", "cc", "CC", "cpp", "CPP", "cxx", "CXX", 0};
        int i;
        char *p;
 
        p = strrchr(fname, '.');
-       if (!p) return -1;
+       if (!p) return NULL;
        p++;
-       for (i=0; extensions[i]; i++) {
-               if (strcmp(p, extensions[i]) == 0) return 0;
+       for (i=0; extensions[i].extension; i++) {
+               if (strcmp(p, extensions[i].extension) == 0) {
+                       return extensions[i].i_extension;
+               }
        }
-       return -1;
+       return NULL;
 }
 
 
@@ -499,7 +559,6 @@ static void process_args(int argc, char **argv)
                }
 
                input_file = argv[i];
-               args_add(stripped_args, argv[i]);
        }
 
        if (!input_file) {
@@ -508,7 +567,8 @@ static void process_args(int argc, char **argv)
                failed();
        }
 
-       if (check_extension(input_file) != 0) {
+       i_extension = check_extension(input_file);
+       if (i_extension == NULL) {
                cc_log("Not a C/C++ file - %s\n", input_file);
                stats_update(STATS_NOTC);
                failed();
index 347ab3660444be1b7df51d8cdb1fccb17bedce49..b4b4c845150c9ce888843cd1cb20bf68c0d50cdf 100644 (file)
--- a/ccache.h
+++ b/ccache.h
@@ -1,4 +1,4 @@
-#define CCACHE_VERSION "1.5"
+#define CCACHE_VERSION "1.6"
 
 #include "config.h"
 
index 547d0cf45cd2c52a93b6f9b932bdc535300c9dcf..e7a884a005501554a4e2b0ecbfdff32760243292 100644 (file)
--- a/ccache.yo
+++ b/ccache.yo
@@ -114,6 +114,15 @@ dit(bf(CCACHE_DISABLE)) If you set the environment variable
 CCACHE_DISABLE then ccache will just call the real compiler,
 bypassing the cache completely.
 
+dit(bf(CCACHE_CPP2)) If you set the environment variable CCACHE_CPP2
+then ccache will not use the optimisation of avoiding the 2nd call to
+the pre-processor by compiling the pre-processed output that was used
+for finding the hash in the case of a cache miss. This is primarily a
+debugging option, although it is possible that some unusual compilers
+will have problems with the intermediate filename extensions used in
+this optimisation, in which case this option could allow ccache to be
+used.
+
 dit(bf(CCACHE_NOSTATS)) If you set the environment variable
 CCACHE_NOSTATS then ccache will not update the statistics files on
 each compile.
@@ -216,6 +225,16 @@ verb(
   ccache cached 4.6 seconds
 )
 
+manpagesection(CREDITS)
+
+Thanks to the following people for their contributions to ccache
+itemize(
+ it() Erik Thiele for the original compilercache script
+ it() Luciano Rocha for the idea of compiling the pre-processor output
+ to avoid a 2nd cpp pass
+ it() Paul Russell for many suggestions and the debian packaging
+)
+
 manpageauthor()
 
 ccache was written by Andrew Tridgell
index 63e46b41fbda3d6d6565b850d3b74296587ea11f..ab31883bde439bb4840ab9a35b681d856722cf9f 100644 (file)
@@ -113,6 +113,14 @@ ccache itself.
 <p><p></p><dt><strong><strong>CCACHE_DISABLE</strong></strong><dd> If you set the environment variable
 CCACHE_DISABLE then ccache will just call the real compiler,
 bypassing the cache completely.
+<p><p></p><dt><strong><strong>CCACHE_CPP2</strong></strong><dd> If you set the environment variable CCACHE_CPP2
+then ccache will not use the optimisation of avoiding the 2nd call to
+the pre-processor by compiling the pre-processed output that was used
+for finding the hash in the case of a cache miss. This is primarily a
+debugging option, although it is possible that some unusual compilers
+will have problems with the intermediate filename extensions used in
+this optimisation, in which case this option could allow ccache to be
+used.
 <p><p></p><dt><strong><strong>CCACHE_NOSTATS</strong></strong><dd> If you set the environment variable
 CCACHE_NOSTATS then ccache will not update the statistics files on
 each compile.
@@ -202,6 +210,15 @@ compiling rsync I get:
 
 </pre>
 
+<p><h2>CREDITS</h2>
+    
+<p>Thanks to the following people for their contributions to ccache
+<ul>
+ <li > Erik Thiele for the original compilercache script
+ <li > Luciano Rocha for the idea of compiling the pre-processor output
+ to avoid a 2nd cpp pass
+ <li > Paul Russell for many suggestions and the debian packaging
+</ul>
 <p><h2>AUTHOR</h2>
     
 <p>ccache was written by Andrew Tridgell