Browse Source

Merge topic 'color-diagnostics'

6ab9fbd43b color: Add tests for CMAKE_COLOR_DIAGNOSTICS
78adb1b952 color: Add CMAKE_COLOR_DIAGNOSTICS environment variable
884d9de8b7 color: Introduce CMAKE_COLOR_DIAGNOSTICS variable

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Acked-by: Frank Dana <[email protected]>
Merge-request: !6990
Brad King 3 years ago
parent
commit
51e81d1f73

+ 1 - 0
Auxiliary/vim/syntax/cmake.vim

@@ -705,6 +705,7 @@ syn keyword cmakeVariable contained
             \ CMAKE_CODEBLOCKS_COMPILER_ID
             \ CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES
             \ CMAKE_CODELITE_USE_TARGETS
+            \ CMAKE_COLOR_DIAGNOSTICS
             \ CMAKE_COLOR_MAKEFILE
             \ CMAKE_COMMAND
             \ CMAKE_COMPILER_2005

+ 9 - 0
Help/envvar/CMAKE_COLOR_DIAGNOSTICS.rst

@@ -0,0 +1,9 @@
+CMAKE_COLOR_DIAGNOSTICS
+-----------------------
+
+.. versionadded:: 3.24
+
+.. include:: ENV_VAR.txt
+
+Specifies a default value for the :variable:`CMAKE_COLOR_DIAGNOSTICS` variable
+when there is no explicit value given on the first run.

+ 1 - 0
Help/manual/cmake-env-variables.7.rst

@@ -31,6 +31,7 @@ Environment Variables that Control the Build
    /envvar/CMAKE_APPLE_SILICON_PROCESSOR
    /envvar/CMAKE_BUILD_PARALLEL_LEVEL
    /envvar/CMAKE_BUILD_TYPE
+   /envvar/CMAKE_COLOR_DIAGNOSTICS
    /envvar/CMAKE_CONFIGURATION_TYPES
    /envvar/CMAKE_CONFIG_TYPE
    /envvar/CMAKE_EXPORT_COMPILE_COMMANDS

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -172,6 +172,7 @@ Variables that Change Behavior
    /variable/CMAKE_CODEBLOCKS_COMPILER_ID
    /variable/CMAKE_CODEBLOCKS_EXCLUDE_EXTERNAL_FILES
    /variable/CMAKE_CODELITE_USE_TARGETS
+   /variable/CMAKE_COLOR_DIAGNOSTICS
    /variable/CMAKE_COLOR_MAKEFILE
    /variable/CMAKE_CONFIGURATION_TYPES
    /variable/CMAKE_DEPENDS_IN_PROJECT_ONLY

+ 10 - 0
Help/release/dev/color-diagnostics.rst

@@ -0,0 +1,10 @@
+color-diagnostics
+-----------------
+
+* The :variable:`CMAKE_COLOR_DIAGNOSTICS` variable was added to control
+  color diagnostics generated by compilers.  This variable also controls
+  color buildsystem messages with :ref:`Makefile Generators`, replacing
+  :variable:`CMAKE_COLOR_MAKEFILE`.
+
+  The :envvar:`CMAKE_COLOR_DIAGNOSTICS` environment was added to set
+  a default value for :variable:`CMAKE_COLOR_DIAGNOSTICS`.

+ 37 - 0
Help/variable/CMAKE_COLOR_DIAGNOSTICS.rst

@@ -0,0 +1,37 @@
+CMAKE_COLOR_DIAGNOSTICS
+-----------------------
+
+.. versionadded:: 3.24
+
+Enable color diagnostics throughout.
+
+This variable uses three states: ``ON``, ``OFF`` and not defined.
+
+When not defined:
+
+* :ref:`Makefile Generators` initialize the :variable:`CMAKE_COLOR_MAKEFILE`
+  variable to ``ON``.  It controls color buildsystem messages.
+
+* GNU/Clang compilers are not invoked with any color diagnostics flag.
+
+When ``ON``:
+
+* :ref:`Makefile Generators` produce color buildsystem messages by default.
+  :variable:`CMAKE_COLOR_MAKEFILE` is not initialized, but may be
+  explicitly set to ``OFF`` to disable color buildsystem messages.
+
+* GNU/Clang compilers are invoked with a flag enabling color diagnostics
+  (``-fcolor-diagnostics``).
+
+When ``OFF``:
+
+* :ref:`Makefile Generators` do not produce color buildsystem messages by
+  default.  :variable:`CMAKE_COLOR_MAKEFILE` is not initialized, but may be
+  explicitly set to ``ON`` to enable color buildsystem messages.
+
+* GNU/Clang compilers are invoked with a flag disabling color diagnostics
+  (``-fno-color-diagnostics``).
+
+If the :envvar:`CMAKE_COLOR_DIAGNOSTICS` environment variable is set, its
+value is used.  Otherwise, ``CMAKE_COLOR_DIAGNOSTICS`` is not defined by
+default.

+ 8 - 3
Modules/CMakeGenericSystem.cmake

@@ -47,11 +47,16 @@ set (CMAKE_SKIP_INSTALL_RPATH "NO" CACHE BOOL
 
 set(CMAKE_VERBOSE_MAKEFILE FALSE CACHE BOOL "If this value is on, makefiles will be generated without the .SILENT directive, and all commands will be echoed to the console during the make.  This is useful for debugging only. With Visual Studio IDE projects all commands are done without /nologo.")
 
+if(DEFINED ENV{CMAKE_COLOR_DIAGNOSTICS} AND NOT DEFINED CACHE{CMAKE_COLOR_DIAGNOSTICS})
+  set(CMAKE_COLOR_DIAGNOSTICS $ENV{CMAKE_COLOR_DIAGNOSTICS} CACHE BOOL "Enable colored diagnostics throughout.")
+endif()
+
 if(CMAKE_GENERATOR MATCHES "Make")
-  set(CMAKE_COLOR_MAKEFILE ON CACHE BOOL
-    "Enable/Disable color output during build."
-    )
+  if(NOT DEFINED CMAKE_COLOR_DIAGNOSTICS)
+    set(CMAKE_COLOR_MAKEFILE ON CACHE BOOL "Enable/Disable color output during build.")
+  endif()
   mark_as_advanced(CMAKE_COLOR_MAKEFILE)
+
   if(DEFINED CMAKE_RULE_MESSAGES)
     set_property(GLOBAL PROPERTY RULE_MESSAGES ${CMAKE_RULE_MESSAGES})
   endif()

+ 6 - 0
Modules/Compiler/Clang.cmake

@@ -114,6 +114,12 @@ else()
     endif()
     set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>)
     set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER> -x ${__pch_header_${lang}})
+
+    # '-fcolor-diagnostics' introduced since Clang 2.6
+    if(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 2.6)
+      set(CMAKE_${lang}_COMPILE_OPTIONS_COLOR_DIAGNOSTICS "-fcolor-diagnostics")
+      set(CMAKE_${lang}_COMPILE_OPTIONS_COLOR_DIAGNOSTICS_OFF "-fno-color-diagnostics")
+    endif()
   endmacro()
 endif()
 

+ 7 - 0
Modules/Compiler/GNU.cmake

@@ -119,4 +119,11 @@ macro(__compiler_gnu lang)
     set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -include <PCH_HEADER>)
     set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -x ${__pch_header_${lang}} -include <PCH_HEADER>)
   endif()
+
+  # '-fdiagnostics-color=always' introduced since GCC 4.9
+  # https://gcc.gnu.org/gcc-4.9/changes.html
+  if(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 4.9)
+    set(CMAKE_${lang}_COMPILE_OPTIONS_COLOR_DIAGNOSTICS "-fdiagnostics-color=always")
+    set(CMAKE_${lang}_COMPILE_OPTIONS_COLOR_DIAGNOSTICS_OFF "-fno-diagnostics-color")
+  endif()
 endmacro()

+ 1 - 0
Source/cmGhsMultiTargetGenerator.cxx

@@ -182,6 +182,7 @@ void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
                                           language, config);
     this->LocalGenerator->AddVisibilityPresetFlags(
       flags, this->GeneratorTarget, language);
+    this->LocalGenerator->AddColorDiagnosticsFlags(flags, language);
 
     // Append old-style preprocessor definition flags.
     if (this->Makefile->GetDefineFlags() != " ") {

+ 24 - 0
Source/cmLocalGenerator.cxx

@@ -1609,6 +1609,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
 
   this->AddCMP0018Flags(compileFlags, target, lang, config);
   this->AddVisibilityPresetFlags(compileFlags, target, lang);
+  this->AddColorDiagnosticsFlags(compileFlags, lang);
   this->AppendFlags(compileFlags, mf->GetDefineFlags());
   this->AppendFlags(compileFlags,
                     this->GetFrameworkFlags(lang, config, target));
@@ -2354,6 +2355,29 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags,
   }
 }
 
+void cmLocalGenerator::AddColorDiagnosticsFlags(std::string& flags,
+                                                const std::string& lang)
+{
+  cmValue diag = this->Makefile->GetDefinition("CMAKE_COLOR_DIAGNOSTICS");
+  if (diag.IsSet()) {
+    std::string colorFlagName;
+    if (diag.IsOn()) {
+      colorFlagName =
+        cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_COLOR_DIAGNOSTICS");
+    } else {
+      colorFlagName =
+        cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_COLOR_DIAGNOSTICS_OFF");
+    }
+
+    std::vector<std::string> options;
+    this->Makefile->GetDefExpandList(colorFlagName, options);
+
+    for (std::string const& option : options) {
+      this->AppendFlagEscape(flags, option);
+    }
+  }
+}
+
 void cmLocalGenerator::AddConfigVariableFlags(std::string& flags,
                                               const std::string& var,
                                               const std::string& config)

+ 1 - 0
Source/cmLocalGenerator.h

@@ -159,6 +159,7 @@ public:
                                   cmGeneratorTarget const* target,
                                   const std::string& lang,
                                   const std::string& config);
+  void AddColorDiagnosticsFlags(std::string& flags, const std::string& lang);
   //! Append flags to a string.
   virtual void AppendFlags(std::string& flags,
                            const std::string& newFlags) const;

+ 5 - 1
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -133,7 +133,11 @@ void cmLocalUnixMakefileGenerator3::Generate()
   // Record whether some options are enabled to avoid checking many
   // times later.
   if (!this->GetGlobalGenerator()->GetCMakeInstance()->GetIsInTryCompile()) {
-    this->ColorMakefile = this->Makefile->IsOn("CMAKE_COLOR_MAKEFILE");
+    if (this->Makefile->IsSet("CMAKE_COLOR_MAKEFILE")) {
+      this->ColorMakefile = this->Makefile->IsOn("CMAKE_COLOR_MAKEFILE");
+    } else {
+      this->ColorMakefile = this->Makefile->IsOn("CMAKE_COLOR_DIAGNOSTICS");
+    }
   }
   this->SkipPreprocessedSourceRules =
     this->Makefile->IsOn("CMAKE_SKIP_PREPROCESSED_SOURCE_RULES");

+ 3 - 0
Tests/RunCMake/CMakeLists.txt

@@ -278,6 +278,9 @@ endif()
 add_RunCMake_test(CMakeDependentOption)
 add_RunCMake_test(CMakeRoleGlobalProperty)
 add_RunCMake_test(CMakeRelease -DCMake_TEST_JQ=${CMake_TEST_JQ})
+if(CMAKE_GENERATOR MATCHES "Make|Ninja")
+  add_RunCMake_test(Color)
+endif()
 if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
   add_RunCMake_test(CompilerChange)
 endif()

+ 3 - 0
Tests/RunCMake/Color/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.23)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 9 - 0
Tests/RunCMake/Color/DiagCommon.cmake

@@ -0,0 +1,9 @@
+enable_language(C)
+
+set(CMAKE_C_COMPILE_OPTIONS_COLOR_DIAGNOSTICS     -DCOLOR_ON)
+set(CMAKE_C_COMPILE_OPTIONS_COLOR_DIAGNOSTICS_OFF -DCOLOR_OFF)
+
+add_library(diag STATIC diag.c)
+if(DEFINED EXPECT_COLOR)
+  target_compile_definitions(diag PRIVATE EXPECT_COLOR=${EXPECT_COLOR})
+endif()

+ 8 - 0
Tests/RunCMake/Color/DiagDefault.cmake

@@ -0,0 +1,8 @@
+include(DiagCommon.cmake)
+
+if(DEFINED CMAKE_COLOR_DIAGNOSTICS)
+  message(FATAL_ERROR "CMAKE_COLOR_DIAGNOSTICS incorrectly defined.")
+endif()
+if(CMAKE_GENERATOR MATCHES "Make" AND NOT DEFINED CMAKE_COLOR_MAKEFILE)
+  message(FATAL_ERROR "CMAKE_COLOR_MAKEFILE incorrectly not defined.")
+endif()

+ 6 - 0
Tests/RunCMake/Color/DiagOff.cmake

@@ -0,0 +1,6 @@
+set(EXPECT_COLOR 0)
+include(DiagCommon.cmake)
+
+if(DEFINED CMAKE_COLOR_MAKEFILE)
+  message(FATAL_ERROR "CMAKE_COLOR_MAKEFILE incorrectly defined.")
+endif()

+ 6 - 0
Tests/RunCMake/Color/DiagOn.cmake

@@ -0,0 +1,6 @@
+set(EXPECT_COLOR 1)
+include(DiagCommon.cmake)
+
+if(DEFINED CMAKE_COLOR_MAKEFILE)
+  message(FATAL_ERROR "CMAKE_COLOR_MAKEFILE incorrectly defined.")
+endif()

+ 14 - 0
Tests/RunCMake/Color/RunCMakeTest.cmake

@@ -0,0 +1,14 @@
+include(RunCMake)
+
+unset(ENV{CMAKE_COLOR_DIAGNOSTICS})
+
+function(run_Diag case)
+  set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/Diag${case}-build")
+  run_cmake_with_options(Diag${case} ${ARGN})
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_command(Diag${case}-build ${CMAKE_COMMAND} --build . --config Debug)
+endfunction()
+
+run_Diag(On -DCMAKE_COLOR_DIAGNOSTICS=ON)
+run_Diag(Off -DCMAKE_COLOR_DIAGNOSTICS=OFF)
+run_Diag(Default)

+ 28 - 0
Tests/RunCMake/Color/diag.c

@@ -0,0 +1,28 @@
+#ifdef EXPECT_COLOR
+#  if EXPECT_COLOR
+#    ifndef COLOR_ON
+#      error "COLOR_ON incorrectly not defined"
+#    endif
+#    ifdef COLOR_OFF
+#      error "COLOR_OFF incorrectly defined"
+#    endif
+#  else
+#    ifdef COLOR_ON
+#      error "COLOR_ON incorrectly defined"
+#    endif
+#    ifndef COLOR_OFF
+#      error "COLOR_OFF incorrectly not defined"
+#    endif
+#  endif
+#else
+#  ifdef COLOR_ON
+#    error "COLOR_ON incorrectly defined"
+#  endif
+#  ifdef COLOR_OFF
+#    error "COLOR_OFF incorrectly defined"
+#  endif
+#endif
+
+void diag(void)
+{
+}

+ 6 - 0
Tests/RunCMake/CommandLine/EnvColorDefault.cmake

@@ -0,0 +1,6 @@
+if(DEFINED CMAKE_COLOR_DIAGNOSTICS)
+  message(FATAL_ERROR "CMAKE_COLOR_DIAGNOSTICS incorrectly defined.")
+endif()
+if(CMAKE_GENERATOR MATCHES "Make" AND NOT DEFINED CMAKE_COLOR_MAKEFILE)
+  message(FATAL_ERROR "CMAKE_COLOR_MAKEFILE incorrectly not defined.")
+endif()

+ 1 - 0
Tests/RunCMake/CommandLine/EnvColorOn-stdout.txt

@@ -0,0 +1 @@
+-- CMAKE_COLOR_DIAGNOSTICS='ON'

+ 4 - 0
Tests/RunCMake/CommandLine/EnvColorOn.cmake

@@ -0,0 +1,4 @@
+message(STATUS "CMAKE_COLOR_DIAGNOSTICS='${CMAKE_COLOR_DIAGNOSTICS}'")
+if(DEFINED CMAKE_COLOR_MAKEFILE)
+  message(FATAL_ERROR "CMAKE_COLOR_MAKEFILE incorrectly defined.")
+endif()

+ 8 - 0
Tests/RunCMake/CommandLine/RunCMakeTest.cmake

@@ -445,6 +445,14 @@ function(run_EnvironmentToolchain)
 endfunction()
 run_EnvironmentToolchain()
 
+function(run_EnvironmentColor)
+  set(ENV{CMAKE_COLOR_DIAGNOSTICS} "ON")
+  run_cmake(EnvColorOn)
+  unset(ENV{CMAKE_COLOR_DIAGNOSTICS})
+  run_cmake(EnvColorDefault)
+endfunction()
+run_EnvironmentColor()
+
 if(RunCMake_GENERATOR STREQUAL "Ninja")
   # Use a single build tree for a few tests without cleaning.
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Build-build)