Manage the HostInfo variable prefix the correct way. The prefix
takes the HostInfo PROJECT_VERSION_MAJOR as the version specifier,
which is not necessary is the same as the PROJECT_VERSION_MAJOR
of the project that uses respective API. Instead of relying on the
current PROJECT_VERSION, use the version info stored in HostInfo
package and adjust the prefix accordingly. This will allow version
mismatching between the project that uses API and HostInfo version.
Change-Id: Idbaec1c7bb203448ceb0f15c9173ad3985c7112d
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
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.5 6.8 6.9
Fixes: QTBUG-133725
Change-Id: I857d7e774fc9f9f5203a58311daea5e7177e0d67
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
[ChangeLog][CMake] CMake packages of public Qt modules don't provide the
targets of their private counterparts anymore. User projects must now
call find_package(Qt6 COMPONENTS FooPrivate) to make use of the
Qt6::FooPrivate target. User projects that rely on the old behavior can
set the CMake variable QT_FIND_PRIVATE_MODULES to ON.
For user projects, the warning message we know from QMake is displayed.
The warning can be disabled by setting the CMake variable
QT_NO_PRIVATE_MODULE_WARNING to ON.
Within Qt itself, find_package(Qt6Foo) will still
find_package(Qt6FooPrivate).
For static Qt builds, we need to wrap usage of private Qt modules in
$<BUILD_INTERFACE> or $<BUILD_LOCAL_INTERFACE> (if CMake's version is >=
3.26). Static builds with CMake < 3.26 will always load the private
modules if the Qt6FooConfig.cmake from Qt's build tree is loaded. This
is the case in non-prefix builds and (in the future) when building
examples as external project.
This amends commit fbbf4ace0188b9718b6d7808021c0b887fd52d9f.
Pick-to: 6.9
Task-number: QTBUG-87776
Change-Id: I78e95248f2b3fa73c3005c61df2fe4f71ad8eeb8
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
qt_register_target_dependencies does the same thing as
qt_record_extra_qt_package_dependency but in more convenient way.
Update the qt_register_target_dependencies signature and adjust naming,
it now accepts PUBLIC and PRIVATE multi-value arguments and called
qt_internal_register_target_dependencies.
Use it and deprecate qt_record_extra_qt_package_dependency.
Pick-to: 6.5 6.8 6.9
Change-Id: I0594cf699ec1e3af7210dd7450fa3f81c1f565ae
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
CMake 3.31 introduced the policy CMP0174 that triggers a warning if a
single-value argument is passed to a function without a value.
We did this doing this when forwarding arguments in code that doesn't
use _qt_internal_forward_function_args yet, e.g. in qt_internal_add_app:
qt_internal_add_executable(...
TARGET_PRODUCT ${arg_TARGET_PRODUCT}
...)
Forward the warning-triggering arguments with
_qt_internal_forward_function_args now, because that only forwards used
arguments.
In the future, we can offload more forwarding work to the
_qt_internal_forward_function_args command and simplify the forwarding
code in qt_internal_add_app and qt_internal_add_tool. This patch only
fixes the worst offenders for now.
Pick-to: 6.8
Change-Id: Ie786691e4b236decf4c62f4dd0751ed76b721177
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
This will be used in a follow up patch to identify them.
Pick-to: 6.8
Task-number: QTBUG-93625
Task-number: QTBUG-112212
Change-Id: I39d5eb9f79ac67af0808efeda4d7f4e0a6908cc9
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Create a script that allows running an app or a test easily similar
to running on host. This improves development workflow and time by
allowing quick runs without having to manually call the various adb
commands to launch, get a pid of the app and then print the logcat,
let alone passing parameters or environment variables.
For normal apps, the app package name is retrieved by the script, run
and live logcat is printed as long as the app is still running.
For tests, the script calls androidtestrunner, allowing test parameters
to be passed to the test.
For CI debugging, this would save quite a lot of hussle and frustration
trying to run or debug a test app.
One other benefit for this is enabling running Android tests from Qt
Creator's testlib plugin without big changes to Qt Creator to support
androidtestrunner explicitly.
Because file(GENERATE) would fail if called twice for the same file,
I use file(WRITE). This is used because at the time of calling the
target executable finalizer, we don't know if the target is a test
or not, so we rely on writing the script first as a normal target,
then call it if the target is a test where it overrides the script.
For this also, parameters passed to the runner or androidtestrunner
can't handle generator expressions.
[ChangeLog][CMake][Android] Add wrapper scripts to run Android apps and
tests with ease from the host.
Task-number: QTBUG-129889
Change-Id: I84e85ce2bbf6944c8aa20bdc2c2b6d7b956bc748
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
The object libraries that are side products from building plugins
should also consider the properties that control the flag handling of
their main plugin targets, otherwise they will inherit the
PlatformInternal flags without knowing what their parent decide.
Functionality now considers QT_SKIP_WARNINGS_ARE_ERRORS and
_qt_internal_use_exceptions properties. The list can be extended in the
future.
Change-Id: If304b3b382d6cd05064bc87e11d3cc87ba7c0d7b
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Backstory.
The main reason why we keep getting "unable to promote 3rd party 'X'
target to global scope" errors when building Qt repositories, is
because we try to promote 3rd party imported targets in a different
scope than where the imported targets were created.
What were the main motivations for promoting 3rd party targets to
global?
1) imported targets are by default local to the directory scope they
were created in
2) we want 3rd party targets to be accessible across subdirectory
scopes, but looked up once, e.g. qt_find_package(JPEG) looked up in
src/gui/CMakeLists.txt, but the target should also be usable in the
sibling scope
src/plugins/imageformats/CMakeLists.txt
Having the package lookup close to the consuming qt module is easier
to maintain, because all the other 3rd party dependency lookups are
in the same file. This goes against the conventional CMake advice
where each subdirectory should look for its own dependencies, or the
dependency should be available directly in the root project scope.
3) to make the 3rd party targets available in the root project scope
as part of the following flow:
QtPostProcess.cmake ->
qt_internal_create_module_depends_file() ->
qt_collect_third_party_deps() ->
get_property(INTERFACE_QT_PACKAGE_NAME) ->
write 3rd party Dependencies.cmake file for each qt module.
Properties can only be queried from an imported target if it's in
the same scope or was promoted to global, otherwise you get
'non-existent target' errors.
4) for prl and pri file generation, where we need the targets to be
available during generator expression evaluation within the
relevant qt module directory scope
Here is a list of approaches I came up with on how to improve the
situation.
1) Make all imported targets global during the Qt build, by iterating
over the directory property IMPORTED_TARGETS and making each one
global.
Requires CMake 3.21.
Status: Already implemented for a long time, but is opt-in.
Pros: Relatively robust
Cons: Minimum CMake version for building Qt is 3.16.
2) Make all imported targets global during the Qt build using the
CMAKE_FIND_PACKAGE_TARGETS_GLOBAL variable.
Requires CMake 3.24.
Status: Not implemented, but can be set by Qt builders directly on
the command line.
Pros: Should be robust
Cons: Minimum CMake version for building Qt is 3.16.
3) Abandon the desire to have a single qt_find_package in a single
directory scope, and embrace the CMake-way of repeating the
dependency in each subdirectory that requires it.
Status: Not implemented.
Pros: Should be robust
Cons: A lot of qt_find_package duplication, will require rewriting
various code paths, QtPostProcess would have to be done at
directory scope, unclear if dependency tracking will still work
work reliably when there might be multiple same-named
directory-scoped targets, other unknown unknowns
4) Move all qt_find_package calls into a $repo_name/dependencies.cmake
file which would be read at project root scope. This would
potentially avoid all scoping issues, because all dependencies will
have to be specified at root scope.
Status: Not implemented.
Pros: No duplication
Cons: Dependencies are not scoped anymore to module directories,
won't be able to conditionally look for dependencies based on
module feature evaluation, not clear yet how this will tie into
standalone tests which are in tests/ subdir, other unknown unknowns
5) Try to promote as many 3rd party libraries at project root scope
as possible.
Currently we have 2 general locations where we look up
dependencies.
One is each qt_find_package call. The other is
Qt6FooDependencies.cmake ->
_qt_internal_find_third_party_dependencies().
Many 3rd party targets are created by
_qt_internal_find_third_party_dependencies() in the root scope, but
not promoted, and then we try to promote them in child scopes using
qt_find_package, which causes the promotion errors.
Starting with 58eefbd0b6169d0749b312268c1ae1e594e04362 and
37a5e001277db9e1392a242171ab2b88cb6c3049 we now record the provided
targets of previous qt_find_package calls.
So instead of waiting to try and promote targets later during the
configuration process, we can make sure we promote the targets at
_qt_internal_find_third_party_dependencies() call time, right
when we lookup the Qt dependencies of the qt repo, in the root
scope.
Status: Implemented in this change
Notably, we only promote 3rd party targets to global for qt builds,
and not user projects, to not accidentally break user project
behaviors.
Also, we only promote 3rd party targets, and not Qt internal
targets like Qt6::Core, Qt6::Platform, Qt6::PlatformCommonInternal,
Qt6::GlobalConfig, etc, for a few reasons:
- the code that requires targets to be global only cares about
3rd party targets
- promoting the internal targets is more prone to breaking, because
there is more than one place where find_package(Qt6Foo) might be
called, and if that ends up being in a different directory scope,
we encounter the same global promotion errors.
Some notable cases where this happens:
- tests/CMakeLists.txt brings in extra Qt packages via
StandaloneTestsConfig.cmake files
- qtbase standalone tests qt_internal_qtbase_pre_project_setup()
calls find_package(Qt6 COMPONENTS BuildInternals) which ends
up creating the Platform target in the root scope instead of
the tests/ scope
- Qt6::BundledLibpng links against Core, which ends up trying to
promote Core's internal dependencies Platform and GlobalConfig
To only promote 3rd party targets, we walk the dependencies of
an initial target recursively, and skip promoting targets that have
the _qt_is_internal_target or
_qt_should_skip_global_promotion_always properties set.
Pros: Improves the situation compared to the status quo
Cons: Still not ideal due to the various filtering of internal
targets and having to mark them as such.
6) Avoid promoting targets to global if we can detect that the target
was created in a different scope than where we are trying to
promote it.
We can do that by comparing the target's BINARY_DIR to the
CMAKE_CURRENT_BINARY_DIR and skip promotion if they are not equal.
Status: Not implemented, but we can consider it because it's
quick to do.
Pros: More robust than newly implemented approach (5)
Cons: Requires CMake 3.18, because trying to read the BINARY_DIR
property on an INTERFACE_LIBRARY would error out.
Also, if we implement it and make it the default when using 3.18+,
we might 'collect' a lot more hidden promotion errors that will
only be revealed later once someone uses CMake 3.16 or 3.17,
because most will probably use newer CMake versions.
Perhaps the trade-off is worth it?
Pick-to: 6.8
Fixes: QTBUG-89204
Fixes: QTBUG-94356
Fixes: QTBUG-95052
Fixes: QTBUG-98807
Fixes: QTBUG-125371
Change-Id: I088a17a98ef35aa69537a3ad208c61de40def581
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Will be used in a future commit to do target filtering.
Pick-to: 6.8
Change-Id: Iaf7039ff456ca11d94c44c6e12f63408d2aaa484
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Introduce some command wrappers for adding the Platform,
PlatformXInternal and GlobalConfig targets, to apply some common
options.
This will allow for less churn in the future when we need to apply
options to all these targets.
The Qt6CoreMacros, Qt6AndroidMacros and Qt6WasmMacros inclusion are
moved before QtBaseGlobalTargets to make the
_qt_internal_add_library command and other platform specific
commands available before we create the Platform targets.
Pick-to: 6.8
Change-Id: I260fdbeb95a39f06951dfefc714d3da604abb0bb
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
As part of fee15182949e88682131399c50b679be83a75385 we enabled framework
debug builds, which left us with an inconsistent library naming. The
framework libraries are always unsuffixed, e.g. QtGui.framework/QtGui,
while we were adding _debug suffixes to the plugins and static libs.
This was confusing macdeployqt, as it uses simple string matching logic
for "_debug_" to detect that a Qt build is a debug build, and since
the framework library didn't have a suffix it then failed to deploy
the suffixed plugins.
We now follow the requirement from the framework naming and skip the
suffixing for all libraries in this configuration.
Pick-to: 6.8
Change-Id: I982253fc46c65aa3fab52f8658f62ef63cdac49f
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
When a shared library target has private dependencies to another
shared library, they are exported by CMake into the target's
IMPORTED_LINK_DEPENDENT_LIBRARIES_<CONFIG> property.
This property then is read by the consuming project to determine which
file paths need to be added to the -rpath-link linker option.
Due to the simple logic that CMake uses to process this property,
if the project CMAKE_BUILD_TYPE does not match the _<CONFIG> part of
the property, the dependent libraries will not be added to
-rpath-link, causing link failures.
Make sure we explicitly set all the possible variants of the property
in our custom Qt6FooAdditionalTargetInfo.cmake file, to ensure we
always pick up the relevant dependent libraries for processing.
In conjunction with 173164cd477211e574c0d04abef51aa0f4c3f78d and
1c287cea291d2a88770ff02771845d2a34e80964 in qtbase, this should
hopefully avoid most -rpath-linking issues for QNX and Yocto builds.
Pick-to: 6.8
Task-number: QTBUG-126727
Change-Id: I16a9cb5553d57e5ea3edc28cc2aab89c77f02a75
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Previously, only a very short subset of options related to attribution
files could be specified to qt_internal_add_module /
qt_internal_extend_target.
It is more convenient to allow specifying most (safe) options, instead
of calling another function.
Unsafe are considered paths like INSTALL_PATH and derivatives, TYPE
which is too generic, and some other ones like LIBRARIES which would
be duplicated, and causes warnings in cmake_parse_arguments if
duplicated.
Change the code to allow specifying most SBOM options and forwarding
them to _qt_internal_extend_sbom.
Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I6eb723e165edf59973d83c66eace43acdce237de
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This change adds a new -sbom configure option to allow generating and
installing an SPDX v2.3 SBOM file when building a qt repo.
The -sbom-dir option can be used to configure the location where
each repo sbom file will be installed.
By default it is installed into
$prefix/$archdatadir/sbom/$sbom_lower_project_name.sdpx
which is basically ~/Qt/sbom/qtbase-6.8.0.spdx
The file is installed as part of the default installation rules, but
it can also be installed manually using the "sbom" installation
component, or "sbom_$lower_project_name" in a top-level build. For
example: cmake install . --component sbom_qtbase
CMake 3.19+ is needed to read the qt_attribution.json files for
copyrights, license info, etc. When using an older cmake version,
configuration will error out. It is possible to opt into using an
older cmake version, but the generated sbom will lack all the
attribution file information.
Using an older cmake version is untested and not officially supported.
Implementation notes.
The bulk of the implementation is split into 4 new files:
- QtPublicSbomHelpers.cmake - for Qt-specific collecting, processing
and dispatching the generation of various pieces of the SBOM document
e.g. a SDPX package associated with a target like Core, a SDPX
file entry for each target binary file (per-config shared library,
archive, executable, etc)
- QtPublicSbomGenerationHelpers.cmake - for non-Qt specific
implementation of SPDX generation. This also has some code that was
taken from the cmake-sbom 3rd party project, so it is dual licensed
under the usual Qt build system BSD license, as well as the MIT
license of the 3rd party project
- QtPublicGitHelpers.cmake - for git related features, mainly to embed
queried hashes or tags into version strings, is dual-licensed for
the same reasons as QtPublicSbomGenerationHelpers.cmake
- QtSbomHelpers.cmake - Qt-specific functions that just forward
arguments to the public functions. These are meant to be used in our
Qt CMakeLists.txt instead of the public _qt_internal_add_sbom ones
for naming consistency. These function would mostly be used to
annotate 3rd party libraries with sbom info and to add sbom info
for unusual target setups (like the Bootstrap library), because most
of the handling is already done automatically via
qt_internal_add_module/plugin/etc.
The files are put into Public cmake files, with the future hope of
making this available to user projects in some capacity.
The distinction of Qt-specific and non-Qt specific code might blur a
bit, and thus the separation across files might not always be
consistent, but it was best effort.
The main purpose of the code is to collect various information about
targets and their relationships and generate equivalent SPDX info.
Collection is currently done for the following targets: Qt modules,
plugins, apps, tools, system libraries, bundled 3rd party libraries
and partial 3rd party sources compiled directly as part of Qt targets.
Each target has an equivalent SPDX package generated with information
like version, license, copyright, CPE (common vulnerability
identifier), files that belong to the package, and relationships on
other SPDX packages (associated cmake targets), mostly gathered from
direct linking dependencies.
Each package might also contain files, e.g. libQt6Core.so for the Core
target. Each file also has info like license id, copyrights, but also
the list of source files that were used to generate the file and a
sha1 checksum.
SPDX documents can also refer to packages in other SPDX documents, and
those are referred to via external document references. This is the
case when building qtdeclarative and we refer to Core.
For qt provided targets, we have complete information regarding
licenses, and copyrights.
For bundled 3rd party libraries, we should also have most information,
which is usually parsed from the
src/3rdparty/libfoo/qt_attribution.json files.
If there are multiple attribution files, or if the files have multiple
entries, we create a separate SBOM package for each of those entries,
because each might have a separate copyright or version, and an sbom
package can have only one version (although many copyrights).
For system libraries we usually lack the information because we don't
have attribution files for Find scripts. So the info needs to be
manually annotated via arguments to the sbom function calls, or the
FindFoo.cmake scripts expose that information in some form and we
can query it.
There are also corner cases like 3rdparty sources being directly
included in a Qt library, like the m4dc files for Gui, or PCRE2 for
Bootstrap.
Or QtWebEngine libraries (either Qt bundled or Chromium bundled or
system libraries) which get linked in by GN instead of CMake, so there
are no direct targets for them.
The information for these need to be annotated manually as well.
There is also a distinction to be made for static Qt builds (or any
static Qt library in a shared build), where the system libraries found
during the Qt build might not be the same that are linked into the
final user application or library.
The actual generation of the SBOM is done by file(GENERATE)-ing one
.cmake file for each target, file, external ref, etc, which will be
included in a top-level cmake script.
The top-level cmake script will run through each included file, to
append to a "staging" spdx file, which will then be used in a
configure_file() call to replace some final
variables, like embedding a file checksum.
There are install rules to generate a complete SBOM during
installation, and an optional 'sbom' custom target that allows
building an incomplete SBOM during the build step.
The build target is just for convenience and faster development
iteration time. It is incomplete because it is missing the installed
file SHA1 checksums and the document verification code (the sha1 of
all sha1s). We can't compute those during the build before the files
are actually installed.
A complete SBOM can only be achieved at installation time. The install
script will include all the generated helper files, but also set some
additional variables to ensure checksumming happens, and also handle
multi-config installation, among other small things.
For multi-config builds, CMake doesn't offer a way to run code after
all configs are installed, because they might not always be installed,
someone might choose to install just Release.
To handle that, we rely on ninja installing each config sequentially
(because ninja places the install rules into the 'console' pool which
runs one task at a time).
For each installed config we create a config-specific marker file.
Once all marker files are present, whichever config ends up being
installed as the last one, we run the sbom generation once, and then
delete all marker files.
There are a few internal variables that can be set during
configuration to enable various checks (and other features) on the
generated spdx files:
- QT_INTERNAL_SBOM_VERIFY
- QT_INTERNAL_SBOM_AUDIT
- QT_INTERNAL_SBOM_AUDIT_NO_ERROR
- QT_INTERNAL_SBOM_GENERATE_JSON
- QT_INTERNAL_SBOM_SHOW_TABLE
- QT_INTERNAL_SBOM_DEFAULT_CHECKS
These use 3rd party python tools, so they are not enabled by default.
If enabled, they run at installation time after the sbom is installed.
We will hopefully enable them in CI.
Overall, the code is still a bit messy in a few places, due to time
constraints, but can be improved later.
Some possible TODOs for the future:
- Do we need to handle 3rd party libs linked into a Qt static library
in a Qt shared build, where the Qt static lib is not installed, but
linked into a Qt shared library, somehow specially?
We can record a package for it, but we can't
create a spdx file record for it (and associated source
relationships) because we don't install the file, and spdx requires
the file to be installed and checksummed. Perhaps we can consider
adding some free-form text snippet to the package itself?
- Do we want to add parsing of .cpp source files for Copyrights, to
embed them into the packages? This will likely slow down
configuration quite a bit.
- Currently sbom info attached to WrapFoo packages in one repo is
not exported / available in other repos. E.g. If we annotate
WrapZLIB in qtbase with CPE_VENDOR zlib, this info will not be
available when looking up WrapZLIB in qtimageformats.
This is because they are IMPORTED libraries, and are not
exported. We might want to record this info in the future.
[ChangeLog][Build System] A new -sbom configure option can be used
to generate and install a SPDX SBOM (Software Bill of Materials) file
for each built Qt repository.
Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I9c730a6bbc47e02ce1836fccf00a14ec8eb1a5f4
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
There was refactoring in 8c41125118768ce037698e0605755128b2da705d to
handle custom postfixes, which caused a regression in the postfix not
being set for macOS frameworks.
Specifically we set CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_DEBUG to
the value of ${${postfix_var}} but that variable was empty, because we
only set it in the PARENT_SCOPE.
Set the variable also in the current scope.
Amends 8c41125118768ce037698e0605755128b2da705d
Pick-to: 6.5 6.7
Change-Id: Iae3f1050bb11805b4cce01ec491a13a3d6c0a9fc
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Applications not necessarly link QtGui module in
qt_internal_add_executable. They still may add link it in followoup
qt_internal_extend_target calls. We should consider this when adding
dependencies on qpa_default_plugins to the internal executables.
Pick-to: 6.7
Change-Id: Icc413bd35b631b3a356e4033faab4e6c01b29a60
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Qt tools and executables may required the static plugins from modules
that are build as part of the Qt build tree. In this case we need to
force plugin importing. This adds the qt_internal_import_plugins call
when we extend the executable target.
Replace the previos solution that considered libraries that were
provided in the arguments of the qt_internal_add_executable call only.
Pick-to: 6.7 6.6 6.5
Fixes: QTBUG-111988
Change-Id: Ifa2cf7f1f68d9f90cafc64f225aebe11d4cdb2ae
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
PACKAGE_PREFIX_PATH is not defined in cmake versions 3.29.x.
We should avoid referring the internal CMake variables.
Use the calculated reverse relative path to the prefix path
instead.
Fixes: QTBUG-124186
Pick-to: 6.5 6.6 6.7
Change-Id: Iefae132e61a3f8e8f5525c0abd6a2d41631c2fb0
Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Versionless targets in Qt6 are interface libraries that link the
versioned libraries using the INTERFACE link type. This makes the
linking chain more complicated than it can be. Also we miss some
significant interface properties in the versionless targets comparing
to the versioned targets.
The new approach manually generates the versionless targets, instead
of using CMake exports.
For CMake versions < 3.18 we now create a copy of the versioned
targets. The copy includes all the relevant INTERFACE properties from
the versioned targets and imported locations for all configs.
For CMake versions >= 3.18 we now create the versionless target ALIASes
which should behave give the transparent access to the versioned
targets.
Using the QT_USE_OLD_VERSION_LESS_TARGETS flag you may force the
behavor of the CMake versions <= 3.18
The change is partial workaround for QTBUG-86533.
Task-number: QTBUG-114706
Change-Id: Iafadf6154eb4912df0697648c031fcc1cbde04e0
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
When building examples as ExternalProjects as part of a multi-config
qtbase build, syncqt can not be located with the following error:
CMake Error at Qt6CoreToolsAdditionalTargetInfo.cmake:10 (message):
Unable to add configure time executable Qt6::syncqt
qtbase/libexec/syncqt doesn't exist
Call Stack (most recent call first):
qtbase/lib/cmake/Qt6CoreTools/Qt6CoreToolsConfig.cmake:44 (include)
qtbase/cmake/QtPublicDependencyHelpers.cmake:65 (find_package)
qtbase/lib/cmake/Qt6Core/Qt6CoreDependencies.cmake:34
(_qt_internal_find_tool_dependencies)
qtbase/lib/cmake/Qt6Core/Qt6CoreConfig.cmake:42 (include)
qtbase/lib/cmake/Qt6/Qt6Config.cmake:165 (find_package)
CMakeLists.txt:13 (find_package)
The Qt6CoreToolsAdditionalTargetInfo.cmake file is used both for
install(EXPORT) Config files as well as export(EXPORT) Config files,
and in the latter case, the path that syncqt is looked up in is not
correct because syncqt is not yet installed.
In addition to checking whether syncqt exists in the install path,
also check if it exists in the build dir.
Ideally the additional path would be stored in a separate file that
is not installed, but the current code infrastructure does not provide
such a feature. Because we store a relative path instead of an
absolute path, the build path does not leak, so the situation is
bearable.
Task-number: QTBUG-90820
Task-number: QTBUG-96232
Change-Id: I16ad5c280751e050bc9b039ebd38ec9a66a6554c
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Replace Qt:: namespace with Qt6:: namespace in target_link_libraries
for the Qt modules/plugins/libraries.
Fixes: QTBUG-114706
Change-Id: Idfd0917dbe1a6a266bc4e9d5f465e550788b5aaf
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Add the reference to unity builds in the documentation of
NO_PCH_SOURCES to fully describe the semantics.
Change-Id: Icfd3ee401efa154da4b8ed9a307d29f2605d948a
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Bundled 3rdparty libraries link Qt platform targets implicitly, which
lead to the dependency resolution when the library is used by another
targets. For qtbase this works just fine since all platform targets
are not imported and they are used from a build tree. But in case if
3rdparty library is built as part of Qt repo different from qtbase
platform targets are imported and trigger the global promotion in
CMake. Usually qt_find_package for the 3rdparty libraries is called
somewhere in src/... directory and since Qt::Platform* targets are
already created in the top-level repo CMakeLists.txt by the
find_package(Qt ...) call, this leads to an error.
The propsed fix forces the global promotion of Qt platform targets
as soon as they created by the one of the initial find_package(Qt ...)
calls.
Change-Id: Iceb53f9ecccbdc438f9bc3bcc836583cfd4de535
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
IMPORTED targets obviously have nothing to sync. So we should ignore
them when collecting dependencies for header sync.
Pick-to: 6.5 6.6 6.7
Change-Id: Ief68ff5eb2eb13a3fe1608445e8f5e6abb5971b4
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
The condition was checking if excluded_genex variables is not an empty
string.
But when the EXCLUDE_FROM_ALL property was unset, the value of
excluded_genex would be "excluded_genex-NOTFOUND" which would fail the
condition, and would end up always adding the generated code block.
Instead of checking for an empty string, check if it's a truth-y value.
This ensures not to add the code block when the property is unset.
Amends 7540b4bd5634c9104a99f9b219531b1e3dd7942d
Change-Id: I126c745e2e6eccad34171456c052a14cad9d887d
Pick-to: 6.7
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: 🌴 Alexey Edelev 🌴 <alexey.edelev@qt.io>
For some reason when building a user project in Release mode, when Qt
was built with -DCMAKE_CONFIGURATION_TYPES=RelWithDebInfo;Debug on
MSVC, will result in linking of Debug object libraries into the user
project.
This does not happen in the same configuration on macOS.
My guess is there is a difference in the logic on which configuration
to choose between the platforms, perhaps based on package lookup order
or something else.
This was observed with qtgrpc's
ProtobufWellKnownTypes_type_registration object library (which is only
built on Windows as an object library).
The issue can be fixed if we explicitly generate per-config imported
location information for object libraries, just like we do for regular
libraries.
That way we'll have uniform build type information for all target
types.
Pick-to: 6.6 6.7
Fixes: QTBUG-119708
Change-Id: I9020b7743cea65bbd92cadd5f570b7e38e999bd4
Reviewed-by: 🌴 Alexey Edelev 🌴 <alexey.edelev@qt.io>
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>
My motivation to do this:
- it got big and tangled again
- sometimes functions need to be added to QtBuild.cmake rather than
to a separate file because they need to be called before some of the
global variables are set, to determine the value of those global
variables (in my case install paths needed to be modified when
building with xcframework support)
- some of the global variable assignments have dependencies on other
variables already being set and it's hard to keep track where that
happens
Split the contents of the file into smaller functions and macros
and place them into pre-existing files when appropriate, or
into new files. The new files are:
- QtBuildHelpers.cmake
- QtBuildPathsHelpers.cmake
- QtMkspecHelpers.cmake
The idea is to have Helpers file only define functions and never call
them, so it's easy to include the file where needed without being
scared of side effects.
QtBuild.cmake will just include the helpers and call one entry point
function to set up everything that was done by the file before.
QtBuild.cmake is not merged into QtSetup, to make it easier to git
blame (it's hard to blame a removed file).
No new features were added as part of the refactoring.
Some function names were renamed (but not all of them) to include
the qt_internal prefix.
Some lines were reformatted so they don't pass 100 chars limit after
the code was placed into a function / macro.
The Helpers includes were re-sorted.
Some function calls were re-ordered where the order call didn't
matter.
Some of the code in QtAndroidHelpers.cmake was wrapped into a macro
so that including the file does not cause side-effects by default.
I'd like to follow up with similar changes for QtSetup.cmake and
QtBuildInternalsConfig.cmake where possible, because having a few
"entry points" into building a Qt submodule is also confusing,
especially for those that aren't familiar with the build system and
why certain things go into certain places.
The intent is to cherry-pick this also to 6.5 and 6.6.
Amends 44cce1a2ea9dadd8b2de93f40de34269dda703c0
Task-number: QTBUG-86035
Change-Id: I02ceff8ceb9b6e9c78bc85d6a42deb02fca3e46b
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Orkun Tokdemir <orkun.tokdemir@qt.io>
QFuture::then() uses QtPrivate::Continuation::create(), which in turn
uses private API from an inline function:
f->d.setContinuation(ContinuationWrapper(std::move(continuation)), fi.d);
f->d is QFutureInterfaceBase (a public class), but its setContinuation()
takes QFutureInterfaceBasePrivate by pointer. Our ELF versioning scripts
mark everything that uses that class as private, resulting in:
4806: 0000000000287d70 365 FUNC GLOBAL PROTECTED 16 _ZN20QFutureInterfaceBase15setContinuationESt8functionIFvRKS_EEP27QFutureInterfaceBasePrivate@@Qt_6_PRIVATE_API
This commit adds an exception for this symbol, causing it to go back to
the regular "Qt_6" ELF version:
5629: 00000000003d6a16 366 FUNC GLOBAL PROTECTED 16 _ZN20QFutureInterfaceBase15setContinuationESt8functionIFvRKS_EEP27QFutureInterfaceBasePrivate@@Qt_6
This solution can probably be cleaned up a bit by moving the marker into
the header files parsed by syncqt, so they follow code motion without
having to remember to update the CMakeLists.txt. That requires some
surgery with syncqt, so not suitable for cherry-picking.
As a drive-by, fix the target_type check
for the _qt_extra_linker_script_content genex property
Fixes: QTBUG-117514
Pick-to: 6.6
Change-Id: I85599ea5ca7a4b79a8bbfffd178b92e73dbe11de
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
The former implies the latter, so it makes little sense to treat them
differently. Even if some types of targets are (currently) never
compiled with PCH, users of qt_internal_all_x() shouldn't need to know
such details.
Pick-to: 6.6 6.5
Change-Id: I8ead238a8d9e55da632b2929638b67724a42d73c
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
If module depends on some module Private part only the sync_headers
dependencies from this public part of this Private module is skipped.
Check if the module is Private and use the public module to read the
_qt_internal_sync_headers_target property.
Amends 0006a564c85d49153288cd3834197effed53394e
Fixes: QTBUG-115712
Pick-to: 6.6
Change-Id: I4678e2a6c9ec8f80862a97d48f0a3b4214ae2307
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
CMP0099 changes the way of LINK_ONLY genex works. With CMP0099 set to
OLD LINK_ONLY genex only links the exact library binary/archive without
propagating other interface options from the target. This feature was
exploited by PlatformXInternal targets to avoid propagating of their
linker options. Nowadays when CMP0099 is forced to NEW by Qt scripts,
including user-facing, we cannot rely on LINK_ONLY genex.
Introduce _qt_is_internal_target property that is set for all Qt
executables and explicitly limits the propagation of the linker
options from PlatformXInternal targets.
Pick-to: 6.5 6.6
Fixes: QTBUG-113641
Change-Id: I3a0ecddb65886e435073feb24c1b47035130ba70
Reviewed-by: Alexandru Croitor (OOO) <alexandru.croitor@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Use the internal target property to store the module_sync_header target
name. The property then is used to collect module_sync_header targets
and build the dependency tree between them. This mechanism only works
for Qt dependencies that are added using qt_internal_extend_target call
that works well at least for out CI builds. The mechanism allows to
omit the race in sync_header runs that might lead to unexpected results
since internal targets like automoc or headersclean_check only depend
directly on module_sync_header target that belong to the module.
Change-Id: I564f3ea0f3c1703e70c4c300fd1307c3214d39d8
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
lld 16.0 is more picky about symbol versioning than previous versions
(and other linkers such as ld.bfd, gold or mold).
It now errors out if a symbol is versioned but not defined
(see 8796677de8900dc154aef45f8620c3f987a40291).
Outside of detecting support for symbol versioning (fixed by 462832),
this causes linking Qt6 libraries other than Qt6Core to fail because
their linker scripts try to add versioning to qt_version_tag, which is
defined in Qt6Core rather than the library being linked.
The obvious (and working) fix is to version qt_version_tag only where it is
defined (Qt6Core), but this is not what the original intent seems to be.
Task-number: QTBUG-111514
Change-Id: I963d417befb0f6b2260c57f059eeda1fe79200c9
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
As I was investigating the NO_UNITY_BUILD_SOURCES issue, I realized that
we don't need to pass these quoted, especially now that we have moved
to `cmake_parse_arguments(PARSE_ARGV`, and we can check their existence
just by checking the `arg_*`, and that should be sufficient.
I also left a warning that we are aware of this.
Pick-to: 6.5
Change-Id: I4d939e80dc4671ea3ae9dc61516279f69ba2c5a5
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Allows sharing tracepoints between modules so that they can share one
trace group.
Pick-to: 6.5
Change-Id: I8de6da6beef02b34700cc2ecb1fad0e72a00b7e0
Reviewed-by: Janne Koskinen <janne.p.koskinen@qt.io>
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Maintain one central place - .cmake.conf - for information
about Qt's copyright.
Pick-to: 6.2 6.5
Change-Id: Ibcbce4313eba9660d459061b0ad00307e267b8f7
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
- Removed the NO_UNITY_BUILD argument from commands that disable it by
default.
- Add a warning in case NO_UNITY_BUILD or NO_UNITY_BUILD_SOURCES is
being used where it is already disabled, e.g., qt_internal_add_test
- Exclude all sources of a target from unity build if NO_UNITY_BUILD
is set on the target. This sounds a bit harsh, but I have noticed that
sometimes the same source file can be included somewhere else, and
some unexpected collision may occur.
- qt_examples_build_end excludes all its examples from the unity build.
- qt_build_test now sets the CMAKE_UNITY_BUILD to OFF before configuring
the tests, and restore its value when done.
Pick-to: 6.5
Task-number: QTBUG-109394
Change-Id: Ia42e7dd5a5bfb151db241deb639325720fd91eec
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Properties specified in EXPORT_PROPERTIES have their values exported
verbatim, without evaluating generator expression they might contain.
This limitation is removed by the introduced functions. They collect
properties that needs to be exported and evaluate generator
expressions inside the properties using file(GENERATE) before
exporting them. The functions generate the ExtraProperties.cmake
file that contains set_property calls with exported properties
and corresponding values.
Change-Id: If32c30a82a62e8bd48bb91f3df21ff2ad8d07243
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
The tracepointgen tool needs to know the enumeration/flag names
and values in order to generate metadata for the tracepoints
in order to pass this information when tracing.
Currently the metadata needs to be provided to the tracepointgen by
hand. This implements metadata parsing from header files.
Task-number: QTBUG-110598
Pick-to: 6.5
Change-Id: Ibb2cc6e724fd2defca4e301af2285b0fdbe8e7f7
Reviewed-by: Antti Määttä <antti.maatta@qt.io>
- The following commands accepts NO_UNITY_BUILD, and
NO_UNITY_BUILD_SOURCES arguments to opt out of the unity build, and
to exclude some source files from unity build, respectively.
- qt_internal_add_executable
- qt_internal_add_module
- qt_internal_add_plugin
- qt_internal_add_tool
- qt_internal_extend_target
- qt_internal_add_common_qt_library_helper
- qt_internal_add_cmake_library
- qt_internal_add_simd_part
- Unity build is disabled by default in these:
- qt_internal_add_test
- qt_internal_add_test_helper
- qt_internal_add_benchmark
- qt_internal_add_3rdparty_library
- qt_update_ignore_pch_source also excludes the files from unity_build
Pick-to: 6.5
Task-number: QTBUG-109394
Change-Id: I5d0e7df633738310a015142a6c73fbb78b6c3467
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
The extra quote enforces the arguments to be string, and stops the
COMMAND_EXPAND_LISTS within
QtDbusHelpers.cmake::qt_create_qdbusxml2cpp_command from expanding it
as a list.
Fixes: QTBUG-110459
Fixes: QTBUG-110450
Task-number: QTBUG-99238
Change-Id: Ifddd6570c7bf8f2d1757f275d9445ce2924a93f1
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
The batcher does not currently work properly with non-qtbase
submodules. Disable them temporarily so that at least the
tests in qtbase are batched. Do this from qtbase so that changes
to each and every submodule are not necessary.
Also, maintain a list of tests that were thus skipped. On any
qt cmake internal function call that refers to such a target,
identify the target as skipped and make the call a no-op.
Fixes: QTBUG-109785
Change-Id: Ib0aa5d39eee8315ffd4ac62f6d1f44fe9bbf7a2f
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
AUTOUIC doesn't handle relative paths to .ui files in parent
directories when using Ninja Multi-Config.
The designer tool in qttools has such a ui file. This leads to the
following error when trying to build qttools together with examples as
ExternalProjects and Ninja Multi-Config:
ninja: error: 'src/designer/src/designer/designer_autogen/
include_Debug/ui_preferencesdialog.h', needed by
'src/designer/src/designer/designer_autogen:Debug',
missing and no known rule to make it
Until cmake is fixed, we can work around the issue by not adding
designer as a dependency when building EP examples, because no example
tries to use the app.
We can't exclude all apps from example dependencies because some
modules use qt_internal_add_app for tools as well, which are called
from public CMake API and also examples.
An example of this is qtapplicationmanager.
Given that we can't exclude all apps, introduce a function to
allow skipping single targets when building EP examples.
This will allow excluding designer specifically.
The examples will now depend on a new ${repo}_src_for_examples target
rather than ${repo}_src, which will exclude skipped targets.
Task-number: QTBUG-90820
Task-number: QTBUG-96232
Task-number: QTBUG-110369
Change-Id: I2f900253bbf7bac917f2293ef604ab3ea8f298e1
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This replaces the qt_parse_all_arguments macro with the built-in
`cmake_parse_arguments(PARSE_ARGV`. In addition, a new function,
_qt_internal_validate_all_args_are_parsed, can be used to check whether
any _UNPARSED_ARGUMENTS have been passed to the function.
Fixes: QTBUG-99238
Change-Id: I8cee83dc92dc6acdaaf747ea6ff9084c11dc649b
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Stub targets introduced in 65b7aacb make the old batch target detecting
measure in qt_internal_extend_target,
qt_internal_undefine_global_definition, qt_internal_add_resource
obsolete, since now the targets actually exist in the build system.
Unconditionally fail if the target does not exist and if it does, query
for its inclusion in the batch
Change-Id: I1cd1d8cc7fbf4bdbd2289a1b38ecbea1e93a06c8
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
In developer builds we don't install tools, so syncqt executable is
located in its RUNTIME_OUTPUT_DIRECTORY but not by install path. This
works fine in general case, but in multi-config builds the
RUNTIME_OUTPUT_DIRECTORY path doesn't match the install path. So syncqt
target points to wrong location in this case. It makes sense to use the
existing IMPORTED_LOCATION of syncqt executable directly if Qt is not
supposed to be installed. Also check if the syncqt executable exists at
the expected location before creating the imported target.
Pick-to: 6.5
Fixes: QTBUG-109864
Change-Id: I0de647b2a73169a0d48bd88edeb7ff00975fa774
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>