On Tuesday 18 of February 2014, interfaSys Sàrl wrote:
> Hello,
>
> I've just tested the patch with a patched gcc48 with -fdiagnostics-color
> support on FreeBSD 9 and it works with one exception.
>
> GCC's documentations says:
> "‘auto’ means to use color only when the standard error is a terminal"
>
> So, if my understanding is correct, this means that, when using
> -fdiagnostics-color=auto , I should be seeing colours when using the
> terminal and indeed, that's the normal behaviour when ccache falls back to
> the compiler (I see colours).
>
> With that patch, I don't see the colours in auto mode. It only works in
> always mode.

 I see. How about this patch?

-- 
 Lubos Lunak
From cacb14929748ae93eacefcfa194aa93689d217eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= <l.lu...@centrum.cz>
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 | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/ccache.c b/ccache.c
index c395fad..e122c50 100644
--- a/ccache.c
+++ b/ccache.c
@@ -1065,6 +1065,24 @@ 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()
+{
+	const char* name = strrchr( orig_args->argv[ 0 ], '/' );
+	name = name ? name + 1 : orig_args->argv[ 0 ];
+	return strstr( name, "clang" ) != NULL;
+}
+
+static bool compiler_is_gcc()
+{
+	const char* name = strrchr(orig_args->argv[ 0 ], '/' );
+	name = name ? name + 1 : orig_args->argv[ 0 ];
+	return strstr(name, "gcc") != NULL || strstr(name, "g++") != NULL;
+}
+
+/*
  * Update a hash sum with information common for the direct and preprocessor
  * modes.
  */
@@ -1128,6 +1146,15 @@ calculate_common_hash(struct args *args, struct mdfour *hash)
 		}
 		free(p);
 	}
+
+	/* Possibly hash GCC_COLORS (for color diagnostics). */
+	if (compiler_is_gcc()) {
+		const char* gcc_colors = getenv("GCC_COLORS");
+		if (gcc_colors != NULL) {
+			hash_delimiter(hash,"gcccolors");
+			hash_string(hash, gcc_colors);
+		}
+	}
 }
 
 /*
@@ -1633,6 +1660,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
@@ -1661,6 +1695,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);
@@ -2017,6 +2052,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
@@ -2307,6 +2362,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_add(stripped_args, "-fcolor-diagnostics");
+			cc_log("Automatically enabling colors");
+		} else if (compiler_is_gcc()) {
+			/*
+			 * 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");
+				cc_log("Automatically enabling colors");
+			}
+		}
+	}
+
+	/*
 	 * Add flags for dependency generation only to the preprocessor command line.
 	 */
 	if (generating_dependencies) {
-- 
1.8.1.4

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

Reply via email to