CMake: Properly handle CONFIG += thread aka Threads::Threads
mkspecs/features/qt.prf adds a dependency on the system threading library if the Qt Core thread feature is enabled. Because qt.prf is loaded by any public or internal Qt project, it's essentially a public dependency for any Qt consumer. To mimic that in CMake, we check if the thread feature is enabled, and and set the Threads::Threads library as a dependency of Qt6::Platform, which is a public target used by all Qt modules and plugins and Qt consumers. We also need to create a Qt6Dependencies.cmake file so we find_package(Threads) every time find_package(Qt6) is called. For the .prl files to be usable, we have to filter out some CMake implementation specific directory separator tokens 'CMAKE_DIRECTORY_ID_SEP' aka '::@', which are added because we call target_link_libraries() with a target created in a different scope (I think). As a result of this change, we shouldn't have to hardcode Threads::Threads in other projects, because it's now a global public dependency. Task-number: QTBUG-85801 Task-number: QTBUG-85877 Change-Id: Ib5d662c43b28e63f7da49d3bd77d0ad751220b31 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
parent
bd2bcd4e1d
commit
92ee9bd6b8
@ -353,6 +353,7 @@ qt_copy_or_install(FILES
|
|||||||
cmake/QtBuildInformation.cmake
|
cmake/QtBuildInformation.cmake
|
||||||
cmake/QtCompilerFlags.cmake
|
cmake/QtCompilerFlags.cmake
|
||||||
cmake/QtCompilerOptimization.cmake
|
cmake/QtCompilerOptimization.cmake
|
||||||
|
cmake/QtConfigDependencies.cmake.in
|
||||||
cmake/QtFeature.cmake
|
cmake/QtFeature.cmake
|
||||||
cmake/QtFinishPrlFile.cmake
|
cmake/QtFinishPrlFile.cmake
|
||||||
cmake/QtFindWrapHelper.cmake
|
cmake/QtFindWrapHelper.cmake
|
||||||
|
@ -3256,7 +3256,12 @@ function(qt_internal_walk_libs target out_var dict_name operation)
|
|||||||
set(lib_target ${lib})
|
set(lib_target ${lib})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(TARGET ${lib_target})
|
# Skip CMAKE_DIRECTORY_ID_SEP. If a target_link_libraries is applied to a target
|
||||||
|
# that was defined in a different scope, CMake appends and prepends a special directory
|
||||||
|
# id separator. Filter those out.
|
||||||
|
if(lib_target MATCHES "^::@")
|
||||||
|
continue()
|
||||||
|
elseif(TARGET ${lib_target})
|
||||||
if ("${lib_target}" MATCHES "^Qt::(.*)")
|
if ("${lib_target}" MATCHES "^Qt::(.*)")
|
||||||
# If both, Qt::Foo and Foo targets exist, prefer the target name without
|
# If both, Qt::Foo and Foo targets exist, prefer the target name without
|
||||||
# namespace. Which one is preferred doesn't really matter. This code exists to
|
# namespace. Which one is preferred doesn't really matter. This code exists to
|
||||||
|
@ -49,6 +49,19 @@ if(APPLE AND (NOT CMAKE_SYSTEM_NAME OR CMAKE_SYSTEM_NAME STREQUAL "Darwin"))
|
|||||||
list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/macos")
|
list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/macos")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Find required dependencies, if any.
|
||||||
|
include(CMakeFindDependencyMacro)
|
||||||
|
set(@INSTALL_CMAKE_NAMESPACE@_DEPENDENCIES_FOUND TRUE)
|
||||||
|
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@Dependencies.cmake")
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@Dependencies.cmake")
|
||||||
|
endif()
|
||||||
|
if(NOT @INSTALL_CMAKE_NAMESPACE@_DEPENDENCIES_FOUND)
|
||||||
|
set(@INSTALL_CMAKE_NAMESPACE@_FOUND False)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Failed to find Qt Platform dependency:
|
||||||
|
${@INSTALL_CMAKE_NAMESPACE@_DEPENDENCY_NOT_FOUND_MESSAGE}")
|
||||||
|
endif()
|
||||||
|
|
||||||
foreach(module ${@INSTALL_CMAKE_NAMESPACE@_FIND_COMPONENTS})
|
foreach(module ${@INSTALL_CMAKE_NAMESPACE@_FIND_COMPONENTS})
|
||||||
find_package(@INSTALL_CMAKE_NAMESPACE@${module}
|
find_package(@INSTALL_CMAKE_NAMESPACE@${module}
|
||||||
${_@INSTALL_CMAKE_NAMESPACE@_FIND_PARTS_QUIET}
|
${_@INSTALL_CMAKE_NAMESPACE@_FIND_PARTS_QUIET}
|
||||||
|
35
cmake/QtConfigDependencies.cmake.in
Normal file
35
cmake/QtConfigDependencies.cmake.in
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# note: _third_party_deps example: "ICU\\;1.0\\;i18n uc data;ZLIB\\;\\;"
|
||||||
|
set(_third_party_deps "@third_party_deps@")
|
||||||
|
|
||||||
|
@third_party_extra@
|
||||||
|
|
||||||
|
foreach(_target_dep ${_third_party_deps})
|
||||||
|
list(GET _target_dep 0 pkg)
|
||||||
|
list(GET _target_dep 1 version)
|
||||||
|
list(GET _target_dep 2 components)
|
||||||
|
set(find_package_args "${pkg}")
|
||||||
|
if(version)
|
||||||
|
list(APPEND find_package_args "${version}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(components)
|
||||||
|
string(REPLACE " " ";" components "${components}")
|
||||||
|
find_dependency(${find_package_args} COMPONENTS ${components})
|
||||||
|
else()
|
||||||
|
find_dependency(${find_package_args})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT ${pkg}_FOUND)
|
||||||
|
set(@INSTALL_CMAKE_NAMESPACE@_DEPENDENCIES_FOUND FALSE)
|
||||||
|
set(__@INSTALL_CMAKE_NAMESPACE@_message "\nPackage: ${pkg}")
|
||||||
|
if(version)
|
||||||
|
string(APPEND __@INSTALL_CMAKE_NAMESPACE@_message "\nVersion: ${version}")
|
||||||
|
endif()
|
||||||
|
if(components)
|
||||||
|
string(APPEND __@INSTALL_CMAKE_NAMESPACE@_message "\nComponents: ${components}")
|
||||||
|
endif()
|
||||||
|
set(@INSTALL_CMAKE_NAMESPACE@_DEPENDENCY_NOT_FOUND_MESSAGE
|
||||||
|
"${__@INSTALL_CMAKE_NAMESPACE@_message}")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
@ -262,10 +262,57 @@ function(qt_internal_create_plugin_depends_file target)
|
|||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
function(qt_internal_create_qt6_dependencies_file)
|
||||||
|
# This is used for substitution in the configured file.
|
||||||
|
set(target "${INSTALL_CMAKE_NAMESPACE}")
|
||||||
|
|
||||||
|
# This is the actual target we're querying.
|
||||||
|
set(actual_target Platform)
|
||||||
|
get_target_property(public_depends "${actual_target}" INTERFACE_LINK_LIBRARIES)
|
||||||
|
|
||||||
|
# We need to collect third party deps that are set on the public Platform target,
|
||||||
|
# like Threads::Threads.
|
||||||
|
# This mimics find_package part of the CONFIG += thread assignment in mkspecs/features/qt.prf.
|
||||||
|
qt_collect_third_party_deps(${actual_target})
|
||||||
|
|
||||||
|
# For Threads we also need to write an extra variable assignment.
|
||||||
|
set(third_party_extra "")
|
||||||
|
if(third_party_deps MATCHES "Threads")
|
||||||
|
string(APPEND third_party_extra "if(NOT QT_NO_THREADS_PREFER_PTHREAD_FLAG)
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||||
|
endif()")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(third_party_deps)
|
||||||
|
# Setup build and install paths.
|
||||||
|
set(path_suffix "${INSTALL_CMAKE_NAMESPACE}")
|
||||||
|
|
||||||
|
qt_path_join(config_build_dir ${QT_CONFIG_BUILD_DIR} ${path_suffix})
|
||||||
|
qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${path_suffix})
|
||||||
|
|
||||||
|
# Configure and install QtDependencies file.
|
||||||
|
configure_file(
|
||||||
|
"${QT_CMAKE_DIR}/QtConfigDependencies.cmake.in"
|
||||||
|
"${config_build_dir}/${target}Dependencies.cmake"
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
|
||||||
|
qt_install(FILES
|
||||||
|
"${config_build_dir}/${target}Dependencies.cmake"
|
||||||
|
DESTINATION "${config_install_dir}"
|
||||||
|
COMPONENT Devel
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
# Create Depends.cmake & Depends.h files for all modules and plug-ins.
|
# Create Depends.cmake & Depends.h files for all modules and plug-ins.
|
||||||
function(qt_internal_create_depends_files)
|
function(qt_internal_create_depends_files)
|
||||||
qt_internal_get_qt_repo_known_modules(repo_known_modules)
|
qt_internal_get_qt_repo_known_modules(repo_known_modules)
|
||||||
|
|
||||||
|
if(PROJECT_NAME STREQUAL "QtBase")
|
||||||
|
qt_internal_create_qt6_dependencies_file()
|
||||||
|
endif()
|
||||||
|
|
||||||
foreach (target ${repo_known_modules})
|
foreach (target ${repo_known_modules})
|
||||||
qt_internal_create_module_depends_file(${target})
|
qt_internal_create_module_depends_file(${target})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
@ -249,7 +249,6 @@ qt_add_module(Core
|
|||||||
../3rdparty/tinycbor/src
|
../3rdparty/tinycbor/src
|
||||||
LIBRARIES
|
LIBRARIES
|
||||||
Qt::GlobalConfigPrivate # special case
|
Qt::GlobalConfigPrivate # special case
|
||||||
Threads::Threads # special case
|
|
||||||
PRECOMPILED_HEADER
|
PRECOMPILED_HEADER
|
||||||
"global/qt_pch.h"
|
"global/qt_pch.h"
|
||||||
NO_PCH_SOURCES
|
NO_PCH_SOURCES
|
||||||
@ -276,6 +275,13 @@ endif()
|
|||||||
|
|
||||||
qt_generate_qconfig_cpp()
|
qt_generate_qconfig_cpp()
|
||||||
|
|
||||||
|
# Handle qtConfig(thread): CONFIG += thread like in qt.prf.
|
||||||
|
# Aka if the feature is enabled, publically link against the threading library.
|
||||||
|
# This also ensures the link flag is in the .prl file.
|
||||||
|
if(QT_FEATURE_thread)
|
||||||
|
target_link_libraries(Platform INTERFACE Threads::Threads)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Handle QObject: Automoc does not work for this as it would
|
# Handle QObject: Automoc does not work for this as it would
|
||||||
# require to spill internals into users:
|
# require to spill internals into users:
|
||||||
qt_add_module(Core_qobject STATIC
|
qt_add_module(Core_qobject STATIC
|
||||||
|
@ -33,7 +33,6 @@ qt_extend_target(QSQLiteDriverPlugin CONDITION QT_FEATURE_system_sqlite
|
|||||||
|
|
||||||
# special case begin
|
# special case begin
|
||||||
if (NOT QT_FEATURE_system_sqlite)
|
if (NOT QT_FEATURE_system_sqlite)
|
||||||
qt_find_package(Threads REQUIRED PROVIDED_TARGETS Threads::Threads)
|
|
||||||
# On newer compilers compiling sqlite.c produces warnings
|
# On newer compilers compiling sqlite.c produces warnings
|
||||||
qt_disable_warnings(QSQLiteDriverPlugin)
|
qt_disable_warnings(QSQLiteDriverPlugin)
|
||||||
endif()
|
endif()
|
||||||
@ -52,8 +51,6 @@ qt_extend_target(QSQLiteDriverPlugin CONDITION NOT QT_FEATURE_system_sqlite
|
|||||||
SQLITE_OMIT_COMPLETE
|
SQLITE_OMIT_COMPLETE
|
||||||
INCLUDE_DIRECTORIES
|
INCLUDE_DIRECTORIES
|
||||||
../../../3rdparty/sqlite
|
../../../3rdparty/sqlite
|
||||||
PUBLIC_LIBRARIES # special case
|
|
||||||
Threads::Threads # special case
|
|
||||||
)
|
)
|
||||||
|
|
||||||
qt_extend_target(QSQLiteDriverPlugin CONDITION CMAKE_BUILD_TYPE STREQUAL Release AND NOT QT_FEATURE_system_sqlite
|
qt_extend_target(QSQLiteDriverPlugin CONDITION CMAKE_BUILD_TYPE STREQUAL Release AND NOT QT_FEATURE_system_sqlite
|
||||||
|
@ -62,7 +62,6 @@ qt_add_module(Test
|
|||||||
QT_BUILD_TESTLIB_LIB # special case
|
QT_BUILD_TESTLIB_LIB # special case
|
||||||
LIBRARIES
|
LIBRARIES
|
||||||
Qt::CorePrivate
|
Qt::CorePrivate
|
||||||
Threads::Threads # special case
|
|
||||||
PUBLIC_LIBRARIES
|
PUBLIC_LIBRARIES
|
||||||
Qt::Core
|
Qt::Core
|
||||||
PRIVATE_MODULE_INTERFACE
|
PRIVATE_MODULE_INTERFACE
|
||||||
|
@ -6,7 +6,6 @@ if(QT_BUILD_STANDALONE_TESTS)
|
|||||||
# special case begin
|
# special case begin
|
||||||
qt_find_package(WrapDBus1 PROVIDED_TARGETS dbus-1)
|
qt_find_package(WrapDBus1 PROVIDED_TARGETS dbus-1)
|
||||||
qt_find_package(ICU COMPONENTS i18n uc data PROVIDED_TARGETS ICU::i18n ICU::uc ICU::data)
|
qt_find_package(ICU COMPONENTS i18n uc data PROVIDED_TARGETS ICU::i18n ICU::uc ICU::data)
|
||||||
qt_find_package(Threads PROVIDED_TARGETS Threads::Threads)
|
|
||||||
qt_find_package(WrapOpenSSL PROVIDED_TARGETS WrapOpenSSL::WrapOpenSSL)
|
qt_find_package(WrapOpenSSL PROVIDED_TARGETS WrapOpenSSL::WrapOpenSSL)
|
||||||
qt_find_package(WrapOpenSSLHeaders PROVIDED_TARGETS WrapOpenSSLHeaders::WrapOpenSSLHeaders)
|
qt_find_package(WrapOpenSSLHeaders PROVIDED_TARGETS WrapOpenSSLHeaders::WrapOpenSSLHeaders)
|
||||||
# special case end
|
# special case end
|
||||||
|
@ -16,7 +16,6 @@ qt_add_test(tst_qmetatype
|
|||||||
../../../other/qvariant_common
|
../../../other/qvariant_common
|
||||||
PUBLIC_LIBRARIES
|
PUBLIC_LIBRARIES
|
||||||
Qt::CorePrivate
|
Qt::CorePrivate
|
||||||
Threads::Threads # special case
|
|
||||||
TESTDATA ${test_data}
|
TESTDATA ${test_data}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -9,6 +9,4 @@ qt_add_test(tst_qpromise
|
|||||||
tst_qpromise.cpp
|
tst_qpromise.cpp
|
||||||
PUBLIC_LIBRARIES
|
PUBLIC_LIBRARIES
|
||||||
Qt::CorePrivate
|
Qt::CorePrivate
|
||||||
LIBRARIES # special case
|
|
||||||
Threads::Threads # solves issue with libpthread linkage # special case
|
|
||||||
)
|
)
|
||||||
|
@ -10,8 +10,6 @@ qt_add_test(tst_qthread
|
|||||||
tst_qthread.cpp
|
tst_qthread.cpp
|
||||||
INCLUDE_DIRECTORIES
|
INCLUDE_DIRECTORIES
|
||||||
../../../../shared
|
../../../../shared
|
||||||
LIBRARIES # special case
|
|
||||||
Threads::Threads # special case
|
|
||||||
)
|
)
|
||||||
|
|
||||||
## Scopes:
|
## Scopes:
|
||||||
|
@ -8,9 +8,6 @@
|
|||||||
add_qt_test(tst_qthreadstorage
|
add_qt_test(tst_qthreadstorage
|
||||||
SOURCES
|
SOURCES
|
||||||
tst_qthreadstorage.cpp
|
tst_qthreadstorage.cpp
|
||||||
LIBRARIES # special case
|
|
||||||
Threads::Threads # special case
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
## Scopes:
|
## Scopes:
|
||||||
|
@ -28,7 +28,6 @@ qt_add_test(tst_qguiapplication
|
|||||||
PUBLIC_LIBRARIES
|
PUBLIC_LIBRARIES
|
||||||
Qt::CorePrivate
|
Qt::CorePrivate
|
||||||
Qt::GuiPrivate
|
Qt::GuiPrivate
|
||||||
Threads::Threads # special case
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Resources:
|
# Resources:
|
||||||
|
@ -10,5 +10,4 @@ qt_add_test(tst_qguitimer
|
|||||||
PUBLIC_LIBRARIES
|
PUBLIC_LIBRARIES
|
||||||
Qt::CorePrivate
|
Qt::CorePrivate
|
||||||
Qt::Gui
|
Qt::Gui
|
||||||
Threads::Threads # special case
|
|
||||||
)
|
)
|
||||||
|
@ -21,12 +21,6 @@ qt_extend_target(tst_qtcpsocket CONDITION WIN32
|
|||||||
ws2_32
|
ws2_32
|
||||||
)
|
)
|
||||||
|
|
||||||
# special case begin
|
|
||||||
set(THREADS_PREFER_PTHREAD_FLAG 1)
|
|
||||||
find_package(Threads)
|
|
||||||
target_link_libraries(tst_qtcpsocket PRIVATE Threads::Threads)
|
|
||||||
# special case end
|
|
||||||
|
|
||||||
#### Keys ignored in scope 4:.:.:test.pro:(CMAKE_BUILD_TYPE STREQUAL Debug):
|
#### Keys ignored in scope 4:.:.:test.pro:(CMAKE_BUILD_TYPE STREQUAL Debug):
|
||||||
# DESTDIR = "../debug"
|
# DESTDIR = "../debug"
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ qt_add_benchmark(qtimer_vs_qmetaobject
|
|||||||
.
|
.
|
||||||
PUBLIC_LIBRARIES
|
PUBLIC_LIBRARIES
|
||||||
Qt::Test
|
Qt::Test
|
||||||
Threads::Threads # special case
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#### Keys ignored in scope 1:.:.:qtimer_vs_qmetaobject.pro:<TRUE>:
|
#### Keys ignored in scope 1:.:.:qtimer_vs_qmetaobject.pro:<TRUE>:
|
||||||
|
Loading…
Reference in New Issue
Block a user