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 {};