From bf6b4167bcaa55abf66f945febea8bcba97cfb98 Mon Sep 17 00:00:00 2001 From: Alexey Edelev Date: Wed, 31 Jan 2024 11:07:10 +0100 Subject: [PATCH] Introduce QTP0003 which controls the BUILD_SHARED_LIBS impact on user projects Since 6.7 we consider the BUILD_SHARED_LIBS when creating libraries using Qt CMake API. This change may affect the user projects that rely on the old strategy of selecting the default library type. To preserve the old behavior this change introduces the QTP0003 policy that allows user to control whether the BUILD_SHARED_LIBS should or shouldn't be considered in library creation process. The policy doesn't affect Qt repos, we assume that we want the NEW behavior by default. Fixes: QTBUG-121707 Change-Id: I4bcfbd8966839731624e3f7ef9e0d6bb2782ac50 Reviewed-by: Qt CI Bot Reviewed-by: Alexandru Croitor Reviewed-by: Leena Miettinen (cherry picked from commit 31b75303d7f9126dcc9bb0e94f0ea4ef1b9c0a71) Reviewed-by: Qt Cherry-pick Bot --- .../externalsites/external-resources.qdoc | 5 ++ src/corelib/CMakeLists.txt | 1 + src/corelib/Qt6CoreMacros.cmake | 27 +++++++- src/corelib/doc/src/cmake/policy/qtp0003.qdoc | 46 +++++++++++++ src/corelib/doc/src/cmake/qt_add_library.qdoc | 9 +-- tests/auto/cmake/CMakeLists.txt | 1 + tests/auto/cmake/test_QTP0003/CMakeLists.txt | 66 +++++++++++++++++++ tests/auto/cmake/test_QTP0003/source.cpp | 4 ++ 8 files changed, 152 insertions(+), 7 deletions(-) create mode 100644 src/corelib/doc/src/cmake/policy/qtp0003.qdoc create mode 100644 tests/auto/cmake/test_QTP0003/CMakeLists.txt create mode 100644 tests/auto/cmake/test_QTP0003/source.cpp diff --git a/doc/global/externalsites/external-resources.qdoc b/doc/global/externalsites/external-resources.qdoc index bd1292f4c8e..272c73b3b01 100644 --- a/doc/global/externalsites/external-resources.qdoc +++ b/doc/global/externalsites/external-resources.qdoc @@ -116,6 +116,11 @@ \title CMake target_link_libraries Documentation */ +/*! + \externalpage https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html + \title CMake BUILD_SHARED_LIBS Documentation +*/ + /*! \externalpage https://conan.io/ \title Conan diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index fb9ff76b315..eba30cbd628 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -357,6 +357,7 @@ qt_internal_add_module(Core ${corelib_extra_cmake_files} POLICIES QTP0002 + QTP0003 ) _qt_internal_setup_deploy_support() diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake index 868461dacab..f46d703f2f0 100644 --- a/src/corelib/Qt6CoreMacros.cmake +++ b/src/corelib/Qt6CoreMacros.cmake @@ -2612,10 +2612,31 @@ function(_qt_internal_add_library target) # This in contrast to CMake which defaults to STATIC. if(NOT arg_STATIC AND NOT arg_SHARED AND NOT arg_MODULE AND NOT arg_INTERFACE AND NOT arg_OBJECT) - if(BUILD_SHARED_LIBS OR (NOT DEFINED BUILD_SHARED_LIBS AND QT6_IS_SHARED_LIBS_BUILD)) - set(type_to_create SHARED) + if(DEFINED BUILD_SHARED_LIBS AND NOT QT_BUILDING_QT AND NOT QT_BUILD_STANDALONE_TESTS) + __qt_internal_setup_policy(QTP0003 "6.7.0" + "BUILD_SHARED_LIBS is set to ${BUILD_SHARED_LIBS} but it has no effect on\ + default library type created by Qt CMake API commands. The default library type\ + is set to the Qt build type.\ + This behavior can be changed by setting QTP0003 to NEW.\ + Check https://doc.qt.io/qt-6/qt-cmake-policy-qtp0003.html for policy details." + ) + qt6_policy(GET QTP0003 build_shared_libs_policy) else() - set(type_to_create STATIC) + set(build_shared_libs_policy "") + endif() + + if(build_shared_libs_policy STREQUAL "NEW" OR QT_BUILDING_QT OR QT_BUILD_STANDALONE_TESTS) + if(BUILD_SHARED_LIBS OR (NOT DEFINED BUILD_SHARED_LIBS AND QT6_IS_SHARED_LIBS_BUILD)) + set(type_to_create SHARED) + else() + set(type_to_create STATIC) + endif() + else() + if(QT6_IS_SHARED_LIBS_BUILD) + set(type_to_create SHARED) + else() + set(type_to_create STATIC) + endif() endif() endif() diff --git a/src/corelib/doc/src/cmake/policy/qtp0003.qdoc b/src/corelib/doc/src/cmake/policy/qtp0003.qdoc new file mode 100644 index 00000000000..70aef6466c9 --- /dev/null +++ b/src/corelib/doc/src/cmake/policy/qtp0003.qdoc @@ -0,0 +1,46 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\page qt-cmake-policy-qtp0003.html +\ingroup qt-cmake-policies +\since 6.7 +\title QTP0003 +\keyword qt_cmake_policy_qtp0003 + +\summary {Consider the BUILD_SHARED_LIBS value when creating Qt libraries.} + +This policy was introduced in Qt 6.7. The policy affects the default type of the +libraries created using \l {Qt CMake API}{CMake Commands in Qt6 Core}, like +\l {qt_add_library}, \l{qt_add_plugin}, \l{qt_add_qml_module}. + +If the policy is set to \c OLD, the default library type that is selected is +aligned with the Qt build type, either \c shared or \c static. + +If the policy is set to \c NEW, the library type is selected according to the +\l {BUILD_SHARED_LIBS}{CMake BUILD_SHARED_LIBS Documentation} value if it's set. +If \c BUILD_SHARED_LIBS is not set, the default library type falls back to the +Qt build type. + +For example, the following code will use the Qt build type as the default +library type for the \c MyLib target, despite the fact \c BUILD_SHARED_LIBS is +set to \c ON: +\badcode +set(BUILD_SHARED_LIBS ON) +... +qt6_add_library(MyLib sourcefile.h sourcefile.cpp) +\endcode + +If you set the QTP0003 to \c NEW before the \l {qt6_add_library}{qt_add_library} +call, \c BUILD_SHARED_LIBS will affect the library default type and \c MyLib +will be the shared library. +\badcode +set(BUILD_SHARED_LIBS ON) +... +qt_policy(SET QTP0003 NEW) +qt6_add_library(MyLib sourcefile.h sourcefile.cpp) +\endcode + +\sa qt_policy, {Qt CMake policies}, qt_add_library + +*/ diff --git a/src/corelib/doc/src/cmake/qt_add_library.qdoc b/src/corelib/doc/src/cmake/qt_add_library.qdoc index ed6e770516c..851a2d6210b 100644 --- a/src/corelib/doc/src/cmake/qt_add_library.qdoc +++ b/src/corelib/doc/src/cmake/qt_add_library.qdoc @@ -45,9 +45,10 @@ library type created depends on how Qt was built. If Qt was built statically, a static library will be created. Otherwise, a shared library will be created. Note that this is different to how CMake's \c{add_library()} command works, where the \c BUILD_SHARED_LIBS variable controls the type of -library created. The \c{qt_add_library()} command considers -\c BUILD_SHARED_LIBS when deciding the library type only if the variable is set -explicitly. +library created. +Since 6.7, the \c{qt_add_library()} command considers \c BUILD_SHARED_LIBS +when deciding the library type only if the variable is set explicitly and +\l {QTP0003} is set to \c NEW. Any \c{sources} provided will be passed through to the internal call to \c{add_library()}. @@ -74,6 +75,6 @@ time. In general, \c MANUAL_FINALIZATION should not be needed unless the project has to support CMake 3.18 or earlier. \sa {qt6_finalize_target}{qt_finalize_target()}, - {qt6_add_executable}{qt_add_executable()} + {qt6_add_executable}{qt_add_executable()}, QTP0003 */ diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index 3fe358cd0b9..90f52620ad0 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -391,3 +391,4 @@ else() endif() _qt_internal_test_expect_pass(test_config_expressions) +_qt_internal_test_expect_pass(test_QTP0003) diff --git a/tests/auto/cmake/test_QTP0003/CMakeLists.txt b/tests/auto/cmake/test_QTP0003/CMakeLists.txt new file mode 100644 index 00000000000..8dda76fdb04 --- /dev/null +++ b/tests/auto/cmake/test_QTP0003/CMakeLists.txt @@ -0,0 +1,66 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) + +project(test_QTP0003) + +find_package(Qt6 COMPONENTS Core REQUIRED) + +if(QT6_IS_SHARED_LIBS_BUILD) + set(qt_build_type "SHARED_LIBRARY") +else() + set(qt_build_type "STATIC_LIBRARY") +endif() + +set(BUILD_SHARED_LIBS ON) +qt6_add_library(MyLib source.cpp) +get_target_property(type MyLib TYPE) +if(NOT "${type}" STREQUAL "${qt_build_type}") + message(FATAL_ERROR "The library uses the default type different from Qt build type when" + "QTP0003 is not set") +endif() + +set(BUILD_SHARED_LIBS OFF) +qt6_add_library(MyLib2 source.cpp) +get_target_property(type MyLib2 TYPE) +if(NOT "${type}" STREQUAL "${qt_build_type}") + message(FATAL_ERROR "The library uses the default type different from Qt build type when" + "QTP0003 is not set") +endif() + +set(BUILD_SHARED_LIBS ON) +qt_policy(SET QTP0003 OLD) +qt6_add_library(MyLib3 source.cpp) +get_target_property(type MyLib3 TYPE) +if(NOT "${type}" STREQUAL "${qt_build_type}") + message(FATAL_ERROR "The library uses the default type different from Qt build type when" + "QTP0003 is set to OLD") +endif() + +set(BUILD_SHARED_LIBS OFF) +qt_policy(SET QTP0003 OLD) +qt6_add_library(MyLib4 source.cpp) +get_target_property(type MyLib4 TYPE) +if(NOT "${type}" STREQUAL "${qt_build_type}") + message(FATAL_ERROR "The library uses the default type different from Qt build type when" + "QTP0003 is set to OLD") +endif() + +set(BUILD_SHARED_LIBS ON) +qt_policy(SET QTP0003 NEW) +qt6_add_library(MyLib5 source.cpp) +get_target_property(type MyLib5 TYPE) +if(NOT "${type}" STREQUAL "SHARED_LIBRARY") + message(FATAL_ERROR "The library doesn't consider the BUILD_SHARED_LIBS when" + "QTP0003 is set to NEW") +endif() + +set(BUILD_SHARED_LIBS OFF) +qt_policy(SET QTP0003 NEW) +qt6_add_library(MyLib6 source.cpp) +get_target_property(type MyLib6 TYPE) +if(NOT "${type}" STREQUAL "STATIC_LIBRARY") + message(FATAL_ERROR "The library doesn't consider the BUILD_SHARED_LIBS when" + "QTP0003 is set to NEW") +endif() diff --git a/tests/auto/cmake/test_QTP0003/source.cpp b/tests/auto/cmake/test_QTP0003/source.cpp new file mode 100644 index 00000000000..0df705acd8e --- /dev/null +++ b/tests/auto/cmake/test_QTP0003/source.cpp @@ -0,0 +1,4 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +class Noop {};