diff options
author | Orkun Tokdemir <ilhanorkuntokdemir@gmail.com> | 2023-06-14 11:10:03 (GMT) |
---|---|---|
committer | Orkun Tokdemir <ilhanorkuntokdemir@gmail.com> | 2023-09-13 16:23:56 (GMT) |
commit | fddd0f0443b4ce81d61f15ee1b2f13105967b25a (patch) | |
tree | 46e0ed1f11a9ac721672977758c2a628478cba32 /Tests | |
parent | 10b09647f2699b32c3d243f595437cb1c63049e2 (diff) | |
download | CMake-fddd0f0443b4ce81d61f15ee1b2f13105967b25a.zip CMake-fddd0f0443b4ce81d61f15ee1b2f13105967b25a.tar.gz CMake-fddd0f0443b4ce81d61f15ee1b2f13105967b25a.tar.bz2 |
Autogen: AUTO*_EXECUTABLE: add support for per-config values
* Per-config values were added to `AUTO*_EXECUTABLE`.
* Dependency order was refactored for `cmake_autogen` and `cmake_autorcc` to
avoid unnecessary rebuilds.
* A new parameter was added for `cmake_autogen` and `cmake_autorcc` to specify the config name of the `auto*_executable` to be used.
* The timestamp target was split into three targets for per-config to avoid redundant `mocs_compilation` builds.
* Per-config `DEP_FILE_RULE_NAME` values were added to `AutogenInfo.json` for `CMAKE_CROSS_CONFIG` usage.
* Some functions were refactored to avoid code duplication.
Fixes: #20074
Diffstat (limited to 'Tests')
-rw-r--r-- | Tests/RunCMake/Autogen/AutoMocExecutableConfig.cmake | 24 | ||||
-rw-r--r-- | Tests/RunCMake/Autogen/AutoRccExecutableConfig.cmake | 24 | ||||
-rw-r--r-- | Tests/RunCMake/Autogen/AutoUicExecutableConfig.cmake | 24 | ||||
-rw-r--r-- | Tests/RunCMake/Autogen/RunCMakeTest.cmake | 164 | ||||
-rw-r--r-- | Tests/RunCMake/Autogen/data.qrc | 4 | ||||
-rw-r--r-- | Tests/RunCMake/Autogen/example.cpp | 5 | ||||
-rw-r--r-- | Tests/RunCMake/Autogen/example.h | 12 | ||||
-rw-r--r-- | Tests/RunCMake/Autogen/example_ui.cpp | 5 | ||||
-rw-r--r-- | Tests/RunCMake/Autogen/example_ui.h | 14 | ||||
-rw-r--r-- | Tests/RunCMake/Autogen/exe.cpp | 4 | ||||
-rw-r--r-- | Tests/RunCMake/Autogen/exe_common.h | 48 | ||||
-rw-r--r-- | Tests/RunCMake/Autogen/exe_debug.cpp | 10 | ||||
-rw-r--r-- | Tests/RunCMake/Autogen/exe_release.cpp | 10 | ||||
-rw-r--r-- | Tests/RunCMake/Autogen/exe_relwithdebinfo.cpp | 10 | ||||
-rw-r--r-- | Tests/RunCMake/Autogen/uiA.ui | 24 |
15 files changed, 382 insertions, 0 deletions
diff --git a/Tests/RunCMake/Autogen/AutoMocExecutableConfig.cmake b/Tests/RunCMake/Autogen/AutoMocExecutableConfig.cmake new file mode 100644 index 0000000..fd3614c --- /dev/null +++ b/Tests/RunCMake/Autogen/AutoMocExecutableConfig.cmake @@ -0,0 +1,24 @@ +enable_language(CXX) + +set(CMAKE_CXX_STANDARD 11) +find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui) + +if(NOT TARGET Qt${with_qt_version}::moc) + message(FATAL_ERROR "Qt${with_qt_version}::moc not found") +endif() + +add_library(dummy STATIC example.cpp) +target_link_libraries(dummy Qt${with_qt_version}::Core + Qt${with_qt_version}::Widgets + Qt${with_qt_version}::Gui) + +get_target_property(moc_location Qt${with_qt_version}::moc IMPORTED_LOCATION) +set_target_properties(dummy PROPERTIES AUTOMOC_MOC_OPTIONS "EXE_PATH=${moc_location}") + +add_executable(mymoc $<$<CONFIG:Debug>:exe_debug.cpp> + $<$<CONFIG:Release>:exe_release.cpp> + $<$<CONFIG:RelWithDebInfo>:exe_relwithdebinfo.cpp> +) + +set_target_properties(dummy PROPERTIES AUTOMOC_EXECUTABLE $<TARGET_FILE:mymoc> + AUTOMOC ON) diff --git a/Tests/RunCMake/Autogen/AutoRccExecutableConfig.cmake b/Tests/RunCMake/Autogen/AutoRccExecutableConfig.cmake new file mode 100644 index 0000000..a0e9ce9 --- /dev/null +++ b/Tests/RunCMake/Autogen/AutoRccExecutableConfig.cmake @@ -0,0 +1,24 @@ +enable_language(CXX) + +set(CMAKE_CXX_STANDARD 11) +find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui) + +if(NOT TARGET Qt${with_qt_version}::rcc) + message(FATAL_ERROR "Qt${with_qt_version}::rcc not found") +endif() + +add_library(dummy STATIC example.cpp data.qrc) +target_link_libraries(dummy Qt${with_qt_version}::Core + Qt${with_qt_version}::Widgets + Qt${with_qt_version}::Gui) + +get_target_property(rcc_location Qt${with_qt_version}::rcc IMPORTED_LOCATION) +set_target_properties(dummy PROPERTIES AUTORCC_OPTIONS "EXE_PATH=${rcc_location}") + +add_executable(myrcc $<$<CONFIG:Debug>:exe_debug.cpp> + $<$<CONFIG:Release>:exe_release.cpp> + $<$<CONFIG:RelWithDebInfo>:exe_relwithdebinfo.cpp> +) + +set_target_properties(dummy PROPERTIES AUTORCC_EXECUTABLE $<TARGET_FILE:myrcc> + AUTORCC ON) diff --git a/Tests/RunCMake/Autogen/AutoUicExecutableConfig.cmake b/Tests/RunCMake/Autogen/AutoUicExecutableConfig.cmake new file mode 100644 index 0000000..ce7675e --- /dev/null +++ b/Tests/RunCMake/Autogen/AutoUicExecutableConfig.cmake @@ -0,0 +1,24 @@ +enable_language(CXX) + +set(CMAKE_CXX_STANDARD 11) +find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui) + +if(NOT TARGET Qt${with_qt_version}::uic) + message(FATAL_ERROR "Qt${with_qt_version}::uic not found") +endif() + +add_library(dummy STATIC example_ui.cpp uiA.ui) +target_link_libraries(dummy Qt${with_qt_version}::Core + Qt${with_qt_version}::Widgets + Qt${with_qt_version}::Gui) + +get_target_property(uic_location Qt${with_qt_version}::uic IMPORTED_LOCATION) +set_target_properties(dummy PROPERTIES AUTOUIC_OPTIONS "EXE_PATH=${uic_location}") + +add_executable(myuic $<$<CONFIG:Debug>:exe_debug.cpp> + $<$<CONFIG:Release>:exe_release.cpp> + $<$<CONFIG:RelWithDebInfo>:exe_relwithdebinfo.cpp> +) + +set_target_properties(dummy PROPERTIES AUTOUIC_EXECUTABLE $<TARGET_FILE:myuic> + AUTOUIC ON) diff --git a/Tests/RunCMake/Autogen/RunCMakeTest.cmake b/Tests/RunCMake/Autogen/RunCMakeTest.cmake index 886065a..12a8f8e 100644 --- a/Tests/RunCMake/Autogen/RunCMakeTest.cmake +++ b/Tests/RunCMake/Autogen/RunCMakeTest.cmake @@ -173,4 +173,168 @@ Automatic MOC for target sub_exe_2") endif() endblock() endif() + + function(run_make_program dir) + execute_process( + COMMAND "${RunCMake_MAKE_PROGRAM}" ${ARGN} + WORKING_DIRECTORY "${dir}" + OUTPUT_VARIABLE make_program_stdout + ERROR_VARIABLE make_program_stderr + RESULT_VARIABLE make_program_result + ) + if (NOT DEFINED RunMakeProgram_expected_result) + set(RunMakeProgram_expected_result 0) + endif() + if(NOT "${make_program_result}" MATCHES "${RunMakeProgram_expected_result}") + message(STATUS " +============ beginning of ${RunCMake_MAKE_PROGRAM}'s stdout ============ +${make_program_stdout} +=============== end of ${RunCMake_MAKE_PROGRAM}'s stdout =============== +") + message(STATUS " +============ beginning of ${RunCMake_MAKE_PROGRAM}'s stderr ============ +${make_program_stderr} +=============== end of ${RunCMake_MAKE_PROGRAM}'s stderr =============== +") + message(FATAL_ERROR + "top ${RunCMake_MAKE_PROGRAM} build failed exited with status ${make_program_result}") + endif() + set(make_program_stdout "${make_program_stdout}" PARENT_SCOPE) + endfunction(run_make_program) + + function(count_substring STRING SUBSTRING COUNT_VAR) + string(LENGTH "${STRING}" STRING_LENGTH) + string(LENGTH "${SUBSTRING}" SUBSTRING_LENGTH) + if (SUBSTRING_LENGTH EQUAL 0) + message(FATAL_ERROR "SUBSTRING_LENGTH is 0") + endif() + + if (STRING_LENGTH EQUAL 0) + message(FATAL_ERROR "STRING_LENGTH is 0") + endif() + + if (STRING_LENGTH LESS SUBSTRING_LENGTH) + message(FATAL_ERROR "STRING_LENGTH is less than SUBSTRING_LENGTH") + endif() + + set(COUNT 0) + string(FIND "${STRING}" "${SUBSTRING}" SUBSTRING_START) + while(SUBSTRING_START GREATER_EQUAL 0) + math(EXPR COUNT "${COUNT} + 1") + math(EXPR SUBSTRING_START "${SUBSTRING_START} + ${SUBSTRING_LENGTH}") + string(SUBSTRING "${STRING}" ${SUBSTRING_START} -1 STRING) + string(FIND "${STRING}" "${SUBSTRING}" SUBSTRING_START) + endwhile() + + set(${COUNT_VAR} ${COUNT} PARENT_SCOPE) + endfunction() + + function(expect_only_once make_program_stdout expected_output test_name) + count_substring("${make_program_stdout}" "${expected_output}" count) + if(NOT count EQUAL 1) + message(STATUS "${test_name}-expect_only_once - FAILED") + message(FATAL_ERROR "Expected to find ${expected_output} exactly once in ${make_program_stdout} but found ${count} occurrences of ${expected_output}") + else() + message(STATUS "${test_name}-expect_only_once - PASSED") + endif() + endfunction() + + function(not_expect make_program_stdout unexpected_output test_name) + count_substring("${make_program_stdout}" "${unexpected_output}" count) + if(NOT count EQUAL 0) + message(STATUS "${test_name}-not_expect - FAILED") + message(FATAL_ERROR "Expected to find ${unexpected_output} exactly 0 times in ${make_program_stdout} but found ${count} occurrences of ${unexpected_output}") + else() + message(STATUS "${test_name}-not_expect - PASSED") + endif() + endfunction() + + if (QtCore_VERSION VERSION_GREATER_EQUAL 5.15.0) + foreach(exe IN ITEMS Moc Uic Rcc) + if(RunCMake_GENERATOR MATCHES "Ninja Multi-Config") + block() + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Auto${exe}ExecutableConfig-build) + run_cmake_with_options(Auto${exe}ExecutableConfig ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTOGEN_VERBOSE=ON) + foreach(config IN ITEMS Debug Release RelWithDebInfo) + block() + run_make_program(${RunCMake_TEST_BINARY_DIR} --verbose -f build-${config}.ninja) + + set(expected_output "running_exe_${config}") + expect_only_once("${make_program_stdout}" "${expected_output}" "Auto${exe}ExecutableConfig-${config}-${expected_output}") + + foreach(sub_config IN ITEMS Debug Release RelWithDebInfo) + if(NOT sub_config STREQUAL config) + set(unexpected_output "running_exe_${sub_config}") + not_expect("${make_program_stdout}" "${unexpected_output}" "Auto${exe}ExecutableConfig-${config}-${unexpected_output}") + endif() + endforeach() + + if (exe STREQUAL "Moc" OR exe STREQUAL "Uic") + set(expected_output "cmake_autogen") + else() + set(expected_output "cmake_autorcc") + endif() + expect_only_once("${make_program_stdout}" "${expected_output}" "Auto${exe}ExecutableConfig-${config}-${expected_output}") + endblock() + endforeach() + endblock() + block() + foreach(ninja_config IN ITEMS Debug Release RelWithDebInfo) + foreach(target_config IN ITEMS Debug Release RelWithDebInfo) + block() + set(TEST_SUFFIX "-CrossConfig-${ninja_config}-${target_config}") + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Auto${exe}ExecutableConfig${TEST_SUFFIX}-build) + set(RunCMake_TEST_VARIANT_DESCRIPTION ${TEST_SUFFIX}) + run_cmake_with_options(Auto${exe}ExecutableConfig ${RunCMake_TEST_OPTIONS} -DCMAKE_CROSS_CONFIGS=all -DCMAKE_DEFAULT_BUILD_TYPE=${ninja_config}) + unset(RunCMake_TEST_VARIANT_DESCRIPTION) + + run_make_program(${RunCMake_TEST_BINARY_DIR} --verbose -f build-${ninja_config}.ninja dummy:${target_config}) + + set(expected_output "running_exe_${ninja_config}") + expect_only_once("${make_program_stdout}" "${expected_output}" "Auto${exe}ExecutableConfig${TEST_SUFFIX}-${expected_output}") + + foreach(sub_config IN ITEMS Debug Release RelWithDebInfo) + if(NOT sub_config STREQUAL ninja_config) + set(unexpected_output "running_exe_${sub_config}") + not_expect("${make_program_stdout}" "${unexpected_output}" "Auto${exe}ExecutableConfig${TEST_SUFFIX}-${unexpected_output}") + endif() + endforeach() + + if (exe STREQUAL "Moc" OR exe STREQUAL "Uic") + set(expected_output "cmake_autogen") + else() + set(expected_output "cmake_autorcc") + endif() + expect_only_once("${make_program_stdout}" "${expected_output}" "Auto${exe}ExecutableConfig${TEST_SUFFIX}-${expected_output}") + endblock() + endforeach() + endforeach() + endblock() + block() + foreach(ninja_config IN ITEMS Debug Release RelWithDebInfo) + set(TEST_SUFFIX "-CrossConfig-${ninja_config}-all-all") + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Auto${exe}ExecutableConfig${TEST_SUFFIX}-build) + set(RunCMake_TEST_VARIANT_DESCRIPTION ${TEST_SUFFIX}) + run_cmake_with_options(Auto${exe}ExecutableConfig ${RunCMake_TEST_OPTIONS} -DCMAKE_CROSS_CONFIGS=all) + unset(RunCMake_TEST_VARIANT_DESCRIPTION) + run_make_program(${RunCMake_TEST_BINARY_DIR} --verbose -f build-${ninja_config}.ninja all:all) + endforeach() + endblock() + elseif (RunCMake_GENERATOR MATCHES "Ninja|Make") + block() + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Auto${exe}ExecutableConfig-build) + foreach(config IN ITEMS Debug Release RelWithDebInfo) + block() + set(RunCMake_TEST_VARIANT_DESCRIPTION "-${config}") + run_cmake_with_options(Auto${exe}ExecutableConfig ${RunCMake_TEST_OPTIONS} -DCMAKE_BUILD_TYPE=${config} -DCMAKE_AUTOGEN_VERBOSE=ON) + unset(RunCMake_TEST_VARIANT_DESCRIPTION) + set(RunCMake_TEST_NO_CLEAN 1) + set(RunCMake_TEST_EXPECT_stdout ".*running_exe_${config}*") + run_cmake_command(Auto${exe}ExecutableConfig-${config}-build ${CMAKE_COMMAND} --build .) + endblock() + endforeach() + endblock() + endif() + endforeach() + endif() endif () diff --git a/Tests/RunCMake/Autogen/data.qrc b/Tests/RunCMake/Autogen/data.qrc new file mode 100644 index 0000000..9bd068c --- /dev/null +++ b/Tests/RunCMake/Autogen/data.qrc @@ -0,0 +1,4 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/res/affine"> +</qresource> +</RCC> diff --git a/Tests/RunCMake/Autogen/example.cpp b/Tests/RunCMake/Autogen/example.cpp new file mode 100644 index 0000000..7f1a781 --- /dev/null +++ b/Tests/RunCMake/Autogen/example.cpp @@ -0,0 +1,5 @@ +#include "example.h" + +Example::Example() +{ +} diff --git a/Tests/RunCMake/Autogen/example.h b/Tests/RunCMake/Autogen/example.h new file mode 100644 index 0000000..e8bfa42 --- /dev/null +++ b/Tests/RunCMake/Autogen/example.h @@ -0,0 +1,12 @@ +#ifndef EXAMPLE_H +#define EXAMPLE_H + +#include <QObject> + +class Example : public QObject +{ + Q_OBJECT + Example(); +}; + +#endif diff --git a/Tests/RunCMake/Autogen/example_ui.cpp b/Tests/RunCMake/Autogen/example_ui.cpp new file mode 100644 index 0000000..fb97c32 --- /dev/null +++ b/Tests/RunCMake/Autogen/example_ui.cpp @@ -0,0 +1,5 @@ +#include "example_ui.h" + +Example::Example() +{ +} diff --git a/Tests/RunCMake/Autogen/example_ui.h b/Tests/RunCMake/Autogen/example_ui.h new file mode 100644 index 0000000..d691133 --- /dev/null +++ b/Tests/RunCMake/Autogen/example_ui.h @@ -0,0 +1,14 @@ +#ifndef EXAMPLE_UI_H +#define EXAMPLE_UI_H + +#include <QObject> + +#include "ui_uiA.h" + +class Example : public QObject +{ + Q_OBJECT + Example(); +}; + +#endif diff --git a/Tests/RunCMake/Autogen/exe.cpp b/Tests/RunCMake/Autogen/exe.cpp new file mode 100644 index 0000000..f8b643a --- /dev/null +++ b/Tests/RunCMake/Autogen/exe.cpp @@ -0,0 +1,4 @@ +int main() +{ + return 0; +} diff --git a/Tests/RunCMake/Autogen/exe_common.h b/Tests/RunCMake/Autogen/exe_common.h new file mode 100644 index 0000000..15311c6 --- /dev/null +++ b/Tests/RunCMake/Autogen/exe_common.h @@ -0,0 +1,48 @@ +#ifndef EXE_COMMON_H +#define EXE_COMMON_H + +#include <cstdlib> +#include <fstream> +#include <string> +#include <vector> + +inline int runRealExe(const int argc, char** argv) +{ + std::vector<std::string> args; + std::string realMocPath; + std::string const pathArg = "EXE_PATH="; + std::string cmd; + if (argc > 1) { + for (int i = 1; i < argc; ++i) { + std::string const arg = argv[i]; + if (arg.find(pathArg) != std::string::npos) { + realMocPath = arg.substr(pathArg.length()); + // if EXE_PATH contains spaces, wrap it in quotes + if (realMocPath.find(" ") != std::string::npos) { + realMocPath = "\"" + realMocPath + "\""; + } + } else { + args.push_back(arg); + } + } + } +#ifdef _WIN32 + cmd += "cmd /C \""; +#endif + cmd += realMocPath + " "; + for (auto arg : args) { + // if arg contains spaces, wrap it in quotes + if (arg.find(' ') != std::string::npos) { + cmd += " \"" + arg + "\""; + } else { + cmd += " " + arg; + } + } +#ifdef _WIN32 + cmd += "\""; +#endif + std::cout << "Running real exe:" << cmd << std::endl; + return std::system(cmd.c_str()); +} + +#endif diff --git a/Tests/RunCMake/Autogen/exe_debug.cpp b/Tests/RunCMake/Autogen/exe_debug.cpp new file mode 100644 index 0000000..ae5185b --- /dev/null +++ b/Tests/RunCMake/Autogen/exe_debug.cpp @@ -0,0 +1,10 @@ +#include <fstream> +#include <iostream> + +#include "exe_common.h" + +int main(int argc, char* argv[]) +{ + std::cout << "running_exe_Debug\n"; + return runRealExe(argc, argv); +} diff --git a/Tests/RunCMake/Autogen/exe_release.cpp b/Tests/RunCMake/Autogen/exe_release.cpp new file mode 100644 index 0000000..384c992 --- /dev/null +++ b/Tests/RunCMake/Autogen/exe_release.cpp @@ -0,0 +1,10 @@ +#include <fstream> +#include <iostream> + +#include "exe_common.h" + +int main(int argc, char* argv[]) +{ + std::cout << "running_exe_Release\n"; + return runRealExe(argc, argv); +} diff --git a/Tests/RunCMake/Autogen/exe_relwithdebinfo.cpp b/Tests/RunCMake/Autogen/exe_relwithdebinfo.cpp new file mode 100644 index 0000000..aa6c558 --- /dev/null +++ b/Tests/RunCMake/Autogen/exe_relwithdebinfo.cpp @@ -0,0 +1,10 @@ +#include <fstream> +#include <iostream> + +#include "exe_common.h" + +int main(int argc, char* argv[]) +{ + std::cout << "running_exe_RelWithDebInfo\n"; + return runRealExe(argc, argv); +} diff --git a/Tests/RunCMake/Autogen/uiA.ui b/Tests/RunCMake/Autogen/uiA.ui new file mode 100644 index 0000000..4c5762e --- /dev/null +++ b/Tests/RunCMake/Autogen/uiA.ui @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UiA</class> + <widget class="QWidget" name="UiA"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QTreeView" name="treeView"/> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> |