[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