_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 <alexandru.croitor@qt.io>
(cherry picked from commit bc0c44d4cd634c574307920968f0ab1bf6cd8305)
Reviewed-by: Orkun Tokdemir <orkun.tokdemir@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
Orkun Tokdemir 2023-07-13 15:30:09 +02:00 committed by Alexandru Croitor
parent dc86b61d77
commit e4c396f254
5 changed files with 93 additions and 5 deletions

View File

@ -101,11 +101,22 @@ function(_qt_internal_create_moc_command infile outfile moc_flags moc_options
set(targetincludes "$<$<BOOL:${targetincludes}>:-I$<JOIN:${targetincludes},;-I>>") set(targetincludes "$<$<BOOL:${targetincludes}>:-I$<JOIN:${targetincludes},;-I>>")
set(targetdefines "$<$<BOOL:${targetdefines}>:-D$<JOIN:${targetdefines},;-D>>") set(targetdefines "$<$<BOOL:${targetdefines}>:-D$<JOIN:${targetdefines},;-D>>")
string(REPLACE ">" "$<ANGLE-R>" _moc_escaped_parameters "${_moc_parameters}") set(_moc_parameters_list_without_genex)
string(REPLACE "," "$<COMMA>" _moc_escaped_parameters "${_moc_escaped_parameters}") 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 ">" "$<ANGLE-R>" _moc_escaped_parameters "${_moc_parameters_list_without_genex}")
string(REPLACE "," "$<COMMA>" _moc_escaped_parameters "${_moc_escaped_parameters}")
string(REPLACE ";" "$<SEMICOLON>" _moc_escaped_parameters "${_moc_escaped_parameters}")
set(concatenated "$<$<BOOL:${targetincludes}>:${targetincludes};>$<$<BOOL:${targetdefines}>:${targetdefines};>$<$<BOOL:${_moc_escaped_parameters}>:${_moc_escaped_parameters};>") set(concatenated "$<$<BOOL:${targetincludes}>:${targetincludes};>$<$<BOOL:${targetdefines}>:${targetdefines};>$<$<BOOL:${_moc_escaped_parameters}>:${_moc_escaped_parameters};>")
list(APPEND concatenated ${_moc_parameters_list_with_genex})
set(concatenated "$<FILTER:$<REMOVE_DUPLICATES:${concatenated}>,EXCLUDE,^-[DI]$>") set(concatenated "$<FILTER:$<REMOVE_DUPLICATES:${concatenated}>,EXCLUDE,^-[DI]$>")
set(concatenated "$<JOIN:${concatenated},\n>") set(concatenated "$<JOIN:${concatenated},\n>")

View File

@ -1,11 +1,32 @@
# Copyright (C) 2022 The Qt Company Ltd. # Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause # SPDX-License-Identifier: BSD-3-Clause
#! [qt_wrap_cpp] #! [qt_wrap_cpp_1]
set(SOURCES myapp.cpp main.cpp) set(SOURCES myapp.cpp main.cpp)
qt_wrap_cpp(SOURCES myapp.h) qt_wrap_cpp(SOURCES myapp.h)
qt_add_executable(myapp ${SOURCES}) 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
"$<$<CONFIG:Debug>:-DMY_OPTION_FOR_DEBUG>"
"-DDEFINE_CMDLINE_SIGNAL=void cmdlineSignal(const QMap<int, int> &i)"
"$<$<CONFIG:Debug>:-DDEFINE_CMDLINE_SIGNAL_IN_GENEX=void cmdlineSignal(const QMap<int$<COMMA> int$<ANGLE-R> &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 "$<$<CONFIG:Debug>:MY_OPTION_FOR_DEBUG>"
"DEFINE_CMDLINE_SIGNAL=void cmdlineSignal(const QMap<int, int> &i)"
"$<$<BOOL:TRUE>:DEFINE_CMDLINE_SIGNAL_IN_GENEX=void cmdlineSignal(const QMap<int$<COMMA> int$<ANGLE-R> &i)>")
#! [qt_wrap_cpp_3]
#! [qt_add_resources] #! [qt_add_resources]
set(SOURCES main.cpp) set(SOURCES main.cpp)

View File

@ -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 set additional \c{OPTIONS} that should be added to the \c{moc} calls.
You can find possible options in the \l{moc}{moc documentation}. 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{$<ANGLE-R>},
\c{$<COMMA>} and \c{$<SEMICOLON>} 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 \c{DEPENDS} allows you to add additional dependencies for recreation of the
generated files. This is useful when the sources have implicit dependencies, 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 like code for a Qt plugin that includes a \c{.json} file using the
@ -50,5 +58,16 @@ Q_PLUGIN_METADATA() macro.
\section1 Examples \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
*/ */

View File

@ -24,3 +24,25 @@ qt_wrap_cpp(moc_file mywrapobject.h
add_executable(QtWrapMacroTest main_wrap_test.cpp ${moc_file}) add_executable(QtWrapMacroTest main_wrap_test.cpp ${moc_file})
target_include_directories(QtWrapMacroTest PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/interface") target_include_directories(QtWrapMacroTest PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/interface")
target_link_libraries(QtWrapMacroTest PRIVATE Qt::Core) target_link_libraries(QtWrapMacroTest PRIVATE Qt::Core)
target_compile_definitions(QtWrapMacroTest PRIVATE "$<$<BOOL:TRUE>:MY_OPTION>"
"$<$<BOOL:TRUE>:DEFINE_CMDLINE_SIGNAL=void cmdlineSignal(const QMap<int$<COMMA> int$<ANGLE-R> &i)>"
"DEFINE_CMDLINE_SIGNAL=void cmdlineSignal(const QMap<int, int> &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}_$<CONFIG>")
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}
)

View File

@ -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})