summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-12-15 14:34:09 (GMT)
committerKitware Robot <kwrobot@kitware.com>2023-12-15 14:34:20 (GMT)
commit6ba3bb0563ca72fa6fa7bc705bdf38187e3fa485 (patch)
treeb44461db107bee8b705602e2316721113d1451cc
parent6a67f71b57cef80f51bd225049198e80f325846b (diff)
parent88863d83d62b7668047ee78a3ada841364e119a0 (diff)
downloadCMake-6ba3bb0563ca72fa6fa7bc705bdf38187e3fa485.zip
CMake-6ba3bb0563ca72fa6fa7bc705bdf38187e3fa485.tar.gz
CMake-6ba3bb0563ca72fa6fa7bc705bdf38187e3fa485.tar.bz2
Merge topic 'cmake-test-launcher'
88863d83d6 fileapi: Add test launcher to codemodel-v2 1ec0372ed4 add_test: Optionally use a launcher for tests running in-project targets 478a5f4e04 fileapi: Make launcher attribute 'arguments' optional b44e38a397 cmFileAPICodemodel: Add missing std::move() Acked-by: Kitware Robot <kwrobot@kitware.com> Tested-by: buildbot <buildbot@kitware.com> Merge-request: !8963
-rw-r--r--Help/command/add_test.rst28
-rw-r--r--Help/envvar/CMAKE_TEST_LAUNCHER.rst11
-rw-r--r--Help/manual/cmake-env-variables.7.rst1
-rw-r--r--Help/manual/cmake-file-api.7.rst4
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/prop_test/PASS_REGULAR_EXPRESSION.rst3
-rw-r--r--Help/prop_test/SKIP_REGULAR_EXPRESSION.rst3
-rw-r--r--Help/prop_test/SKIP_RETURN_CODE.rst3
-rw-r--r--Help/prop_test/WILL_FAIL.rst3
-rw-r--r--Help/prop_tgt/TEST_LAUNCHER.rst20
-rw-r--r--Help/release/dev/cmake-test-launcher.rst7
-rw-r--r--Help/variable/CMAKE_TEST_LAUNCHER.rst16
-rw-r--r--Source/cmFileAPICodemodel.cxx19
-rw-r--r--Source/cmTarget.cxx1
-rw-r--r--Source/cmTestGenerator.cxx12
-rw-r--r--Source/cmake.cxx10
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake4
-rw-r--r--Tests/RunCMake/CrosscompilingEmulator/AddTest.cmake6
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-check.py17
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.cross.json3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json1
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json8
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json8
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_cross_emulator.json1
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher.json105
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher_and_cross_emulator.json109
-rw-r--r--Tests/RunCMake/FileAPI/cxx/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/FileAPI/cxx/cross/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/add_test/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/add_test/TestLauncher-check.cmake28
-rw-r--r--Tests/RunCMake/add_test/TestLauncher.cmake22
-rw-r--r--Tests/RunCMake/add_test/TestLauncher/CMakeLists.txt9
-rw-r--r--Tests/RunCMake/add_test/TestLauncherProperty.cmake41
-rw-r--r--Tests/RunCMake/add_test/simple_src_exiterror.cxx4
-rw-r--r--Tests/RunCMake/property_init/Executable.cmake1
37 files changed, 503 insertions, 22 deletions
diff --git a/Help/command/add_test.rst b/Help/command/add_test.rst
index 02dd3986..37b9563 100644
--- a/Help/command/add_test.rst
+++ b/Help/command/add_test.rst
@@ -27,9 +27,31 @@ directory the test is created in.
``add_test`` options are:
``COMMAND``
- Specify the test command-line. If ``<command>`` specifies an executable
- target created by :command:`add_executable`, it will automatically be
- replaced by the location of the executable created at build time.
+ Specify the test command-line.
+
+ If ``<command>`` specifies an executable target created by
+ :command:`add_executable`:
+
+ * It will automatically be replaced by the location of the executable
+ created at build time.
+
+ * .. versionadded:: 3.3
+
+ The target's :prop_tgt:`CROSSCOMPILING_EMULATOR`, if set, will be
+ used to run the command on the host::
+
+ <emulator> <command>
+
+ * .. versionadded:: 3.29
+
+ The target's :prop_tgt:`TEST_LAUNCHER`, if set, will be
+ used to launch the command::
+
+ <launcher> <command>
+
+ If the :prop_tgt:`CROSSCOMPILING_EMULATOR` is also set, both are used::
+
+ <launcher> <emulator> <command>
The command may be specified using
:manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/envvar/CMAKE_TEST_LAUNCHER.rst b/Help/envvar/CMAKE_TEST_LAUNCHER.rst
new file mode 100644
index 0000000..d620ce5
--- /dev/null
+++ b/Help/envvar/CMAKE_TEST_LAUNCHER.rst
@@ -0,0 +1,11 @@
+CMAKE_TEST_LAUNCHER
+-------------------
+
+.. versionadded:: 3.29
+
+.. include:: ENV_VAR.txt
+
+The default value for the :variable:`CMAKE_TEST_LAUNCHER` 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_TEST_LAUNCHER`.
diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst
index 55f07b7..5272ab9 100644
--- a/Help/manual/cmake-env-variables.7.rst
+++ b/Help/manual/cmake-env-variables.7.rst
@@ -56,6 +56,7 @@ Environment Variables that Control the Build
/envvar/CMAKE_MSVCIDE_RUN_PATH
/envvar/CMAKE_NO_VERBOSE
/envvar/CMAKE_OSX_ARCHITECTURES
+ /envvar/CMAKE_TEST_LAUNCHER
/envvar/CMAKE_TOOLCHAIN_FILE
/envvar/DESTDIR
/envvar/LDFLAGS
diff --git a/Help/manual/cmake-file-api.7.rst b/Help/manual/cmake-file-api.7.rst
index 0d60311..fd28dbe 100644
--- a/Help/manual/cmake-file-api.7.rst
+++ b/Help/manual/cmake-file-api.7.rst
@@ -1022,6 +1022,10 @@ with members:
An emulator for the target platform when cross-compiling.
See the :prop_tgt:`CROSSCOMPILING_EMULATOR` target property.
+ ``test``
+ A start program for the execution of tests.
+ See the :prop_tgt:`TEST_LAUNCHER` target property.
+
This field was added in codemodel version 2.7.
``link``
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index b0f3db0..458cb73 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -398,6 +398,7 @@ Properties on Targets
/prop_tgt/Swift_MODULE_DIRECTORY
/prop_tgt/Swift_MODULE_NAME
/prop_tgt/SYSTEM
+ /prop_tgt/TEST_LAUNCHER
/prop_tgt/TYPE
/prop_tgt/UNITY_BUILD
/prop_tgt/UNITY_BUILD_BATCH_SIZE
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 80acd90..0e778f8 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -117,6 +117,7 @@ Variables that Provide Information
/variable/CMAKE_Swift_COMPILATION_MODE
/variable/CMAKE_Swift_MODULE_DIRECTORY
/variable/CMAKE_Swift_NUM_THREADS
+ /variable/CMAKE_TEST_LAUNCHER
/variable/CMAKE_TOOLCHAIN_FILE
/variable/CMAKE_TWEAK_VERSION
/variable/CMAKE_VERBOSE_MAKEFILE
diff --git a/Help/prop_test/PASS_REGULAR_EXPRESSION.rst b/Help/prop_test/PASS_REGULAR_EXPRESSION.rst
index 9f92491..b19e637 100644
--- a/Help/prop_test/PASS_REGULAR_EXPRESSION.rst
+++ b/Help/prop_test/PASS_REGULAR_EXPRESSION.rst
@@ -23,7 +23,8 @@ Example:
To run a test that may have a system-level failure, but still pass if
``PASS_REGULAR_EXPRESSION`` matches, use a CMake command to wrap the
executable run. Note that this will prevent automatic handling of the
-:prop_tgt:`CROSSCOMPILING_EMULATOR` target property.
+:prop_tgt:`CROSSCOMPILING_EMULATOR` and :prop_tgt:`TEST_LAUNCHER`
+target property.
.. code-block:: cmake
diff --git a/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst b/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst
index 9836412..8717a0a 100644
--- a/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst
+++ b/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst
@@ -25,7 +25,8 @@ Example:
To run a test that may have a system-level failure, but still skip if
``SKIP_REGULAR_EXPRESSION`` matches, use a CMake command to wrap the
executable run. Note that this will prevent automatic handling of the
-:prop_tgt:`CROSSCOMPILING_EMULATOR` target property.
+:prop_tgt:`CROSSCOMPILING_EMULATOR` and :prop_tgt:`TEST_LAUNCHER`
+target property.
.. code-block:: cmake
diff --git a/Help/prop_test/SKIP_RETURN_CODE.rst b/Help/prop_test/SKIP_RETURN_CODE.rst
index 096eb09..57fc031 100644
--- a/Help/prop_test/SKIP_RETURN_CODE.rst
+++ b/Help/prop_test/SKIP_RETURN_CODE.rst
@@ -25,7 +25,8 @@ signal abort, or heap errors may fail the test even if the return code matches.
To run a test that may have a system-level failure, but still skip if
``SKIP_RETURN_CODE`` matches, use a CMake command to wrap the executable run.
Note that this will prevent automatic handling of the
-:prop_tgt:`CROSSCOMPILING_EMULATOR` target property.
+:prop_tgt:`CROSSCOMPILING_EMULATOR` and :prop_tgt:`TEST_LAUNCHER` target
+property.
.. code-block:: cmake
diff --git a/Help/prop_test/WILL_FAIL.rst b/Help/prop_test/WILL_FAIL.rst
index 53437d2..9d61ab7 100644
--- a/Help/prop_test/WILL_FAIL.rst
+++ b/Help/prop_test/WILL_FAIL.rst
@@ -19,7 +19,8 @@ is ``true``:
To run a test that may have a system-level failure, but still pass if
``WILL_FAIL`` is set, use a CMake command to wrap the executable run.
Note that this will prevent automatic handling of the
-:prop_tgt:`CROSSCOMPILING_EMULATOR` target property.
+:prop_tgt:`CROSSCOMPILING_EMULATOR` and :prop_tgt:`TEST_LAUNCHER`
+target property.
.. code-block:: cmake
diff --git a/Help/prop_tgt/TEST_LAUNCHER.rst b/Help/prop_tgt/TEST_LAUNCHER.rst
new file mode 100644
index 0000000..2e44492
--- /dev/null
+++ b/Help/prop_tgt/TEST_LAUNCHER.rst
@@ -0,0 +1,20 @@
+TEST_LAUNCHER
+-------------
+
+.. versionadded:: 3.29
+
+Use the given launcher to run executables.
+This command will be added as a prefix to :command:`add_test` commands
+for build target system executables and is meant to be run on the host
+machine.
+
+It effectively acts as a run script for tests in a similar way
+to how :variable:`CMAKE_<LANG>_COMPILER_LAUNCHER` works for compilation.
+
+If this property contains a :ref:`semicolon-separated list <CMake Language
+Lists>`, then the first value is the command and remaining values are its
+arguments.
+
+This property is initialized by the value of the
+:variable:`CMAKE_TEST_LAUNCHER` variable if it is set when a target
+is created.
diff --git a/Help/release/dev/cmake-test-launcher.rst b/Help/release/dev/cmake-test-launcher.rst
new file mode 100644
index 0000000..e97498d
--- /dev/null
+++ b/Help/release/dev/cmake-test-launcher.rst
@@ -0,0 +1,7 @@
+cmake-test-launcher
+-------------------
+
+* A :variable:`CMAKE_TEST_LAUNCHER` variable and corresponding
+ :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.
diff --git a/Help/variable/CMAKE_TEST_LAUNCHER.rst b/Help/variable/CMAKE_TEST_LAUNCHER.rst
new file mode 100644
index 0000000..c527188
--- /dev/null
+++ b/Help/variable/CMAKE_TEST_LAUNCHER.rst
@@ -0,0 +1,16 @@
+CMAKE_TEST_LAUNCHER
+-------------------
+
+.. versionadded:: 3.29
+
+This variable is used to specify a launcher for running tests, added
+by the :command:`add_test` command, that run an executable target.
+If this variable contains a :ref:`semicolon-separated list <CMake Language
+Lists>`, then the first value is the command and remaining values are its
+arguments.
+
+This variable can be initialized via an
+:envvar:`CMAKE_TEST_LAUNCHER` environment variable.
+
+It is also used as the default value for the
+:prop_tgt:`TEST_LAUNCHER` target property of executables.
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index a6c3c66..30a7e67 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -2102,7 +2102,9 @@ Json::Value Target::DumpLauncher(const char* name, const char* type)
for (std::string const& arg : cmMakeRange(commandWithArgs).advance(1)) {
args.append(arg);
}
- launcher["arguments"] = args;
+ if (!args.empty()) {
+ launcher["arguments"] = std::move(args);
+ }
}
return launcher;
}
@@ -2110,13 +2112,16 @@ Json::Value Target::DumpLauncher(const char* name, const char* type)
Json::Value Target::DumpLaunchers()
{
Json::Value launchers;
- bool allow =
- this->GT->Makefile->GetDefinition("CMAKE_CROSSCOMPILING").IsOn();
- Json::Value launcher;
- if (allow) {
- launcher = DumpLauncher("CROSSCOMPILING_EMULATOR", "emulator");
+ {
+ Json::Value launcher = DumpLauncher("TEST_LAUNCHER", "test");
if (!launcher.empty()) {
- launchers.append(launcher);
+ launchers.append(std::move(launcher));
+ }
+ }
+ if (this->GT->Makefile->IsOn("CMAKE_CROSSCOMPILING")) {
+ Json::Value emulator = DumpLauncher("CROSSCOMPILING_EMULATOR", "emulator");
+ if (!emulator.empty()) {
+ launchers.append(std::move(emulator));
}
}
return launchers;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 169d808..832bf57 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -594,6 +594,7 @@ TargetProperty const StaticTargetProperties[] = {
{ "CROSSCOMPILING_EMULATOR"_s, IC::ExecutableTarget },
{ "EXPORT_COMPILE_COMMANDS"_s, IC::CanCompileSources },
{ "FOLDER"_s },
+ { "TEST_LAUNCHER"_s, IC::ExecutableTarget },
// Xcode properties
{ "XCODE_GENERATE_SCHEME"_s, IC::NeedsXcode },
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index ca1226a..2831d0d 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -168,6 +168,18 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
// Use the target file on disk.
exe = target->GetFullPath(config);
+ // Prepend with the test launcher if specified.
+ cmValue launcher = target->GetProperty("TEST_LAUNCHER");
+ if (cmNonempty(launcher)) {
+ cmList launcherWithArgs{ *launcher };
+ std::string launcherExe(launcherWithArgs[0]);
+ cmSystemTools::ConvertToUnixSlashes(launcherExe);
+ os << cmOutputConverter::EscapeForCMake(launcherExe) << " ";
+ for (std::string const& arg : cmMakeRange(launcherWithArgs).advance(1)) {
+ os << cmOutputConverter::EscapeForCMake(arg) << " ";
+ }
+ }
+
// Prepend with the emulator when cross compiling if required.
cmValue emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
if (cmNonempty(emulator)) {
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index a25147a..fd22957 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -2515,6 +2515,16 @@ int cmake::ActualConfigure()
"Name of generator toolset.", cmStateEnums::INTERNAL);
}
+ if (!this->State->GetInitializedCacheValue("CMAKE_TEST_LAUNCHER")) {
+ cm::optional<std::string> testLauncher =
+ cmSystemTools::GetEnvVar("CMAKE_TEST_LAUNCHER");
+ if (testLauncher && !testLauncher->empty()) {
+ std::string message = "Test launcher to run tests executable.";
+ this->AddCacheEntry("CMAKE_TEST_LAUNCHER", *testLauncher, message,
+ cmStateEnums::STRING);
+ }
+ }
+
if (!this->State->GetInitializedCacheValue(
"CMAKE_CROSSCOMPILING_EMULATOR")) {
cm::optional<std::string> emulator =
diff --git a/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake b/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake
index 588b77b..459e922 100644
--- a/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake
+++ b/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake
@@ -26,3 +26,7 @@ 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()
+
+if(NOT testfile_contents MATCHES "add_test[(]UsesTestLauncherAndEmulator[^\n]+pseudo_test_launcher.*pseudo_emulator[^\n]+\n")
+ message(SEND_ERROR "Did not use test launcher and emulator when they should be used. ${error_details}")
+endif()
diff --git a/Tests/RunCMake/CrosscompilingEmulator/AddTest.cmake b/Tests/RunCMake/CrosscompilingEmulator/AddTest.cmake
index 23e2e8d..4bcb2cf 100644
--- a/Tests/RunCMake/CrosscompilingEmulator/AddTest.cmake
+++ b/Tests/RunCMake/CrosscompilingEmulator/AddTest.cmake
@@ -18,3 +18,9 @@ add_test(NAME UsesEmulatorWithExecTargetFromSubdirAddedWithoutGenex
add_test(NAME DoesNotUseEmulatorWithExecTargetFromSubdirAddedWithGenex
COMMAND $<TARGET_FILE:generated_exe_in_subdir_added_to_test_with_genex>)
+
+add_executable(generated_exe_test_launcher simple_src_exiterror.cxx)
+set_property(TARGET generated_exe_test_launcher PROPERTY TEST_LAUNCHER "pseudo_test_launcher")
+
+add_test(NAME UsesTestLauncherAndEmulator
+ COMMAND generated_exe_test_launcher)
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
index cb90eba..5f41ad9 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
@@ -410,15 +410,18 @@ def check_target(c):
expected_keys.append("launchers")
def check_launcher(actual, expected):
assert is_dict(actual)
- launcher_keys = ["arguments", "command", "type"]
+ launcher_keys = ["command", "type"]
+ if "arguments" in expected:
+ launcher_keys.append("arguments")
assert sorted(actual.keys()) == sorted(launcher_keys)
assert matches(actual["command"], expected["command"])
assert matches(actual["type"], expected["type"])
- if expected["arguments"] is not None:
- check_list_match(lambda a, e: matches(a, e),
- actual["arguments"], expected["arguments"],
- missing_exception=lambda e: "argument: %s" % e,
- extra_exception=lambda a: "argument: %s" % actual["arguments"])
+ if "arguments" in expected:
+ if expected["arguments"] is not None:
+ check_list_match(lambda a, e: matches(a, e),
+ actual["arguments"], expected["arguments"],
+ missing_exception=lambda e: "argument: %s" % e,
+ extra_exception=lambda a: "argument: %s" % actual["arguments"])
check_list_match(lambda a, e: matches(a["type"], e["type"]),
obj["launchers"], expected["launchers"],
check=check_launcher,
@@ -806,6 +809,8 @@ def gen_check_targets(c, g, inSource):
read_codemodel_json_data("targets/cxx_exe.json"),
read_codemodel_json_data("targets/cxx_exe_cross_emulator.json"),
read_codemodel_json_data("targets/cxx_exe_cross_emulator_args.json"),
+ read_codemodel_json_data("targets/cxx_exe_test_launcher_and_cross_emulator.json"),
+ read_codemodel_json_data("targets/cxx_exe_test_launcher.json"),
read_codemodel_json_data("targets/cxx_standard_compile_feature_exe.json"),
read_codemodel_json_data("targets/cxx_standard_exe.json"),
read_codemodel_json_data("targets/cxx_shared_lib.json"),
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.cross.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.cross.json
index 09a9d04..8f6ded5 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.cross.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.cross.json
@@ -6,7 +6,8 @@
"childSources": null,
"targetIds": [
"^cxx_exe_cross_emulator::@ee4a268216d1f53c4e2e$",
- "^cxx_exe_cross_emulator_args::@ee4a268216d1f53c4e2e$"
+ "^cxx_exe_cross_emulator_args::@ee4a268216d1f53c4e2e$",
+ "^cxx_exe_test_launcher_and_cross_emulator::@ee4a268216d1f53c4e2e$"
],
"projectName": "Cxx",
"minimumCMakeVersion": "3.13",
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json
index defb865..912d664 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json
@@ -9,6 +9,7 @@
"^ALL_BUILD::@a56b12a3f5c0529fb296$",
"^ZERO_CHECK::@a56b12a3f5c0529fb296$",
"^cxx_exe::@a56b12a3f5c0529fb296$",
+ "^cxx_exe_test_launcher::@a56b12a3f5c0529fb296$",
"^cxx_standard_compile_feature_exe::@a56b12a3f5c0529fb296$",
"^cxx_standard_exe::@a56b12a3f5c0529fb296$",
"^cxx_lib::@a56b12a3f5c0529fb296$",
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json
index ea738f8..c8a1a83 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json
@@ -13,6 +13,8 @@
"^cxx_exe::@a56b12a3f5c0529fb296$",
"^cxx_exe_cross_emulator::@ee4a268216d1f53c4e2e$",
"^cxx_exe_cross_emulator_args::@ee4a268216d1f53c4e2e$",
+ "^cxx_exe_test_launcher_and_cross_emulator::@ee4a268216d1f53c4e2e$",
+ "^cxx_exe_test_launcher::@a56b12a3f5c0529fb296$",
"^cxx_standard_compile_feature_exe::@a56b12a3f5c0529fb296$",
"^cxx_standard_exe::@a56b12a3f5c0529fb296$",
"^cxx_shared_lib::@a56b12a3f5c0529fb296$",
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json
index 2a093ab..3a83d29 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json
@@ -91,6 +91,14 @@
"backtrace": null
},
{
+ "id": "^cxx_exe_test_launcher_and_cross_emulator::@ee4a268216d1f53c4e2e$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_exe_test_launcher::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ },
+ {
"id": "^cxx_standard_compile_feature_exe::@a56b12a3f5c0529fb296$",
"backtrace": null
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
index b7cbc14..ec72eb8 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
@@ -131,6 +131,14 @@
"backtrace": null
},
{
+ "id": "^cxx_exe_test_launcher_and_cross_emulator::@ee4a268216d1f53c4e2e$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_exe_test_launcher::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ },
+ {
"id": "^cxx_standard_compile_feature_exe::@a56b12a3f5c0529fb296$",
"backtrace": null
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_cross_emulator.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_cross_emulator.json
index 9bd2d5d..bbd973b 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_cross_emulator.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_cross_emulator.json
@@ -80,7 +80,6 @@
"install": null,
"launchers" : [
{
- "arguments" : null,
"command": "^no-such-emulator(\\.exe)?$",
"type" : "emulator"
}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher.json
new file mode 100644
index 0000000..9002368
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher.json
@@ -0,0 +1,105 @@
+{
+ "name": "cxx_exe_test_launcher",
+ "id": "^cxx_exe_test_launcher::@a56b12a3f5c0529fb296$",
+ "directorySource": "^cxx$",
+ "projectName": "Cxx",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "fileSets": null,
+ "sources": [
+ {
+ "path": "^empty\\.cxx$",
+ "isGenerated": null,
+ "fileSetName": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 49,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ],
+ "includes": null,
+ "frameworks": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 49,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^cxx_exe_test_launcher(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_exe_test_launcher(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_exe_test_launcher\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^cxx$",
+ "source": "^cxx$",
+ "install": null,
+ "launchers" : [
+ {
+ "command": "^no-such-launcher(\\.exe)?$",
+ "type" : "test"
+ }
+ ],
+ "link": {
+ "language": "CXX",
+ "lto": null,
+ "commandFragments": [
+ {
+ "fragment" : ".*",
+ "role" : "flags",
+ "backtrace": null
+ }
+ ]
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher_and_cross_emulator.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher_and_cross_emulator.json
new file mode 100644
index 0000000..06e7a7b
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_test_launcher_and_cross_emulator.json
@@ -0,0 +1,109 @@
+{
+ "name": "cxx_exe_test_launcher_and_cross_emulator",
+ "id": "^cxx_exe_test_launcher_and_cross_emulator::@ee4a268216d1f53c4e2e$",
+ "directorySource": "^cxx/cross$",
+ "projectName": "Cxx",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "fileSets": null,
+ "sources": [
+ {
+ "path": "^empty\\.cxx$",
+ "isGenerated": null,
+ "fileSetName": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/cross/CMakeLists\\.txt$",
+ "line": 9,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/cross/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ],
+ "includes": null,
+ "frameworks": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^cxx/cross/CMakeLists\\.txt$",
+ "line": 9,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/cross/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^cxx_exe_test_launcher_and_cross_emulator(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^cxx/cross/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_exe_test_launcher_and_cross_emulator(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^cxx/cross/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_exe_test_launcher_and_cross_emulator\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^cxx/cross$",
+ "source": "^cxx/cross$",
+ "install": null,
+ "launchers" : [
+ {
+ "command": "^no-such-launcher(\\.exe)?$",
+ "type" : "test"
+ },
+ {
+ "command": "^no-such-emulator(\\.exe)?$",
+ "type" : "emulator"
+ }
+ ],
+ "link": {
+ "language": "CXX",
+ "lto": null,
+ "commandFragments": [
+ {
+ "fragment" : ".*",
+ "role" : "flags",
+ "backtrace": null
+ }
+ ]
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt
index 91a9969..c465297 100644
--- a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt
+++ b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt
@@ -46,4 +46,7 @@ if(_rdeps)
)
endif()
+add_executable(cxx_exe_test_launcher ../empty.cxx)
+set_property(TARGET cxx_exe_test_launcher PROPERTY TEST_LAUNCHER no-such-launcher)
+
add_subdirectory(cross)
diff --git a/Tests/RunCMake/FileAPI/cxx/cross/CMakeLists.txt b/Tests/RunCMake/FileAPI/cxx/cross/CMakeLists.txt
index 87baf19..2f2594f 100644
--- a/Tests/RunCMake/FileAPI/cxx/cross/CMakeLists.txt
+++ b/Tests/RunCMake/FileAPI/cxx/cross/CMakeLists.txt
@@ -5,3 +5,7 @@ set_property(TARGET cxx_exe_cross_emulator PROPERTY CROSSCOMPILING_EMULATOR no-s
add_executable(cxx_exe_cross_emulator_args ../../empty.cxx)
set_property(TARGET cxx_exe_cross_emulator_args PROPERTY CROSSCOMPILING_EMULATOR "no-such-emulator;arg1;arg2 with space")
+
+add_executable(cxx_exe_test_launcher_and_cross_emulator ../../empty.cxx)
+set_property(TARGET cxx_exe_test_launcher_and_cross_emulator PROPERTY TEST_LAUNCHER "no-such-launcher")
+set_property(TARGET cxx_exe_test_launcher_and_cross_emulator PROPERTY CROSSCOMPILING_EMULATOR "no-such-emulator")
diff --git a/Tests/RunCMake/add_test/RunCMakeTest.cmake b/Tests/RunCMake/add_test/RunCMakeTest.cmake
index ec6f6dd..8b5c915 100644
--- a/Tests/RunCMake/add_test/RunCMakeTest.cmake
+++ b/Tests/RunCMake/add_test/RunCMakeTest.cmake
@@ -41,3 +41,9 @@ block()
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(EmptyArgument-ctest ${CMAKE_CTEST_COMMAND} -C Debug)
endblock()
+
+set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_TEST_LAUNCHER=/path/to/pseudo_test_launcher")
+
+run_cmake(TestLauncherProperty)
+run_cmake(TestLauncher)
diff --git a/Tests/RunCMake/add_test/TestLauncher-check.cmake b/Tests/RunCMake/add_test/TestLauncher-check.cmake
new file mode 100644
index 0000000..78020a6
--- /dev/null
+++ b/Tests/RunCMake/add_test/TestLauncher-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[(]DoesNotUseTestLauncher [^\n]+pseudo_test_launcher[^\n]+\n")
+ message(SEND_ERROR "Used test launcher when it should not be used. ${error_details}")
+endif()
+
+if(NOT testfile_contents MATCHES "add_test[(]UsesTestLauncher [^\n]+pseudo_test_launcher[^\n]+\n")
+ message(SEND_ERROR "Did not use test launcher when it should be used. ${error_details}")
+endif()
+
+if(testfile_contents MATCHES "add_test[(]DoesNotUseTestLauncherWithGenex [^\n]+pseudo_test_launcher[^\n]+\n")
+ message(SEND_ERROR "Used test launcher when it should not be used. ${error_details}")
+endif()
+
+if(NOT testfile_contents MATCHES "add_test[(]UsesTestLauncherWithExecTargetFromSubdirAddedWithoutGenex [^\n]+pseudo_test_launcher[^\n]+\n")
+ message(SEND_ERROR "Did not use test launcher when it should be used. ${error_details}")
+endif()
+
+if(testfile_contents MATCHES "add_test[(]DoesNotUseTestLauncherWithExecTargetFromSubdirAddedWithGenex [^\n]+pseudo_test_launcher[^\n]+\n")
+ message(SEND_ERROR "Used test launcher when it should not be used. ${error_details}")
+endif()
diff --git a/Tests/RunCMake/add_test/TestLauncher.cmake b/Tests/RunCMake/add_test/TestLauncher.cmake
new file mode 100644
index 0000000..8ad3be9
--- /dev/null
+++ b/Tests/RunCMake/add_test/TestLauncher.cmake
@@ -0,0 +1,22 @@
+project(test_launcher LANGUAGES C)
+
+enable_testing()
+add_test(NAME DoesNotUseLauncher
+ COMMAND ${CMAKE_COMMAND} -E echo "Hi")
+
+add_executable(generated_exe simple_src_exiterror.cxx)
+set_target_properties(generated_exe PROPERTIES LINKER_LANGUAGE C)
+
+add_test(NAME UsesTestLauncher
+ COMMAND generated_exe)
+
+add_test(NAME DoesNotUseTestLauncherWithGenex
+ COMMAND $<TARGET_FILE:generated_exe>)
+
+add_subdirectory(TestLauncher)
+
+add_test(NAME UsesTestLauncherWithExecTargetFromSubdirAddedWithoutGenex
+ COMMAND generated_exe_in_subdir_added_to_test_without_genex)
+
+add_test(NAME DoesNotUseTestLauncherWithExecTargetFromSubdirAddedWithGenex
+ COMMAND $<TARGET_FILE:generated_exe_in_subdir_added_to_test_with_genex>)
diff --git a/Tests/RunCMake/add_test/TestLauncher/CMakeLists.txt b/Tests/RunCMake/add_test/TestLauncher/CMakeLists.txt
new file mode 100644
index 0000000..fb40a59
--- /dev/null
+++ b/Tests/RunCMake/add_test/TestLauncher/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_executable(generated_exe_in_subdir_added_to_test_without_genex
+ ${CMAKE_CURRENT_SOURCE_DIR}/../simple_src_exiterror.cxx)
+set_target_properties(generated_exe_in_subdir_added_to_test_without_genex
+ PROPERTIES LINKER_LANGUAGE C)
+
+add_executable(generated_exe_in_subdir_added_to_test_with_genex
+ ${CMAKE_CURRENT_SOURCE_DIR}/../simple_src_exiterror.cxx)
+set_target_properties(generated_exe_in_subdir_added_to_test_with_genex
+ PROPERTIES LINKER_LANGUAGE C)
diff --git a/Tests/RunCMake/add_test/TestLauncherProperty.cmake b/Tests/RunCMake/add_test/TestLauncherProperty.cmake
new file mode 100644
index 0000000..e86f42b
--- /dev/null
+++ b/Tests/RunCMake/add_test/TestLauncherProperty.cmake
@@ -0,0 +1,41 @@
+
+# This tests setting the TEST_LAUNCHER target property from the
+# CMAKE_TEST_LAUNCHER variable.
+
+# -DCMAKE_TEST_LAUNCHER=/path/to/pseudo_test_launcher is passed to this
+# test
+
+project(test_launcher LANGUAGES C)
+
+add_executable(target_with_test_launcher simple_src_exiterror.cxx)
+set_target_properties(target_with_test_launcher PROPERTIES LINKER_LANGUAGE C)
+get_property(launcher TARGET target_with_test_launcher
+ PROPERTY TEST_LAUNCHER)
+if(NOT "${launcher}" MATCHES "pseudo_test_launcher")
+ message(SEND_ERROR "Default TEST_LAUNCHER property not set")
+endif()
+
+set_property(TARGET target_with_test_launcher
+ PROPERTY TEST_LAUNCHER "another_test_launcher")
+get_property(launcher TARGET target_with_test_launcher
+ PROPERTY TEST_LAUNCHER)
+if(NOT "${launcher}" MATCHES "another_test_launcher")
+ message(SEND_ERROR
+ "set_property/get_property TEST_LAUNCHER is not consistent")
+endif()
+
+unset(CMAKE_TEST_LAUNCHER CACHE)
+add_executable(target_without_test_launcher simple_src_exiterror.cxx)
+set_target_properties(target_without_test_launcher PROPERTIES LINKER_LANGUAGE C)
+get_property(launcher TARGET target_without_test_launcher
+ PROPERTY TEST_LAUNCHER)
+if(NOT "${launcher}" STREQUAL "")
+ message(SEND_ERROR "Default TEST_LAUNCHER property not set to null")
+endif()
+
+add_executable(target_with_empty_test_launcher simple_src_exiterror.cxx)
+set_target_properties(target_with_empty_test_launcher PROPERTIES LINKER_LANGUAGE C)
+set_property(TARGET target_with_empty_test_launcher PROPERTY TEST_LAUNCHER "")
+
+enable_testing()
+add_test(NAME test_target_with_empty_test_launcher COMMAND target_with_empty_test_launcher)
diff --git a/Tests/RunCMake/add_test/simple_src_exiterror.cxx b/Tests/RunCMake/add_test/simple_src_exiterror.cxx
new file mode 100644
index 0000000..6ce7183
--- /dev/null
+++ b/Tests/RunCMake/add_test/simple_src_exiterror.cxx
@@ -0,0 +1,4 @@
+int main(int, char**)
+{
+ return 13;
+}
diff --git a/Tests/RunCMake/property_init/Executable.cmake b/Tests/RunCMake/property_init/Executable.cmake
index ede0e4b..a5e4fb8 100644
--- a/Tests/RunCMake/property_init/Executable.cmake
+++ b/Tests/RunCMake/property_init/Executable.cmake
@@ -17,6 +17,7 @@ set(properties
# Metadata
"CROSSCOMPILING_EMULATOR" "emu" "<SAME>"
+ "TEST_LAUNCHER" "test" "<SAME>"
)
prepare_target_types(executable