Re: [ccache] Support for color diagnostics

2014-06-26 Thread Lubos Lunak
On Thursday 26 of June 2014, Paul Smith wrote:
> On Thu, 2014-06-26 at 18:44 +0200, Lubos Lunak wrote:
> > Caveats:
> > - Compiles with and without colors are considered different from each
> > other (so they are "duplicated").
>
> This doesn't seem ideal, does it?

 No, it doesn't seem ideal. It doesn't seem easy to avoid either.

-- 
 Lubos Lunak
___
ccache mailing list
ccache@lists.samba.org
https://lists.samba.org/mailman/listinfo/ccache


Re: [ccache] Support for color diagnostics

2014-06-26 Thread Paul Smith
On Thu, 2014-06-26 at 18:44 +0200, Lubos Lunak wrote:
> Caveats:
> - Compiles with and without colors are considered different from each
> other (so they are "duplicated").

This doesn't seem ideal, does it?  If I'm understanding this correctly
won't this cause rebuilds based on whether you're redirecting output or
not?

___
ccache mailing list
ccache@lists.samba.org
https://lists.samba.org/mailman/listinfo/ccache


Re: [ccache] Support for color diagnostics

2014-06-26 Thread Lubos Lunak
On Saturday 14 of June 2014, Joel Rosdahl wrote:
> Hi Lubos,
>
> Sorry about the ping delay. I've now looked at your patch and it looks
> promising.
...
> I suggest passing the argument list as an argument to the compiler_is_*
> functions instead of relying on global variables.
>
> When extracting the compiler name, I suggest using basename() from util.c.
> That way it will work on Windows as well.

 Attached is an updated patch that passes also all the tests.

-- 
 Lubos Lunak
From b466ec1fde17ff72989a39c51fbe3f1c68284967 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= 
Date: Fri, 29 Nov 2013 12:14:03 +0100
Subject: [PATCH] support compiler color diagnostics if possible

Clang and GCC (starting with 4.9) support color output if possible,
but since ccache redirects stderr to a file, they detect the output
is not a terminal and do not enable colors. Try to detect if colors
would be used and force colors explicitly.

Caveats:
- Compiles with and without colors are considered different from each
  other (so they are "duplicated").
- GCC decided to roll its own name for the option, so it's necessary
  to guess which compiler is actually used.
---
 ccache.c | 79 
 1 file changed, 79 insertions(+)

diff --git a/ccache.c b/ccache.c
index e583329..49a6c53 100644
--- a/ccache.c
+++ b/ccache.c
@@ -1095,6 +1095,26 @@ hash_compiler(struct mdfour *hash, struct stat *st, const char *path,
 }
 
 /*
+ * Note that these compiler checks are unreliable, so nothing should hard-depend on them.
+ */
+
+static bool compiler_is_clang(struct args *args)
+{
+	char* name = basename(args->argv[ 0 ]);
+	bool is = strstr( name, "clang" ) != NULL;
+	free(name);
+	return is;
+}
+
+static bool compiler_is_gcc(struct args *args)
+{
+	char* name = basename(args->argv[ 0 ]);
+	bool is = strstr(name, "gcc") != NULL || strstr(name, "g++") != NULL;
+	free(name);
+	return is;
+}
+
+/*
  * Update a hash sum with information common for the direct and preprocessor
  * modes.
  */
@@ -1158,6 +1178,15 @@ calculate_common_hash(struct args *args, struct mdfour *hash)
 		}
 		free(p);
 	}
+
+	/* Possibly hash GCC_COLORS (for color diagnostics). */
+	if (compiler_is_gcc(args)) {
+		const char* gcc_colors = getenv("GCC_COLORS");
+		if (gcc_colors != NULL) {
+			hash_delimiter(hash,"gcccolors");
+			hash_string(hash, gcc_colors);
+		}
+	}
 }
 
 /*
@@ -1554,6 +1583,13 @@ is_precompiled_header(const char *path)
 	   || str_eq(get_extension(path), ".pth");
 }
 
+static bool color_output_possible()
+{
+	const char* term_env = getenv("TERM");
+
+	return isatty(STDERR_FILENO) && term_env && strcasecmp(term_env, "DUMB") != 0;
+}
+
 /*
  * Process the compiler options into options suitable for passing to the
  * preprocessor and the real compiler. The preprocessor options don't include
@@ -1582,6 +1618,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
 	int argc;
 	char **argv;
 	bool result = true;
+	bool found_color_diagnostics = false;
 
 	expanded_args = args_copy(args);
 	stripped_args = args_init(0, NULL);
@@ -1938,6 +1975,26 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
 			free(arg);
 		}
 
+		if (str_eq(argv[i], "-fcolor-diagnostics")
+		|| str_eq(argv[i], "-fno-color-diagnostics")
+		|| str_eq(argv[i], "-fdiagnostics-color")
+		|| str_eq(argv[i], "-fdiagnostics-color=always")
+		|| str_eq(argv[i], "-fno-diagnostics-color")
+		|| str_eq(argv[i], "-fdiagnostics-color=never")) {
+			args_add(stripped_args, argv[i]);
+			found_color_diagnostics = true;
+			continue;
+		}
+		if (str_eq(argv[i], "-fdiagnostics-color=auto")) {
+			if (color_output_possible()) {
+/* Output is redirected, so color output must be forced. */
+args_add(stripped_args, "-fdiagnostics-color=always");
+cc_log("Automatically forcing colors");
+			}
+			found_color_diagnostics = true;
+			continue;
+		}
+
 		/*
 		 * Options taking an argument that we may want to rewrite to relative paths
 		 * to get better hit rate. A secondary effect is that paths in the standard
@@ -2228,6 +2285,28 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
 	}
 
 	/*
+	 * Since output is redirected, compilers will not color their output by default,
+	 * so force it explicitly if it would be otherwise done.
+	 */
+	if (!found_color_diagnostics && color_output_possible()) {
+		if (compiler_is_clang(args)) {
+			args_add(stripped_args, "-fcolor-diagnostics");
+			cc_log("Automatically enabling colors");
+		} else if (compiler_is_gcc(args)) {
+			/*
+			 * GCC has it since 4.9, but that'd require detecting what GCC
+			 * version is used for the actual compile. However it requires
+			 * also GCC_COLORS to be set (and not empty), so use that
+			 * for detecting if GCC would use colors.
+			 */
+			if (getenv("GCC_COLORS") != NULL && getenv("GCC_COLORS")[ 0 ] != '\0') {
+args_add(stripped_args, "-fdiagnostics-color");
+