Browse Source

cmake: Allow CMAKE_TOOLCHAIN_FILE to be set by environment variable

When no `CMAKE_TOOLCHAIN_FILE` is explicitly specified while creating
a new build tree, check for an environment variable of the same name.
Brad King 4 years ago
parent
commit
6c34ed9b87

+ 12 - 0
Help/envvar/CMAKE_TOOLCHAIN_FILE.rst

@@ -0,0 +1,12 @@
+CMAKE_TOOLCHAIN_FILE
+--------------------
+
+.. versionadded:: 3.21
+
+.. include:: ENV_VAR.txt
+
+The ``CMAKE_TOOLCHAIN_FILE`` environment variable specifies a default value
+for the :variable:`CMAKE_TOOLCHAIN_FILE` variable when there is no explicit
+configuration given on the first run while creating a new build tree.
+On later runs in an existing build tree the value persists in the cache
+as :variable:`CMAKE_TOOLCHAIN_FILE`.

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

@@ -41,6 +41,7 @@ Environment Variables that Control the Build
    /envvar/CMAKE_MSVCIDE_RUN_PATH
    /envvar/CMAKE_NO_VERBOSE
    /envvar/CMAKE_OSX_ARCHITECTURES
+   /envvar/CMAKE_TOOLCHAIN_FILE
    /envvar/DESTDIR
    /envvar/LDFLAGS
    /envvar/MACOSX_DEPLOYMENT_TARGET

+ 5 - 0
Help/release/dev/env-toolchain-file.rst

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

+ 3 - 0
Help/variable/CMAKE_TOOLCHAIN_FILE.rst

@@ -10,3 +10,6 @@ platform and compiler related information.
 
 Relative paths are allowed and are interpreted first as relative to the
 build directory, and if not found, relative to the source directory.
+
+This is initialized by the :envvar:`CMAKE_TOOLCHAIN_FILE` environment
+variable if it is set when a new build tree is first created.

+ 10 - 0
Source/cmake.cxx

@@ -2040,6 +2040,16 @@ int cmake::ActualConfigure()
                         this->GlobalGenerator->GetExtraGeneratorName().c_str(),
                         "Name of external makefile project generator.",
                         cmStateEnums::INTERNAL);
+
+    if (!this->State->GetInitializedCacheValue("CMAKE_TOOLCHAIN_FILE")) {
+      std::string envToolchain;
+      if (cmSystemTools::GetEnv("CMAKE_TOOLCHAIN_FILE", envToolchain) &&
+          !envToolchain.empty()) {
+        this->AddCacheEntry("CMAKE_TOOLCHAIN_FILE", envToolchain.c_str(),
+                            "The CMake toolchain file",
+                            cmStateEnums::FILEPATH);
+      }
+    }
   }
 
   if (cmProp instance =

+ 1 - 0
Tests/RunCMake/CommandLine/EnvToolchain-toolchain.cmake

@@ -0,0 +1 @@
+set(ENV_TOOLCHAIN 1)

+ 3 - 0
Tests/RunCMake/CommandLine/EnvToolchain.cmake

@@ -0,0 +1,3 @@
+message(STATUS "ENV{CMAKE_TOOLCHAIN_FILE}='$ENV{CMAKE_TOOLCHAIN_FILE}'")
+message(STATUS "CMAKE_TOOLCHAIN_FILE='${CMAKE_TOOLCHAIN_FILE}'")
+message(STATUS "ENV_TOOLCHAIN='${ENV_TOOLCHAIN}'")

+ 5 - 0
Tests/RunCMake/CommandLine/EnvToolchainAbsolute-stdout.txt

@@ -0,0 +1,5 @@
+-- ENV{CMAKE_TOOLCHAIN_FILE}='[^
+]*/Tests/RunCMake/CommandLine/EnvToolchain-toolchain.cmake'
+-- CMAKE_TOOLCHAIN_FILE='[^
+]*/Tests/RunCMake/CommandLine/EnvToolchain-toolchain.cmake'
+-- ENV_TOOLCHAIN='1'

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

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

+ 4 - 0
Tests/RunCMake/CommandLine/EnvToolchainIgnore-stdout.txt

@@ -0,0 +1,4 @@
+-- ENV{CMAKE_TOOLCHAIN_FILE}='[^
+]*/Tests/RunCMake/CommandLine/EnvToolchain-toolchain.cmake'
+-- CMAKE_TOOLCHAIN_FILE=''
+-- ENV_TOOLCHAIN=''

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

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

+ 3 - 0
Tests/RunCMake/CommandLine/EnvToolchainNone-stdout.txt

@@ -0,0 +1,3 @@
+-- ENV{CMAKE_TOOLCHAIN_FILE}=''
+-- CMAKE_TOOLCHAIN_FILE=''
+-- ENV_TOOLCHAIN=''

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

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

+ 4 - 0
Tests/RunCMake/CommandLine/EnvToolchainNoneExisting-stdout.txt

@@ -0,0 +1,4 @@
+-- ENV{CMAKE_TOOLCHAIN_FILE}='[^
+]*/Tests/RunCMake/CommandLine/EnvToolchain-toolchain.cmake'
+-- CMAKE_TOOLCHAIN_FILE=''
+-- ENV_TOOLCHAIN=''

+ 4 - 0
Tests/RunCMake/CommandLine/EnvToolchainRelative-stdout.txt

@@ -0,0 +1,4 @@
+-- ENV{CMAKE_TOOLCHAIN_FILE}='EnvToolchain-toolchain.cmake'
+-- CMAKE_TOOLCHAIN_FILE='[^
+]*/Tests/RunCMake/CommandLine/EnvToolchainRelative-build/EnvToolchain-toolchain.cmake'
+-- ENV_TOOLCHAIN='1'

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

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

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

@@ -344,6 +344,33 @@ if(RunCMake_GENERATOR MATCHES "Unix Makefiles" OR RunCMake_GENERATOR MATCHES "Ni
   run_EnvironmentExportCompileCommands()
 endif()
 
+function(run_EnvironmentToolchain)
+  set(ENV{CMAKE_TOOLCHAIN_FILE} "${RunCMake_SOURCE_DIR}/EnvToolchain-toolchain.cmake")
+  run_cmake(EnvToolchainAbsolute)
+  run_cmake_with_options(EnvToolchainIgnore -DCMAKE_TOOLCHAIN_FILE=)
+  unset(ENV{CMAKE_TOOLCHAIN_FILE})
+
+  set(ENV{CMAKE_TOOLCHAIN_FILE} "EnvToolchain-toolchain.cmake")
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/EnvToolchainRelative-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  configure_file("${RunCMake_SOURCE_DIR}/EnvToolchain-toolchain.cmake" "${RunCMake_TEST_BINARY_DIR}/EnvToolchain-toolchain.cmake" COPYONLY)
+  run_cmake(EnvToolchainRelative)
+  unset(ENV{CMAKE_TOOLCHAIN_FILE})
+  unset(RunCMake_TEST_NO_CLEAN)
+
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/EnvToolchainNone-build)
+  run_cmake(EnvToolchainNone)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}/CMakeFiles")
+  set(ENV{CMAKE_TOOLCHAIN_FILE} "${RunCMake_SOURCE_DIR}/EnvToolchain-toolchain.cmake")
+  run_cmake_command(EnvToolchainNoneExisting ${CMAKE_COMMAND} .)
+  unset(ENV{CMAKE_TOOLCHAIN_FILE})
+  unset(RunCMake_TEST_NO_CLEAN)
+endfunction()
+run_EnvironmentToolchain()
+
 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)