CMP0132: Don't set compiler environment variables on first run

When running CMake for the first time in a build tree, for some
generators CMake would set compiler environment variables
like CC, CXX, etc. when the corresponding language is enabled.
That behavior was never documented and can result in different
behavior between the first and subsequent runs. Add a policy
to no longer set those environment variables.

Fixes: #21378
This commit is contained in:
Craig Scott 2022-03-23 14:31:04 +11:00 committed by Brad King
parent 774a9eb210
commit 05e510bf0b
15 changed files with 76 additions and 2 deletions

View File

@ -58,6 +58,7 @@ Policies Introduced by CMake 3.24
.. toctree::
:maxdepth: 1
CMP0132: Do not set compiler environment variables on first run. </policy/CMP0132>
CMP0131: LINK_LIBRARIES supports the LINK_ONLY generator expression. </policy/CMP0131>
CMP0130: while() diagnoses condition evaluation errors. </policy/CMP0130>

26
Help/policy/CMP0132.rst Normal file
View File

@ -0,0 +1,26 @@
CMP0132
-------
.. versionadded:: 3.24
Apart from when using the Xcode generator and some Visual Studio generators,
CMake 3.23 and below will set environment variables like :envvar:`CC`,
:envvar:`CXX`, etc. when the corresponding language is enabled.
This only occurs on the very first time CMake is run in a build directory,
and the environment variables are only defined at configure time, not build
time. On subsequent CMake runs, these environment variables are not set,
opening up the opportunity for different behavior between the first and
subsequent CMake runs. CMake 3.24 and above prefer to not set these
environment variables when a language is enabled, even on the first run in
a build directory.
The ``OLD`` behavior for this policy sets the relevant environment variable
on the first run when a language is enabled. The ``NEW`` behavior for this
policy does not set any such environment variables.
This policy was introduced in CMake version 3.24. Use the
:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
Unlike many policies, CMake version |release| does *not* warn
when this policy is not set and simply uses ``OLD`` behavior.
.. include:: DEPRECATED.txt

View File

@ -0,0 +1,6 @@
set-env-var-first-run
---------------------
* CMake no longer sets environment variables like :envvar:`CC`, :envvar:`CXX`,
etc. when enabling the corresponding language during the first CMake run in
a build directory. See policy :policy:`CMP0132`.

View File

@ -759,7 +759,9 @@ void cmGlobalGenerator::EnableLanguage(
needTestLanguage[lang] = true;
// Some generators like visual studio should not use the env variables
// So the global generator can specify that in this variable
if (!mf->GetDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV")) {
if ((mf->GetPolicyStatus(cmPolicies::CMP0132) == cmPolicies::OLD ||
mf->GetPolicyStatus(cmPolicies::CMP0132) == cmPolicies::WARN) &&
!mf->GetDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV")) {
// put ${CMake_(LANG)_COMPILER_ENV_VAR}=${CMAKE_(LANG)_COMPILER
// into the environment, in case user scripts want to run
// configure, or sub cmakes

View File

@ -393,7 +393,10 @@ class cmMakefile;
3, 24, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0131, \
"LINK_LIBRARIES supports the LINK_ONLY generator expression.", 3, \
24, 0, cmPolicies::WARN)
24, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0132, \
"Do not set compiler environment variables on first run", 3, 24, 0, \
cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \

View File

@ -0,0 +1,15 @@
if(NOT "$ENV{CC}" STREQUAL "")
message(STATUS "Test environment already sets CC, test being SKIPPED")
return()
elseif(CMAKE_GENERATOR MATCHES "Xcode|Visual Studio")
message(STATUS "This generator never sets CC, test being SKIPPED")
return()
endif()
enable_language(C)
if("$ENV{CC}" STREQUAL "")
message(STATUS "CC was left unset")
else()
message(STATUS "CC was set to $ENV{CC}")
endif()

View File

@ -0,0 +1 @@
SKIPPED|CC was left unset

View File

@ -0,0 +1,2 @@
cmake_policy(SET CMP0132 NEW)
include(CMP0132-Common.cmake)

View File

@ -0,0 +1 @@
SKIPPED|CC was set

View File

@ -0,0 +1,2 @@
cmake_policy(SET CMP0132 OLD)
include(CMP0132-Common.cmake)

View File

@ -0,0 +1 @@
SKIPPED|CC was set

View File

@ -0,0 +1,2 @@
include(CMP0132-Common.cmake)

View File

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

View File

@ -0,0 +1,7 @@
include(RunCMake)
if(NOT CMAKE_GENERATOR_NO_COMPILER_ENV)
run_cmake(CMP0132-WARN)
run_cmake(CMP0132-OLD)
run_cmake(CMP0132-NEW)
endif()

View File

@ -148,6 +148,8 @@ if("${CMAKE_C_COMPILER_ID}" STREQUAL "LCC" OR
add_RunCMake_test("CMP0129")
endif()
add_RunCMake_test(CMP0132)
# The test for Policy 65 requires the use of the
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
# generators ignore. The policy will have no effect on those generators.