From e4c396f254ac61630278b96a68057f263920a73f Mon Sep 17 00:00:00 2001 From: Orkun Tokdemir Date: Thu, 13 Jul 2023 15:30:09 +0200 Subject: [PATCH] _qt_internal_create_moc_command: Fix genex parse The function was replacing the `>` character in generator expressions coming from `add_compile_definitions`. This was creating generator expression syntax errors. Discard generator expressions from character replacing. Add tests for the three cases. Amends 5bb745f62ba1aa63e4bbd107b279d96bd06dffda Fixes: QTBUG-111717 Fixes: QTBUG-119716 Change-Id: I694d2908738085fdf15112834f20183a9f393422 Reviewed-by: Alexandru Croitor (cherry picked from commit bc0c44d4cd634c574307920968f0ab1bf6cd8305) Reviewed-by: Orkun Tokdemir Reviewed-by: Qt CI Bot Reviewed-by: Alexey Edelev --- src/corelib/Qt6CoreMacros.cmake | 15 +++++++++-- .../doc/snippets/cmake-macros/examples.cmake | 25 +++++++++++++++++-- src/corelib/doc/src/cmake/qt_wrap_cpp.qdoc | 21 +++++++++++++++- .../test_moc_macro_target/CMakeLists.txt | 22 ++++++++++++++++ .../check_moc_parameters.cmake | 15 +++++++++++ 5 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 tests/auto/cmake/test_moc_macro_target/check_moc_parameters.cmake diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake index d9789c2ae00..1d32af86c77 100644 --- a/src/corelib/Qt6CoreMacros.cmake +++ b/src/corelib/Qt6CoreMacros.cmake @@ -101,11 +101,22 @@ function(_qt_internal_create_moc_command infile outfile moc_flags moc_options set(targetincludes "$<$:-I$>") set(targetdefines "$<$:-D$>") - string(REPLACE ">" "$" _moc_escaped_parameters "${_moc_parameters}") - string(REPLACE "," "$" _moc_escaped_parameters "${_moc_escaped_parameters}") + set(_moc_parameters_list_without_genex) + set(_moc_parameters_list_with_genex) + foreach(_moc_parameter ${_moc_parameters}) + if(_moc_parameter MATCHES "\\\$<") + list(APPEND _moc_parameters_list_with_genex ${_moc_parameter}) + else() + list(APPEND _moc_parameters_list_without_genex ${_moc_parameter}) + endif() + endforeach() + string(REPLACE ">" "$" _moc_escaped_parameters "${_moc_parameters_list_without_genex}") + string(REPLACE "," "$" _moc_escaped_parameters "${_moc_escaped_parameters}") + string(REPLACE ";" "$" _moc_escaped_parameters "${_moc_escaped_parameters}") set(concatenated "$<$:${targetincludes};>$<$:${targetdefines};>$<$:${_moc_escaped_parameters};>") + list(APPEND concatenated ${_moc_parameters_list_with_genex}) set(concatenated "$,EXCLUDE,^-[DI]$>") set(concatenated "$") diff --git a/src/corelib/doc/snippets/cmake-macros/examples.cmake b/src/corelib/doc/snippets/cmake-macros/examples.cmake index 3afaec0fdaa..c8d5e710814 100644 --- a/src/corelib/doc/snippets/cmake-macros/examples.cmake +++ b/src/corelib/doc/snippets/cmake-macros/examples.cmake @@ -1,11 +1,32 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause -#! [qt_wrap_cpp] +#! [qt_wrap_cpp_1] set(SOURCES myapp.cpp main.cpp) qt_wrap_cpp(SOURCES myapp.h) qt_add_executable(myapp ${SOURCES}) -#! [qt_wrap_cpp] +#! [qt_wrap_cpp_1] + +#! [qt_wrap_cpp_2] +set(SOURCES myapp.cpp main.cpp) +qt_wrap_cpp(SOURCES myapp.h + TARGET myapp + OPTIONS + "$<$:-DMY_OPTION_FOR_DEBUG>" + "-DDEFINE_CMDLINE_SIGNAL=void cmdlineSignal(const QMap &i)" + "$<$:-DDEFINE_CMDLINE_SIGNAL_IN_GENEX=void cmdlineSignal(const QMap int$ &i)>") +qt_add_executable(myapp ${SOURCES}) +#! [qt_wrap_cpp_2] + +#! [qt_wrap_cpp_3] +set(SOURCES myapp.cpp main.cpp) +qt_wrap_cpp(SOURCES myapp.h + TARGET myapp) +qt_add_executable(myapp ${SOURCES}) +target_compile_definitions(myapp PRIVATE "$<$:MY_OPTION_FOR_DEBUG>" + "DEFINE_CMDLINE_SIGNAL=void cmdlineSignal(const QMap &i)" + "$<$:DEFINE_CMDLINE_SIGNAL_IN_GENEX=void cmdlineSignal(const QMap int$ &i)>") +#! [qt_wrap_cpp_3] #! [qt_add_resources] set(SOURCES main.cpp) diff --git a/src/corelib/doc/src/cmake/qt_wrap_cpp.qdoc b/src/corelib/doc/src/cmake/qt_wrap_cpp.qdoc index 03b7a866a7a..0624651869a 100644 --- a/src/corelib/doc/src/cmake/qt_wrap_cpp.qdoc +++ b/src/corelib/doc/src/cmake/qt_wrap_cpp.qdoc @@ -43,6 +43,14 @@ when scanning the source files with \c{moc}. You can set additional \c{OPTIONS} that should be added to the \c{moc} calls. You can find possible options in the \l{moc}{moc documentation}. +The \c{OPTIONS} can evaluate generator expressions when \c{TARGET} is set. +\note If the \c{OPTIONS} include both generator expressions and special +characters, use variables to implement them. For example, use \c{$}, +\c{$} and \c{$} instead of \c{>}, \c{,} and \c{:}. Otherwise, +the generator expression will not be evaluated correctly. \c {OPTIONS} are +wrapped in generator expressions, so you must escape special characters in +them. + \c{DEPENDS} allows you to add additional dependencies for recreation of the generated files. This is useful when the sources have implicit dependencies, like code for a Qt plugin that includes a \c{.json} file using the @@ -50,5 +58,16 @@ Q_PLUGIN_METADATA() macro. \section1 Examples -\snippet cmake-macros/examples.cmake qt_wrap_cpp +\snippet cmake-macros/examples.cmake qt_wrap_cpp_1 + +In the following example, the generator expressions passed to \c{OPTIONS} +will be evaluated since \c{TARGET} is set. The argument is specified this way to +avoid syntax errors in the generator expressions. + +\snippet cmake-macros/examples.cmake qt_wrap_cpp_2 + +The following example uses \l{https://cmake.org/cmake/help/latest/command/target_compile_definitions.html}{target_compile_definitions} +to set \l{https://cmake.org/cmake/help/latest/prop_tgt/COMPILE_DEFINITIONS.html}{COMPILE_DEFINITIONS} which will be added to +\c{OPTIONS}. +\snippet cmake-macros/examples.cmake qt_wrap_cpp_3 */ diff --git a/tests/auto/cmake/test_moc_macro_target/CMakeLists.txt b/tests/auto/cmake/test_moc_macro_target/CMakeLists.txt index 1af937bc102..9ed88680977 100644 --- a/tests/auto/cmake/test_moc_macro_target/CMakeLists.txt +++ b/tests/auto/cmake/test_moc_macro_target/CMakeLists.txt @@ -24,3 +24,25 @@ qt_wrap_cpp(moc_file mywrapobject.h add_executable(QtWrapMacroTest main_wrap_test.cpp ${moc_file}) target_include_directories(QtWrapMacroTest PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/interface") target_link_libraries(QtWrapMacroTest PRIVATE Qt::Core) + +target_compile_definitions(QtWrapMacroTest PRIVATE "$<$:MY_OPTION>" + "$<$:DEFINE_CMDLINE_SIGNAL=void cmdlineSignal(const QMap int$ &i)>" + "DEFINE_CMDLINE_SIGNAL=void cmdlineSignal(const QMap &i)") + +set(parameters_file_base "${CMAKE_CURRENT_BINARY_DIR}/moc_mywrapobject.cpp_parameters") +# check if generator is multi-config +if(CMAKE_CONFIGURATION_TYPES) + set(parameters_file "${parameters_file_base}_$") +else() + if(NOT CMAKE_BUILD_TYPE STREQUAL "") + set(parameters_file "${parameters_file_base}_${CMAKE_BUILD_TYPE}") + else() + set(parameters_file "${parameters_file_base}") + endif() +endif() + +add_custom_command(TARGET QtWrapMacroTest + POST_BUILD + COMMAND ${CMAKE_COMMAND} "-DPARAMETERS_FILE_PATH=${parameters_file}" -P check_moc_parameters.cmake + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) diff --git a/tests/auto/cmake/test_moc_macro_target/check_moc_parameters.cmake b/tests/auto/cmake/test_moc_macro_target/check_moc_parameters.cmake new file mode 100644 index 00000000000..4ca8fab1193 --- /dev/null +++ b/tests/auto/cmake/test_moc_macro_target/check_moc_parameters.cmake @@ -0,0 +1,15 @@ + +function(check_parameters file_path) + file(READ ${file_path} file_content) + foreach(compile_option IN ITEMS "-DDEFINE_CMDLINE_SIGNAL" "-DMY_OPTION") + string(REGEX MATCHALL "${compile_option}" matches ${file_content}) + list(LENGTH matches matches_length) + if(matches_length GREATER 1) + message(FATAL_ERROR "${compile_option} is defined multiple times in ${file_path}") + elseif(matches_length EQUAL 0) + message(FATAL_ERROR "${compile_option} is not defined in ${file_path}") + endif() + endforeach() +endfunction() + +check_parameters(${PARAMETERS_FILE_PATH})