Previously we had four-ish locations where the CMAKE_BUILD_TYPE was
force set.
Twice in QtBuildInternalsExtra.cmake via
qt_internal_force_set_cmake_build_type_conditionally(), depending on
some conditions. This was executed right at
find_package(Qt6 COMPONENTS BuildInternals)
time.
And twice in qt_internal_set_default_build_type() via
qt_build_repo_begin() / qt_prepare_standalone_project() that goes
through QtSetup.cmake. This was executed only if the relevant functions
were called, rather than directly at find_package() time.
The exact logic of which build type ended up being set was very
confusing.
Refactor the code to decide the build type in one single location
when qt_build_repo_begin() / qt_prepare_standalone_project() are
called, rather than directly at find_package() time.
The actual logic when we override the build type depends on many
factors:
- when an explicit CMAKE_BUILD_TYPE is given, honor it, unless it's
a multi-config build
- when it's a multi-config build, don't set any CMAKE_BUILD_TYPE,
use the value of CMAKE_CONFIGURATION_TYPES
- when it's a qtbase build, compute a default unless an explicit value
was given
- the default is Debug if FEATURE_developer_build is ON
- otherwise the default is Release
- when it's a top-level build, only choose a build type for qtbase
- when it's another repo build, use the original build type unless
another was given explicitly (including in a top-level build)
- when it's a standalone tests build
- if qt is multi-config, the tests will be single config, due to
various CI failure reasons, this hasn't changed
- if qt is single config, use the original unless an explicit
value was given
- when it's a single standalone test build, use the original unless
an explicit value was given
To determine when an explicit CMAKE_BUILD_TYPE was given in contrast
to when it was default initialized, we now have one single function
that uses a few heuristics.
The heuristics are needed because we can't reliably determine an
explicitly given 'Debug' build on Windows, because CMake default
initializes to that.
The heuristics include:
- checking whether CMAKE_BUILD_TYPE_INIT is different from
CMAKE_BUILD_TYPE
- checking what the CMAKE_BUILD_TYPE was before the first project()
call when CMake default initializes
- we save the previous value in the qt.toolchain.cmake file
- also in QtAutoDetect during qtbase configuration
- also when building the sqldrivers project
- honoring the value of QT_NO_FORCE_SET_CMAKE_BUILD_TYPE
As a result of the above changes, the build type will be set exactly
zero or one times, for a particular build directory.
Note that the configure script also has some logic on which
CMAKE_BUILD_TYPE / CMAKE_CONFIGURATION_TYPES to pass to CMake
depending on whether -debug / -release / -debug-and-release /
-force-debug-info were passed. But once the values are passed,
CMake will honor them.
Amends 48841c34d2e86a741ec9992b9704c0fa5973503c
Amends 8c912cddebe544010e7da3f87af5b21f3328d7ec
Task-number: QTBUG-114958
Task-number: QTBUG-120436
Change-Id: I30db14d1e8e9ff9bd2d7ea1d2256cdeb9493ca0d
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
(cherry picked from commit 49902cc6ce228c9365c54b0dbe777ae63720310c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
When the user:
- has a non-developer-build -debug-and-release Qt
- and tries to configure the sqldrivers project with
-DCMAKE_BUILD_TYPE=Debug
our build system discarded the user request, and defaulted to
'Release'.
That happens because CMake sets CMAKE_BUILD_TYPE_INIT to 'Debug' by
default on Windows-MSVC, and we have no marker to differentiate
that the 'Debug' value was user-specified.
We have such a marker
- via the
__qt_auto_detect_cmake_build_type_before_project_call variable
when configuring qtbase / top-level qt
- via the
__qt_toolchain_cmake_build_type_before_project_call variable when
configuring via the qt toolchain file (although that doesn't apply
when configuring a multi-config build for obscure reasons, which
should be addressed).
A conservative fix is to add a new variable / marker called
__qt_internal_standalone_project_cmake_build_type_before_project_call
which the 'sqldrivers' project will set with the build type that is
detected before the first project() call, and use that to decide
whether to override the build type, similar how we do with toolchain
file variable.
We could reuse one of the previous variables, but I figured it's better
to be explicit with a new one. And hopefully we can clean up the whole
logic in a follow-up commit.
Amends 48841c34d2e86a741ec9992b9704c0fa5973503c
Amends 8c912cddebe544010e7da3f87af5b21f3328d7ec
Pick-to: 6.6 6.5
Fixes: QTBUG-120436
Task-number: QTBUG-114958
Change-Id: I37e3d8041088fe6084a9976ecc80ddd62d73ef81
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 5b5fa7b75a2465e085c7df61c64755bb65b51f1c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Split all code in QtSetup into separate functions and macros, put them
in more appropriate files, and call them in
qt_internal_setup_build_and_global_variables.
A new QtBuildOptionsHelpers.cmake is created which takes care of
computing the default values of user-customizable options that are not
pure configure features, like the cmake build type, whether to build
tests / examples, whether to enable ccache, etc.
The new function calls added in
qt_internal_setup_build_and_global_variables
try to preserve the previous code flow when QtBuild was included
in-between the code that was run in QtSetup.
Macros that have dependencies on various global variables were marked
as such with inline comments for easier navigation and comprehension.
After this change, QtSetup.cmake just includes QtBuild.cmake. We leave
it to exist for easier git blaming, but new code should not be added
to it unless really necessary.
The intent is to merge a variant of this change to 6.6 and 6.5 as
well.
Task-number: QTBUG-86035
Change-Id: I3409c2d3ea8ee19a69104b12ab2692966ba5f9cf
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>