[ccache] Via file patch

Michael McTernan Michael.McTernan at ttpcom.com
Sun Jun 6 13:53:54 GMT 2004


Hmm,

Looks like the attachement got lost.  Retry.

Thanks,

Mike

> -----Original Message-----
> From: ccache-bounces+mm1=ttpcom.com at lists.samba.org
> [mailto:ccache-bounces+mm1=ttpcom.com at lists.samba.org]On Behalf Of
> Michael McTernan
> Sent: 06 June 2004 14:43
> To: ccache at lists.samba.org
> Subject: [ccache] Via file patch
> 
> 
> Hi there,
> 
> I've been trying to use ccache with the ARM compilers (SDT and 
> RVCT).  These
> compilers have a feature to support 'via' files; files which 
> contain a list
> of command line options, one per line.
> 
> Since ccache doesn't understand via files it doesn't properly process all
> the command line options, and fails as a result.  I've made a 
> patch to allow
> support for via files, which is attached.
> 
> To apply the patch, extract a clean version of the ccache-2.3 tarball, cd
> into the newly extracted directory and run the command:
> 
> patch -i vias.patch -u -p1
> 
> [Assuming that you place the the patch file into the same directory]
> 
> Then configure && make as normal.  To enable via file processing, set the
> environment variable CCACHE_VIA to the exact text of the option that
> indicates a via file.  eg. for the TCC and ARMCC, I would export
> CCACHE_VIA=-via.
> 
> Thanks,
> 
> Mike
> 
> --
> Michael McTernan
> Software
> TTPCom Ltd
> Melbourn Science Park, Cambridge Road, Melbourn, Hertfordshire, 
> SG8 6HQ, UK
> T: +44 1763 266266 | F: +44 1763 261216
> michael.mcternan at ttpcom.com | www.ttpcom.com
> 
> 
-------------- next part --------------
diff -Naurw ccache-2.3/ccache.1 ccache-2.3.via/ccache.1
--- ccache-2.3/ccache.1	2003-09-28 05:48:18.000000000 +0100
+++ ccache-2.3.via/ccache.1	2004-06-06 14:05:21.560836800 +0100
@@ -241,6 +241,16 @@
 the default\&. On HP-UX set this environment variable to "i" if you use
 the aCC compiler\&.
 .IP 
+.IP "\fBCCACHE_VIA\fP" 
+Look for "via" files and process additional
+options within them as if they were on the command line\&  Some
+compilers will allow the command line to be shorter by processing one
+or more "via" files where each line in the file is treated as if it
+were an argument to the compiler\&  This environment variable can be
+set the the exact text of the via file command, which is often
+"-via", such that ccache can examine all command line options\&  This
+does not alter the way in which the compiler is invoked\&
+.IP 
 .PP 
 .SH "CACHE SIZE MANAGEMENT" 
 .PP 
diff -Naurw ccache-2.3/ccache.c ccache-2.3.via/ccache.c
--- ccache-2.3/ccache.c	2003-09-28 05:48:18.000000000 +0100
+++ ccache-2.3.via/ccache.c	2004-06-04 19:23:58.149607500 +0100
@@ -35,6 +35,9 @@
 /* the original argument list */
 static ARGS *orig_args;
 
+/* the arguments in via files */
+static ARGS *via_args = NULL;
+
 /* the output filename being compiled to */
 static char *output_file;
 
@@ -56,6 +59,9 @@
 /* the name of the cpp stderr file */
 static char *cpp_stderr;
 
+/* the name of the via file argument */
+static char *via_file_opt = NULL;
+
 /* the name of the statistics file */
 char *stats_file = NULL;
 
@@ -84,6 +90,10 @@
 	{"ii", "ii"},
 	{NULL, NULL}};
 
+
+/* prototype needed for recursive function */
+static void process_viafile(const char *fname, int *found_c_opt, int *found_S_opt);
+
 /*
   something went badly wrong - just execute the real compiler
 */
@@ -140,12 +150,62 @@
 		gethostname(hostname, sizeof(hostname)-1);
 #endif
 		hostname[sizeof(hostname)-1] = 0;
-		asprintf(&ret, "%s.%u", hostname, (unsigned)getpid());
+        x_asprintf(&ret, "%s.%u", hostname, (unsigned)getpid());
 	}
 
 	return ret;
 }
 
+/* add an argument list to the hash */
+static void find_arghash(ARGS *args)
+{
+    struct stat st;
+    int         i;
+
+    /* first the arguments */
+    for (i=1;i<args->argc;i++) {
+        /* some arguments don't contribute to the hash. The
+           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 (i < args->argc-1) {
+            if (strcmp(args->argv[i], "-I") == 0 ||
+                strcmp(args->argv[i], "-include") == 0 ||
+                strcmp(args->argv[i], "-L") == 0 ||
+                strcmp(args->argv[i], "-D") == 0 ||
+                strcmp(args->argv[i], "-idirafter") == 0 ||
+                strcmp(args->argv[i], "-isystem") == 0) {
+                i++;
+                continue;
+            }
+        }
+        if (strncmp(args->argv[i], "-I", 2) == 0 ||
+            strncmp(args->argv[i], "-L", 2) == 0 ||
+            strncmp(args->argv[i], "-D", 2) == 0 ||
+            strncmp(args->argv[i], "-idirafter", 10) == 0 ||
+            strncmp(args->argv[i], "-isystem", 8) == 0) {
+            continue;
+        }
+
+        /* if the option is for a via file, skip it */
+        if(via_file_opt && strcmp(args->argv[i], via_file_opt) == 0)
+        {
+            i++;
+            continue;
+        }
+
+        if (strncmp(args->argv[i], "--specs=", 8) == 0 &&
+            stat(args->argv[i]+8, &st) == 0) {
+            /* if given a explicit specs file, then hash that file, but
+               don't include the path to it in the hash */
+            hash_file(args->argv[i]+8);
+            continue;
+        }
+
+        /* all other arguments are included in the hash */
+        hash_string(args->argv[i]);
+    }
+}
 
 /* run the real compiler and put the result in cache */
 static void to_cache(ARGS *args)
@@ -247,7 +307,7 @@
 
 /* find the hash for a command. The hash includes all argument lists,
    plus the output from running the compiler with -E */
-static void find_hash(ARGS *args)
+static void find_hash(ARGS *args, ARGS *aux_args)
 {
 	int i;
 	char *path_stdout, *path_stderr;
@@ -277,42 +337,10 @@
 	   by the compiler as a .ii file */
 	hash_string(i_extension);
 
-	/* first the arguments */
-	for (i=1;i<args->argc;i++) {
-		/* some arguments don't contribute to the hash. The
-		   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 (i < args->argc-1) {
-			if (strcmp(args->argv[i], "-I") == 0 ||
-			    strcmp(args->argv[i], "-include") == 0 ||
-			    strcmp(args->argv[i], "-L") == 0 ||
-			    strcmp(args->argv[i], "-D") == 0 ||
-			    strcmp(args->argv[i], "-idirafter") == 0 ||
-			    strcmp(args->argv[i], "-isystem") == 0) {
-				i++;
-				continue;
-			}
-		}
-		if (strncmp(args->argv[i], "-I", 2) == 0 ||
-		    strncmp(args->argv[i], "-L", 2) == 0 ||
-		    strncmp(args->argv[i], "-D", 2) == 0 ||
-		    strncmp(args->argv[i], "-idirafter", 10) == 0 ||
-		    strncmp(args->argv[i], "-isystem", 8) == 0) {
-			continue;
-		}
-
-		if (strncmp(args->argv[i], "--specs=", 8) == 0 &&
-		    stat(args->argv[i]+8, &st) == 0) {
-			/* if given a explicit specs file, then hash that file, but
-			   don't include the path to it in the hash */
-			hash_file(args->argv[i]+8);
-			continue;
-		}
+    /* the compiler options */
+    find_arghash(args);
+    if(aux_args) find_arghash(aux_args);
 
-		/* all other arguments are included in the hash */
-		hash_string(args->argv[i]);
-	}
 
 	/* the compiler driver size and date. This is a simple minded way
 	   to try and detect compiler upgrades. It is not 100% reliable */
@@ -376,7 +404,7 @@
 			unlink(path_stdout);
 		}
 		unlink(path_stderr);
-		cc_log("the preprocessor gave %d\n", status);
+        cc_log("the preprocessor (%s) gave %d\n", args->argv[0], status);
 		stats_update(STATS_PREPROCESSOR);
 		failed();
 	}
@@ -606,21 +634,12 @@
 }
 
 
-/* 
-   process the compiler options to form the correct set of options 
-   for obtaining the preprocessor output
-*/
-static void process_args(int argc, char **argv)
+/* process the compiler options to form the correct set of options
+   for obtaining the preprocessor output */
+static void process_arglist(int argc, char **argv, ARGS *dest_args, int *found_c_opt, int *found_S_opt)
 {
 	int i;
-	int found_c_opt = 0;
-	int found_S_opt = 0;
 	struct stat st;
-	char *e;
-
-	stripped_args = args_init(0, NULL);
-
-	args_add(stripped_args, argv[0]);
 
 	for (i=1; i<argc; i++) {
 		/* some options will never work ... */
@@ -641,15 +660,15 @@
 
 		/* we must have -c */
 		if (strcmp(argv[i], "-c") == 0) {
-			args_add(stripped_args, argv[i]);
-			found_c_opt = 1;
+            args_add(dest_args, argv[i]);
+            *found_c_opt = 1;
 			continue;
 		}
 
 		/* -S changes the default extension */
 		if (strcmp(argv[i], "-S") == 0) {
-			args_add(stripped_args, argv[i]);
-			found_S_opt = 1;
+            args_add(dest_args, argv[i]);
+            *found_S_opt = 1;
 			continue;
 		}
 		
@@ -675,7 +694,7 @@
 		   can strip line number info 
 		*/
 		if (strncmp(argv[i], "-g", 2) == 0) {
-			args_add(stripped_args, argv[i]);
+            args_add(dest_args, argv[i]);
 			if (strcmp(argv[i], "-g0") != 0) {
 				enable_unify = 0;
 			}
@@ -686,9 +705,10 @@
 		if (strcmp(argv[i], "--ccache-skip") == 0) {
 			i++;
 			if (i == argc) {
+                cc_log("--ccache-skip specified with no argument to skip!\n");
 				failed();
 			}
-			args_add(stripped_args, argv[i]);
+            args_add(dest_args, argv[i]);
 			continue;
 		}
 
@@ -705,24 +725,39 @@
 			for (j=0;opts[j];j++) {
 				if (strcmp(argv[i], opts[j]) == 0) {
 					if (i == argc-1) {
-						cc_log("missing argument to %s\n", 
-						       argv[i]);
+                        cc_log("missing argument to %s\n", argv[i]);
 						stats_update(STATS_ARGS);
 						failed();
 					}
 						
-					args_add(stripped_args, argv[i]);
-					args_add(stripped_args, argv[i+1]);
+                    args_add(dest_args, argv[i]);
 					i++;
+                    args_add(dest_args, argv[i]);
 					break;
 				}
 			}
 			if (opts[j]) continue;
 		}
 
+        /* via files */
+        if (via_file_opt && strcmp(via_file_opt, argv[i])==0) {
+            if (i == argc-1) {
+                cc_log("missing argument to %s\n", argv[i]);
+                stats_update(STATS_ARGS);
+                failed();
+            }
+
+            args_add(dest_args, argv[i]);
+            i++;
+            args_add(dest_args, argv[i]);
+
+            process_viafile(argv[i], found_c_opt, found_S_opt);
+            continue;
+        }
+
 		/* other options */
 		if (argv[i][0] == '-') {
-			args_add(stripped_args, argv[i]);
+            args_add(dest_args, argv[i]);
 			continue;
 		}
 
@@ -730,7 +765,7 @@
 		   an option, not an input file. This allows us to
 		   cope better with unusual compiler options */
 		if (stat(argv[i], &st) != 0 || !S_ISREG(st.st_mode)) {
-			args_add(stripped_args, argv[i]);
+            args_add(dest_args, argv[i]);
 			continue;			
 		}
 
@@ -755,6 +790,83 @@
 
 		input_file = argv[i];
 	}
+}
+
+
+/* read contents of a viafile into an argument list and then process with
+   process_arglist in the normal way */
+static void process_viafile(const char *fname, int *found_c_opt, int *found_S_opt)
+{
+    char **argv;
+    int    argc, argvlen;
+    char  *line;
+    int    linelen;
+    FILE  *f;
+
+    /* attempt to open the input file */
+    f = fopen(fname, "r");
+    if (!f) {
+        cc_log("failed to open via file '%s' for reading\n", fname);
+        return;
+    }
+
+    /* create a array, initially of 64 elements */
+    argvlen = 64;
+    argv = x_malloc(argvlen * sizeof(char *));
+    argc = 0;
+
+    do {
+
+        /* create storage for the line */
+        line = x_malloc(linelen = 32);
+
+        /* read a line and link to argv array */
+        if(x_getline(&line, &linelen, f) != -1) {
+            argv[argc] = line;
+            argc++;
+
+            /* increase length if needed */
+            if(argc==argvlen) {
+                argvlen += 64;
+                argv    = x_realloc(argv, argvlen * sizeof(char *));
+            }
+        } else {
+            break;
+        }
+
+    } while(1);
+
+    fclose(f);
+
+    /* now process the arglist */
+    process_arglist(argc, argv, via_args, found_c_opt, found_S_opt);
+
+    /* now free it all */
+    while(argc > 0) {
+        free(argv[--argc]);
+    }
+
+    free(argv);
+
+}
+
+
+static void process_args(int argc, char **argv)
+{
+    const char  *e;
+    int          found_c_opt = 0;
+    int          found_S_opt = 0;
+    struct stat  st;
+
+    /* init the stripped args list(s) */
+    stripped_args = args_init(0, NULL);
+    args_add(stripped_args, argv[0]);
+    if(via_file_opt) {
+        via_args = args_init(0, NULL);
+    }
+
+    /* process the argument list recursively */
+    process_arglist(argc, argv, stripped_args, &found_c_opt, &found_S_opt);
 
 	if (!input_file) {
 		cc_log("No input file found\n");
@@ -837,11 +949,14 @@
 		enable_unify = 1;
 	}
 
+    /* get the via file switch if set */
+    via_file_opt = getenv("CCACHE_VIA");
+
 	/* process argument list, returning a new set of arguments for pre-processing */
 	process_args(orig_args->argc, orig_args->argv);
 
 	/* run with -E to find the hash */
-	find_hash(stripped_args);
+    find_hash(stripped_args, via_args);
 
 	/* if we can return from cache at this point then do */
 	from_cache(1);
diff -Naurw ccache-2.3/ccache.h ccache-2.3.via/ccache.h
--- ccache-2.3/ccache.h	2003-09-28 05:48:18.000000000 +0100
+++ ccache-2.3.via/ccache.h	2004-06-06 13:46:47.028217600 +0100
@@ -82,6 +82,7 @@
 char *x_strdup(const char *s);
 void *x_realloc(void *ptr, size_t size);
 void *x_malloc(size_t size);
+int   x_getline(char **lineptr, size_t *n, FILE *stream);
 void traverse(const char *dir, void (*fn)(const char *, struct stat *));
 char *str_basename(const char *s);
 char *dirname(char *s);
diff -Naurw ccache-2.3/execute.c ccache-2.3.via/execute.c
--- ccache-2.3/execute.c	2003-09-28 05:48:18.000000000 +0100
+++ ccache-2.3.via/execute.c	2004-06-04 17:11:03.078732800 +0100
@@ -39,6 +39,7 @@
 		unlink(path_stdout);
 		fd = open(path_stdout, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0666);
 		if (fd == -1) {
+            cc_log("Failed to open stdout file: %s\n", path_stdout);
 			exit(STATUS_NOCACHE);
 		}
 		dup2(fd, 1);
@@ -47,6 +48,7 @@
 		unlink(path_stderr);
 		fd = open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0666);
 		if (fd == -1) {
+            cc_log("Failed to open stderr file: %s\n", path_stderr);
 			exit(STATUS_NOCACHE);
 		}
 		dup2(fd, 2);
diff -Naurw ccache-2.3/util.c ccache-2.3.via/util.c
--- ccache-2.3/util.c	2003-09-28 05:48:18.000000000 +0100
+++ ccache-2.3.via/util.c	2004-06-06 13:45:12.842785600 +0100
@@ -245,6 +245,10 @@
 char *str_basename(const char *s)
 {
 	char *p = strrchr(s, '/');
+
+    if (!p) {
+        p = strrchr(s, '\\');
+    }
 	if (p) {
 		return x_strdup(p+1);
 	} 
@@ -430,3 +434,46 @@
 	close(fd);
 	return 0;
 }
+
+/* safe version of getline */
+int x_getline(char **lineptr, size_t *n, FILE *stream)
+{
+    static char  line[256];
+    char        *ptr;
+    unsigned int len;
+
+    if (lineptr == NULL || n == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    if (ferror (stream)) return -1;
+
+    if (feof(stream)) return -1;
+
+    fgets(line,256,stream);
+
+    ptr = strchr(line,'\n');
+    if(!ptr) strchr(line,'\r');
+
+    if (ptr) {
+        /* set the newline to a null and trim space */
+        do {
+            *ptr = '\0';
+            ptr--;
+        } while(ptr >= line && isspace(*ptr));
+
+    }
+
+    len = strlen(line);
+
+    if((len+1) < 256) {
+        ptr = x_realloc(*lineptr, 256);
+        *lineptr = ptr;
+        *n = 256;
+    }
+
+    strcpy(*lineptr,line);
+    return(len);
+
+}
\ No newline at end of file
diff -Naurw ccache-2.3/web/ccache-man.html ccache-2.3.via/web/ccache-man.html
--- ccache-2.3/web/ccache-man.html	2003-09-28 05:49:00.000000000 +0100
+++ ccache-2.3.via/web/ccache-man.html	2004-06-06 14:00:40.216283200 +0100
@@ -194,6 +194,14 @@
 systems like this you can use the CCACHE_EXTENSION option to override
 the default. On HP-UX set this environment variable to "i" if you use
 the aCC compiler.
+<p><p></p><dt><strong><strong>CCACHE_VIA</strong></strong><dd> Look for 'via' files and process additional
+options within them as if they were on the command line.  Some
+compilers will allow the command line to be shorter by processing one
+or more 'via' files where each line in the file is treated as if it
+were an argument to the compiler.  This environment variable can be
+set the the exact text of the via file command, which is often
+'-via', such that ccache can examine all command line options.  This
+does not alter the way in which the compiler is invoked.
 <p></dl>
 <p><h2>CACHE SIZE MANAGEMENT</h2>
     


More information about the ccache mailing list