CMake: Work around upstream AUTOGEN issue with discarded dependencies
Upstream CMake has a nasty bug where AUTOGEN dependencies are discarded if a library is added as a dependency more than once (or rather the number of times it is added is not equal to the number of configured build configs). This can result in racy build failures, where a <module>_autogen target is supposed to depend on some <other_module>_sync_headers target, but doesn't, and thus moc generates empty metatypes files because it can't find a synced header. To avoid the AUTOGEN dependencies from being discarded, manually add all dependencies passed to qt_internal_extend_target to the AUTOGEN_TARGET_DEPENDS property. The issue is fixed in CMake 4.0, so the workaround is gated on the cmake version used. Add a flag called QT_NO_AUTOGEN_DISCARDED_DEPENDENCIES_WORKAROUND to disable the workaround, in case the fix gets reverted upstream. Pick-to: 6.8 6.5 Fixes: QTBUG-133725 Change-Id: I857d7e774fc9f9f5203a58311daea5e7177e0d67 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> (cherry picked from commit fcb20586316aff2ccc39e2ae840b79f8b0e904a7) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
ac0e10db65
commit
71130a16f8
@ -214,3 +214,53 @@ function(qt_make_output_file infile prefix suffix source_dir binary_dir result)
|
||||
file(MAKE_DIRECTORY "${outpath}")
|
||||
set("${result}" "${outpath}/${prefix}${outfilename}${suffix}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Work around AUTOGEN issue when a library is added as a dependency more than once, and the autogen
|
||||
# library dependency results in being discarded. To mitigate that, add all autogen dependencies
|
||||
# manually, based on the passed in dependencies.
|
||||
# CMake 4.0+ has a fix, so we don't need the extra logic.
|
||||
# See https://gitlab.kitware.com/cmake/cmake/-/issues/26700
|
||||
function(qt_internal_work_around_autogen_discarded_dependencies target)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.0
|
||||
OR QT_NO_AUTOGEN_DISCARDED_DEPENDENCIES_WORKAROUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(libraries ${ARGN})
|
||||
set(final_libraries "")
|
||||
|
||||
foreach(lib IN LISTS libraries)
|
||||
# Skip non-target dependencies.
|
||||
if(NOT TARGET "${lib}")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# Resolve alias targets, because AUTOGEN_TARGET_DEPENDS doesn't seem to handle them.
|
||||
get_target_property(aliased_target "${lib}" ALIASED_TARGET)
|
||||
if(aliased_target)
|
||||
set(lib "${aliased_target}")
|
||||
endif()
|
||||
|
||||
# Skip imported targets, they don't have sync_headers targets.
|
||||
get_target_property(imported "${lib}" IMPORTED)
|
||||
if(imported)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# Resolve Qt private modules to their public counterparts.
|
||||
get_target_property(is_private_module "${lib}" _qt_is_private_module)
|
||||
get_target_property(public_module_target "${lib}" _qt_public_module_target_name)
|
||||
|
||||
if(is_private_module AND public_module_target)
|
||||
set(lib "${public_module_target}")
|
||||
endif()
|
||||
|
||||
# Another TARGET check, just in case.
|
||||
if(TARGET "${lib}")
|
||||
list(APPEND final_libraries "${lib}")
|
||||
endif()
|
||||
endforeach()
|
||||
if(final_libraries)
|
||||
set_property(TARGET ${target} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS "${final_libraries}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
@ -232,6 +232,9 @@ function(qt_internal_extend_target target)
|
||||
)
|
||||
endif()
|
||||
|
||||
set(all_libraries ${arg_LIBRARIES} ${arg_PUBLIC_LIBRARIES})
|
||||
qt_internal_work_around_autogen_discarded_dependencies(${target} ${all_libraries})
|
||||
|
||||
if(QT_GENERATE_SBOM)
|
||||
set(sbom_args "")
|
||||
_qt_internal_forward_function_args(
|
||||
|
Loading…
x
Reference in New Issue
Block a user