[PATCH] update ccache for MSVC from 2.4 to 3.1.8

Peter Foley (via Code Review) gerrit at gerrit.libreoffice.org
Tue Mar 19 14:26:53 PDT 2013


Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/2856

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/dev-tools refs/changes/56/2856/1

update ccache for MSVC from 2.4 to 3.1.8

Change-Id: I84c1fdc3f40bd2cefc47b5dc06c186d73ba72a08
---
M ccache-msvc/README.txt
M ccache-msvc/bin/ccache.exe
D ccache-msvc/patches/0001-MSVC-Add-MSVC-under-Cygwin-support.patch
A ccache-msvc/patches/0001-make-MSVC-work.patch
D ccache-msvc/patches/0002-MSVC-Fix-detection-of-the-MSVC-compiler.patch
A ccache-msvc/patches/0002-redirect-stdout-for-showIncludes.patch
D ccache-msvc/patches/0003-MSVC-Re-route-the-preprocessor-s-stderr-to-stdout-to.patch
A ccache-msvc/patches/0003-cl.exe-does-not-like-unix-style-paths.patch
D ccache-msvc/patches/0004-MSVC-Handle-the-error-output-correctly-when-the-comp.patch
9 files changed, 339 insertions(+), 908 deletions(-)



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 @@
 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
--- a/ccache-msvc/bin/ccache.exe
+++ b/ccache-msvc/bin/ccache.exe
Binary files 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 <kendy at 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 <pefoley2 at 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 <kendy at 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 <pefoley2 at 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 <kendy at 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 <pefoley2 at 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 <kendy at 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
-

-- 
To view, visit https://gerrit.libreoffice.org/2856
To unsubscribe, visit https://gerrit.libreoffice.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I84c1fdc3f40bd2cefc47b5dc06c186d73ba72a08
Gerrit-PatchSet: 1
Gerrit-Project: dev-tools
Gerrit-Branch: master
Gerrit-Owner: Peter Foley <pefoley2 at verizon.net>



More information about the LibreOffice mailing list