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
--- 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