29 Commits

Author SHA1 Message Date
Alexandru Croitor
d2ed84514d CMake: Skip sbom file checksum checks for excluded test targets
If a developer configured Qt with
 -DQT_GENERATE_SBOM=ON
 -DQT_BUILD_TESTS=ON
 -DQT_BUILD_TESTS_BY_DEFAULT=OFF

The would get the following error upon installation of qtmultimedia:

CMake Error at
qt_sbom/SPDXRef-PackagedFile-qt-plugin-MockMultimediaPlugin.cmake:5
  (message):
  Cannot find 'plugins/multimedia/libmockmultimediaplugin.a' to
  compute its checksum.

This happens because QT_BUILD_TESTS_BY_DEFAULT == ON sets the
EXCLUDE_FROM_ALL directory property on the tests directory, which
means all plugins created under tests/ subdir are not installed by
default, and the SBOM code could not read the installed files to check
the checksums.

In such a case, set a QT_INTERNAL_TEST_TARGETS_EXCLUDE_FROM_ALL
directory-scoped variable in the tests/ subdir, and use that as a
marker for the sbom code to know it should skip the checksum check.

Pick-to: 6.8 6.9
Fixes: QTBUG-137168
Change-Id: I970c3bc5732cc648549e5099fa1d50b3b39cb26f
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2025-05-26 20:11:33 +02:00
Alexandru Croitor
43e166bd08 CMake: Support manual multiple projects within-a-repo SBOM generation
Certain repositories like qtwebengine contain multiple projects from
the perspective of online installer packaging. In this case the
QtWebEngine and QtPdf projects are expected to have separate SBOM
documents.

Introduce a new QT_SKIP_SBOM_AUTO_PROJECT variable that can be set
before qt_build_repo to disable the auto-generation of an SBOM
document for the current repo project.

Introduce two new internal functions
qt_internal_sbom_begin/end_qt_repo_project to allow to manually start
and end the SBOM generation for a project within a repo.

Because the intermediate file names that assemble the SBOM use the
project name as a key, and the project name would be the same for
qtwebengine, allow differentiating between the current project name
and the real qt repo project name.

The current project name is used for the file names, whereas the
real qt repo project name is used to extract the dependencies on
other repos, to ensure correct dependency build rules.

As a drive-by, improve the document dir path search list when an SBOM
document can't be found.

Pick-to: 6.8
Task-number: QTBUG-128893
Task-number: QTBUG-122899
Change-Id: I61b68098242e7c49b98420265c29af78303c3233
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-12-05 15:37:00 +01:00
Alexandru Croitor
ffef516884 CMake: Support cmake --install . --prefix <path> for SBOM generation
Before this change, the SBOM generation only considered the
CMAKE_INSTALL_PREFIX set at configure time for the purposes of file
checksum computation, external document lookup, and SBOM file
installation.

When cmake --install . --prefix <path> is used, the install time
CMAKE_INSTALL_PREFIX variable is overridden with the provided path,
and can be different from the configure time value.

This path was applied to the installation of regular files, libraries,
etc, but not to the SBOM generation. This caused issues like not being
able to find a library to compute its checksum.

Instead of hard-coding the value to QT_STAGING_PREFIX, just don't pass
a value at all, and rely on the new default of using an
install-time-evaluated \${CMAKE_INSTALL_PREFIX}.

Keep the ability of specifying a custom prefix just in case.

Modify all the code that used a hard-coded CMAKE_INSTALL_PREFIX to use
a install-time-evaluated one instead.

As a drive-by, also set a proper default value for the INSTALL_SBOM_DIR
option.

Pick-to: 6.8
Fixes: QTBUG-131883
Change-Id: Ifde6ab282ac40f10c5bf51976121065c7dc631eb
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-12-05 15:37:00 +01:00
Alexandru Croitor
3066e9e38d CMake: Add doc_tools build and install targets
Add doc_tools and install_doc_tools custom targets.
These are meant to build and install documentation and code generation
tools that participate in documentation generation.

Such tools should be annotated with the IS_DOC_TOOL option to their
qt_internal_add_tool call.

In qtbase, such generator tools are qdbusxml2cpp and qvkgen.

Pick-to: 6.8
Task-number: QTBUG-91243
Task-number: QTBUG-128730
Change-Id: Idebffc6f50d8547ce76c1102a20d60d436e44cfd
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2024-10-31 00:51:07 +01:00
Alexandru Croitor
c64190caa7 CMake: Add an install_tools target for static builds
We offer a build target called 'host_tools' to build just host tools
and their dependencies within a Qt build, but it was not possible to
easily install the built tools.

Add convenience custom targets called 'install_tools' and
'install_tools_stripped' to install the host tools when building
a static Qt build.

The convenience targets will be useful for qdoc static builds, to
easily be able and install the tools, without having to specify each
tool's install target separately.

The current approach doesn't work for shared Qt builds because it
would necessitate tracking the libraries that the tools depend on, so
those are installed as well.

So for now, this is limited to static builds only, where there
are no shared library dependencies that have to be installed.

The implementation passes 'host_tools' as an installation component
for qt_internal_add_tool installed targets. The custom target then
just calls cmake --install with the component name.

Pick-to: 6.8
Task-number: QTBUG-91243
Task-number: QTBUG-128730
Change-Id: Ic047ec3b8683043f496b4b2c3cf883a3e70440b3
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2024-10-31 00:51:06 +01:00
Alexandru Croitor
c997e3bb8b CMake: Clean up _qt_internal_finalize_batch
The _qt_internal_finalize_batch function had a bunch of problems,
style-wise and function-wise:
- it called find_package(Qt6) in its body, which broke when
  configuring qtbase with in-tree tests

- it constantly rewrote the merged blacklist file on each
  reconfiguration

- it used file(WRITE) to concatenate content

- it was in the public API file

The changes are:
- Move the function to the internal test helpers file.

- Change it to use qt_configure_file instead of file(WRITE).

- Call it at the end of the qt_build_tests for a repo, or at the end
  of configuring a super build, instead of relying on a finalizer.

- Remove the find_package call. The reason this was added in the first
  place, was to populate the __qt_core_macros_module_base_dir variable
  so that qt_internal_add_resource configure_file call doesn't fail in
  standalone tests build.
  The variable was unset because the finalized function was called in
  the top level directory scope, whereas the very first find_package
  call was in the tests/ scope, meaning the variable was empty.
  This is still a problem in the top-level build where the tests scope
  and the top-level scope are different. Work around it by relying on
  a global property to reset the value if it's empty.

Amends 6a9e89121d7766a34c4281d298057bfbe8af36b3

Pick-to: 6.8
Change-Id: Id6fe41ee86d09b8118bea52cac8a59965d7ecb9e
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2024-10-29 16:09:56 +01:00
Alexandru Croitor
08d1d113f1 CMake: Add a way to skip configuring the doc targets
Can be useful for non-Makefile and Ninja generators, even if they
are unsupported for building Qt.

Pick-to: 6.8
Change-Id: I02a622c89f725c3ae5b51ea345a530eaa5529976
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-10-18 15:16:59 +02:00
Alexandru Croitor
34f127834c CMake: Use lowercase project name for skipping tests and examples
Previously one had to specify names like 'QtSvg' to -skip-tests
and -skip-examples, but this is not the same behavior as what
the -submodules and -skip options expect.

To keep it consistent, change the code to consider only the lower case
names.

Amends 25b89f2c88cdfc98bfa462949531a33f7ef50996
Amends 7c9efdf40c9d9f7f89f7a9be0c06e0d3ec54ec2c

Pick-to: 6.7 6.8
Fixes: QTBUG-127857
Change-Id: Ie80edb98ce16b6835fe361198953e36b8255102a
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-08-12 15:21:57 +02:00
Alexey Edelev
40def71797 Avoid creating the installed test plugins when configuring standalone tests
When configuring standalone tests with some installable plugins, these
plugins land inside the actual build/install directory after
build/installation. This makes imposible to configure the same
standalone tests second time since the same plugin targets attempt to
be created within the build tree, while they are already found by the
respective find_package(<Qt Module>) call.
This change introduces and uses the tests-wide
qt_internal_configuring_tests variable to mark the plugins that are
built within the tests build tree and disallows loading them by the
find_package call when building standalone tests.

The trick is simple: PluginConfig.cmake files skip plugin creation if
the respective plugin is a test plugin and the standalone test project
matches the plugin repo project.

Also we now oblige module maintainers to mark such plugins using the
TEST_PLUGIN argument of the qt_internal_add_plugin function. This is
needed to prevent breakage when the exact test is build alone and the
qt_internal_configuring_tests is not set. If plugin is not marked as
TEST_PLUGIN and is built as part of test build tree the warning is
displayed to remind the maintainer about the missing flag. Suggest to
make this flag mandatory for all test plugins, and throw a FATAL_ERROR
if the plugin is not marked respectively.

Fixes: QTBUG-127781
Change-Id: I51f8b2f2c979911dad7c90926d841c8b8f1bb5d7
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2024-08-12 14:56:16 +02:00
Alexandru Croitor
85f37700e8 CMake: Generate a config.redo script in per-repo build dirs
Before we only generated a 'config.redo' script in the build dir of
qtbase or a top-level build. After this change, we will also generate
one when configuring repos in a per-repo build of qt.

This allows quick fresh reconfiguration of a repo, without having to
remember how it was configured before.

To make that happen, we need to duplicate parts of the '-redo' code
that was initially added in configure, into qt-configure-module, both
for the Unix and Windows scripts.

Slight adjustments had to be made to account for the source repo path
argument, that needs to be skipped from being added into the
config.opt.in file.

We also need to modify the code that generates the config.redo file to
do it at the start of each repo configuration, rather than just when
configuring qtbase.

Amends 8ffb6ce64cb0183bf6805497b398463549c1ed8d

Change-Id: I76cd5296ea23ca5bfef6b8975c82416b628bc5d1
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-07-30 16:12:19 +02:00
Alexandru Croitor
d2e85cede0 CMake: Prevent most global promotion errors when building Qt
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>
2024-07-11 19:02:55 +02:00
Alexandru Croitor
31126b2b77 CMake: Make ninja 'sbom' work for top-level builds
We need to pass all dirs where sboms will be generated, for external
document referencing.

We also need to set up dependencies between the repo sbom custom
targets, so that qtsvg sbom is only run after qtbase sbom.
We use the dependencies.yaml info to set up the dependencies.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: Id3331e11742bc2c86e7ed52ce26b3ff21eace359
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-06-25 20:57:50 +02:00
Alexey Edelev
a2631f5bc0 Fix the per-repo config.opt/.summary files installation
Add the file renaming rules.

Task-number: QTBUG-78749
Change-Id: Ibf13d3570c076e4c287b7d44430be90e98a1e72b
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-06-25 11:48:39 +02:00
Alexey Edelev
7d0c56c236 Install per-repo config.opt files for non-top-level builds
Counterpart of the config.opt files installation for the top-level
build.

Task-number: QTBUG-78749
Change-Id: I4b5b20dafc8a043c3b309235ef662f08f8ef0bb8
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2024-06-21 22:14:19 +02:00
Alexandru Croitor
37a5e00127 CMake: Generate an SPDX v2.3 SBOM file for each built repository
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>
2024-06-13 16:54:47 +02:00
Tim Blechmann
7a62c96238 CMake: add licenseRule.json to IDE projects
Some repos have licenseRule.json files. Adding them to the IDE projects.

Pick-to: 6.7
Change-Id: I7fdc054d244d48e3343866775671d8f4f4c9390b
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Lucie Gerard <lucie.gerard@qt.io>
2024-04-24 16:41:23 +08:00
Tim Blechmann
bd2dc0c3ed CMake: split _extra_files targets
Separate config.tests, coin, cmake, licenses and changelogs into
independent targets to keep the IDE projects more organized.

Pick-to: 6.7
Change-Id: Ie33d45799621c2d7ec6f022ffcfac132ac4c7b94
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-04-12 08:36:05 +08:00
Tim Blechmann
003a191152 cmake: add _extra_files IDE target from heuristics
Lots of files in the repos are not included into the generated IDE
projects. Therefore we add utility targets (custom targets), which are
populated by glob patterns, which should fit most files that are found
in qt's subprojects.

Pick-to: 6.7
Change-Id: I1b731e65f8db319d3cec817eea5c23a1eeaefb22
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-04-12 08:36:01 +08:00
Alexey Edelev
6760bae2fa Suppress the warning about unused QT_INTERNAL_CALLED_FROM_CONFIGURE
Add the dummy check if the variable is defined to suppress the warning.

Pick-to: 6.7
Change-Id: If3bb0ef6a2587693c0ec898ceb3080ebfc1e82a7
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-04-11 01:27:32 +02:00
Alexandru Croitor
270315e019 CMake: Fix finding standalone parts config file for yocto
When building standalone tests of qtsvg targeting yocto, the
standalone parts config file was not found.

That's because it specifies a new CMAKE_STAGING_PREFIX for each built
repo, and the QtSvgTestsConfig.cmake file will be located there,
rather than in QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX, where
the QtBuildInternalsConfig.cmake file is.

So in this case, we always have to prefer looking into
CMAKE_STAGING_PREFIX for the file.

Amends 62905163bf887c2c2c9ba7edcd64c96d237a6e95

Task-number: QTBUG-90820
Task-number: QTBUG-96232
Change-Id: I8902381afa4267e40dfb2ad47e44285a806a35e2
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
2024-03-19 16:04:59 +01:00
Alexandru Croitor
62905163bf CMake: Allow building all examples as standalone just like tests
Introduce a new libexec/qt-internal-configure-examples script that
allows to configure and build "standalone examples" just like
"standalone tests".

This is a prerequisite for using deployment api in examples for prefix
builds, otherwise deployment api gets confused not finding various
information that it expects from an installed qt.

Because the various conditions in the build system for standalone
examples are similar to standalone tests, introduce a new
QT_BUILD_STANDALONE_PARTS variable and use that in the conditions.
The variable should not be set by the user, and is instead set by the
build system whenever QT_BUILD_STANDALONE_TESTS/EXAMPLES is set.

Unfortunately due to no common file being available before the first
project() call, in qtbase builds, per-repo builds and top-level builds,
we need to duplicate the code for setting QT_BUILD_STANDALONE_PARTS for
all three cases.

Task-number: QTBUG-90820
Task-number: QTBUG-96232
Change-Id: Ia40d03a0e8f5142abe5c7cd4ff3000df4a5f7a8a
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2024-03-14 11:44:16 +01:00
Alexandru Croitor
dd052a0a01 CMake: Warn when examples are not added via qt_internal_add_example
To ensure examples can be built as ExternalProjects, the example
subdirectories need to be added via qt_internal_add_example rather
than just add_subdirectory.
qt_internal_add_example is also needed for correct installation of
example sources.

To catch examples that are still not added via
qt_internal_add_example, set a QT_WARN_ABOUT_EXAMPLE_ADD_SUBDIRECTORY
variable at the top of the examples/CMakeLists.txt directory scope
and show a warning in qt_add_executable whenever that variable is
TRUE.

Calls of qt_internal_add_example will set the variable to FALSE,
making sure the warning is not shown for properly added examples.

This is limited to developer builds and can be opted out of via the
QT_NO_WARN_ABOUT_EXAMPLE_ADD_SUBDIRECTORY_WARNING variable.

qt_add_executable is used as the 'hook' for showing the error, because
that is the most likely function to be used in examples.
We don't use qt_standard_project_setup in all projects yet, so we
don't want to use that one.

Task-number: QTBUG-90820
Task-number: QTBUG-123096
Change-Id: I7a0b0b2cc60c70903db03b56c06494c127a62420
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2024-03-11 13:48:23 +01:00
Joerg Bornemann
55d81b3eff CMake: Remove qt_internal_compute_features_from_possible_inputs
This function calculated the values of the features 'no-prefix' and
'developer-build' from INPUT_* values. Since configure directly
translates -no-prefix and -developer-build to FEATURE_no_prefix and
FEATURE_developer_build, we can remove the function.

Task-number: QTBUG-120529
Change-Id: Ide1fa61af175d8f6a6aa6363dfdfa94912836345
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2024-02-13 20:11:21 +01:00
Tim Blechmann
25b89f2c88 cmake: build repo helpers - fine-grained test/example options
the tests/examples could only be enabled globally. when working on a
specific repo, it's beneficial to disable tests/examples for other
projects to reduce project sizes (and cmake configure/generate times)

Change-Id: I0026ba87b667d427043cc8eb1baa6c28b2046dd7
Pick-to: 6.7
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2024-02-08 23:30:29 +08:00
Alexey Edelev
161c2f9544 Add the the implicit promotion to global for Qt platform targets
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>
2024-01-31 19:20:06 +01:00
Alexey Edelev
0d7cda9cda Fix encapsulation of qt_build_internals_add_toplevel_targets
The function uses external non-cache variable that is set in different
cmake macro. It's better to pass the value as argument.

Pick-to: 6.5 6.6 6.7
Change-Id: I282bd506cf2dcd998a0ddd7deaad244fab34a8db
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2023-12-22 06:35:09 +01:00
Alexandru Croitor
2b1f233863 CMake: Mostly unify includes into a single location
Make the QtBuildRepoHelpers and QtBuildRepoExamplesHelpers files
that were previously loaded as part of BuildInternals package instead
be loaded when qt_internal_include_all_helpers is called.

Load all the helpers as soon as find_package(QtBuildInternals) is
called rather than when qt_build_repo() is called.

This is a behavior change, but because including the Qt's Helpers
should have no side-effects aside from defining functions,
it should be fine.

This lets us have a unified location where to include Helpers files,
instead of thinking whether it needs to be done in QtBuildInternals or
in QtBuildHelpers or some other place.

Move also some additional inclusions into the same function.

Note that including some upstream CMake files like CMakeFindBinUtils
does have side-effects, but we've been doing it already anyway,
so moving it to the top should not make a difference because any
modifications we would do to the globally assigned variables would
have come later when we actually called our own functions.

Task-number: QTBUG-86035
Change-Id: I33f36f7e8db69d504c34a4d4a094b98f6fa50ee4
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2023-11-27 19:53:42 +01:00
Alexandru Croitor
b8f9252507 CMake: Move qt_internal_read_repo_dependencies into QtBuildRepoHelpers
Previously qt_internal_read_repo_dependencies had to be defined
before QtBuildInternalsExtra.cmake was included because the file
called the function.

Instead of calling the function in QtBuildInternalsExtra.cmake, just
call it later after the Helpers have been loaded. We can do this
because the function is always called unconditionally, so no point in
doing it in the generated file.
This lets us move the function into the QtBuildRepoHelpers.

Amends 98e8180e56322ce065e39cc1ef1d65b54caa8c25
Amends a804ac3d881fb036619f323f64e778a9e00b181d

Task-number: QTBUG-86035
Change-Id: Idffed8f2eb9d728c779b77b31eba0d24d85752ea
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2023-11-27 19:53:42 +01:00
Alexandru Croitor
720b8ee673 CMake: Split and refactor QtBuildInternalsConfig.cmake
Move most of the code into two new files:
- QtBuildRepoHelpers.cmake
- QtBuildRepoExamplesHelpers.cmake

Task-number: QTBUG-86035
Change-Id: I48c4e7c64f0ffb600118172b8e69b26018f36ffb
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
2023-11-27 19:53:42 +01:00