aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--devel/ccache/Makefile17
-rw-r--r--devel/ccache/files/extra-patch-colors199
2 files changed, 214 insertions, 2 deletions
diff --git a/devel/ccache/Makefile b/devel/ccache/Makefile
index d7d7ccb53f7e..a3178d010636 100644
--- a/devel/ccache/Makefile
+++ b/devel/ccache/Makefile
@@ -3,7 +3,7 @@
PORTNAME= ccache
PORTVERSION= 3.1.9
-PORTREVISION= 5
+PORTREVISION= 6
CATEGORIES= devel
MASTER_SITES= http://www.samba.org/ftp/ccache/ \
CRITICAL
@@ -21,17 +21,30 @@ SUB_FILES= ${HOWTO} world-ccache pkg-message ccache-update-links.sh
PORTDOCS= ccache-howto-freebsd.txt MANUAL.html
-OPTIONS_DEFINE= CLANGLINK LLVMLINK STATIC DOCS TINDERBOX
+OPTIONS_DEFINE= CLANGLINK LLVMLINK STATIC DOCS TINDERBOX COLORS
+COLORS_DESC= Support compiler colors
CLANGLINK_DESC= Create clang compiler links if clang is installed
LLVMLINK_DESC= Create llvm compiler links if llvm is installed
TINDERBOX_DESC= Create tarball for tinderbox usage
+COLORS_EXTRA_PATCHES= ${FILESDIR}/extra-patch-colors
+COLORS_USES= compiler
+
OPTIONS_SUB= yes
STATIC_LDFLAGS= -static
.include <bsd.port.options.mk>
+.include <bsd.port.pre.mk>
+
+.if ${PORT_OPTIONS:MCOLORS}
+. if ${COMPILER_TYPE} == clang
+CPPFLAGS+= -DCC_IS_CLANG
+. elif ${COMPILER_TYPE} = gcc
+CPPFLAGS+= -DCC_IS_GCC
+. endif
+.endif
PLIST_SUB+= CCLINKDIR="${CCLINKDIR}"
diff --git a/devel/ccache/files/extra-patch-colors b/devel/ccache/files/extra-patch-colors
new file mode 100644
index 000000000000..63e94b9074df
--- /dev/null
+++ b/devel/ccache/files/extra-patch-colors
@@ -0,0 +1,199 @@
+CC_IS_CLANG and CC_IS_GCC added by me. Adapated from 3.2 patch. - bdrewery
+
+Original author:
+
+From cacb14929748ae93eacefcfa194aa93689d217eb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= <l.lunak@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.orig 2014-03-02 00:16:33.335546870 -0600
++++ ccache.c 2014-03-02 00:16:35.888546332 -0600
+@@ -849,14 +849,42 @@ hash_compiler(struct mdfour *hash, struc
+ if (!hash_multicommand_output(hash, compilercheck, orig_args->argv[0])) {
+ fatal("Failure running compiler check command: %s", compilercheck);
+ }
+ }
+ }
+
+ /*
++ * 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 ];
++#ifdef CC_IS_CLANG
++ if (strcmp(name, "cc") == 0 || strcmp(name, "CC") == 0 ||
++ strcmp(name, "c++") == 0)
++ return true;
++#endif
++ return strstr( name, "clang" ) != NULL;
++}
++
++static bool compiler_is_gcc()
++{
++ const char* name = strrchr(orig_args->argv[ 0 ], '/' );
++#ifdef CC_IS_GCC
++ if (strcmp(name, "cc") == 0 || strcmp(name, "CC") == 0 ||
++ strcmp(name, "c++") == 0)
++ return true;
++#endif
++ 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.
+ */
+ static void
+ calculate_common_hash(struct args *args, struct mdfour *hash)
+ {
+ struct stat st;
+@@ -913,14 +941,23 @@ calculate_common_hash(struct args *args,
+ stats_update(STATS_BADEXTRAFILE);
+ failed();
+ }
+ q = NULL;
+ }
+ 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);
++ }
++ }
+ }
+
+ /*
+ * Update a hash sum with information specific to the direct and preprocessor
+ * modes and calculate the object hash. Returns the object hash on success,
+ * otherwise NULL. Caller frees.
+ */
+@@ -1273,14 +1310,21 @@ find_compiler(int argc, char **argv)
+
+ bool
+ is_precompiled_header(const char *path)
+ {
+ return str_eq(get_extension(path), ".gch");
+ }
+
++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
+ * -E; this is added later. Returns true on success, otherwise false.
+ */
+ bool
+ cc_process_args(struct args *orig_args, struct args **preprocessor_args,
+@@ -1301,14 +1345,15 @@ cc_process_args(struct args *orig_args,
+ bool dependency_filename_specified = false;
+ /* is the dependency makefile target name specified with -MT or -MQ? */
+ bool dependency_target_specified = false;
+ struct args *stripped_args = NULL, *dep_args = NULL;
+ int argc = orig_args->argc;
+ char **argv = orig_args->argv;
+ bool result = true;
++ bool found_color_diagnostics = false;
+
+ stripped_args = args_init(0, NULL);
+ dep_args = args_init(0, NULL);
+
+ args_add(stripped_args, argv[0]);
+
+ for (i = 1; i < argc; i++) {
+@@ -1551,14 +1596,34 @@ cc_process_args(struct args *orig_args,
+
+ /* Input charset needs to be handled specially. */
+ if (str_startswith(argv[i], "-finput-charset=")) {
+ input_charset = argv[i];
+ continue;
+ }
+
++ 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 that we may want to rewrite
+ * to relative paths to get better hit rate. A secondary effect
+ * is that paths in the standard error output produced by the
+ * compiler will be normalized.
+ */
+ if (compopt_takes_path(argv[i])) {
+@@ -1765,14 +1830,36 @@ cc_process_args(struct args *orig_args,
+ cc_log("Not a regular file: %s", output_obj);
+ stats_update(STATS_DEVICE);
+ result = false;
+ goto out;
+ }
+
+ /*
++ * 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");
++ }
++ }
++ }
++
++ /*
+ * Some options shouldn't be passed to the real compiler when it compiles
+ * preprocessed code:
+ *
+ * -finput-charset=XXX (otherwise conversion happens twice)
+ * -x XXX (otherwise the wrong language is selected)
+ */
+ *preprocessor_args = args_copy(stripped_args);