diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2021-09-21 09:07:43 +0200 |
---|---|---|
committer | Brett Stottlemyer <bstottle@ford.com> | 2021-09-22 08:28:11 -0400 |
commit | b927a7c3f1fda7149b855d1c41bf6fb4d64c981e (patch) | |
tree | 5d54aff135458ceda655c0ea616a7443575b7ab8 | |
parent | 02ae142e3cdb37f2ae10016628e9c256ec21e117 (diff) |
CMake: Manually run moc on generated rep_$name_$type headers
User projects might have cmake_minimum_required set to 3.1, which
means that the CMP0071 policy is set to OLD and AUTOMOC is not
used for GENERATED header files.
This leads to compilation / linking errors.
Don't rely on AUTOMOC and instead run moc manually on the generated
header files using qt6_wrap_cpp.
Ensure that all qt6_wrap_cpp calls have a CMake target given so that
they moc call gets the target's include dirs and compile definitions.
Also, for macOS framework prefix builds, we need to be explicit in
passing the location of the RemoteObjects framework.
This avoids 'error: Parse error at "("' messages when running moc.
Ideally this would be fixed in the implementation of qt6_wrap_cpp
somewhat like it was done in
d57ccd923f0df6abf6943c97e8223c9a24f0e4ae but that exact fix can't be
applied to qt6_wrap_cpp because we don't have an explicit list of
dependency include directories at configure time and CMake does not
allow complicated regular expression transformations at generation
time to detect and replace the -I flags with -F flags.
Fixes: QTBUG-95832
Change-Id: If773e61151c87fec6cc878ef5ef777487bf1ec7c
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Brett Stottlemyer <bstottle@ford.com>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit debee63fa7f9a1dc408a82f20f7a36f74c53e301)
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
-rw-r--r-- | src/remoteobjects/Qt6RemoteObjectsMacros.cmake | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/src/remoteobjects/Qt6RemoteObjectsMacros.cmake b/src/remoteobjects/Qt6RemoteObjectsMacros.cmake index 21b764e..3cbeaf6 100644 --- a/src/remoteobjects/Qt6RemoteObjectsMacros.cmake +++ b/src/remoteobjects/Qt6RemoteObjectsMacros.cmake @@ -34,6 +34,31 @@ # # $QT_END_LICENSE$ +# With a macOS framework Qt build, moc needs to be passed -F<framework-path> arguments to resolve +# framework style includes like #include <QtCore/qobject.h> +# Extract the location of the Qt frameworks by querying the imported location of QtRemoteObjects +# framework parent directory. +function(_qt_internal_get_remote_objects_framework_path out_var) + set(value "") + if(APPLE AND QT_FEATURE_framework) + get_target_property(ro_path ${QT_CMAKE_EXPORT_NAMESPACE}::RemoteObjects IMPORTED_LOCATION) + string(REGEX REPLACE "(.*)/Qt[^/]+\\.framework.*" "\\1" ro_fw_path "${ro_path}") + if(ro_fw_path) + set(value "${ro_fw_path}") + endif() + endif() + set(${out_var} "${value}" PARENT_SCOPE) +endfunction() + +function(_qt_internal_get_remote_objects_framework_path_moc_options out_var) + _qt_internal_get_remote_objects_framework_path(ro_fw_path) + if(ro_fw_path) + set(${out_var} "OPTIONS" "-F${ro_fw_path}" PARENT_SCOPE) + else() + set(${out_var} "" PARENT_SCOPE) + endif() +endfunction() + function(_qt_internal_add_repc_files type target) set(options) set(oneValueArgs) @@ -49,19 +74,28 @@ function(_qt_internal_add_repc_files type target) endif() set(repc_incpath) ########### TODO + _qt_internal_get_remote_objects_framework_path_moc_options(extra_moc_options) foreach(it ${ARGS_SOURCES}) get_filename_component(outfilename ${it} NAME_WE) get_filename_component(extension ${it} EXT) if ("${extension}" STREQUAL ".h" OR "${extension}" STREQUAL ".hpp") + # This calls moc on an existing header file to extract metatypes json information + # which is then passed to the tool to generate another header. qt6_wrap_cpp(qtro_moc_files "${it}" - __QT_INTERNAL_OUTPUT_MOC_JSON_FILES json_list) + __QT_INTERNAL_OUTPUT_MOC_JSON_FILES json_list + TARGET "${target}" + ${extra_moc_options}) + + # Pass the generated metatypes .json file to the tool. set(infile ${json_list}) set_source_files_properties(${qtro_moc_files} PROPERTIES HEADER_FILE_ONLY ON) list(APPEND outfiles ${qtro_moc_files}) else() + # Pass the .rep file to the tool. get_filename_component(infile ${it} ABSOLUTE) endif() set(outfile ${CMAKE_CURRENT_BINARY_DIR}/rep_${outfilename}_${type}.h) + add_custom_command( OUTPUT ${outfile} ${QT_TOOL_PATH_SETUP_COMMAND} @@ -73,6 +107,14 @@ function(_qt_internal_add_repc_files type target) VERBATIM ) list(APPEND outfiles ${outfile}) + + # The generated header file needs to be manually moc'ed (without using AUTOMOC) and then + # added as source to compile into the target. + qt6_wrap_cpp(qtro_moc_files "${outfile}" TARGET "${target}" ${extra_moc_options}) + set_source_files_properties("${outfile}" PROPERTIES + GENERATED TRUE + SKIP_AUTOGEN ON) + list(APPEND outfiles ${qtro_moc_files}) endforeach() target_sources(${target} PRIVATE ${outfiles}) endfunction() @@ -98,10 +140,16 @@ endfunction() # Create .rep interface file from QObject header function(qt6_reps_from_headers target) list(POP_FRONT ARGV) + _qt_internal_get_remote_objects_framework_path_moc_options(extra_moc_options) + foreach(it ${ARGV}) get_filename_component(outfilename ${it} NAME_WE) + # This calls moc on an existing header file to extract metatypes json information + # which is then passed to the tool to generate a .rep file. qt6_wrap_cpp(qtro_moc_files "${it}" - __QT_INTERNAL_OUTPUT_MOC_JSON_FILES json_list) + __QT_INTERNAL_OUTPUT_MOC_JSON_FILES json_list + TARGET "${target}" + ${extra_moc_options}) set(infile ${json_list}) set_source_files_properties(${qtro_moc_files} PROPERTIES HEADER_FILE_ONLY ON) list(APPEND outfiles ${qtro_moc_files}) |