Bug 1171610 - Automatically enable color in compiler output; r?glandium draft
authorGregory Szorc <gps@mozilla.com>
Wed, 09 Nov 2016 14:01:24 -0800
changeset 437479 0a3de4e24e0085b6fd6190bdac2dcfb4d2785395
parent 437246 d38d06f85ef59c5dbb5d4a1a8d895957a78714de
child 536649 22c1fad46ecac5a8b26eb07b519575a82cdcf44c
push id35423
push userbmo:gps@mozilla.com
push dateFri, 11 Nov 2016 00:01:48 +0000
reviewersglandium
bugs1171610, 1315785
milestone52.0a1
Bug 1171610 - Automatically enable color in compiler output; r?glandium GCC and Clang will colorize compiler output automatically if stdout is a TTY. Unfortunately, when the build backend is invoked via `mach`, stdout is not a TTY. 6e9a4c0b9cd8 (bug 1315785) changed mach so it exports an environment variable indicating whether mach's original stdout is a TTY. This was later used to add color flags to `cargo` invocations. Building on that work, this patch adds color flags to compiler invocations if the compiler supports color and a mach TTY is detected. The result is that compiler output from `mach build` will be colorized automatically if Clang or a modern version of GCC is used. The only issue I see with this is that Clang doesn't "unset" its color sequences when printing a newline. As a result, mach's time line prefixing can sometimes inherit "bold" or other stylings. AFAICT this is only a minor cosmetic concern. GCC does not exhibit this issue. MozReview-Commit-ID: 5Icu6aXGZBL
build/moz.configure/toolchain.configure
config/config.mk
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -834,16 +834,37 @@ def debug_flags(env_debug_flags, enable_
         return enable_debug_flags[0]
     if env_debug_flags:
         return env_debug_flags[0]
     return default_debug_flags
 
 set_config('MOZ_DEBUG_FLAGS', debug_flags)
 add_old_configure_assignment('MOZ_DEBUG_FLAGS', debug_flags)
 
+@depends(c_compiler)
+def color_cflags(info):
+    # We could test compiling with flags. By why incur the overhead when
+    # color support should always be present in a specific toolchain
+    # version?
+
+    # Code for auto-adding this flag to compiler invocations needs to
+    # determine if an existing flag isn't already present. That is likely
+    # using exact string matching on the returned value. So if the return
+    # value changes to e.g. "<x>=always", exact string match may fail and
+    # multiple color flags could be added. So examine downstream consumers
+    # before adding flags to return values.
+    if info.type == 'gcc' and info.version >= '4.9.0':
+        return '-fdiagnostics-color'
+    elif info.type == 'clang':
+        return '-fcolor-diagnostics'
+    else:
+        return ''
+
+set_config('COLOR_CFLAGS', color_cflags)
+
 # Some standard library headers (notably bionic on Android) declare standard
 # functions (e.g. getchar()) and also #define macros for those standard
 # functions.  libc++ deals with this by doing something like the following
 # (explanatory comments added):
 #
 #   #ifdef FUNC
 #   // Capture the definition of FUNC.
 #   inline _LIBCPP_INLINE_VISIBILITY int __libcpp_FUNC(...) { return FUNC(...); }
--- a/config/config.mk
+++ b/config/config.mk
@@ -335,16 +335,41 @@ ASFLAGS += $(MOZBUILD_ASFLAGS)
 
 ifndef CROSS_COMPILE
 HOST_CFLAGS += $(RTL_FLAGS)
 endif
 
 HOST_CFLAGS += $(HOST_DEFINES) $(MOZBUILD_HOST_CFLAGS)
 HOST_CXXFLAGS += $(HOST_DEFINES) $(MOZBUILD_HOST_CXXFLAGS)
 
+# We only add color flags if neither the flag to disable color
+# (e.g. "-fno-color-diagnostics" nor a flag to control color
+# (e.g. "-fcolor-diagnostics=never") is present.
+define colorize_flags
+ifeq (,$(filter $(COLOR_CFLAGS:-f%=-fno-%),$$(1))$(findstring $(COLOR_CFLAGS),$$(1)))
+$(1) += $(COLOR_CFLAGS)
+endif
+endef
+
+color_flags_vars := \
+  COMPILE_CFLAGS \
+  COMPILE_CXXFLAGS \
+  COMPILE_CMFLAGS \
+  COMPILE_CMMFLAGS \
+  HOST_CFLAGS \
+  HOST_CXXFLAGS \
+  LDFLAGS \
+  $(NULL)
+
+ifdef MACH_STDOUT_ISATTY
+ifdef COLOR_CFLAGS
+$(foreach var,$(color_flags_vars),$(eval $(call colorize_flags,$(var))))
+endif
+endif
+
 #
 # Name of the binary code directories
 #
 # Override defaults
 
 SDK_LIB_DIR = $(DIST)/sdk/lib
 SDK_BIN_DIR = $(DIST)/sdk/bin