From 05e510bf0bf8d730b03e8b389d088919825b4b5a Mon Sep 17 00:00:00 2001 From: Craig Scott Date: Wed, 23 Mar 2022 14:31:04 +1100 Subject: 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 --- Help/manual/cmake-policies.7.rst | 1 + Help/policy/CMP0132.rst | 26 ++++++++++++++++++++++++++ Help/release/dev/set-env-var-first-run.rst | 6 ++++++ Source/cmGlobalGenerator.cxx | 4 +++- Source/cmPolicies.h | 5 ++++- Tests/RunCMake/CMP0132/CMP0132-Common.cmake | 15 +++++++++++++++ Tests/RunCMake/CMP0132/CMP0132-NEW-stdout.txt | 1 + Tests/RunCMake/CMP0132/CMP0132-NEW.cmake | 2 ++ Tests/RunCMake/CMP0132/CMP0132-OLD-stdout.txt | 1 + Tests/RunCMake/CMP0132/CMP0132-OLD.cmake | 2 ++ Tests/RunCMake/CMP0132/CMP0132-WARN-stdout.txt | 1 + Tests/RunCMake/CMP0132/CMP0132-WARN.cmake | 2 ++ Tests/RunCMake/CMP0132/CMakeLists.txt | 3 +++ Tests/RunCMake/CMP0132/RunCMakeTest.cmake | 7 +++++++ Tests/RunCMake/CMakeLists.txt | 2 ++ 15 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 Help/policy/CMP0132.rst create mode 100644 Help/release/dev/set-env-var-first-run.rst create mode 100644 Tests/RunCMake/CMP0132/CMP0132-Common.cmake create mode 100644 Tests/RunCMake/CMP0132/CMP0132-NEW-stdout.txt create mode 100644 Tests/RunCMake/CMP0132/CMP0132-NEW.cmake create mode 100644 Tests/RunCMake/CMP0132/CMP0132-OLD-stdout.txt create mode 100644 Tests/RunCMake/CMP0132/CMP0132-OLD.cmake create mode 100644 Tests/RunCMake/CMP0132/CMP0132-WARN-stdout.txt create mode 100644 Tests/RunCMake/CMP0132/CMP0132-WARN.cmake create mode 100644 Tests/RunCMake/CMP0132/CMakeLists.txt create mode 100644 Tests/RunCMake/CMP0132/RunCMakeTest.cmake diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 9bf2913..17a3764 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -58,6 +58,7 @@ Policies Introduced by CMake 3.24 .. toctree:: :maxdepth: 1 + CMP0132: Do not set compiler environment variables on first run. CMP0131: LINK_LIBRARIES supports the LINK_ONLY generator expression. CMP0130: while() diagnoses condition evaluation errors. diff --git a/Help/policy/CMP0132.rst b/Help/policy/CMP0132.rst new file mode 100644 index 0000000..fadbbdc --- /dev/null +++ b/Help/policy/CMP0132.rst @@ -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 diff --git a/Help/release/dev/set-env-var-first-run.rst b/Help/release/dev/set-env-var-first-run.rst new file mode 100644 index 0000000..c3f7d9f --- /dev/null +++ b/Help/release/dev/set-env-var-first-run.rst @@ -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`. diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index baa54e5..fb84cd1 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -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 diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 3b9d067..434c51c 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -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) \ diff --git a/Tests/RunCMake/CMP0132/CMP0132-Common.cmake b/Tests/RunCMake/CMP0132/CMP0132-Common.cmake new file mode 100644 index 0000000..796f61c --- /dev/null +++ b/Tests/RunCMake/CMP0132/CMP0132-Common.cmake @@ -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() diff --git a/Tests/RunCMake/CMP0132/CMP0132-NEW-stdout.txt b/Tests/RunCMake/CMP0132/CMP0132-NEW-stdout.txt new file mode 100644 index 0000000..8056c2c --- /dev/null +++ b/Tests/RunCMake/CMP0132/CMP0132-NEW-stdout.txt @@ -0,0 +1 @@ +SKIPPED|CC was left unset diff --git a/Tests/RunCMake/CMP0132/CMP0132-NEW.cmake b/Tests/RunCMake/CMP0132/CMP0132-NEW.cmake new file mode 100644 index 0000000..fabb419 --- /dev/null +++ b/Tests/RunCMake/CMP0132/CMP0132-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0132 NEW) +include(CMP0132-Common.cmake) diff --git a/Tests/RunCMake/CMP0132/CMP0132-OLD-stdout.txt b/Tests/RunCMake/CMP0132/CMP0132-OLD-stdout.txt new file mode 100644 index 0000000..c131428 --- /dev/null +++ b/Tests/RunCMake/CMP0132/CMP0132-OLD-stdout.txt @@ -0,0 +1 @@ +SKIPPED|CC was set diff --git a/Tests/RunCMake/CMP0132/CMP0132-OLD.cmake b/Tests/RunCMake/CMP0132/CMP0132-OLD.cmake new file mode 100644 index 0000000..aae4f2a --- /dev/null +++ b/Tests/RunCMake/CMP0132/CMP0132-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0132 OLD) +include(CMP0132-Common.cmake) diff --git a/Tests/RunCMake/CMP0132/CMP0132-WARN-stdout.txt b/Tests/RunCMake/CMP0132/CMP0132-WARN-stdout.txt new file mode 100644 index 0000000..c131428 --- /dev/null +++ b/Tests/RunCMake/CMP0132/CMP0132-WARN-stdout.txt @@ -0,0 +1 @@ +SKIPPED|CC was set diff --git a/Tests/RunCMake/CMP0132/CMP0132-WARN.cmake b/Tests/RunCMake/CMP0132/CMP0132-WARN.cmake new file mode 100644 index 0000000..c07e5db --- /dev/null +++ b/Tests/RunCMake/CMP0132/CMP0132-WARN.cmake @@ -0,0 +1,2 @@ + +include(CMP0132-Common.cmake) diff --git a/Tests/RunCMake/CMP0132/CMakeLists.txt b/Tests/RunCMake/CMP0132/CMakeLists.txt new file mode 100644 index 0000000..5ff8d3e --- /dev/null +++ b/Tests/RunCMake/CMP0132/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.23) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CMP0132/RunCMakeTest.cmake b/Tests/RunCMake/CMP0132/RunCMakeTest.cmake new file mode 100644 index 0000000..db599ce --- /dev/null +++ b/Tests/RunCMake/CMP0132/RunCMakeTest.cmake @@ -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() diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index fffbc6b..8ea5a50 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -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. -- cgit v0.12