Browse Source

cmake: Allow CMAKE_BUILD_TYPE to be set by environment variable

When no `CMAKE_BUILD_TYPE` is explicitly specified while creating a new
build tree, check for an environment variable of the same name.

Issue: #20983
Brad King 4 years ago
parent
commit
e216b9bbd3

+ 10 - 0
Help/envvar/CMAKE_BUILD_TYPE.rst

@@ -0,0 +1,10 @@
+CMAKE_BUILD_TYPE
+----------------
+
+.. versionadded:: 3.22
+
+.. include:: ENV_VAR.txt
+
+The ``CMAKE_BUILD_TYPE`` environment variable specifies a default value
+for the :variable:`CMAKE_BUILD_TYPE` variable when there is no explicit
+configuration given on the first run while creating a new build tree.

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

@@ -30,6 +30,7 @@ Environment Variables that Control the Build
 
    /envvar/CMAKE_APPLE_SILICON_PROCESSOR
    /envvar/CMAKE_BUILD_PARALLEL_LEVEL
+   /envvar/CMAKE_BUILD_TYPE
    /envvar/CMAKE_CONFIG_TYPE
    /envvar/CMAKE_EXPORT_COMPILE_COMMANDS
    /envvar/CMAKE_GENERATOR

+ 5 - 0
Help/release/dev/env-init-configs.rst

@@ -0,0 +1,5 @@
+env-init-configs
+----------------
+
+* The :envvar:`CMAKE_BUILD_TYPE` environment variable was added to
+  provide a default value for the :variable:`CMAKE_BUILD_TYPE` variable.

+ 3 - 2
Help/variable/CMAKE_BUILD_TYPE.rst

@@ -26,8 +26,9 @@ value of ``CMAKE_BUILD_TYPE`` will be ``ReLeAsE``.
 
 This variable is initialized by the first :command:`project` or
 :command:`enable_language` command called in a project when a new build
-tree is first created.  A toolchain-specific default is chosen when a
-language is enabled.
+tree is first created.  If the :envvar:`CMAKE_BUILD_TYPE` environment
+variable is set, its value is used.  Otherwise, a toolchain-specific
+default is chosen when a language is enabled.
 
 See :variable:`CMAKE_CONFIGURATION_TYPES` for specifying the configuration
 with multi-config generators.

+ 12 - 0
Source/cmGlobalGenerator.cxx

@@ -498,6 +498,18 @@ bool cmGlobalGenerator::CheckLanguages(
 void cmGlobalGenerator::EnableLanguage(
   std::vector<std::string> const& languages, cmMakefile* mf, bool optional)
 {
+  if (!this->IsMultiConfig()) {
+    std::string envBuildType;
+    if (!mf->GetDefinition("CMAKE_BUILD_TYPE") &&
+        cmSystemTools::GetEnv("CMAKE_BUILD_TYPE", envBuildType)) {
+      mf->AddCacheDefinition(
+        "CMAKE_BUILD_TYPE", envBuildType,
+        "Choose the type of build.  Options include: empty, "
+        "Debug, Release, RelWithDebInfo, MinSizeRel.",
+        cmStateEnums::STRING);
+    }
+  }
+
   if (languages.empty()) {
     cmSystemTools::Error("EnableLanguage must have a lang specified!");
     cmSystemTools::SetFatalErrorOccured();

+ 2 - 0
Tests/RunCMake/CommandLine/EnvBuildType-stdout.txt

@@ -0,0 +1,2 @@
+-- ENV{CMAKE_BUILD_TYPE}='BuildTypeEnv'
+-- CMAKE_BUILD_TYPE='BuildTypeEnv'

+ 2 - 0
Tests/RunCMake/CommandLine/EnvBuildType.cmake

@@ -0,0 +1,2 @@
+message(STATUS "ENV{CMAKE_BUILD_TYPE}='$ENV{CMAKE_BUILD_TYPE}'")
+message(STATUS "CMAKE_BUILD_TYPE='${CMAKE_BUILD_TYPE}'")

+ 2 - 0
Tests/RunCMake/CommandLine/EnvBuildTypeIgnore-stdout.txt

@@ -0,0 +1,2 @@
+-- ENV{CMAKE_BUILD_TYPE}='BuildTypeEnv'
+-- CMAKE_BUILD_TYPE='BuildTypeOpt'

+ 1 - 0
Tests/RunCMake/CommandLine/EnvBuildTypeIgnore.cmake

@@ -0,0 +1 @@
+include(EnvBuildType.cmake)

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

@@ -344,6 +344,17 @@ if(RunCMake_GENERATOR MATCHES "Unix Makefiles" OR RunCMake_GENERATOR MATCHES "Ni
   run_EnvironmentExportCompileCommands()
 endif()
 
+function(run_EnvironmentBuildType)
+  set(ENV{CMAKE_BUILD_TYPE} "BuildTypeEnv")
+  run_cmake(EnvBuildType)
+  run_cmake_with_options(EnvBuildTypeIgnore -DCMAKE_BUILD_TYPE=BuildTypeOpt)
+  unset(ENV{CMAKE_BUILD_TYPE})
+endfunction()
+
+if(RunCMake_GENERATOR MATCHES "Make|^Ninja$")
+  run_EnvironmentBuildType()
+endif()
+
 function(run_EnvironmentToolchain)
   set(ENV{CMAKE_TOOLCHAIN_FILE} "${RunCMake_SOURCE_DIR}/EnvToolchain-toolchain.cmake")
   run_cmake(EnvToolchainAbsolute)