ccache-msvc/README.txt | 24 ccache-msvc/bin/ccache.exe |binary ccache-msvc/patches/0001-MSVC-Add-MSVC-under-Cygwin-support.patch | 726 ---------- ccache-msvc/patches/0001-make-MSVC-work.patch | 140 + ccache-msvc/patches/0002-MSVC-Fix-detection-of-the-MSVC-compiler.patch | 33 ccache-msvc/patches/0002-redirect-stdout-for-showIncludes.patch | 135 + ccache-msvc/patches/0003-MSVC-Re-route-the-preprocessor-s-stderr-to-stdout-to.patch | 67 ccache-msvc/patches/0003-cl.exe-does-not-like-unix-style-paths.patch | 57 ccache-msvc/patches/0004-MSVC-Handle-the-error-output-correctly-when-the-comp.patch | 65 9 files changed, 339 insertions(+), 908 deletions(-)
New commits: commit 2f4b4613f300931e32abeb9912733e7cb0489102 Author: Peter Foley <pefol...@verizon.net> Date: Fri Sep 14 21:20:15 2012 -0400 update ccache for MSVC from 2.4 to 3.1.8 Change-Id: I84c1fdc3f40bd2cefc47b5dc06c186d73ba72a08 Reviewed-on: https://gerrit.libreoffice.org/2856 Reviewed-by: Jan Holesovsky <ke...@suse.cz> Tested-by: Jan Holesovsky <ke...@suse.cz> diff --git a/ccache-msvc/README.txt b/ccache-msvc/README.txt index 89f0769..056f477 100644 --- a/ccache-msvc/README.txt +++ b/ccache-msvc/README.txt @@ -1,28 +1,20 @@ ccache for MSVC =============== -This is a serie of patches that enable ccache to work with Microsoft Visual -C++ compiler. This is an experimental work - works for me for the LibreOffice -building, but of course in is not guaranteed to work for you :-) Also the -time saved is not that huge, the preprocessing takes quite some time with MSVC. +This is a series of patches that enable ccache to work with Microsoft Visual +C++ compiler. This is an experimental work - works for me for building LibreOffice, +but of course is not guaranteed to work for you :-) How to make it work for you with LibreOffice: # copy it somewhere visible in your PATH cp bin/ccache.exe ~/bin -# set it up (and make sure the variables are setup in your environment) -cat >> ~/.bashrc << EOF -export PATH=~/bin:"$PATH" -export CC="ccache C:/PROGRA~1/MICROS~1.0/VC/bin/cl.exe" -export CXX="ccache C:/PROGRA~1/MICROS~1.0/VC/bin/cl.exe" -EOF - ccache -M 10G # enjoy it! :-) cd LibreOffice/master -./autogen.sh +./autogen.sh --enable-ccache # check that ccache is visible in the output of autogen.sh before running make make @@ -32,17 +24,15 @@ ccache -s How to build your own version ----------------------------- -If you do not trust the ccache.exe binary, you can build your own. It is -based on a pre-historic 2.4 release, but I did not have the energy to update -my old patches against anything more recent, so I am afraid you have to live -with that ;-) +If you do not trust the ccache.exe binary, you can build your own. +The patches are based on 3.1.8 so they may not apply on a different version. # get it and apply the patches git clone git//git.samba.org/ccache.git ~/ccache cd ~/ccache -git checkout -b ccache-msvc v2.4 git am ~/dev-tools/ccache-msvc/patches/* # build it +./autogen.sh ./configure make diff --git a/ccache-msvc/bin/ccache.exe b/ccache-msvc/bin/ccache.exe index 9f7ed6a..992bd94 100755 Binary files a/ccache-msvc/bin/ccache.exe and b/ccache-msvc/bin/ccache.exe differ diff --git a/ccache-msvc/patches/0001-MSVC-Add-MSVC-under-Cygwin-support.patch b/ccache-msvc/patches/0001-MSVC-Add-MSVC-under-Cygwin-support.patch deleted file mode 100644 index 98ff5e7..0000000 --- a/ccache-msvc/patches/0001-MSVC-Add-MSVC-under-Cygwin-support.patch +++ /dev/null @@ -1,726 +0,0 @@ -From 24f4ca7ecf6899c9b0018c6075f7ed47ffb4b21b Mon Sep 17 00:00:00 2001 -From: Jan Holesovsky <ke...@suse.cz> -Date: Sun, 17 Apr 2011 23:40:14 +0200 -Subject: [PATCH 1/4] MSVC: Add MSVC (under Cygwin) support. - ---- - ccache.c | 469 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- - ccache.h | 9 ++ - execute.c | 51 +++++++ - util.c | 21 +++ - 4 files changed, 495 insertions(+), 55 deletions(-) - -diff --git a/ccache.c b/ccache.c -index c15ced5..efede2a 100644 ---- a/ccache.c -+++ b/ccache.c -@@ -65,6 +65,12 @@ char *stats_file = NULL; - /* can we safely use the unification hashing backend? */ - static int enable_unify; - -+/* what compiler are we using? */ -+static compiler_type compiler = COMPILER_GCC; -+ -+/* should we output all the options into a file? */ -+static int args_into_file = 0; -+ - /* a list of supported file extensions, and the equivalent - extension for code that has been through the pre-processor - */ -@@ -153,17 +159,29 @@ static const char *tmp_string(void) - /* run the real compiler and put the result in cache */ - static void to_cache(ARGS *args) - { -- char *path_stderr; -+ char *path_stdout, *path_stderr; - char *tmp_stdout, *tmp_stderr, *tmp_hashname; -+ char *tmp; - struct stat st1, st2; -- int status; -+ int status = -1; - - x_asprintf(&tmp_stdout, "%s/tmp.stdout.%s", temp_dir, tmp_string()); - x_asprintf(&tmp_stderr, "%s/tmp.stderr.%s", temp_dir, tmp_string()); - x_asprintf(&tmp_hashname, "%s/tmp.hash.%s.o", temp_dir, tmp_string()); - -- args_add(args, "-o"); -- args_add(args, tmp_hashname); -+ switch (compiler) { -+ case COMPILER_GCC: -+ args_add(args, "-o"); -+ args_add(args, tmp_hashname); -+ break; -+ case COMPILER_MSVC: -+ x_asprintf(&tmp, "-Fo%s", tmp_hashname); -+ args_add(args, tmp); -+ break; -+ default: -+ cc_log("Unknown compiler!? (argv[0]='%s')\n", args->argv[0]); -+ failed(); -+ } - - /* Turn off DEPENDENCIES_OUTPUT when running cc1, because - * otherwise it will emit a line like -@@ -178,18 +196,41 @@ static void to_cache(ARGS *args) - } else { - args_add(args, i_tmpfile); - } -- status = execute(args->argv, tmp_stdout, tmp_stderr); -- args_pop(args, 3); - -- if (stat(tmp_stdout, &st1) != 0 || st1.st_size != 0) { -- cc_log("compiler produced stdout for %s\n", output_file); -- stats_update(STATS_STDOUT); -+ switch (compiler) { -+ case COMPILER_GCC: -+ status = execute(args->argv, tmp_stdout, tmp_stderr); -+ args_pop(args, 3); -+ if (stat(tmp_stdout, &st1) != 0 || st1.st_size != 0) { -+ cc_log("compiler produced stdout for %s\n", output_file); -+ stats_update(STATS_STDOUT); -+ unlink(tmp_stdout); -+ unlink(tmp_stderr); -+ unlink(tmp_hashname); -+ failed(); -+ } - unlink(tmp_stdout); -- unlink(tmp_stderr); -- unlink(tmp_hashname); -+ break; -+ case COMPILER_MSVC: -+ if (!args_into_file) { -+ status = execute(args->argv, tmp_stdout, tmp_stderr); -+ } -+ else { -+ char *tmp_args; -+ x_asprintf(&tmp_args, "%s.tmp.%s.arg", hashname, tmp_string()); -+ -+ status = execute_msvc_external_args( -+ args->argv, -+ tmp_args, -+ tmp_stdout, -+ tmp_stderr); -+ } -+ args_pop(args, 2); -+ break; -+ default: -+ /* just for case */ - failed(); - } -- unlink(tmp_stdout); - - if (status != 0) { - int fd; -@@ -228,11 +269,13 @@ static void to_cache(ARGS *args) - failed(); - } - -+ x_asprintf(&path_stdout, "%s.stdout", hashname); - x_asprintf(&path_stderr, "%s.stderr", hashname); - - if (stat(tmp_stderr, &st1) != 0 || - stat(tmp_hashname, &st2) != 0 || - rename(tmp_hashname, hashname) != 0 || -+ (compiler == COMPILER_MSVC && rename(tmp_stdout, path_stdout) != 0) || - rename(tmp_stderr, path_stderr) != 0) { - cc_log("failed to rename tmp files - %s\n", strerror(errno)); - stats_update(STATS_ERROR); -@@ -246,6 +289,7 @@ static void to_cache(ARGS *args) - free(tmp_stderr); - free(tmp_stdout); - free(path_stderr); -+ free(path_stdout); - } - - /* find the hash for a command. The hash includes all argument lists, -@@ -257,7 +301,7 @@ static void find_hash(ARGS *args) - char *hash_dir; - char *s; - struct stat st; -- int status; -+ int status = -1; - int nlevels = 2; - char *input_base; - char *tmp; -@@ -282,35 +326,61 @@ static void find_hash(ARGS *args) - - /* 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++; -+ switch (compiler) { -+ case COMPILER_GCC: -+ /* 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], "-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; -+ 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; -+ } -+ break; -+ case COMPILER_MSVC: -+ /* 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 (strncmp(args->argv[i], "/I", 2) == 0 || -+ strncmp(args->argv[i], "-I", 2) == 0 || -+ strncmp(args->argv[i], "/D", 2) == 0 || -+ strncmp(args->argv[i], "-D", 2) == 0 || -+ strncmp(args->argv[i], "/u", 2) == 0 || -+ strncmp(args->argv[i], "-u", 2) == 0 || -+ strncmp(args->argv[i], "/U", 2) == 0 || -+ strncmp(args->argv[i], "-U", 2) == 0 || -+ strncmp(args->argv[i], "/AI", 3) == 0 || -+ strncmp(args->argv[i], "-AI", 3) == 0) { -+ continue; -+ } -+ /* TODO more of them to ignore? */ -+ break; -+ default: -+ cc_log("Unknown compiler!? (argv[0]='%s')\n", args->argv[0]); -+ failed(); - } - - /* all other arguments are included in the hash */ -@@ -364,10 +434,37 @@ static void find_hash(ARGS *args) - - if (!direct_i_file) { - /* run cpp on the input file to obtain the .i */ -- args_add(args, "-E"); -- args_add(args, input_file); -- status = execute(args->argv, path_stdout, path_stderr); -- args_pop(args, 2); -+ switch (compiler) { -+ case COMPILER_GCC: -+ args_add(args, "-E"); -+ args_add(args, input_file); -+ status = execute(args->argv, path_stdout, path_stderr); -+ args_pop(args, 2); -+ break; -+ case COMPILER_MSVC: -+ args_add(args, "-E"); -+ args_add(args, input_file); -+ if (!args_into_file) { -+ status = execute(args->argv, path_stdout, path_stderr); -+ } -+ else { -+ char *path_args; -+ x_asprintf(&path_args, "%s/%s.tmp.%s.arg", -+ temp_dir, -+ input_base, tmp_string()); -+ -+ status = execute_msvc_external_args( -+ args->argv, -+ path_args, -+ path_stdout, -+ path_stderr); -+ } -+ args_pop(args, 2); -+ break; -+ default: -+ cc_log("Unknown compiler!? (argv[0]='%s')\n", args->argv[0]); -+ failed(); -+ } - } else { - /* we are compiling a .i or .ii file - that means we - can skip the cpp stage and directly form the -@@ -577,6 +674,11 @@ static void find_compiler(int argc, char **argv) - base = strdup(path); - } - -+ /* do we use Visual C++? */ -+ if (strcmp(base, "cl") == 0 || strcmp(base, "cl.exe") == 0) { -+ compiler = COMPILER_MSVC; -+ } -+ - orig_args->argv[0] = find_executable(base, MYNAME); - - /* can't find the compiler! */ -@@ -594,6 +696,7 @@ static const char *check_extension(const char *fname, int *direct_i) - { - int i; - const char *p; -+ char *tmp; - - if (direct_i) { - *direct_i = 0; -@@ -602,25 +705,39 @@ static const char *check_extension(const char *fname, int *direct_i) - p = strrchr(fname, '.'); - if (!p) return NULL; - p++; -- for (i=0; extensions[i].extension; i++) { -- if (strcmp(p, extensions[i].extension) == 0) { -- if (direct_i && strcmp(p, extensions[i].i_extension) == 0) { -- *direct_i = 1; -+ -+ switch (compiler) { -+ case COMPILER_GCC: -+ for (i=0; extensions[i].extension; i++) { -+ if (strcmp(p, extensions[i].extension) == 0) { -+ if (direct_i && strcmp(p, extensions[i].i_extension) == 0) { -+ *direct_i = 1; -+ } -+ p = getenv("CCACHE_EXTENSION"); -+ if (p) return p; -+ return extensions[i].i_extension; - } -- p = getenv("CCACHE_EXTENSION"); -- if (p) return p; -- return extensions[i].i_extension; - } -+ break; -+ case COMPILER_MSVC: -+ if (direct_i) { -+ /* no direct_i support */ -+ *direct_i = 0; -+ } -+ x_asprintf(&tmp, "pre.%s", p); -+ return tmp; -+ break; -+ default: -+ cc_log("Unknown compiler!?\n"); -+ failed(); - } -+ - return NULL; - } - - --/* -- process the compiler options to form the correct set of options -- for obtaining the preprocessor output --*/ --static void process_args(int argc, char **argv) -+/* gcc compiler options */ -+static void process_args_gcc(int argc, char **argv) - { - int i; - int found_c_opt = 0; -@@ -831,6 +948,248 @@ static void process_args(int argc, char **argv) - } - } - -+ -+/* process the MSVC arguments */ -+static void msvc_options(char *arg, int *c_opt) -+{ -+ struct stat st; -+ -+ if (strlen(arg) == 0) { -+ return; -+ } -+ -+ /* some options will never work ... */ -+ if (strcmp(arg, "/E") == 0 || -+ strcmp(arg, "-E") == 0 || -+ strcmp(arg, "/EP") == 0 || -+ strcmp(arg, "-EP") == 0 || -+ strcmp(arg, "/P") == 0 || -+ strcmp(arg, "-P") == 0) { -+ failed(); -+ } -+ -+ /* we must have /c */ -+ if (strcmp(arg, "/c") == 0 || -+ strcmp(arg, "-c") == 0) { -+ args_add(stripped_args, arg); -+ if (c_opt) { -+ *c_opt = 1; -+ } -+ else { -+ failed(); -+ } -+ return; -+ } -+ -+ /* the definition of the output file */ -+ if (strncmp(arg, "/Fo", 3) == 0 || -+ strncmp(arg, "-Fo", 3) == 0) { -+ output_file = x_strdup(&arg[3]); -+ return; -+ } -+ -+ /* other options */ -+ if (arg[0] == '/' || -+ arg[0] == '-') { -+ args_add(stripped_args, arg); -+ return; -+ } -+ -+ /* if an argument isn't a plain file then assume its -+ an option, not an input file. This allows us to -+ cope better with unusual compiler options */ -+ if (stat(arg, &st) != 0 || !S_ISREG(st.st_mode)) { -+ args_add(stripped_args, arg); -+ return; -+ } -+ -+ if (input_file) { -+ if (check_extension(arg, NULL)) { -+ cc_log("multiple input files (%s and %s)\n", -+ input_file, arg); -+ stats_update(STATS_MULTIPLE); -+ } else if (c_opt && !*c_opt) { -+ cc_log("called for link with %s\n", arg); -+ if (strstr(arg, "conftest.")) { -+ stats_update(STATS_CONFTEST); -+ } else { -+ stats_update(STATS_LINK); -+ } -+ } else { -+ cc_log("non C/C++ file %s\n", arg); -+ stats_update(STATS_NOTC); -+ } -+ failed(); -+ } -+ -+ input_file = x_strdup(arg); -+} -+ -+/* MSVC compiler options */ -+static void process_args_msvc(int argc, char **argv) -+{ -+ int i; -+ int found_c_opt = 0; -+ /* FIXME do we have to handle it? -+ 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++) { -+ /* we have to look into the @file */ -+ if (argv[i][0] == '@') { -+ FILE *file; -+ char buf[4096]; -+ -+ args_into_file = 1; -+ -+ file = fopen(argv[i]+1, "r"); -+ if (!file) { -+ cc_log("fopen failed! %s\n", argv[i]+1); -+ failed(); -+ } -+ while (!feof(file)) { -+ char *begin, *end; -+ fgets(buf, 4096, file); -+ -+ begin = end = buf; -+ while (begin && *begin) { -+ int finish = 0; -+ -+ /* FIXME handle escapes, ", ', etc. */ -+ for (; *end && -+ *end != ' ' && -+ *end != '\n' && -+ *end != '\r'; -+ ++end); -+ -+ if (*end) { -+ *end = 0; -+ ++end; -+ } -+ else { -+ finish = 1; -+ } -+ -+ /* process the options */ -+ msvc_options(begin, &found_c_opt); -+ -+ begin = finish? NULL: end; -+ } -+ } -+ fclose(file); -+ continue; -+ } -+ -+ /* The user knows best: just swallow the next arg */ -+ if (strcmp(argv[i], "--ccache-skip") == 0) { -+ i++; -+ if (i == argc) { -+ failed(); -+ } -+ args_add(stripped_args, argv[i]); -+ continue; -+ } -+ -+ /* process the options */ -+ msvc_options(argv[i], &found_c_opt); -+ } -+ -+ if (!input_file) { -+ cc_log("No input file found\n"); -+ stats_update(STATS_NOINPUT); -+ failed(); -+ } -+ -+ i_extension = check_extension(input_file, &direct_i_file); -+ if (i_extension == NULL) { -+ cc_log("Not a C/C++ file - %s\n", input_file); -+ stats_update(STATS_NOTC); -+ failed(); -+ } -+ -+ if (!found_c_opt) { -+ cc_log("No -c option found for %s\n", input_file); -+ /* I find that having a separate statistic for autoconf tests is useful, -+ as they are the dominant form of "called for link" in many cases */ -+ if (strstr(input_file, "conftest.")) { -+ stats_update(STATS_CONFTEST); -+ } else { -+ stats_update(STATS_LINK); -+ } -+ failed(); -+ } -+ -+ -+ /* don't try to second guess the compilers heuristics for stdout handling */ -+ if (output_file && strcmp(output_file, "-") == 0) { -+ stats_update(STATS_OUTSTDOUT); -+ failed(); -+ } -+ -+ if (!output_file) { -+ char *p,*q; -+ char *tmp; -+ tmp = x_strdup(input_file); -+ p = strrchr(tmp, '\\'); -+ q = strrchr(tmp, '/'); -+ if (p || q) { -+ tmp = (p > q)? p+1: q+1; -+ } -+ p = strrchr(tmp, '.'); -+ if (!p) { -+ cc_log("badly formed tmp %s\n", tmp); -+ stats_update(STATS_ARGS); -+ failed(); -+ } -+ *p = 0; -+ x_asprintf(&output_file, "%s.obj", tmp); -+ /* FIXME something for the found_S_opt case as well? -+ p[1] = found_S_opt ? 's' : 'o'; -+ p[2] = 0;*/ -+ } -+ -+ /* cope with -o /dev/null */ -+ if (strcmp(output_file,"/dev/null") != 0 && stat(output_file, &st) == 0 && !S_ISREG(st.st_mode)) { -+ cc_log("Not a regular file %s\n", output_file); -+ stats_update(STATS_DEVICE); -+ failed(); -+ } -+ -+ if ((e=getenv("CCACHE_PREFIX"))) { -+ char *p = find_executable(e, MYNAME); -+ if (!p) { -+ perror(e); -+ exit(1); -+ } -+ args_add_prefix(stripped_args, p); -+ } -+} -+ -+ -+/* -+ process the compiler options to form the correct set of options -+ for obtaining the preprocessor output -+*/ -+static void process_args(int argc, char **argv) -+{ -+ switch (compiler) { -+ case COMPILER_GCC: -+ process_args_gcc(argc, argv); -+ break; -+ case COMPILER_MSVC: -+ process_args_msvc(argc, argv); -+ break; -+ default: -+ cc_log("Unknown compiler!? (argv[0]='%s')\n", argv[0]); -+ failed(); -+ } -+} -+ - /* the main ccache driver function */ - static void ccache(int argc, char *argv[]) - { -diff --git a/ccache.h b/ccache.h -index faec597..a09de1b 100644 ---- a/ccache.h -+++ b/ccache.h -@@ -63,6 +63,11 @@ enum stats { - STATS_END - }; - -+typedef enum { -+ COMPILER_GCC, -+ COMPILER_MSVC -+} compiler_type; -+ - typedef unsigned uint32; - - #include "mdfour.h" -@@ -126,6 +131,10 @@ void wipe_all(const char *dir); - int execute(char **argv, - const char *path_stdout, - const char *path_stderr); -+int execute_msvc_external_args(char **argv, -+ const char *path_args, -+ const char *path_stdout, -+ const char *path_stderr); - char *find_executable(const char *name, const char *exclude_name); - - typedef struct { -diff --git a/execute.c b/execute.c -index 4b98ab7..245d78c 100644 ---- a/execute.c -+++ b/execute.c -@@ -68,6 +68,57 @@ int execute(char **argv, - - - /* -+ execute a compiler backend, capturing all output to the given paths -+ the full path to the compiler to run is in argv[0] -+ all the other args are stored in a @file -+*/ -+int execute_msvc_external_args(char **argv, -+ const char *path_args, -+ const char *path_stdout, -+ const char *path_stderr) -+{ -+ char *tmp; -+ FILE *file; -+ char **a; -+ static ARGS *tmp_args; -+ int status = -1; -+ -+ /* create the file */ -+ file = fopen(path_args, "w"); -+ a = argv; -+ if (!file || !(*a)) { -+ return -1; -+ } -+ /* skip the compiler (argv[0]) */ -+ ++a; -+ if (!(*a)) { -+ return -1; -+ } -+ -+ for (; *a; ++a) { -+ if (strchr(*a, '"')) { -+ /* FIXME escape properly instead of failing */ -+ return -1; -+ } -+ fprintf(file, "\"%s\" ", *a); -+ } -+ fprintf(file, "\n"); -+ fclose(file); -+ -+ /* create temporary args with @file as the only param */ -+ tmp_args = args_init(0, NULL); -+ args_add(tmp_args, argv[0]); -+ x_asprintf(&tmp, "@%s", path_args); -+ args_add(tmp_args, tmp); -+ -+ status = execute(tmp_args->argv, path_stdout, path_stderr); -+ -+ unlink(path_args); -+ return status; -+} -+ -+ -+/* - find an executable by name in $PATH. Exclude any that are links to exclude_name - */ - char *find_executable(const char *name, const char *exclude_name) -diff --git a/util.c b/util.c -index ec5ccdd..2ca5461 100644 ---- a/util.c -+++ b/util.c -@@ -245,6 +245,12 @@ void traverse(const char *dir, void (*fn)(const char *, struct stat *)) - char *str_basename(const char *s) - { - char *p = strrchr(s, '/'); -+#ifdef __CYGWIN__ -+ char *q = strrchr(s, '\\'); -+ if (!p || (q && (q > p))) { -+ p = q; -+ } -+#endif - if (p) { - return x_strdup(p+1); - } -@@ -437,6 +443,21 @@ int create_empty_file(const char *fname) - const char *get_home_directory(void) - { - const char *p = getenv("HOME"); -+ -+ /* FIXME this is just for MSVC - do it better */ -+ const char *homedrive = getenv("HOMEDRIVE"); -+ const char *homepath = getenv("HOMEPATH"); -+ char *tmp; -+ -+ if (homedrive) { -+ if (homepath) { -+ x_asprintf(&tmp, "%s\\%s", homedrive, homepath); -+ return tmp; -+ } -+ else { -+ return homedrive; -+ } -+ } - if (p) { - return p; - } --- -1.7.2.3 - diff --git a/ccache-msvc/patches/0001-make-MSVC-work.patch b/ccache-msvc/patches/0001-make-MSVC-work.patch new file mode 100644 index 0000000..c81abad --- /dev/null +++ b/ccache-msvc/patches/0001-make-MSVC-work.patch @@ -0,0 +1,140 @@ +From f4926a6f06fd43a76b2ecbc2a9735f0bc64785c8 Mon Sep 17 00:00:00 2001 +From: Peter Foley <pefol...@verizon.net> +Date: Thu, 13 Sep 2012 16:51:33 -0400 +Subject: [PATCH 1/3] make MSVC work + +--- + ccache.c | 45 +++++++++++++++++++++++++++++++++++++++------ + ccache.h | 5 +++++ + 2 files changed, 44 insertions(+), 6 deletions(-) + +diff --git a/ccache.c b/ccache.c +index 0e93486..2235656 100644 +--- a/ccache.c ++++ b/ccache.c +@@ -89,6 +89,9 @@ static struct args *orig_args; + /* the source file */ + static char *input_file; + ++/* what compiler are we using? */ ++static compiler_type type = COMPILER_GCC; ++ + /* The output file being compiled to. */ + static char *output_obj; + +@@ -571,7 +574,7 @@ process_preprocessed_file(struct mdfour *hash, const char *path) + static void + to_cache(struct args *args) + { +- char *tmp_stdout, *tmp_stderr, *tmp_obj; ++ char *tmp_stdout, *tmp_stderr, *tmp_obj, *tmp; + struct stat st; + int status; + size_t added_bytes = 0; +@@ -591,8 +594,15 @@ to_cache(struct args *args) + tmp_obj = format("%s.tmp.%s", cached_obj, tmp_string()); + } + +- args_add(args, "-o"); +- args_add(args, tmp_obj); ++ if (type == COMPILER_MSVC) { ++ tmp = format("%s%s", "-Fo", tmp_obj); ++ args_add(args, tmp); ++ } else { ++ args_add(args, "-o"); ++ args_add(args, tmp_obj); ++ } ++ ++ + + /* Turn off DEPENDENCIES_OUTPUT when running cc1, because + * otherwise it will emit a line like +@@ -604,7 +614,16 @@ to_cache(struct args *args) + if (conf->run_second_cpp) { + args_add(args, input_file); + } else { +- args_add(args, i_tmpfile); ++ if (type == COMPILER_MSVC) { ++ if (str_eq(conf->cpp_extension,"ii")) { ++ tmp = format("%s%s", "-Tp", i_tmpfile); ++ } else { ++ tmp = format("%s%s", "-Tc", i_tmpfile); ++ } ++ args_add(args, tmp); ++ } else { ++ args_add(args, i_tmpfile); ++ } + } + + cc_log("Running real compiler"); +@@ -614,7 +633,7 @@ to_cache(struct args *args) + if (stat(tmp_stdout, &st) != 0) { + fatal("Could not create %s (permission denied?)", tmp_stdout); + } +- if (st.st_size != 0) { ++ if (st.st_size != 0 && type != COMPILER_MSVC) { + cc_log("Compiler produced stdout"); + stats_update(STATS_STDOUT); + tmp_unlink(tmp_stdout); +@@ -1375,6 +1394,10 @@ find_compiler(char **argv) + free(base); + if (is_full_path(orig_args->argv[0])) { + /* a full path was given */ ++ /* are we using Visual C++? */ ++ if (str_eq(basename(orig_args->argv[0]), "cl") || str_eq(basename(orig_args->argv[0]), "cl.exe")) { ++ type = COMPILER_MSVC; ++ } + return; + } + base = basename(orig_args->argv[0]); +@@ -1384,6 +1407,10 @@ find_compiler(char **argv) + if (!str_eq(conf->compiler, "")) { + base = conf->compiler; + } ++ /* are we using Visual C++? */ ++ if (str_eq(base, "cl") || str_eq(base, "cl.exe")) { ++ type = COMPILER_MSVC; ++ } + + compiler = find_executable(base, MYNAME); + +@@ -1573,6 +1600,12 @@ cc_process_args(struct args *args, struct args **preprocessor_args, + continue; + } + ++ /* MSVC */ ++ if (str_startswith(argv[i], "-Fo")) { ++ output_obj = make_relative_path(x_strdup(&argv[i][3])); ++ continue; ++ } ++ + /* debugging is handled specially, so that we know if we + can strip line number info + */ +@@ -1596,7 +1629,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args, + /* These options require special handling, because they + behave differently with gcc -E, when the output + file is not specified. */ +- if (str_eq(argv[i], "-MD") || str_eq(argv[i], "-MMD")) { ++ if ((str_eq(argv[i], "-MD") && type != COMPILER_MSVC) || str_eq(argv[i], "-MMD")) { + generating_dependencies = true; + args_add(dep_args, argv[i]); + continue; +diff --git a/ccache.h b/ccache.h +index 18a2b9e..7a0fbef 100644 +--- a/ccache.h ++++ b/ccache.h +@@ -53,6 +53,11 @@ enum stats { + STATS_END + }; + ++typedef enum { ++ COMPILER_GCC, ++ COMPILER_MSVC ++} compiler_type; ++ + #define SLOPPY_INCLUDE_FILE_MTIME 1 + #define SLOPPY_FILE_MACRO 2 + #define SLOPPY_TIME_MACROS 4 +-- +1.7.9 diff --git a/ccache-msvc/patches/0002-MSVC-Fix-detection-of-the-MSVC-compiler.patch b/ccache-msvc/patches/0002-MSVC-Fix-detection-of-the-MSVC-compiler.patch deleted file mode 100644 index d15f563..0000000 --- a/ccache-msvc/patches/0002-MSVC-Fix-detection-of-the-MSVC-compiler.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 30bec927b0b755b26c9106462276038bdb69753a Mon Sep 17 00:00:00 2001 -From: Jan Holesovsky <ke...@suse.cz> -Date: Mon, 18 Apr 2011 15:13:15 +0200 -Subject: [PATCH 2/4] MSVC: Fix detection of the MSVC compiler. - ---- - ccache.c | 6 +++++- - 1 files changed, 5 insertions(+), 1 deletions(-) - -diff --git a/ccache.c b/ccache.c -index efede2a..b4e7e21 100644 ---- a/ccache.c -+++ b/ccache.c -@@ -662,11 +662,15 @@ static void find_compiler(int argc, char **argv) - if (strcmp(base, MYNAME) == 0) { - args_remove_first(orig_args); - free(base); -+ base = str_basename(argv[1]); -+ if (strcmp(base, "cl") == 0 || strcmp(base, "cl.exe") == 0) { -+ compiler = COMPILER_MSVC; -+ } - if (strchr(argv[1],'/')) { - /* a full path was given */ -+ free(base); - return; - } -- base = str_basename(argv[1]); - } - - /* support user override of the compiler */ --- -1.7.2.3 - diff --git a/ccache-msvc/patches/0002-redirect-stdout-for-showIncludes.patch b/ccache-msvc/patches/0002-redirect-stdout-for-showIncludes.patch new file mode 100644 index 0000000..5590511 --- /dev/null +++ b/ccache-msvc/patches/0002-redirect-stdout-for-showIncludes.patch @@ -0,0 +1,135 @@ +From b5e87e9392c098c28a6023fbbec8d99aeac608b8 Mon Sep 17 00:00:00 2001 +From: Peter Foley <pefol...@verizon.net> +Date: Fri, 14 Sep 2012 19:22:53 -0400 +Subject: [PATCH 2/3] redirect stdout for -showIncludes + +--- + ccache.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 files changed, 65 insertions(+), 1 deletions(-) + +diff --git a/ccache.c b/ccache.c +index 2235656..5963cee 100644 +--- a/ccache.c ++++ b/ccache.c +@@ -116,6 +116,9 @@ static char *cached_obj; + */ + static char *cached_stderr; + ++/* for MSVC */ ++static char *cached_stdout; ++ + /* + * Full path to the file containing the dependency information + * (cachedir/a/b/cdef[...]-size.d). +@@ -641,7 +644,8 @@ to_cache(struct args *args) + tmp_unlink(tmp_obj); + failed(); + } +- tmp_unlink(tmp_stdout); ++ if (type != COMPILER_MSVC) ++ tmp_unlink(tmp_stdout); + + /* + * Merge stderr from the preprocessor (if any) and stderr from the real +@@ -674,6 +678,22 @@ to_cache(struct args *args) + cc_log("Failed opening %s: %s", tmp_stderr, strerror(errno)); + failed(); + } ++ if (type == COMPILER_MSVC) { ++ int fd_stdout = open(tmp_stdout, O_RDONLY | O_BINARY); ++ if (fd_stdout == -1) { ++ cc_log("Failed opening %s: %s", tmp_stdout, strerror(errno)); ++ failed(); ++ } ++ copy_fd(fd_stdout, fd_result); ++ close(fd_stdout); ++ fd_stdout = open(tmp_stdout, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); ++ if (fd_stdout == -1) { ++ cc_log("Failed opening %s: %s", tmp_stdout, strerror(errno)); ++ failed(); ++ } ++ copy_fd(fd_cpp_stderr, fd_stdout); ++ close(fd_stdout); ++ } + copy_fd(fd_cpp_stderr, fd_result); + copy_fd(fd_real_stderr, fd_result); + close(fd_cpp_stderr); +@@ -699,11 +719,15 @@ to_cache(struct args *args) + copy_fd(fd, 2); + close(fd); + tmp_unlink(tmp_stderr); ++ if (type == COMPILER_MSVC) ++ tmp_unlink(tmp_stdout); + exit(status); + } + } + + tmp_unlink(tmp_stderr); ++ if (type == COMPILER_MSVC) ++ tmp_unlink(tmp_stdout); + tmp_unlink(tmp_obj); + failed(); + } +@@ -747,6 +771,36 @@ to_cache(struct args *args) + } + } + ++ if (type == COMPILER_MSVC) { ++ if (stat(tmp_stdout, &st) != 0) { ++ cc_log("Failed to stat %s: %s", tmp_stdout, strerror(errno)); ++ stats_update(STATS_ERROR); ++ failed(); ++ } ++ if (st.st_size > 0) { ++ if (move_uncompressed_file( ++ tmp_stdout, cached_stdout, ++ conf->compression ? conf->compression_level : 0) != 0) { ++ cc_log("Failed to move %s to %s: %s", tmp_stdout, cached_stdout, ++ strerror(errno)); ++ stats_update(STATS_ERROR); ++ failed(); ++ } ++ cc_log("Stored in cache: %s", cached_stdout); ++ if (conf->compression) { ++ stat(cached_stdout, &st); ++ } ++ added_bytes += file_size(&st); ++ added_files += 1; ++ } else { ++ tmp_unlink(tmp_stdout); ++ if (conf->recache) { ++ /* If recaching, we need to remove any previous .stdout. */ ++ x_unlink(cached_stdout); ++ } ++ } ++ } ++ + if (output_to_real_object_first) { + int ret; + if (conf->hard_link && !conf->compression) { +@@ -927,6 +981,8 @@ update_cached_result_globals(struct file_hash *hash) + cached_obj_hash = hash; + cached_obj = get_path_in_cache(object_name, ".o"); + cached_stderr = get_path_in_cache(object_name, ".stderr"); ++ if (type == COMPILER_MSVC) ++ cached_stdout = get_path_in_cache(object_name, ".stdout"); + cached_dep = get_path_in_cache(object_name, ".d"); + stats_file = format("%s/%c/stats", conf->cache_dir, object_name[0]); + free(object_name); +@@ -1334,6 +1390,14 @@ from_cache(enum fromcache_call_mode mode, bool put_object_in_manifest) + copy_fd(fd_stderr, 2); + close(fd_stderr); + } ++ /* Send the stdout for MSVC */ ++ if (type == COMPILER_MSVC) { ++ int fd_stdout = open(cached_stdout, O_RDONLY | O_BINARY); ++ if (fd_stdout != -1) { ++ copy_fd(fd_stdout, 1); ++ close(fd_stdout); ++ } ++ } + + /* Create or update the manifest file. */ + if (conf->direct_mode +-- +1.7.9 diff --git a/ccache-msvc/patches/0003-MSVC-Re-route-the-preprocessor-s-stderr-to-stdout-to.patch b/ccache-msvc/patches/0003-MSVC-Re-route-the-preprocessor-s-stderr-to-stdout-to.patch deleted file mode 100644 index d3243e6..0000000 --- a/ccache-msvc/patches/0003-MSVC-Re-route-the-preprocessor-s-stderr-to-stdout-to.patch +++ /dev/null @@ -1,67 +0,0 @@ -From cd5b0208db501364359fb53bd4f1d77dd58714bd Mon Sep 17 00:00:00 2001 -From: Jan Holesovsky <ke...@suse.cz> -Date: Mon, 18 Apr 2011 16:12:24 +0200 -Subject: [PATCH 3/4] MSVC: Re-route the preprocessor's stderr to stdout, to handle -showIncludes. - ---- - ccache.c | 34 ++++++++++++++++++++++++++++++++-- - 1 files changed, 32 insertions(+), 2 deletions(-) - -diff --git a/ccache.c b/ccache.c -index b4e7e21..7df5d01 100644 ---- a/ccache.c -+++ b/ccache.c -@@ -550,7 +550,8 @@ static void find_hash(ARGS *args) - static void from_cache(int first) - { - int fd_stderr, fd_cpp_stderr; -- char *stderr_file; -+ int fd_stdout; -+ char *stderr_file, *stdout_file; - int ret; - struct stat st; - -@@ -624,10 +625,39 @@ static void from_cache(int first) - i_tmpfile = NULL; - } - -+ /* send the stdout - only on MSVC */ -+ switch (compiler) { -+ case COMPILER_MSVC: -+ x_asprintf(&stdout_file, "%s.stdout", hashname); -+ fd_stdout = open(stdout_file, O_RDONLY | O_BINARY); -+ if (fd_stdout == -1) { -+ /* it isn't in cache ... */ -+ free(stdout_file); -+ return; -+ } -+ copy_fd(fd_stdout, 1); -+ close(fd_stdout); -+ break; -+ default: -+ break; -+ } -+ - /* send the cpp stderr, if applicable */ - fd_cpp_stderr = open(cpp_stderr, O_RDONLY | O_BINARY); - if (fd_cpp_stderr != -1) { -- copy_fd(fd_cpp_stderr, 2); -+ switch (compiler) { -+ case COMPILER_MSVC: -+ /* MSVC is confused, and writes the showIncludes to -+ stderr when preprocessing, but to stdout when compiling. -+ Here we assume that during preprocessing, only the -+ dependency info is of some value, so let's store it -+ where it is expected in the 'real run'. */ -+ copy_fd(fd_cpp_stderr, 1); -+ break; -+ default: -+ copy_fd(fd_cpp_stderr, 2); -+ break; -+ } - close(fd_cpp_stderr); - unlink(cpp_stderr); - free(cpp_stderr); --- -1.7.2.3 - diff --git a/ccache-msvc/patches/0003-cl.exe-does-not-like-unix-style-paths.patch b/ccache-msvc/patches/0003-cl.exe-does-not-like-unix-style-paths.patch new file mode 100644 index 0000000..30efcaa --- /dev/null +++ b/ccache-msvc/patches/0003-cl.exe-does-not-like-unix-style-paths.patch @@ -0,0 +1,57 @@ +From e090ba015d393cc968246c7b0c8765d1c987add1 Mon Sep 17 00:00:00 2001 +From: Peter Foley <pefol...@verizon.net> +Date: Sun, 16 Sep 2012 12:08:49 -0400 +Subject: [PATCH 3/3] cl.exe does not like unix-style paths + +--- + ccache.c | 14 ++++++++++++++ + 1 files changed, 14 insertions(+), 0 deletions(-) + +diff --git a/ccache.c b/ccache.c +index 5963cee..a8f689e 100644 +--- a/ccache.c ++++ b/ccache.c +@@ -26,6 +26,9 @@ + #else + #include "getopt_long.h" + #endif ++#ifdef __CYGWIN__ ++#include <sys/cygwin.h> ++#endif + #include "hashtable.h" + #include "hashtable_itr.h" + #include "hashutil.h" +@@ -273,6 +276,15 @@ clean_up_tmp_files() + } + } + ++static char * ++conv_path_to_win(char * unix_path) ++{ ++ ssize_t size = cygwin_conv_path(CCP_POSIX_TO_WIN_A, unix_path, NULL, 0); ++ char *win_path = (char*)malloc(size); ++ cygwin_conv_path(CCP_POSIX_TO_WIN_A, unix_path, win_path, size); ++ return win_path; ++} ++ + static const char * + temp_dir() + { +@@ -1461,6 +1473,7 @@ find_compiler(char **argv) + /* are we using Visual C++? */ + if (str_eq(basename(orig_args->argv[0]), "cl") || str_eq(basename(orig_args->argv[0]), "cl.exe")) { + type = COMPILER_MSVC; ++ conf->cache_dir = conv_path_to_win(conf->cache_dir); + } + return; + } +@@ -1474,6 +1487,7 @@ find_compiler(char **argv) + /* are we using Visual C++? */ + if (str_eq(base, "cl") || str_eq(base, "cl.exe")) { + type = COMPILER_MSVC; ++ conf->cache_dir = conv_path_to_win(conf->cache_dir); + } + + compiler = find_executable(base, MYNAME); +-- +1.7.9 diff --git a/ccache-msvc/patches/0004-MSVC-Handle-the-error-output-correctly-when-the-comp.patch b/ccache-msvc/patches/0004-MSVC-Handle-the-error-output-correctly-when-the-comp.patch deleted file mode 100644 index d8c673e..0000000 --- a/ccache-msvc/patches/0004-MSVC-Handle-the-error-output-correctly-when-the-comp.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 129beb48680166f53f5ce5a384add0c9e506ed00 Mon Sep 17 00:00:00 2001 -From: Jan Holesovsky <ke...@suse.cz> -Date: Mon, 15 Aug 2011 15:15:58 +0200 -Subject: [PATCH 4/4] MSVC: Handle the error output correctly when the compilation fails. - ---- - ccache.c | 23 +++++++++++++++++++++-- - 1 files changed, 21 insertions(+), 2 deletions(-) - -diff --git a/ccache.c b/ccache.c -index 7df5d01..263dc66 100644 ---- a/ccache.c -+++ b/ccache.c -@@ -234,9 +234,18 @@ static void to_cache(ARGS *args) - - if (status != 0) { - int fd; -+ int error_fd = 2; - cc_log("compile of %s gave status = %d\n", output_file, status); - stats_update(STATS_STATUS); - -+ if (compiler == COMPILER_MSVC) { -+ /* MSVC is confused, and writes the showIncludes to -+ stderr when preprocessing, but to stdout when compiling. -+ Let's try to make it consistent, and output everything to -+ stdout regardless what is happening. */ -+ error_fd = 1; -+ } -+ - fd = open(tmp_stderr, O_RDONLY | O_BINARY); - if (fd != -1) { - if (strcmp(output_file, "/dev/null") == 0 || -@@ -245,7 +254,7 @@ static void to_cache(ARGS *args) - /* we might have some stderr from cpp */ - int fd2 = open(cpp_stderr, O_RDONLY | O_BINARY); - if (fd2 != -1) { -- copy_fd(fd2, 2); -+ copy_fd(fd2, error_fd); - close(fd2); - unlink(cpp_stderr); - cpp_stderr = NULL; -@@ -254,9 +263,19 @@ static void to_cache(ARGS *args) - - /* we can use a quick method of - getting the failed output */ -- copy_fd(fd, 2); -+ copy_fd(fd, error_fd); - close(fd); - unlink(tmp_stderr); -+ -+ if (compiler == COMPILER_MSVC) { -+ /* MSVC sends even errors to stdout, copy -+ them too */ -+ fd = open(tmp_stdout, O_RDONLY | O_BINARY); -+ copy_fd(fd, error_fd); -+ close(fd); -+ unlink(tmp_stdout); -+ } -+ - if (i_tmpfile && !direct_i_file) { - unlink(i_tmpfile); - } --- -1.7.2.3 - _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits