From ca5a300d7fee308a0f32bf677e4bb5d74ebbd0cc Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Thu, 2 Nov 2023 17:48:15 +0100 Subject: add_test: Honor CROSSCOMPILING_EMULATOR only when cross-compiling Add policy CMP0158 to provide compatibility for existing projects. Fixes: #23672 --- Help/command/add_test.rst | 6 +++++ Help/manual/cmake-policies.7.rst | 1 + Help/policy/CMP0158.rst | 27 +++++++++++++++++++++ Help/release/dev/cmake-test-launcher.rst | 4 ++++ Source/cmPolicies.h | 6 ++++- Source/cmTest.cxx | 1 + Source/cmTest.h | 8 +++++++ Source/cmTestGenerator.cxx | 4 +++- .../AddTest-CMP0158-NEW-check.cmake | 28 ++++++++++++++++++++++ .../AddTest-CMP0158-NEW.cmake | 25 +++++++++++++++++++ .../AddTest-CMP0158-OLD-check.cmake | 28 ++++++++++++++++++++++ .../AddTest-CMP0158-OLD.cmake | 25 +++++++++++++++++++ .../CrosscompilingEmulator/RunCMakeTest.cmake | 2 ++ 13 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 Help/policy/CMP0158.rst create mode 100644 Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-NEW-check.cmake create mode 100644 Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-NEW.cmake create mode 100644 Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-OLD-check.cmake create mode 100644 Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-OLD.cmake diff --git a/Help/command/add_test.rst b/Help/command/add_test.rst index 37b9563..557c858 100644 --- a/Help/command/add_test.rst +++ b/Help/command/add_test.rst @@ -42,6 +42,12 @@ directory the test is created in. + .. versionchanged:: 3.29 + + The emulator is used only when + :variable:`cross-compiling `. + See policy :policy:`CMP0158`. + * .. versionadded:: 3.29 The target's :prop_tgt:`TEST_LAUNCHER`, if set, will be diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index ddde877..35b4497 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -57,6 +57,7 @@ Policies Introduced by CMake 3.29 .. toctree:: :maxdepth: 1 + CMP0158: add_test() honors CMAKE_CROSSCOMPILING_EMULATOR only when cross-compiling. CMP0157: Swift compilation mode is selected by an abstraction. CMP0156: De-duplicate libraries on link lines based on linker capabilities. diff --git a/Help/policy/CMP0158.rst b/Help/policy/CMP0158.rst new file mode 100644 index 0000000..4289c6d --- /dev/null +++ b/Help/policy/CMP0158.rst @@ -0,0 +1,27 @@ +CMP0158 +------- + +.. versionadded:: 3.29 + +:command:`add_test` honors :variable:`CMAKE_CROSSCOMPILING_EMULATOR` only +when :variable:`cross-compiling `. + +In CMake 3.28 and below, :command:`add_test` unconditionally used the +:prop_tgt:`CROSSCOMPILING_EMULATOR` target property (initialized by the +:variable:`CMAKE_CROSSCOMPILING_EMULATOR` variable) to run test commands +naming executable targets. CMake 3.29 and above prefer to use the emulator +only when the :variable:`CMAKE_CROSSCOMPILING` variable is enabled. The +:variable:`CMAKE_TEST_LAUNCHER` variable may be used instead when not +cross-compiling. This policy provides compatibility for projects that +have not been updated. + +The ``OLD`` behavior for this policy is for :command:`add_test` to use +the :prop_tgt:`CROSSCOMPILING_EMULATOR` target property unconditionally. +The ``NEW`` behavior for this policy is for :command:`add_test` to use +the :prop_tgt:`CROSSCOMPILING_EMULATOR` target property only when +:variable:`cross-compiling `. + +This policy was introduced in CMake version 3.29. 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. diff --git a/Help/release/dev/cmake-test-launcher.rst b/Help/release/dev/cmake-test-launcher.rst index e97498d..a82a8ad 100644 --- a/Help/release/dev/cmake-test-launcher.rst +++ b/Help/release/dev/cmake-test-launcher.rst @@ -5,3 +5,7 @@ cmake-test-launcher :prop_tgt:`TEST_LAUNCHER` target property were added to specify a launcher to be used by executable targets when invoked by tests added by the :command:`add_test` command. + +* The :command:`add_test` command now honors + :variable:`CMAKE_CROSSCOMPILING_EMULATOR` only when cross-compiling. + See policy :policy:`CMP0158`. diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 7964f32..f038c6b 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -480,7 +480,11 @@ class cmMakefile; 29, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0157, \ "Swift compilation mode selected by an abstraction.", 3, 29, 0, \ - cmPolicies::WARN) + cmPolicies::WARN) \ + SELECT(POLICY, CMP0158, \ + "add_test() honors CMAKE_CROSSCOMPILING_EMULATOR only when " \ + "cross-compiling.", \ + 3, 28, 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/Source/cmTest.cxx b/Source/cmTest.cxx index b0d9c2d..7c9969c 100644 --- a/Source/cmTest.cxx +++ b/Source/cmTest.cxx @@ -9,6 +9,7 @@ cmTest::cmTest(cmMakefile* mf) : Backtrace(mf->GetBacktrace()) + , PolicyStatusCMP0158(mf->GetPolicyStatus(cmPolicies::CMP0158)) { this->Makefile = mf; this->OldStyle = true; diff --git a/Source/cmTest.h b/Source/cmTest.h index 8b50b87..480966a 100644 --- a/Source/cmTest.h +++ b/Source/cmTest.h @@ -9,6 +9,7 @@ #include #include "cmListFileCache.h" +#include "cmPolicies.h" #include "cmPropertyMap.h" #include "cmValue.h" @@ -60,6 +61,12 @@ public: bool GetOldStyle() const { return this->OldStyle; } void SetOldStyle(bool b) { this->OldStyle = b; } + /** Get/Set if CMP0158 policy is NEW */ + bool GetCMP0158IsNew() const + { + return this->PolicyStatusCMP0158 == cmPolicies::NEW; + } + /** Set/Get whether lists in command lines should be expanded. */ bool GetCommandExpandLists() const; void SetCommandExpandLists(bool b); @@ -74,4 +81,5 @@ private: cmMakefile* Makefile; cmListFileBacktrace Backtrace; + cmPolicies::PolicyStatus PolicyStatusCMP0158; }; diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx index 2831d0d..3194d8f 100644 --- a/Source/cmTestGenerator.cxx +++ b/Source/cmTestGenerator.cxx @@ -167,6 +167,8 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, if (target && target->GetType() == cmStateEnums::EXECUTABLE) { // Use the target file on disk. exe = target->GetFullPath(config); + auto useEmulator = !this->GetTest()->GetCMP0158IsNew() || + this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING"); // Prepend with the test launcher if specified. cmValue launcher = target->GetProperty("TEST_LAUNCHER"); @@ -182,7 +184,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, // Prepend with the emulator when cross compiling if required. cmValue emulator = target->GetProperty("CROSSCOMPILING_EMULATOR"); - if (cmNonempty(emulator)) { + if (cmNonempty(emulator) && useEmulator) { cmList emulatorWithArgs{ *emulator }; std::string emulatorExe(emulatorWithArgs[0]); cmSystemTools::ConvertToUnixSlashes(emulatorExe); diff --git a/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-NEW-check.cmake b/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-NEW-check.cmake new file mode 100644 index 0000000..8a6a702 --- /dev/null +++ b/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-NEW-check.cmake @@ -0,0 +1,28 @@ +set(testfile "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake") +if(EXISTS "${testfile}") + file(READ "${testfile}" testfile_contents) +else() + message(FATAL_ERROR "Could not find expected CTestTestfile.cmake.") +endif() + +set(error_details "There is a problem with generated test file: ${testfile}") + +if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulator [^\n]+pseudo_emulator[^\n]+\n") + message(SEND_ERROR "Used emulator when it should not be used. ${error_details}") +endif() + +if(testfile_contents MATCHES "add_test[(]ShouldNotUseEmulator [^\n]+pseudo_emulator[^\n]+\n") + message(SEND_ERROR "Used emulator when it should be used. ${error_details}") +endif() + +if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulatorWithGenex [^\n]+pseudo_emulator[^\n]+\n") + message(SEND_ERROR "Used emulator when it should not be used. ${error_details}") +endif() + +if(testfile_contents MATCHES "add_test[(]ShouldNotUseEmulatorWithExecTargetFromSubdirAddedWithoutGenex [^\n]+pseudo_emulator[^\n]+\n") + message(SEND_ERROR "Used emulator when it should be used. ${error_details}") +endif() + +if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulatorWithExecTargetFromSubdirAddedWithGenex [^\n]+pseudo_emulator[^\n]+\n") + message(SEND_ERROR "Used emulator when it should not be used. ${error_details}") +endif() diff --git a/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-NEW.cmake b/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-NEW.cmake new file mode 100644 index 0000000..9f9547c --- /dev/null +++ b/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-NEW.cmake @@ -0,0 +1,25 @@ +if(CMAKE_CROSSCOMPILING) + message(FATAL_ERROR "cross compiling") +endif() + +cmake_policy(SET CMP0158 NEW) + +enable_testing() +add_test(NAME DoesNotUseEmulator + COMMAND ${CMAKE_COMMAND} -E echo "Hi") + +add_executable(generated_exe simple_src_exiterror.cxx) + +add_test(NAME ShouldNotUseEmulator + COMMAND generated_exe) + +add_test(NAME DoesNotUseEmulatorWithGenex + COMMAND $) + +add_subdirectory(AddTest) + +add_test(NAME ShouldNotUseEmulatorWithExecTargetFromSubdirAddedWithoutGenex + COMMAND generated_exe_in_subdir_added_to_test_without_genex) + +add_test(NAME DoesNotUseEmulatorWithExecTargetFromSubdirAddedWithGenex + COMMAND $) diff --git a/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-OLD-check.cmake b/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-OLD-check.cmake new file mode 100644 index 0000000..588b77b --- /dev/null +++ b/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-OLD-check.cmake @@ -0,0 +1,28 @@ +set(testfile "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake") +if(EXISTS "${testfile}") + file(READ "${testfile}" testfile_contents) +else() + message(FATAL_ERROR "Could not find expected CTestTestfile.cmake.") +endif() + +set(error_details "There is a problem with generated test file: ${testfile}") + +if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulator [^\n]+pseudo_emulator[^\n]+\n") + message(SEND_ERROR "Used emulator when it should not be used. ${error_details}") +endif() + +if(NOT testfile_contents MATCHES "add_test[(]UsesEmulator [^\n]+pseudo_emulator[^\n]+\n") + message(SEND_ERROR "Did not use emulator when it should be used. ${error_details}") +endif() + +if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulatorWithGenex [^\n]+pseudo_emulator[^\n]+\n") + message(SEND_ERROR "Used emulator when it should not be used. ${error_details}") +endif() + +if(NOT testfile_contents MATCHES "add_test[(]UsesEmulatorWithExecTargetFromSubdirAddedWithoutGenex [^\n]+pseudo_emulator[^\n]+\n") + message(SEND_ERROR "Did not use emulator when it should be used. ${error_details}") +endif() + +if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulatorWithExecTargetFromSubdirAddedWithGenex [^\n]+pseudo_emulator[^\n]+\n") + message(SEND_ERROR "Used emulator when it should not be used. ${error_details}") +endif() diff --git a/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-OLD.cmake b/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-OLD.cmake new file mode 100644 index 0000000..910f1b4 --- /dev/null +++ b/Tests/RunCMake/CrosscompilingEmulator/AddTest-CMP0158-OLD.cmake @@ -0,0 +1,25 @@ +if(CMAKE_CROSSCOMPILING) + message(FATAL_ERROR "cross compiling") +endif() + +cmake_policy(SET CMP0158 OLD) + +enable_testing() +add_test(NAME DoesNotUseEmulator + COMMAND ${CMAKE_COMMAND} -E echo "Hi") + +add_executable(generated_exe simple_src_exiterror.cxx) + +add_test(NAME UsesEmulator + COMMAND generated_exe) + +add_test(NAME DoesNotUseEmulatorWithGenex + COMMAND $) + +add_subdirectory(AddTest) + +add_test(NAME UsesEmulatorWithExecTargetFromSubdirAddedWithoutGenex + COMMAND generated_exe_in_subdir_added_to_test_without_genex) + +add_test(NAME DoesNotUseEmulatorWithExecTargetFromSubdirAddedWithGenex + COMMAND $) diff --git a/Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake b/Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake index 1ffd91c..c595f1a 100644 --- a/Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake +++ b/Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake @@ -6,6 +6,8 @@ set(RunCMake_TEST_OPTIONS run_cmake(CrosscompilingEmulatorProperty) run_cmake(TryRun) run_cmake(AddTest) +run_cmake(AddTest-CMP0158-OLD) +run_cmake(AddTest-CMP0158-NEW) function(CustomCommandGenerator_run_and_build case) # Use a single build tree for a few tests without cleaning. -- cgit v0.12