Compare commits

..

273 Commits

Author SHA1 Message Date
Thiago Macieira
6ce164b3e0 QThread/Unix: move the pthread_key to a file-scope static
So that the pthread_key is destroyed much later than now, at QtCore
unload time instead of a bit earlier in exit(). That's important so it
runs later than the Q_DESTRUCTOR_FUNCTION for QLibraryStore
(qlibrary.cpp), which is what unloads plugins, whose unload-time
destructors may be attempting to quit() & wait() for their worker
threads.

I had to keep the destruction of the exiting thread's adopted thread
where it was: a function-local static's destructor. As noted in the
comment added by 1da7558bfd7626bcc40a214a90ae5027f32f6c7f, we need
QThreadData::cleanup() to run before the libraries start to unload
because we need to delete the event dispatcher.

Init priority 10 will place it after the QHash random seed and qsimd
initialization, on ELF systems and on Windows. On other systems (incl.
Apple ones), the order probably depends on the order of the files in the
CMakeLists.txt. I thought that would mean the destructor for thread/
would run before plugin/ but that apparently is not the case. But that's
fragile.

Amends 1da7558bfd7626bcc40a214a90ae5027f32f6c7f, which amended other
things...

Fixes: QTBUG-132697
Task-number: QTBUG-102984
Task-number: QTBUG-132381
Pick-to: 6.8
Change-Id: Id7263d6ffe7a5949cd84e35d942ad0e02df1b455
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 2f69a05bd0cd7ce63890f709ff3ed7a4f78acd70)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-12 17:40:00 +00:00
Thiago Macieira
ea6d467c05 tst_Q*Application: add tests for unusual qApp creations and exits
This commit adds one unusual creation and three more unusual exits:
* creation of the Q*Application in a thread (QTBUG-130895)
* exits using ::exit() instead of returning from main():
  * from the main thread's event loop
  * from an auxiliary thread
  * from inside an auxiliary thread's event loop

All of these exercise the moment the QAdoptedThread & QThreadData for
the main thread is destroyed, which are, respectively:
* thread exit time, running thread-specific destructors
* inside exit(), running atexit()-like callbacks (qthread_*.cpp)
* [tst_static_q*application] inside exit(), running static destructors
  (added in commit 1da7558bfd7626bcc40a214a90ae5027f32f6c7f)

Unlike the tst_static_q*application tests, the calls to ::exit() cannot
be a regular QtTest because that would cause the log output to be
incomplete. The threaded Q*Application could be a test of its own, but
since I needed to add the helper anyway, I chose to add the test there.

For the majority of the tests, the failure mode is going to be a crash
on exit.

Task-number: QTBUG-12673
Task-number: QTBUG-132429
Pick-to: 6.8
Change-Id: I1062ef500356bd97dd0cfffda4aeeda9afa138e8
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit bfbd1a281dd00c47df315c06e895bf5d53cd8764)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-12 17:40:00 +00:00
Christian Ehrlicher
2bb83f6b16 QIcon: don't search for high-res svg icons
There is no need to search for high-res svg icons - a svg scalable by
design. Also the QSvgIconEngine does not support it.

Pick-to: 6.8
Change-Id: Ib76c887900ce77268e9c0253cb697b8de9e7f10e
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit c64774eef72411029f7c2fb611328f25b83ff8ca)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-12 09:05:44 +00:00
Tor Arne Vestbø
197a46313d coin: Ignore exit code of LastTest.log copy if COIN_CTEST_IGNORE_EXIT_CODE
If COIN_CTEST_IGNORE_EXIT_CODE is in effect and ctest aborts for some
reason (for example due to the workitem being cancelled) the ctest exit
code will be ignored, as expected, but we will not have a LastTest.log
to copy, which will fail the workitem unexpectedly.

We now match the ignoreExitCode of the LastTest.log copy with the ctest
run.

Change-Id: I9df0f863a42dd4cf25cee1694e85cb32058a4e5b
Reviewed-by: Toni Saario <toni.saario@qt.io>
(cherry picked from commit 0e2067334d58787464a3554730042dba37413c6d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-11 14:02:54 +00:00
Marc Mutz
58221c1955 QTemporaryFile: fix incorrect info about duplicate placeholders
The docs said only the first placeholder would be considered; in fact,
it considers only the last.

Fix the docs and add a test (also for QTemporaryDir).

Amends b4bb4449aea7592afdb9b9134bb90c40fe29735a.

While 6.6 and earlier are unaffected by the incorrect documentation,
pick this to all active branches in order to verify the behavior is
the same everywhere.

Pick-to: 6.8 6.5 6.2 5.15
Fixes: QTBUG-132597
Change-Id: Ia7a37f714f834191b07420d31ca9024702b537cc
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit e7abbc7bf3ab06359b2847b1e1a46c38d8bc6581)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-11 08:48:30 +00:00
Alexandru Croitor
0cb2413219 CMake: Fix sbom git vars not being available in various scopes
Initially the git vars were assigned to the parent scope of the
_qt_internal_sbom_begin_project function, with the intent to set them
in the global scope. But the function was later wrapped in other
functions, so the variables stopped being accessible.

Instead of playing with recursive PARENT_SCOPEs, save the variables in
global properties like we do for other info, and use a new
_qt_internal_sbom_get_git_version_vars() function to query the vars in
the code that needs them.

This fixes generated purls to contain the git version and hashes.

Also add a new internal API wrapper macro called
qt_internal_sbom_get_git_version_vars to allow calling it
in other repos.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I061b34f418c1ecc1c66c8c01ef758d2f40611ede
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 41a92bf6f1486259ef25db775520cba647e1cc15)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-11 08:48:30 +00:00
Alexandru Croitor
65b1756d01 CMake: Split SBOM implementation into separate files
The SBOM implementation got somewhat large. Split the code into
several new QtPublicSbomFooHelpers.cmake files, to make it more
manageable.

No code or behavior was changed.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: Ia0ca1792eec21d12c4bb4cabe63279e1f5c07e3d
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 27d2b54b5d2bc5a69edc2de703b2ca34cb2637dc)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-11 08:48:29 +00:00
Christian Ehrlicher
3536eb32bf QStandardItem: correctly set model during insertRows()
When calling insertRows(), the model of the child items was not
correctly updated. insertRow() is behaving correctly.

Pick-to: 6.8
Fixes: QTBUG-131372
Change-Id: I8b6aef7ab97887c6eb46eb21b992d76e4d59b3a0
Reviewed-by: David Faure <david.faure@kdab.com>
(cherry picked from commit 5bab8448feb2661f871e71d71a95afaffcb1656a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-11 08:48:29 +00:00
Marc Mutz
3660ff9ff8 tst_QSaveFile: QVERIFY the commit() return value in symlink() test
It's kinda is important to verify that commit() worked; all the
follow-up tests assume it, so wrap the calls in QVERIFY().

Amends 7e5e7eeaa1418d959906cdf9d717c984c9fc7a7e.

Pick-to: 6.8 6.5 5.15
Change-Id: I01185d65a5ec06ed122e59c43d9cdcc3a7157259
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 97fe38ff0d1e60f92c0bfa6fb3571a0433e60352)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-11 00:04:16 +00:00
Marc Mutz
b2dad9724d tst_QSaveFile: mark a QString const
To ensure we don't overwrite it in this quite long function.

Amends 7e5e7eeaa1418d959906cdf9d717c984c9fc7a7e.

Pick-to: 6.8 6.5 5.15
Change-Id: Ie5f81b50d2d66ba9e064810f8cbc1a7af298cc2b
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 67a906b5564a1ccf03e547aa78fc6fd910d9cd15)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-11 00:04:09 +00:00
Marc Mutz
ab9021e2d6 QSaveFile: mention that you need to setFileName() before open()
... in the descriptiong of the (QObject*) ctor.

Pick-to: 6.8 6.5 5.15
Change-Id: I1b8a788eff1fbb50134b51de7d9ee8f7cb2af785
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 6397dac97962e40104e6a94bc147e093af8186e2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-11 00:04:03 +00:00
Alexandru Croitor
3ee0cb32e0 CMake: Fix LINK_LIBRARIES not being properly processed for SBOM
There was a typo in the link_libraries variable name, where an upper
case 'L' was used instead of a lower case 'l'.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: I206a161107cf7510856ad8740dada88e12341e94
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 2affe46b2543f7d2de1939e049a0d783b5a7dcfb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-10 17:30:19 +00:00
Alexandru Croitor
7d0b4be42d CMake: Fix purl variant list iteration
The correct syntax is IN LISTS, not IN_LIST.

Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: Ibf64e48ffcf0b061887b7b015096d588b14bce57
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 4c5d9a3ca339f36f10922f9b1d5849fca1f2bdc4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-10 17:30:19 +00:00
Tor Arne Vestbø
b07580da56 macOS: Completely disable lldb backtraces in QtTestLib on Apple Silicon
They result in lldb hanging, which was previously only a case when SIP
was enabled, but can now be reproduced on macOS 15 even with SIP disabled.

 https://github.com/llvm/llvm-project/issues/53254

Pick-to: 6.8
Change-Id: Ifa09f8cf22522b5a1028db1f250ebe9e1543cf9d
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit 50d5914f28b535790f8eca6210adad24fe76940b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-10 14:49:26 +00:00
Tor Arne Vestbø
b04935ed9f macOS: Enable crash reporting for tests via Swift
Swift 5.9 includes built in crash reporting, printing stack traces,
libraries, and registers to stdout/err.

https://www.swift.org/blog/swift-5.9-backtraces/

As (Core)Foundation is written in Swift nowadays, we get this feature
for free even in our "C++" apps, as we always link to CoreFoundation.

To enable the feature the binary needs the com.apple.security.get-task-allow
entitlement, so we add it for all our tests automatically.

The final piece is to run the tests with SWIFT_BACKTRACE=enable=yes,
but we'll do this in our CI provisioning, as setting it from within
testlib doesn't seem to work.

Pick-to: 6.8
Change-Id: I31090efee06460f45522093e17f900e76590b282
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
(cherry picked from commit 9bebdc97f161cc58461530fa0171e0defc6cc1ee)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-10 14:49:24 +00:00
Ivan Solovev
0db648ba3b QMetaEnum::valueToKeys: fix REMOVED_SINCE version
Should be 6.9. The entries in removed_api.cpp are already added to the
correct place, just the macro in the public header used wrong version.

Amends d41b87e06742b491c4e36aeae32e03f85b078d69.

Change-Id: I88749dbeb070206c42feb4ffc504f260f8857823
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit da799c20d763b5534152dca52fef12fda875acc2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-10 14:17:26 +00:00
Ivan Solovev
5e84f22a0a [docs] Fix a typo in the QColorSpace class name
That prevented qdoc from generating the docs for the fromPrimaries()
function.

Amends bde2292247bf4849852355c0dcc71f97c9daace9.

Found in Qt 6.9 API review.

Change-Id: I2f5c57a4dc4a437798907c64fb657c9fda61e0df
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit e2756158dcf87fea757475d711ac9cda20f42152)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-10 10:47:34 +00:00
Christian Ehrlicher
c74f0ccf15 QTreeView: fix Private::intersectedRect()
Don't try to update the left and right boundaries when no valid idxRect
was found.
Also fix the early exit check - we can exit when the idxRect is
completely below *or* completely above the current viewport.

This amends 2f9c72028d2481f587f378a256654d0a362e3d44.

Pick-to: 6.8
Fixes: QTBUG-132670
Task-number: QTBUG-124173
Change-Id: I51f9e12c66268318e597facfbe4df74367d1089a
Reviewed-by: David Faure <david.faure@kdab.com>
(cherry picked from commit 9d4b5fa017199627a42477a842a4e1ef349bb1ae)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 23:20:17 +00:00
Alexandru Croitor
2220e447ca CMake: Fix file path in checksum computation to allow spaces
Pick-to: 6.8
Task-number: QTBUG-122899
Change-Id: Ica5f830e6d7ca9d8acbc13ebec543ee3cf96b3fe
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 242e29332373d91e1ffff344e1733bd38094606e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 18:34:47 +00:00
Alexandru Croitor
fafb4f11ef CMake: Use the $<VERSION> placeholder in qt_attribution.json
For all CPE and PURL fields where it makes sense, to avoid
duplication.

Pick-to: 6.8
Task-number: QTBUG-132181
Change-Id: Icd1c5267e4e9b582eea28150ebd1b2cca3852229
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit 82dc92cb1b94de12761f23ad6ec27feb2aca43cd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 18:34:41 +00:00
Alexandru Croitor
21815ae5e5 CMake: Replace placeholders in CPE and PURL strings in SBOMs
Replace instances of $<VERSION> in CPE and PURL strings read from
qt_attribution.json files with the version of the package being
processed.

This avoids duplicating the version in qt_attribution.json files in 3
different fields Version, CPE, and PURL.

Pick-to: 6.8
Task-number: QTBUG-132181
Change-Id: I91af17c82dbb936739f4811bf86043e00ee49a78
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit bc3bbb51b7b48d3c4a44a432441938863582242c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 18:34:34 +00:00
Alexandru Croitor
a32359a101 CMake: Add internal functions to get various kinds of spdx ids
These can be useful when adding custom relationships to the generated
SBOM document.

Sample usages could be:

qt_internal_sbom_get_target_spdx_id(Svg svg_spdx_id)
qt_internal_sbom_get_project_spdx_id(project_spdx_id)
qt_internal_sbom_get_external_document_ref_spdx_id(
    "qt5compat" document_ref_spdx_id)

Pick-to: 6.8
Task-number: QTBUG-122899
Task-number: QTBUG-129901
Task-number: QTBUG-131377
Change-Id: Idbd5c8bffece50871f995805b619226e32957866
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit 97ac4053137c7d0ff5ec71de22cf8c0c7af7006a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 18:34:28 +00:00
Alexandru Croitor
97775f43a1 CMake: Add way to convert JSON SPDX to tag/value SPDX document
Add a new qt_internal_sbom_generate_tag_value_spdx_document function
that takes an input SPDX JSON file and generates a tag/value SPDX
file. This is needed by WebEngine to convert the Chromium JSON file to
a tag/value SPDX file so we can reference it as an external document.

To ensure the external document is found, we now always add the
current sbom build directories as install prefixes. This was
previously done only for top-level builds.

To ensure the converted external document is referenced only after it
is converted, it needs to be converted before any targets mention
packages from within it.

A sample usage might be:

qt_internal_sbom_generate_tag_value_spdx_document(
    OPERATION_ID qt5compat
    INPUT_JSON_FILE_PATH "${external_sbom_file_path}"
    OUT_VAR_OUTPUT_FILE_NAME external_output_file_name
    OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH external_output_file_path
)

Pick-to: 6.8
Task-number: QTBUG-122899
Task-number: QTBUG-129901
Task-number: QTBUG-131377
Change-Id: I5d5397f788c8c7960b6fc233c2868244e5816e0b
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit b8f5e5f554c0c8b340b532b998fed5ef2a87eefd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 18:34:21 +00:00
Alexandru Croitor
5a878ca693 CMake: Allow adding custom SBOM relationships to targets and projects
Add a new SBOM_RELATIONSHIPS option to qt_internal_extend_target and
friends that allows adding custom relationships to the current target.

Add a new function qt_internal_sbom_add_project_relationship that
allows adding custom relationships to the current project SBOM
document.

A sample usage might be:

qt_internal_sbom_get_project_spdx_id(project_spdx_id)
qt_internal_sbom_get_target_spdx_id(Svg svg_spdx_id)

qt_internal_extend_target(Svg
    SBOM_RELATIONSHIPS
        "${svg_spdx_id} DESCENDANT_OF ${project_spdx_id}"
)

qt_internal_sbom_add_project_relationship(
    RELATIONSHIPS
        "${svg_spdx_id} CONTAINS NOASSERTION"
        "${svg_spdx_id} DESCRIBES NOASSERTION"
        "${project_spdx_id} DESCRIBES NOASSERTION"
)

Pick-to: 6.8
Task-number: QTBUG-122899
Task-number: QTBUG-129901
Task-number: QTBUG-131377
Change-Id: Ie0119ca71b047c7515e1deaf84a5a67ea01b5274
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit d079fdd76cf3f44181c6099b845ba9b41892740e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 18:34:15 +00:00
Alexandru Croitor
a33ce2a2ca CMake: Fix project spdx id used in implicit relationships
We shouldn't be using the direct project name in spdx relationships,
but rather the sanitized name which is prefixed with
'SPDXRef-Package-', to ensure sbom validation succeeds.

Also we should default PROJECT_FOR_SPDX_ID to
"Package-${arg_PROJECT}" if it's not set.

Pick-to: 6.8
Task-number: QTBUG-122899
Task-number: QTBUG-129901
Task-number: QTBUG-131377
Change-Id: I354babcf4fea5f6efd9b32422dd8d3835ef50f15
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit f086e72b7e6332412a7c87bc435398a0e3dee305)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 18:34:08 +00:00
Alexandru Croitor
31237ffd5f CMake: Add API to allow referencing external packages in the SPDX SBOM
This change modifies the existing implementation of the
external references API to have better named options and better
behavior.
It also adds comments and exposes an internal API wrapper around the
existing implementation.
It's meant to be used by qtwebengine to reference the
Chromium-generated SBOM.

As a drive-by, it removes the previously unused RENAME option.

A sample usage could be:

qt_internal_sbom_get_external_document_ref_spdx_id(
    "qt5compat" document_ref_spdx_id)
qt_internal_sbom_add_external_reference(
    EXTERNAL_DOCUMENT_FILE_PATH "/path/to/qt5compat-6.8.1.spdx.json"
    EXTERNAL_DOCUMENT_SPDX_ID "${document_ref_spdx_id}"
)

Pick-to: 6.8
Task-number: QTBUG-122899
Task-number: QTBUG-129901
Task-number: QTBUG-131377
Change-Id: I13d0fe4d803449bec42f8b454c8131e4d727669a
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Moss Heim <moss.heim@qt.io>
(cherry picked from commit 9a3998692c10964a919942147d8d8035e878b167)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 18:34:01 +00:00
Alexandru Croitor
419979e0dc CMake: Add API to include custom cmake files during SBOM generation
Allow including custom cmake files at predefined steps of the sbom
generation using the new internal
qt_internal_sbom_add_cmake_include_step API.

This covers pre-existing steps like BEGIN, END, POST_GENERATION, and
VERIFY, as well as two new steps, BEFORE_CHECKSUM and AFTER_CHECKSUM.

A sample usage of the new API could be:

set(step_path "${CMAKE_CURRENT_BINARY_DIR}/run_some_cmake.cmake")
file(WRITE "${step_path}"
    "
    # This is a CMake script to run some CMake code.
    message(STATUS \"Running some CMake code...\")
    message(STATUS \"Done running some CMake code.\")
    "
)

foreach(step IN ITEMS BEGIN END BEFORE_CHECKSUM
                      AFTER_CHECKSUM POST_GENERATION VERIFY)
    qt_internal_sbom_add_cmake_include_step(
        STEP "${step}"
        INCLUDE_PATH "${step_path}"
    )
endforeach()

Pick-to: 6.8
Task-number: QTBUG-122899
Task-number: QTBUG-129901
Task-number: QTBUG-131377
Change-Id: I6f9512bf3a3bc3ebeb7d21426e5a3833280e42a5
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit 8c754dcbb139ba83f033b3b3fc1d9edb8a909811)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 18:33:55 +00:00
Alexandru Croitor
6ed0b578a8 CMake: Add SBOM support for translations, custom files and friends
This change introduces a new SBOM API to add info about various kinds
of files to a target SBOM package. The new function name is called
qt_internal_sbom_add_files().

The motivating case is including SBOM information for qt translation
files, resources (e.g. webengine data files) and any other kind of
custom files.

A sample call might look like:

qt_internal_sbom_add_files(Translations
    FILES "${qm_files}"
    SOURCE_FILES_ONE_PER_INPUT_FILE "${ts_files}"
    FILE_TYPE "QT_TRANSLATION"
    INSTALL_PATH "${INSTALL_TRANSLATIONSDIR}"
)

While the motivating case is Qt-specific, the function implementation
is being somewhat future proofed for the not-yet created public SBOM
API.

The new API supports adding files to any target that is backed by an
SBOM package, so all targets created by qt_internal_add_module()
and friends, as well as ones created by qt_internal_add_sbom().

It can be called multiple times for the same target, with a different
set of files, to e.g. assign a different license, or file type per
file set. Note that the file set doesn't have anything to do with
CMake's concept of file sets.
The function is also multi-config aware, and allows specifying
different install paths per config, as well as generator expressions
in file names. But the multi-config support is a bit wonky, and might
need some rethinking in the future.

Note that the custom files must be installed and available in the
specified qt install path, because the file contents will be
checksummed at install time and embedded into the sbom document.
Calling the new API does not do installation itself.

Implementation wise, the function call flow is
- project calls qt_internal_sbom_add_files() one or more times
- at finalization time, the _qt_internal_sbom_add_target finalizer is
  called for a target, which then calls
  _qt_internal_sbom_handle_target_custom_files()
- the latter calls _qt_internal_sbom_handle_target_custom_file_set()
  for each file set that was added to the target
- the latter calls _qt_internal_sbom_handle_multi_config_custom_file()
  for each input file in the file set, which ultimately calls
  _qt_internal_sbom_add_custom_file()

Pick-to: 6.8
Task-number: QTBUG-122899
Task-number: QTBUG-128320
Change-Id: Iafde26ebd68f4168b49e55fbc8ad1c251e98d4b0
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit b085fe6ad9eee69791bc3c15bfeb7cc41245519a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 18:33:48 +00:00
Alexandru Croitor
04c3e5e5a7 CMake: Remove SBOM multi-config dead code
These variables were not used anywhere.

Pick-to: 6.8
Task-number: QTBUG-128893
Task-number: QTBUG-122899
Change-Id: If53b3fd8200971dcfde69cefa4df07b67d5669c5
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 42a58d661947cbbe8c1c5f26cea2d92e25a54f46)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 18:33:41 +00:00
Alexandru Croitor
6e74281ba3 CMake: Move SBOM project ops setup to run at project begin time
Previously Python and other sbom tooling was looked up at SBOM
project end time.
This was fine for the use cases we had so far, but it prevents
introducing new API that wants call the spdx tools before the end of
the project. Such API will be introduced in a follow up change.

Move the python interpreter, python dependency lookup and other sbom
tooling setup to happen at project begin time.

Pick-to: 6.8
Task-number: QTBUG-122899
Task-number: QTBUG-129901
Task-number: QTBUG-131377
Change-Id: Ic8884e378c0ffd9720ede26b0c61f4122f3bb9d9
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 2fa815341c68148ff00c6d16be017f80e4032ef1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 18:33:35 +00:00
Alexey Edelev
df5c9259af Split the tool dendencies lookup to Qt and 3rd party
Tool dependencies that are added using the
qt_record_extra_package_dependency function now are considered as
the third party dependencies. This allows using two different
approaches when looking for the dependencies of Qt tools.

All dependencies that are Qt tools now go to the path invented in
035fbd068b5a3fbc18b7868ecac9a6a6a2f6602c and use the
_qt_internal_find_tool_dependencies function which is designed to
look for Qt packages and uses CONFIG signature of find_package.

To look for the non-Qt modules we should use more generic find_package
signature and _qt_internal_find_third_party_dependencies fits perfecly
for these purpose.

Note that it's known issue that the
_qt_internal_find_third_party_dependencies command also may find
"target" tools when crosscompiling, but this commmit doesn't reinvent
it. We already have various places which make the scoped "host"
dependencies lookups to ensure that "host" tools look for the "host"
dependencies in build systems like yocto.

Ammends 035fbd068b5a3fbc18b7868ecac9a6a6a2f6602c

Task-number: QTBUG-132340
Fixes: QTBUG-132622
Fixes: QTBUG-132616
Pick-to: 6.8 6.5
Change-Id: I9effba3d405ceec720a8a2a332250619cd56f598
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
(cherry picked from commit f881e06dd44c377772dd3b99793ab7552c7cd64e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 10:58:45 +00:00
Even Oscar Andersen
887601bf0e Make QWasmScreen::allWindows return all (wasm) windows
It seems that findChildren does not return every window if called
at an inconvenient time.

This causes not all windows to be returned, and later the
QWasmCompositor will not detect a valid window to compose,
and therefor goes to disabled.

Fixes: QTBUG-132414
Change-Id: I6c872071751d5a2fbdeea36fb8f4c7e9677fd7d0
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
(cherry picked from commit 5c5844cedb938c38ea595957b172c48a67c502fc)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 05:56:51 +00:00
Joerg Bornemann
83cb2ca344 CMake: Simplify Qt6FooPrivate -> Qt6Foo package dependency setup
This amends commit fbbf4ace0188b9718b6d7808021c0b887fd52d9f.

Remove the EXTRA_PACKAGE_DEPENDENCIES argument that was added in
mentioned commit, and use the qt_register_target_dependencies function
instead to add the package dependency Qt6FooPrivate -> Qt6Foo.

Task-number: QTBUG-87776
Change-Id: I08a48954576dc3c0b6fde809f90d2022201d7eb0
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 2d38af3125d18255007f7451f31e26e9c16af45a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 00:51:20 +00:00
Volker Hilsheimer
58113ca96e QFontIconEngine: implement actualSize correctly and fit pixmap to it
Some icon glyphs might not be square, and actualSize needs to return a
size that fits into, and maintains the aspect ratio of, the requested
size.

Compute the bounding rect of the text/glyph that would be rendered, and
scale it to fit into the requested size.

Use that to return a pixmap of the correct size.

As a drive-by, fix the cache-testing by comparing the
deviceIndependentSize of the stored pixmap with the size we want.

Change-Id: Ic6fd0f0e260b3e3946d032941d9b677463d5c145
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit be9682d372e0021ff112817dc146f5768ac6f28c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-09 00:51:20 +00:00
Marc Mutz
96c5792d5b QUuid: mark Version::UnixEpoch as since 6.9
... because it is.

Amends d89cef439f5c1a58aeff879a12d9a33292764b7f.

Change-Id: I82cfb386c058a0dda873022377ec91368c71e026
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 4af8a20e8e0384d3de4af6c2b47a0783ba28bbc3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 20:27:36 +00:00
Volker Hilsheimer
59420d3a0b JNI: avoid detach attempt when populating an uninitialized QString
QString::data on a non-const string will needlessly try to detach.
Avoid that by accessing the raw data pointer.

Addresses header review comment.

Change-Id: I89b4d3451cda517e5c5ca08173510b3529ce73aa
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit bf2491acc74528004af8d5f4caf50e88fcb86f89)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 20:22:08 +00:00
Volker Hilsheimer
30e7ce0fc1 JNI: add missing qxptype_traits.h include to qjniobject.h
We use qxp::is_detected_v. Addresses header review comment.

Change-Id: I57bb2bb2158d82e2cd5e6df5885cde8aedb63b4f
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit 611914421d8dae7546842aa5097000ed135117db)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 20:22:08 +00:00
Volker Hilsheimer
1ed487f1ac JNI: Simplify Traits specialization for QJniArrayMutableValueRef<T>
Just inherit from Traits<T>. Addresses header review comment.

Change-Id: If11df666a925a13e54e94b30e42316a6aa06bbc7
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit c5c3730400d0f7bb1f1b93117f8ad5c1262ed695)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 20:22:07 +00:00
Joerg Bornemann
a090ecbdd1 CMake: Don't export 3rdparty dependency find_package calls
...of private modules in public modules. This isn't necessary anymore
since the Qt6FooPrivateDependencies.cmake files contain these 3rdparty
dependencies proper.

This reverts commit dae078e521c3932c66436cbdbfaf5294a1842901.
This amends commit fbbf4ace0188b9718b6d7808021c0b887fd52d9f.

Task-number: QTBUG-87776
Change-Id: I2c425d49fe7beb790abf9a94f089d43fde8b047e
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
(cherry picked from commit e7816586b612050adf0cd872b81d04b606ec2b54)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 20:22:07 +00:00
Volker Hilsheimer
087db1d000 JNI: fix declaration of QJniArray(Mutable)Iterator postfix operators
As per the standard at [1], the second parameter has to be int, while
difference_type is jint (which is also int, so no difference in
practice, esp for the already released QJniArrayIterator).

https://eel.is/c++draft/over.oper#over.inc-1.sentence-3

Addresses API review comment.

Change-Id: Idea11f83048b9b65548ec1ac8abc2586c6e61a27
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit 291c5ec433131d43921e77f3b6565e89cc0b3420)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 20:22:07 +00:00
Ivan Solovev
b18c3ecdbd [docs] Add description of other C++20 features to the overview
Task-number: QTBUG-128837
Pick-to: 6.8
Change-Id: I07731cd75c97c16eb008a76727b2ae831c029284
Reviewed-by: Jaishree Vyas <jaishree.vyas@qt.io>
(cherry picked from commit 82f6938d8ad66468576c52da7d85a2288f78af7e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 20:22:07 +00:00
Topi Reinio
85088954de Third party code attribution: Change Id to lower case
Each 3rd party license attribution is identified by a
unique Id key, which should be all lower case and without
spaces. See QUIP-7 for more info. about the
qt_attribution.json file format:
https://contribute.qt-project.org/quips/7.

Pick-to: 6.8
Change-Id: Iaa233a0e6180945e014b9a407bbd61df591f1dea
Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io>
(cherry picked from commit 1926df8d57c2b6c600a5486b1939d96b21f7f812)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 20:22:06 +00:00
Alexandru Croitor
fa8effc7da Silence qcompare.h "zero as null pointer constant" warnings on macOS
When using qmake to build a user project on macOS, the Qt headers are
included with the -I option, rather than the -isystem option. This
means that the compiler will not silence warnings that are generated
while parsing Qt headers.

If the user project compiles their code with the
-Wzero-as-null-pointer-constant compiler option, this leads to
warnings like:

/QtCore.framework/Headers/qcompare.h:226:78:
 warning: zero as null pointer constant
     [-Wzero-as-null-pointer-constant]
  friend constexpr bool is_eq  (partial_ordering o) noexcept
  { return o == 0; }
                ^
                nullptr

Fixing qmake to use -isystem instead of -I is not trivial.
We already silence these warnings for gcc in the header file.
Do it for clang as well.

Amends bdd41f491c0f85ae0897a1c7372c5ecda62a5aab

Pick-to: 6.8
Fixes: QTBUG-132581
Change-Id: I7883248b7be548580a03333e76620ac10f57733a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 0711eb60716b53dc86cacb2fc19b72aa4ffee3d0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 17:23:58 +00:00
Ahmad Samir
69277b9ed9 tst_Q{Chrono,}Timer: fix typo in CMakelists.txt
Spotted by Thiago in code review.

Amends bd764cc1ca578759f16fbe292fbe14a243b7d263 and
9cf47946fc872ed95f1b3a766658dd5076a5d473.

Pick-to: 6.8
Change-Id: I01b04d2c80c62158917e6f190418053edc0a0fe5
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 4073a75959e00722271b8784cb8cb2ee40756ff6)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 16:57:15 +00:00
Volker Hilsheimer
103aa5afb2 JNI: replace va_arg helper with variadic template
Android 15 (at least) seems to have changed how float arguments are
passed to native functions, breaking our (conceptually correct) code for
processing the va_arg list into a list of static argument types of the
function implementation.

To fix this, we have to move away from using a va_arg function, and
register a function with statically typed arguments instead.

Use a template function that we instantiate with variadic arguments
deduced from the actual function, using a factory-helper that generates
a JNINativeMethod struct with that template instantiation as the
function pointer. Move all of that into a struct where we can also
declare the signature string as compile-time constant without cluttering
the namespace with static objects.

We can now remove the helpers that took care of type promotion in va_arg
functions, and of the tuple-construction from a va_list.

As a drive-by, don't cast function pointers to void *; it's strictly
speaking undefined behavior in C and should have generated a compiler
warning, if not a hard error [1]. We must initialize the
JNINativeMethod::fnPtr member with the address of the function pointer
instead.

[1] https://port70.net/~nsz/c/c11/n1570.html#6.3.2.3p8

Also, declare the native method as the JNICALL calling convention. That
is only defined on Windows, so makes no difference in practice, but it's
the correct thing to do anyway.

Fixes: QTBUG-132410
Pick-to: 6.8
Change-Id: I190b95fcbcd07cf99c6765fa426c3c351f91994a
Reviewed-by: Volker Krause <vkrause@kde.org>
(cherry picked from commit e91a17873ee4ae58d369b8eb70029cf895b31d03)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 03:05:46 +00:00
Christian Ehrlicher
37effa5dd3 Windows11Style: Misc cleanup for drawControl(CE_ItemViewItem)
Cleanup CE_ItemViewItem branch in drawControl():
 - use local rect instead rect, vopt->rect or option->rect for
   consistency
 - move out viewItemPosition comparisons into local booleans
 - fix coding style
 - merge two QPainter::drawLine() calls into one

Pick-to: 6.8
Task-number: QTBUG-131585
Change-Id: I7cd2f96a2a733a55d5e7fb5956c59bd043317cb2
Reviewed-by: Wladimir Leuschner <wladimir.leuschner@qt.io>
(cherry picked from commit 44edab7c84be101025dc6f9a74f87944ea3a22e9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 03:05:43 +00:00
Giuseppe D'Angelo
1426bd170b QBitmap: undeprecate the QBitmap(QSize) constructor
There is no reason why the QBitmap(int w,int h) constructor is not
deprecated, and the one taking a QSize is. Since there's no deprecation
marker in the source code, I'm assuming this is just a documentation
issue.

Amends 111115bf8862b7cd1197c2ef8a4b475c882776d4.

Change-Id: I700de1821ab23ce85e793734c7048d1b2031ce9d
Pick-to: 6.8 6.5
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 7f7605c22f0e1847612e9e283eead75a1ace409e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 03:05:41 +00:00
Volker Krause
e342a52613 Expand tst_qjniobject to cover float arguments in JNI native methods
Demonstrates the problem described in the bug report on Android
15/x86_64. QEXPECT_FAIL the relevant test cases until the next
commit fixes the problem.

Task-number: QTBUG-132410
Pick-to: 6.8
Change-Id: I065fd29282ef42ed75a2ed8177ded183c92aa6e3
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 749367da8c3309c98b3285836c2bd8abcd7274b1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 03:05:40 +00:00
Axel Spoerl
8b7bf25f7f QtGuiTest namespace: Export symbols
Export functions in the namespace explicitly, to enable usage outside
Qt.

Change-Id: I1d3ea8f043b83cc38a9c6f4ff372e7bb37f2b0cc
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 31e1a79120e1ef9b681b45b2d2c3a7dfef752b8b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 03:05:37 +00:00
Volker Hilsheimer
6a6ce2474e JNI: fix JNI warning from local reference mixup
When making an object array, we use a LocalFrame to get access to the
conversion routine, but manage the frame of local references manually in
chunks of 100 objects. If any of the conversion routines uses the
LocalFrame's implicit frame management, then we push and pop frames out
of order.

Disable the frame's implicit frame management, and only use our chunk
management.

Amends 37638c84efaf2810ad49da0b987f19287d8c4ad6.

Pick-to: 6.8
Change-Id: I93be77ffc8750bb90fd7daed8c273169b03a29e4
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit fe6222b7561faa52f12a961d7c5417e364cf0236)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 03:05:35 +00:00
Thiago Macieira
b39b3551b7 QStandardPaths: use qTokenizer
Avoids allocating memory for the array.

Change-Id: I425235b948609e5f0ffcfffd0f93375a224e5bcb
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 403a47cfd571c9954e91234084c6994901939326)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 02:49:40 +00:00
Shawn Rutledge
96fe113608 doc: Fix description of QSizeF::fromCGSize
Change-Id: I22c3c5a50d624dc1f6a46aa5f1630c08267c4925
Pick-to: 6.8 6.5 5.15
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
(cherry picked from commit 9d6614d74cda8eae886f72a688271cdcd3ddcddd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 02:49:40 +00:00
Thiago Macieira
875ccc41f4 tst_QSaveFile: add a test for attempting to overwrite a dir
This is not the same as the 'directory' test below, which tests that we
can't open() a QSaveFile on something that already is a directory. For
this one, the target file did not exist when we open()ed, but has become
a directory since then.

Change-Id: I92d13f103693d375e742fffdd74053dd1b86d81f
Reviewed-by: David Faure <david.faure@kdab.com>
(cherry picked from commit f4ff7c40588a4515504e22266d15816ca8616cba)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 02:49:40 +00:00
Thiago Macieira
765aa27aa3 QMessagePattern: "precompile" the default pattern
So we don't have to parse it on first use if it isn't set. This should
be a small performance gain for everyone who uses the default, which is
usually the majority of people.

Change-Id: I10c471715457dcfa3a1dfffd2768ce605e4f7e30
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
(cherry picked from commit e04f109456bbcb184963b8ed71944b958b35c201)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-08 02:49:39 +00:00
Mårten Nordheim
9a1edf52d4 tst_Http2: Test SETTINGS_HEADER_TABLE_SIZE handling
This somewhat duplicates some other tests, namely the QHttp2Connection
one, but tst_http2 is our only coverage of the HTTP/2 code prior to 6.8.

This change adds a test where the server sets the
SETTINGS_HEADER_TABLE_SIZE to 0, effectively disabling the dynamic
table. We, in an earlier patch, makes the HPack table error out if
a new header entry is about to be added if the table has not been
resized below a changed 'max'. So, we take advantage of that here and
set the new 'max' capacity without resizing the table, or updating
dynamic capacity causing it to fail if the client doesn't send the
expected Dynamic Table Size Update.

Task-number: QTBUG-132277
Pick-to: 6.8 6.5
Change-Id: I1ca8ca7828d5b83606e7adbcfc13c154fa1e3cab
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit f7c3acd27ff48b24f99086be206acbe7e00e3208)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 22:33:06 +00:00
Assam Boudjelthia
aae66d7518 Android: fix warnings about Class raw type usage
Using Class<?> fixes the warning.

Pick-to: 6.8
Change-Id: Ia65aa78509c41d041970631dc21c8dd72459e674
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
(cherry picked from commit f342f27a0cc6c82f9503c0002b6fd32cb3ada3c3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 22:33:06 +00:00
Jøger Hansegård
11abd87046 Implement QUniqueHandle move assignment using MOVE_AND_SWAP macro
This removes boilerplate and the extra complication of std::addressof.

Task-number: QTBUG-132507
Pick-to: 6.8
Change-Id: I07091ec0ac526975cf55361a9811fad77eb152c2
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 30ae70a110ee2460744e4fb78bae29b75effbf72)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 22:33:06 +00:00
Assam Boudjelthia
a892eb50d3 Android: add android test runner docs to the build
Amends 5735d7ac861fe99a71d8044977e5f487c401ca12.

Pick-to: 6.8
Task-number: QTBUG-84330
Change-Id: Ie78f88cf84376c08e44d887b09d116845882788b
Reviewed-by: Nicholas Bennett <nicholas.bennett@qt.io>
(cherry picked from commit 1fb369211e3e477de8531485a33241d5d99b7a21)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 22:33:06 +00:00
Assam Boudjelthia
e3feb85abc Android: pass safe area margins to relevant windows only
Instead of passing the safe area margins to all windows
or top windows, we can instead call the listener for
setOnApplyWindowInsetsListener() on specific QtWindow
and have it pass the windowId with the callback to C++.
What was missing before was that the listner was not reset
after removing the window and also, we don't need to
necessarily require a window matching the id to be found,
so that if no window is found we can assume that the callback
is not valid.

Task-number: QTBUG-131519
Change-Id: Idd411e407ac8f5992aa6684ece70329198de1bc2
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit d7860d445d462dae853358c8b956fa6b1b6a2fc7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 22:33:06 +00:00
Jøger Hansegård
bded4bd5fc Require that the handle type used with QUniqueHandle is quite noexcept
QUniqueHandle is intended for handle types or opaque pointers that are
no-throw constructible, copyable, and assignable, and has nothrow
comparison and relation operators. This patch ensures that this holds
true, and makes most of the QUniqueHandle noexcept specifiers valid.

This will make it easier to implement the comparison and relation
operators in terms of the Qt comparison framework.

Task-number: QTBUG-132507
Pick-to: 6.8
Change-Id: Id9fc3fac72a2337541e49c3b4613b8fd082796af
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 49f1877bbbb8f96d81144861558bdcc81e758a58)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 22:33:06 +00:00
Mårten Nordheim
55dc2af21d QHttp2Connection: Fix handling of MAX_HEADER_TABLE_SIZE setting
We need to, following the RFC, send a Dynamic Table Size Update using
HPack once we have acknowledged the setting as long as the new size is
smaller, or if we decide to use the new, larger size.

It's further complicated by the fact that we need to send this update on
the next 'field block' (anything with headers in it), and we may have
multiple SETTING frames come in, and we need to then acknowledge the
_smallest_ one as well as the _final_ one. This is so the decoder on the
peer's side can know that we have set the smallest size, and trimmed our
tables thusly, before going to the larger size.

This could, for example, be used to clear the table.

Task-number: QTBUG-132277
Pick-to: 6.8
Change-Id: I2b886e125f2c197bc3d42aa0b2bbd308ed2a687c
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit 57f44d6d882e09f1560f86816fac6ca8d06264fc)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 22:33:05 +00:00
Peter Kling
40608d0a37 CMake: fix absolute paths w/o suffix in pri/prl files
In the update from 6.7.2 to 6.7.3, commit `ea0f00d5d` changed how linker
flags like `ws2_32` are treated when generating pri/prl files.
Specifically, before the commit a flag like `ws2_32` was left
untouched. The above commit changed it such that such flags are
converted to `-lws2_32` (seemingly in order to better support FFmpeg,
according to the commit message). However, this change also affects
absolute paths if the file has no extension. That is, after the above
mentioned commit, an absolute path linker flag to, say, a dylib on macOS
without a suffix will result in prepending the `-l` flag. This will
result in errors during link time.

An example where this caused problems can be found in the nixpkgs PR
draft #367206 (https://github.com/NixOS/nixpkgs/pull/367206).

This adds a small check to ensure that `-l` is not prepended if the
linker flag is an absolute path without a suffix.

Change-Id: I2c7ce3aac6624e1a27c59af233e3da2c1ae7ba60
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 714ae22b84553271a2809c393dd1a5a90089cc19)
2025-01-07 18:14:42 +00:00
Tor Arne Vestbø
b5c3a3fe73 Add change-notification signal to QInputDevice::capabilities property
On some platforms the capabilities of a device can change at runtime,
and we don't want to model this as a "new device" appearing in place
of the old one.

We already made the capabilities property non-CONSTANT, but let's add
a NOTIFY as well for completeness.

I considered making the capabilities member protected, but
QXcbConnection's xi2 handling relies on modifying the caps
as part of creating the device.

Fixes: QTBUG-132281
Change-Id: Ic345475b179f4562cdd39ecf51c7d6738ad47a74
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
(cherry picked from commit d74079873bbbff8701ec9b254647624775ced27a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 13:17:09 +00:00
Marc Mutz
79bd27a82b CompactContinuation: make sure what is being deleted by runObj
A lambda creates a struct with a function-call operator. So use of
'this' in a lambda body is always a bit ambiguous (the outer object?
Or the lambda itself? even though C++ defines it unabiguously to the
former).

Use a named capture variable instead of 'this' to make it obvious what
is being deleted.

Amends 699162c6fa6121cc496338f1d8d6e1b4287f7760.

Change-Id: I48d82d788d495bac43c6adb114dfdd95a8dd0d1f
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 21811161c9109c28da70b7bb9b28df33fa9b7766)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 13:17:09 +00:00
David Faure
2a121a9506 Fix wrong value for 'noon' in tst_bench_qdatetime
12 hours corresponds to 43,200 seconds, not 43,200 milliseconds.
Amends commit 3febcd6286a3cd22db4f294e7f31a94c07c51fb0

Pick-to: 6.8 6.5
Change-Id: I2eb3abcab18cd87d51ae70b5fbaeac71a8fcd0a8
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
(cherry picked from commit 0e2656f9371f92db3bb95ee5ba52c44a91e5ce68)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 13:17:09 +00:00
Marc Mutz
1b09c46051 CompactContinuation: make type member const
Because it can be.

Helps readers understand that the type of a continuation doesn't
change once constructed.

Amends 699162c6fa6121cc496338f1d8d6e1b4287f7760.

Change-Id: I43848204cfd8584e6e55d7fbca1b22d30b391e50
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 9dadca4d4e6058299f9d50ae28fd734717d7fdc5)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 13:17:09 +00:00
Christian Ehrlicher
bf535c4c66 Windows11 style: fix drawing horizontal progressbar in rtl mode
The progressbar content calculation assumes that
subElementRect(SE_ProgressBarContents) returns a rect at 0/0 which is
not the case for progressbars in rtl mode. Fix it by moving the topLeft
edge to 0/0 and translating the painter accordingly

Pick-to: 6.8
Task-number: QTBUG-132459
Change-Id: I614589c9094b0da3c02867b45570d4dfdca61a18
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
(cherry picked from commit 314a5b972646a4f2ef9c1f49ddfd335f546336ab)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 13:17:09 +00:00
Christian Ehrlicher
5ff8c2eb00 Windows11Style: enable mouse tracking for QTableView
Mouse tracking is needed for windows 11 style since it is using
QStyle::State_MouseOver to draw the cells.

Pick-to: 6.8
Fixes: QTBUG-129242
Change-Id: Ib79ac5a8c14ac8c70365e87120f80b4e4ee4c5b9
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
(cherry picked from commit 85333b3d8cb89bf58c6c6c0db7c3db5c95b4cbfc)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 13:17:08 +00:00
Volker Hilsheimer
11b9657b08 JNI: don't access null jobject
When Java calls a native function that expects a QString with a null
String object, then we get a nullptr jstring. We must not try to convert
that to a QString.

Add the necessary checks at the call-site of the toQString helper, and
an assert to the helper itself. Add test case.

Change-Id: If5c55c702bdb3f89ac45fdf3912af2ac295f5e5c
Reviewed-by: Volker Krause <vkrause@kde.org>
(cherry picked from commit db6a9834d2b109e81cc73ef3c64d0c420237e9dc)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 13:17:08 +00:00
Thiago Macieira
6dc19b55fc QThread/Unix: revert to pthread destruction instead of thread_local
Amends 65093a84c2b94b1543fd4593bc45d491951d28d4, which changed how we
destroyed the main thread's QThreadData. This merges the call to
destroy_current_thread_data() for both types of Unix systems: those with
broken thread_local destructors and those with working ones. It turns
out that the function got called too early for us in those working
systems (see updated comment).

The clean up of the QThreadData is split into two different mechanisms:
 * for any auxiliary thread, when it exits, PThread will call back to
   destroy_current_thread_data()
 * for the thread that called ::exit(), PThread won't, but ::exit() will
   invoke set_thread_data()::TlsKey's destructor

This is different from the situation that existed prior to commit
65093a84c2b94b1543fd4593bc45d491951d28d4: first, there's no code in
qcoreapplication.cpp for this (all in qthread_unix.cpp). Second one may
call ::exit() from any thread, whether that is the thread that called
main(), the thread Qt thinks is theMainThread, or any other.

This commit moves the tst_QCoreApplication check for no extant objects
to a new test. I've chosen to add a new test instead of running a helper
binary via QProcess because we do have a couple of !QT_CONFIG(process)
platforms in the CI, and this is too important.

Credit to OSS-Fuzz for finding this, though it is not itself a fuzzying
problem (all tests of a given structure were crashing on exit).

Fixes: QTBUG-132381
Task-number: QTBUG-130895
Task-number: QTBUG-129927
Task-number: QTBUG-129846
Task-number: QTBUG-130341
Task-number: QTBUG-117996
Pick-to: 6.8
Change-Id: Ie294dce7263b4189f89ffffd9155ec71d31b89d9
Reviewed-by: Robert Löhning <robert.loehning@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 1da7558bfd7626bcc40a214a90ae5027f32f6c7f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 03:46:12 +00:00
Thiago Macieira
60eaa42a25 Revert "Add categorized logging of delete later machinery"
This reverts commit c3a2b9f35a9a12ff3c6f5f0d11844de161b47c2a.

Unfortunately, some of the log messages happen WAY too late at process
exit time, when QtCore is unloading. In particular, the worst offender
is the one in QThreadPrivate::finish(), which is called after the last
QObject in the thread that called ::exit() was getting destroyed. This
implies we have Static (De)Initialization Order Fiascos happening (the
logging recurses into qlocale.cpp and the defaultLocalePrivate global
static has already been destroyed).

I need to revert this commit in order to fix QThreadData destruction.
The functionality is welcome back in QtCore once the fixes are in, so
long as whoever does it fixes the issues we're seeing in the CI (and I
can't reproduce on my development machine). I've created QTBUG-132429 to
track the reversal and see if the functionality can be brought back in.

Task-number: QTBUG-120124
Task-number: QTBUG-132429
Pick-to: 6.8
Change-Id: Iecf8f14529c7a2bb2185fffdfd328066098826b1
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 357351b7ab8ab2eee865d2449ffcca9c9f502fd3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-07 03:46:07 +00:00
Friedemann Kleint
7f78908b44 Mime type browser example: Add translator loader code
Enable testing translations.

Task-number: QTBUG-127004
Pick-to: 6.8
Change-Id: Ie83092b4db5bcf516834cf0b5b564a67d7ab6227
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit 8778a493606c8733d72db1c09fff5e4bf1f13cc0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-06 18:08:10 +00:00
Mate Barany
9413c19cc1 Update CLDR to v46
New languages added with v46
- Kara-Kalpak
- Swampy Cree

Several new Chinese-language locales have been added, including one
using Latin script, which invalidated some prior QLocale tests, which
have been adjusted to fit.

Some obsolete time-zone identifiers are now treated as deprecated
aliases. These have lost their AnyTerritory association, implying
changes to QTimeZone tests.

Many redundant likely sub-tag rules for unspecified language have been
dropped, in favor of simpler rules.

[ChangeLog][Third-Party Code] Updated CLDR data, used by QLocale, to
v46.

Task-number: QTBUG-130877
Pick-to: 6.8
Change-Id: I92cf210422c7759dd829a7ca2f845d20e263d25b
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
(cherry picked from commit e316276b76b9c3768ca4e19a04d03308ef21fe12)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-06 17:56:36 +00:00
Mårten Nordheim
2101e91465 HPack: test and fix Dynamic Table Size Update
Expose some new API to make it easier to test too.
Will be used in follow-up patches for a http2 bugfix.

The setMaxDynamicTableSize() method no longer sets capacity or evicts
entries. This can then be used to set the new maximum size which we will
accept later when we receive a Dynamic Table Size Update.

This flow makes sense with both encoder and decoder. The decoder would
usually be set by us when we send our SETTINGS frame, and then the
Dynamic Table Size Update would be sent by the peer.
For the encoder we would set the maximum size when we receive the
SETTINGS frame, and then we must defer the actual resizing until we
can send the Dynamic Table Size Update ourselves, usually along with the
next HEADERS frame.

Pick-to: 6.8 6.5
Task-number: QTBUG-132277
Change-Id: I959f5006eb09427d130735efe136da8c04453fa2
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit be477819ac17850632bca6ce59ee2c8ef11191cd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-06 17:56:33 +00:00
Jan Moeller
a306131977 Check for valid QAccessibleInterface before invoking action
To avoid illegal access, the change ensures that the QAccessibleInterface
is non-null and valid before accessing its QAccessibleActionInterface.

The check for the validity was also added to existing code which
previously only checked for the QAccessibleInterface not being null.

Fixes: QTBUG-132059
Pick-to: 6.8
Change-Id: I69fc4f9bb052ded8f188032d324666d0c00b9c3c
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Reviewed-by: Lars Schmertmann <lars.schmertmann@governikus.de>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 279c891ddf0ad10dd86c8fc836ce385df57593c4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-06 17:44:48 +00:00
Morteza Jamshidi
59861df8ce Draw icon overlay manually instead of relying on the api
Even with SHGSI_LINKOVERLAY flag set, loaded Icon with
SHDefExtractIcon doesn't have any overlay, so we draw
it manually.

Pick-to: 6.8
Fixes: QTBUG-131843
Change-Id: Iae4c2da12104a361b9a8cf05c78adcdb698f1f82
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
(cherry picked from commit fd7bc16e9fbdc63bd22ba90d0c20b36ccffd2bae)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-06 17:44:48 +00:00
Richard Moe Gustavsen
9db6df1a56 iOS: remove registered undo/redo actions upon qiostextresponder dealloc
QIOSTextResponder add actions to its own NSUndoManager. But
we need to remove those actions again when the responder is
deallocated, otherwise it can lead to a crash in UIKit when
swiping between apps.

Fixes: QTBUG-123843
Pick-to: 6.8 6.5 6.2
Change-Id: I404751bc50692a960e568ff2eb0f1754da0cec31
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 42f29da7a5b6c6969c169e9a868696a968ca930d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-06 17:44:48 +00:00
Morteza Jamshidi
6d8afaac84 Windows: Add Key_Backtab as possible key combination for Shift+Tab
In windows Backtab key event always comes as "Shift+Backtab".
So in order for Backtab key to be recognized as a shortcut sequence,
we also consider Backtab without shift modifier a possibility.

Fixes: QTBUG-94890
Change-Id: I20a7b404b57d8df5bea23765257a178f2e098ed0
Pick-to: 6.8
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
(cherry picked from commit 4d9f99c4ea70cdae58c80e1bfdbabefe3abb455f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-06 17:09:27 +00:00
Jøger Hansegård
64c5043a40 Add missing noexcept specifiers for QUniqueHandle handle traits
Handle traits should be simple, and not require exceptions. Note that
we should not make calls to fclose() or close() noexcept, because these
are POSIX cancellation points.

Pick-to: 6.8
Change-Id: I8bbf573b1346eafd52c6080dbb024f8b3bc89359
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit a80d1bf2716b1ba404799d6a09003b145b73b079)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-06 14:03:25 +00:00
Kaloyan Chehlarski
0ce8e1db2b Fixup minimum MSVC version check when configuring Qt
The message displayed to the user says they need "at least Visual Studio
2019", but in reality the minimum is now 2022.

Amends 9a409295c7cfe74b4fb6b1892f4ff86d4f3c23f3

Pick-to: 6.8
Change-Id: Idaedd72d114b994fddd2ba7574fb7a45ca0a3e85
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit 652250295c7f9812b49c522ab2fbe518ac9690e4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-06 14:03:25 +00:00
Alexandru Croitor
0e14e9042d CMake: Handle DESTDIR for SBOM doc references in top-level builds
When installing a top-level build using the DESTDIR env var mechanism,
the SBOM generation process could not find the qtbase sbom document,
while generating the qtshadertools document.

Make sure to prepend the DESTDIR env var to the install-time install
prefix, when looking for external SBOM documents.

Pick-to: 6.8
Fixes: QTBUG-132188
Change-Id: I1cdb75842fc552b43d982f05444b5ddc1fe58595
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit f2ce68d8f31f4c90471183d66075bd6fd5955d6a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-06 14:03:25 +00:00
Ivan Solovev
7b356f0f31 QtConcurrent: fix support for callables with deduced return type
Commit 6ebe3d0f0806069f906522dfe9b81baa3f3478de introduced extra
SFINAE checks on the template conditions.
However, it broke the case of using callables with deduced return
type, because SFINAE does not work for such conditions and treated
as a hard error instead.

Fix by explicitly providing all template parameters, so that compiler
could figure a better overload on its own.

Only QtConcurrent::blockingMapped() seems to be affected, but add
unit-tests to check all other methods as well.

Fixes: QTBUG-130766
Pick-to: 6.8 6.5
Change-Id: I1ddbe712d8ce04ac96ba13841cb569d728cfb943
Reviewed-by: Tatiana Borisova <tatiana.borisova@qt.io>
(cherry picked from commit f73765682e7c8f1e0e78b7464deec57c7f2669ba)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-06 14:03:25 +00:00
Jøger Hansegård
33f37ff637 Test that reset() and move assignment handles self-assignment
Calling reset() with the owned handle should maintain ownership and not
leak resources. Move assignment should also handle self-assignment
without leaks. The new tests verifies that this holds true.

Task-number: QTBUG-132507
Pick-to: 6.8
Change-Id: Icdfa4d67b06b71a74e810593e57449b51982c98c
Reviewed-by: Tim Blechmann <tim.blechmann@qt.io>
(cherry picked from commit 03bd9491491881529ad28cd6d672edfdda9a0065)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-06 14:03:25 +00:00
Tim Blechmann
cffb015be5 gui: link with OpenGL framework
qopengl.h pulls in headers from the OpenGL framework on macos when
opengl is enabled. We should therefore also link the OpenGL framework.

fixes linker error in libqcocoa:
Undefined symbols for architecture x86_64:
  "_glGetIntegerv", referenced from:
QCocoaGLContext::updateSurfaceFormat() in
libqcocoa.a(qcocoaglcontext.mm.o)
  "_glGetString", referenced from:
QCocoaGLContext::updateSurfaceFormat() in
libqcocoa.a(qcocoaglcontext.mm.o)

Change-Id: I02d2c80e2652da0cf16eaca7ab161cf711599dc2
Pick-to: 6.8 6.5
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 6f41c1652f73e1d79d6a4a91d009671a1e285b15)
2025-01-06 11:05:34 +00:00
Jøger Hansegård
8adfacca61 Add missing noexcept specifiers for QUniqueHandle handle traits
Handle traits should be simple, and not require exceptions. This patch
will allow us to improve the noexcept correctness of QUniqueHandle.

Pick-to: 6.8
Change-Id: I84d92818a2fcea5b98e09c0b7dc08b251751396c
Reviewed-by: Tim Blechmann <tim.blechmann@qt.io>
(cherry picked from commit 3c57c7357422bdfda60f56901a7590b258915b6b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-05 16:32:11 +00:00
Juha Vuolle
ee432b6431 Rename Gui test utility's factor() to scaleFactor()
This makes it more clear which 'factor' the function is about.
The function internally calls a pre-existing 'factor()' function,
but since that is a static method of QHighDpiScaling, there the
meaning of 'factor' is more clear from the call context:
QHighDpiScaling::factor(window).

Resulted from API review.

Amends: 5ac4f04325a56d47812f528fe31ceb0d4932f664

Task-number: QTBUG-132090
Change-Id: I869bc05116d334b53b23a46aa2bb788432f250de
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit f9376703c92e957c7334a2ff42a801237f53c8bf)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-05 16:02:25 +00:00
Lars Schmertmann
850ed0222f Android: Fix freeze on start when the activity was destroyed before
This can be tested by enabling "Don't keep activities" in the developer
options. With this option Android will immediately destroy the activity
when it is moved to the background. In this case registerBackends will
be called the first time before the BackendRegister was created. Because
m_backendsRegistered was set to true even if it failed, the final call has
no effect. So we need to ensure to set m_backendsRegistered only if a
BackendRegister is available.

Fixes: QTBUG-132085
Pick-to: 6.8
Change-Id: I2ea1c0e0737c982594ceb06cbaf540399c45e3f4
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit 9903242ecab82c1ed72dcaf90e90a171c942a84a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-05 11:46:17 +00:00
Jøger Hansegård
b72c4988fb Implement QUniqueHandle::release() using std::exchange
This does not change the behavior of release() but gives more
compact code.

Task-number: QTBUG-132507
Pick-to: 6.8
Change-Id: I5b34c80409ca0e9e9a5e9aee9ef7bc80017610af
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit ec0c62385e0df00f42bc9fb5e117cb8b994cfc96)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-03 16:05:55 +00:00
Alexandru Croitor
cdc8811492 CMake: Error out when xcode / SDK version check fail in Qt 6.8+
Starting with Qt 6.8+ we should error out if the minimum sdk / Xcode
version requirements are not met.

An opt out is added for cmake build tests, otherwise all the tests
that use private cmake api will fail to configure when run on older
Xcode or SDK versions in the CI.
We do this by checking for a new QT_INTERNAL_IS_CMAKE_BUILD_TEST
variable.
We do the check inside
_qt_internal_check_apple_sdk_and_xcode_versions
instead of passing
a QT_FORCE_WARN_APPLE_SDK_AND_XCODE_CHECK variable to the test
configuration, because not all cmake build tests use private api, so
this way the list of projects that get the opt out is more
constrained.

Pick-to: 6.8
Task-number: QTBUG-119490
Change-Id: I1284616c91341848a9cf6406fbf35750707d1227
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit a13bfec63df2cf206e354ab56fc017a1f0eb8f6d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-03 16:05:51 +00:00
Jøger Hansegård
5653829bf8 Make QUniqueHandle::reset() default to invalid handle
Having a defaulted argument to QUniqueHandle::reset() gives a convenient
way of releasing ownership without assigning a new handle, and makes
the QUniqueHandle API more similar to std::unique_ptr.

Task-number: QTBUG-132507
Pick-to: 6.8
Change-Id: I842d4545d7cc2da8fe2df08280d0d816ed4be7fd
Reviewed-by: Tim Blechmann <tim.blechmann@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 248ac4128fe86150532ff7146d0459abb5260946)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-03 16:05:49 +00:00
Alexey Edelev
2378455647 Unset the temporary variables in Dependencies scripts
Unset the temporary variables to avoid littering the scope.

Pick-to: 6.8
Change-Id: Ibd6b2896113a9fcd9eae7bc202dc0dc8c7a9f9bd
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit 96bb0db5afbab2c5cc32a6b19abc74497c839f5a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-03 15:59:40 +00:00
Alexey Edelev
d83081c78e Assume that the Qt Plugin package is FOUND by default
Set the <package>_FOUND variable to TRUE by default, so the follow
logic that need to change the flag only need to take care about
setting it to FALSE if something exceptional occurred.

Amends 8d0283ad2cae3d8fbd4b1b7ee5c6454f7fcc079c

Pick-to: 6.8 6.5
Change-Id: Idd4407ea77e81703b5fa8cc5efa8c52b53d401ae
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit 13608241793f6671500868c9ce96468f604f651e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-03 15:59:38 +00:00
Alexey Edelev
b942110a4a Adopt the Qt dependencies lookup mechanism for tools dependencies
The existing lookup mechanism doesn't consider Qt path when looking for
the Qt Tool package dependencies. In good scenario this leads to the
missing Qt Tool package, in worst case scenario the Tool package could
be found by alternative search path and attempt using the invalid
tools.

Use the lookup functionality we have for Qt modules when looking for
dependencies of the Qt tools. This will look the tools in Qt search
paths first and only then attempt looking elsewhere, considering the
QT_HOST_PATH.

Pick-to: 6.8 6.5
Fixes: QTBUG-132340
Change-Id: I570c03037f2a92922d2546a4f5fde1bc17a7f812
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
(cherry picked from commit 035fbd068b5a3fbc18b7868ecac9a6a6a2f6602c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-03 15:59:34 +00:00
Alexey Edelev
ee533138d8 Use the 'call' command when generating the command scripts
cmd.exe has a huge problem when running the batch scripts locating
by paths contaning spaces and more the one set of quotes in arguments.
This can be worked around by using the 'call' command as the test
command runner.

Fixes: QTBUG-132258
Pick-to: 6.8 6.5
Change-Id: I9b6fb0f8bccf44456e4cb9b79f3c6bd3f9fe4678
Reviewed-by: Even Oscar Andersen <even.oscar.andersen@qt.io>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
(cherry picked from commit 10a3859809fc0b6e1edd6cbb93e409f0513a9bbe)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-03 15:59:31 +00:00
Marc Mutz
c35cb5fe9a QRhiWidget: mark (Private&, parent, flags) ctor explicit
Found in API-review.

Amends 8386dfee05d35057836f93d182ef96674a6fd11e.

Change-Id: I5ad063b17356f75084655f1af353ba34a5deb4bf
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit be8391e56dc76f88058b432b015711cd7bce9c35)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-03 14:16:08 +00:00
Marc Mutz
ffb442db62 qpropertytesthelper_p.h: port from QScopedPointer to std::optional
It's more efficient (doesn't need to allocate the QSignalSpies on the
heap) and makes the header fit for the upcoming QT_NO_SCOPED_POINTER.

VxWorks seems to have a problem with its std::optional implementation,
though:

   QWARN  : tst_QAbstractAnimation::stateBinding() Trying to construct an instance of an invalid type, type id: -2125884168
   QWARN  : tst_QAbstractAnimation::stateBinding() Trying to construct an instance of an invalid type, type id: -2125884172
   QWARN  : tst_QAbstractAnimation::stateBinding() Trying to construct an instance of an invalid type, type id: -2125884024
   Received signal 11 (SIGSEGV), code 2, for address 0x0000000d

So write a small optional-like wrapper around std::unique_ptr for that
platform.

Amends 930e59b798d9e3d08e17440980d33a08fb411cbe.

Pick-to: 6.8 6.5
Task-number: QTBUG-132213
Change-Id: Icf85678d616bc96c7d74b982d0b919ea3f13265a
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
(cherry picked from commit 7bd47fb70881e7240c027cd2844866c99f8f096d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-03 10:38:12 +00:00
Shawn Rutledge
5ead2a3d63 Fix QTransform::quadToQuad() to work with QRectF
A typical usage for mapping a 4-point polygon to a rectangle might be

  QTransform transform;
  bool ok = QTransform::quadToQuad(polygon, polygon->boundingRect(),
                                   transform);

It works because the QPolygonF(QRectF) ctor is implicitly called on
the second argument; but that ctor turns it into a 5-point polygon.
So it should be legal for QTransform functions to work with 5-point
closed paths.

Fixes: QTBUG-21329
Change-Id: Iae249012e14b8a3e8d3b0dfa35da8f9759359832
Pick-to: 6.8 6.5 5.15
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
(cherry picked from commit 48b1af941c50ab28cc92f9ea65a8a74a32eaf2bc)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 19:39:17 +00:00
Alexandru Croitor
ff596bfac8 Revert "CMake: Temporarily allow using any version in Qt's CI"
We updated the minimum CMake version used in CI for Qt 6.9+ to 3.22.
Enforce the minimum CMake version in CI to avoid regressions.

This reverts commit 5803af38aab09b7e47230a494e14654031d024e7.

Task-number: QTBUG-131169
Change-Id: Ifc91644dd26e465be44bfa7cfe6f99e295a174a9
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit dcd057a31b54de637a5ca8bb8a5d46e753d3066a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 19:19:27 +00:00
Aurélien Brooke
076a818f74 rhi: vulkan: fix crash when making readbacks in consecutive frames
When requesting a readback every frame, the readback activeFrameSlot
alternates between 0 and 1. Suppose we are in currentFrame 1, and
process a list of readbacks of slots [1, 0]. First, we skip the readback
of slot 0 since it does not match the currentFrame 1. The list thus
remains [1, 0]. Then, we process the readback of slot 1, and call
activeTextureReadbacks.removeLast(). This removes the readback of slot
0, while in reality we processed the readback of slot 1. The
activeTextureReadbacks is now [1], containing a readback for which we
called vmaDestroyBuffer(), leading to a crash ("double-free" attempt) in
Vulkan on the next function call.

To fix this, remove the readback that is actually processed (index i)
instead of the last one. Since we iterate backwards, indices remain
valid.

Pick-to: 6.8
Change-Id: Idd4296de45167edd0a9da345dcc1c3b6ac71a6d6
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
(cherry picked from commit 73405890b8911dd1a58120665ce63a38281c6ce4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 19:19:27 +00:00
Michał Łoś
f13ef41580 VxWorks: Enable video device discovery
Video devices should be discovered by VxWorks properly.

Pick-to: 6.8
Task-number: QTBUG-115777
Change-Id: Ib6719fc9480827aed296343e0b91286ae8408c8a
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
(cherry picked from commit fbd7c7c45af8102090cf9e606ade565e5357a220)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 19:19:27 +00:00
Marc Mutz
7aadf25ccd QThreadStorage: replace QScoped- with std::unique_ptr
This only affects the !QT_CONFIG(thread) case and requires the rewrite
of the old-style static cleanup() deleter protocol into the modern
operator()() one.

As a drive-by, mark the deleter noexcept, like destructors are
supposed to be.

Pick-to: 6.8
Task-number: QTBUG-132213
Change-Id: I8839865880647d76b77eb9a3f2858067db86234e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 6da1f72311b844b2232da3067ad6e1e24614e67c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 19:19:27 +00:00
Marc Mutz
77de3d45d3 Remove QT_NO_CAST_FROM_ASCII from QT_ENABLE_STRICT_MODE_UP_TO
QT_NO_CAST_FROM_ASCII is a policy setting, not a strictness
setting. The other components of QT_ENABLE_STRICT_MODE_UP_TO all deal
with clearly undesirable APIs, which QString(const char*) cannot be
said to be.

Keeping it in QT_ENABLE_STRICT_MODE_UP_TO would seriously impede the
use of strict mode in Qt itself (cf. QTBUG-132327).

Amends 3a6c8e02b6d1b0574da52b0087092d0c74aa92c1.

[ChangeLog][QtCore][QT_ENABLE_STRICT_MODE_UP_TO] No longer includes
QT_NO_CAST_FROM_ASCII. If you wish to continue using
QT_NO_CAST_FROM_ASCII, you need to define it in addition to
QT_ENABLE_STRICT_MODE_UP_TO. The reason for this change is that, while
everything else in strict mode should eventually become the default,
we're not proposing to remove the ability to construct a QString from
a const char*. QT_NO_CAST_FROM_BYTEARRAY and QT_NO_CAST_TO_ASCII
remain enabled in strict mode, though.

Task-number: QTBUG-132327
Pick-to: 6.8
Change-Id: I36b850833b1de79a47de975ca28d3591a0a0e089
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
(cherry picked from commit f9163ae7a8167daded0798654d99a2e3a5aaa2b5)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 15:23:07 +00:00
Ivan Solovev
90fab1e4e9 Fix QtFuture::when{All,Any}() overload resolution
Both whenAll() and whenAny() have two overloads:
* an overload taking two input iterators, e.g.
  whenAll(IntpuIt begin, InputIt end)
* an overload taking an arbitrary number of future objects, e.g.
  whenAll(Futures &&... futures)

The public APIs are properly constrained, but internally they call
QtPrivate::when*Impl() template functions, that have the same two
overloads, but do not have any constraints.

As a result, passing exactly two QFuture<T>{} objects was leading to
the compiler picking the Impl overload that takes a pair of iterators.

Fix it by applying a subset of constraints from the public API to
the private implementation as well.

Amends 102f7d31c469a546f52c930a047bd294fb198186 which was introduced
for Qt 6.3, so picking down to Qt 6.5.

Fixes: QTBUG-131959
Pick-to: 6.8 6.5
Change-Id: Ide29ac9a494d07870e92957c40c1f614e56825f8
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
(cherry picked from commit 8aef5b0d8fd57684abe39c88af8c14d8882ef07b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 13:58:28 +00:00
Ivan Solovev
73b8c83ec7 Do not duplicate JsonFormat enum
The enum already exists in QJsonDocument, so there is no reason to
introduce a new one in QJsonValue.

Instead, use the fact that we only need to forward-declare QJsonValue
in QJsonDocument's header, include the latter into qjsonvalue.h, and
use a type alias.

For Qt 7, pre-program moving of the enum into QJsonValue and using
an alias in QJsonDocument.

Amends ac73079dee5f0260528a5c217a82cb0beafb0a56.

Found in Qt 6.9 API review.

[ChangeLog][QtCore][Potentially Source-Incompatible Changes] The
QJsonDocument header no longer includes QJsonValue.
The backward-compatible fix is to include all needed headers
explicitly and to not rely on the transitive includes.

Change-Id: I7c5219a239149e4a87d4780c4277d111983ad0f4
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 3cb87d891bb040f73fb68b6c5e7e82518f603c59)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 12:07:32 +00:00
Joerg Bornemann
523f711295 CMake: Yield error if VCPKG_ROOT variable is missing
...and vcpkg usage was requested.

The user got no further feedback why vcpkg wasn't used despite passing
the -vcpkg configure argument.

Pick-to: 6.8
Change-Id: Ib43c2045f093c3887a63406e37f37bdd681341cd
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit fecae6ab1b1aa36f43b5cd87b229de4df37e44ab)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 10:25:22 +00:00
Marc Mutz
c806d2bbbc sqlbrowser example: use = default on empty dtors
Idiomatic C++11 code.

Amends 2690822428deec4f0c08f4d118d69a7c6036369e, which, however,
inherited the issue from older code.

Pick-to: 6.8
Change-Id: Iba1fb9874bd93b4a560c33e3ecf62ecaa96d8bda
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 19564e033cf65a0a67680285d1cbcc85c9437aaf)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 09:57:54 +00:00
Marc Mutz
101fedb17f sqlbrowser example: fix ugly margin around ConnectionWidget
When a layout is used to arrange the children of a non-top-level
custom widget, the layout's contentsMargins need to be manually set to
zero to avoid extra empty space around the widgets, misaligning it
w.r.t. its siblings.

Add the necessary call.

Amends 2690822428deec4f0c08f4d118d69a7c6036369e, which, however,
inherited the missing margin adjustment from older code.

Pick-to: 6.8
Change-Id: Icd1945a4f2b1635f031e50758ec2f1ec9313ae27
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 15524d1623a1400e4de15e57408e37020d394986)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 09:57:48 +00:00
Marc Mutz
cc1af8409a sqlbrowser example: use explicit / override
Examples should show idiomatic use of Qt and C++, so mark the custom
widget constructors in this example as explicit and their destructors
are override.

Amends 2690822428deec4f0c08f4d118d69a7c6036369e, which, however,
inherited the missing explicit from older code.

Pick-to: 6.8
Change-Id: I5b5b49f69330c6f139345bed7264c85a36c36e9b
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit e0e9a5627376e04aba1b2ca2591554851d7de240)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 09:57:42 +00:00
Marc Mutz
88600c3096 sqlbrowser example: use unique_ptr to hold m_ui
The old code used manual memory mangement (raw new/delete) to
(de)allocate the Ui struct. This is so 80s.

Use an owning smart pointer to manage the memory. Ordinarily, this
would have been QScopedPointer, but seeing as that doesn't have a
create() method to hide the raw new, use std::unique_ptr and
std::make_unique() instead.

Amends 2690822428deec4f0c08f4d118d69a7c6036369e.

Pick-to: 6.8
Change-Id: Icabb9154eb38630855e14094b958af0214516f6b
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 0da2c2c4ef2219967db87021eece2a60b6e207af)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 09:57:35 +00:00
Marc Mutz
02f05bdb5f sqlbrowser example: use idiomatic Qt [3/3]: use form-layout
The old code used a grid layout inside the QGroupBox, but the design
with labels in the first and edit-widgets in the second column lends
itself to a QFormLayout, which adapts the alignment of the widgets to
the platform style, so use that.

Amends 2690822428deec4f0c08f4d118d69a7c6036369e, which, however,
inherited all of the above from even older code.

Pick-to: 6.8
Change-Id: I528f0ce9d8cb7a997fbfabcdca887c059f571b38
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 9c099ef942216d01261c26b60e3727a2a467f12a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 09:57:29 +00:00
Marc Mutz
8dbd0828e9 sqlbrowser example: use idiomatic Qt [2/3]: use button-box / override accept()
- The old code used two QPushButtons in a QHBoxLayout to provide
  Ok/Cancel buttons. This hard-codes the positions and text (and
  icons) of these buttons, instead of adapting to the platform style.

  The new code simply uses QDialogButtonBox, which is designed for
  this purpose.

- Also, the old code connected the Ok button's clicked() signal to a
  custom slot that then called QDialog::accept(). This means that the
  code in the custom slot is not executed when the dialog is accepted
  by other means (e.g. return press in one of the line edits
  ("auto-default"), though I'm not sure here).

  The new code uses the idiomatic Qt way of overriding
  QDialog::accept() instead, and connects the button-box's accepted()
  signal to it. This is done in the .ui file, so it already works in
  Designer preview.

- Finally, the old code made a manual connection from the Cancel
  button to QDialog::reject().

  The new code uses the Qt idiom of connecting in the .ui file
  directly, using QDialogButtonBox::rejected() as the signal.

Amends 2690822428deec4f0c08f4d118d69a7c6036369e, which, however,
inherited all of the above from even older code.

Pick-to: 6.8
Change-Id: I83afd6156a0811e0c0f99f2480625ea6b69ff78b
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 3419c299369ac1da94ba5710aaf5f5f65c38c33c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 09:57:23 +00:00
Marc Mutz
f2b88b3225 sqlbrowser example: use idiomatic Qt [1/3]: disabling group-box
The old code connected to the wrong signal and therefore had to write
a custom slot to perform the disabling of the group-box.

The new code simply connects the QCheckBox::toggled(bool) signal to
the directly-compatible QWidget::setDisabled(bool) slot, removing the
need for a custom slot.

Also move the connection into the .ui file, so it works already when
checking the form in QtDesigner.

Amends 2690822428deec4f0c08f4d118d69a7c6036369e, which, however, only
inherited the issues from older code.

Pick-to: 6.8
Change-Id: Ia834f92de270bb7b18981273188f6e5b6cd457a2
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 53826d1cde26f825d1983476c6697f72130e351f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-02 09:57:17 +00:00
Thiago Macieira
381dca29ff Replace qgetenv() calls converted to QString with qEnvironmentVariable()
It's slightly more efficient.

Change-Id: Id5ac04fc27eee108c8e5fffd786c3d5f793a0a9d
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
(cherry picked from commit db34e27f7f6ade54bfae59e5eed14c05ac508a49)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-01 19:55:21 +00:00
Thiago Macieira
36d260014f qEnvironmentVariable: avoid a temporary QByteArray
Because we don't need one. I guess I was just lazy.

Amends b12fd1fa9d0b64e3cb66fa68c85392dbde8e175b ("Long live
qEnvironmentVariable()").

Pick-to: 6.8
Change-Id: I5b9141c5a32f9d784e0bfffdc3e4d742790aebdd
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit ce95c26034cc5b3ae8094c1521221e5b2f13ecfa)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-01-01 16:46:29 +00:00
Ahmad Samir
01edc916d2 moc: fix GCC -Wextra-semi colon after member function definitions
As pointed out by Thiago the QT_DECLARE_METATYPE calls are redundant, so
remove them.

Task-number: QTBUG-132101
Pick-to: 6.8
Change-Id: I73800e70d3f270fb87941d4e053aa7ac5ed1841c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 3bb4c4949fed9ccf8653151c78d5130b8db00716)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-31 23:59:24 +00:00
Ahmad Samir
5171b7f488 src/plugins/*: fix GCC -Wextra-semi colon after member func definition
Pick-to: 6.8
Task-number: QTBUG-132101
Change-Id: I947fdb66df9b6d86c60139046166395e4ae42127
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 997abb0520cdfbde60e0fe4fdb133e15e24ce871)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-31 23:09:12 +00:00
Ahmad Samir
cc369ad07f QCryptographicHash: hashInto(): check the buffer size earlier
We can use hashLengthInternal() to check if the buffer is big enough.
This matches what the QCH::hash() method does, it also has an assert
that `result.size() == ba.size()`, so we can assume this works with
OpenSSL's EVP_MD_get_size() in EVP::finalizeUnchecked().

Amends c70c81b371993ca865d523bb5f37eac4eb8a972b.

Pick-to: 6.8
Change-Id: I64935f3d590ab243b361a0b764f011c388820e32
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit b83e825fab16f83f86149ead78efb6ec3d2fa16d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-31 23:09:11 +00:00
Marc Mutz
11f485ea68 tst_QImage: fix discarded QFile::open() results
Wrap them in QVERIFY(), as usual.

Found by QFile::open()-turned-nodiscard-come-6.10.

Amends e673e5a257569eaa816c6acd31dd754efd9f8c75 and
25c96d547b4563cbfedcec6093d68116148d8599.

Pick-to: 6.8
Change-Id: Id39e5d9e500b524af8443cb57916a12f98bd7c23
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit cf6ae9a90106a3557a8df1e0d2567b02a4ef6ded)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-31 19:03:28 +00:00
Marc Mutz
c970909437 tst_Q(Gui)EventLoop: Unbreak UBSan build
The tests peek into QEventLoopPrivate, which means that a UBSan build
needs access to QEventLoopPrivate's type_info, for which we need to
export the class.

Amends 3af20bd8eb8c75017c5d6d138d7c42914ee5bee3, which fixed the weak
vtable that, presumably, made this test work before.

Pick-to: 6.8
Change-Id: I4104ba95093fa240c5ef7d9d5bf287c1652333f0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit 8bf54385319df958ea88f9998e7690d4c35e354d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-31 10:13:04 +00:00
Marc Mutz
5cd16659ff Port QtCore from QScoped- to std::unique_ptr [1/2]: private uses
This patch series is in preparation of enabling QT_NO_SCOPED_POINTER
when building QtCore, a prerequisite for enabling this opt-out in leaf
modules.

This first part of the patch series ports objects whose use cannot
"leak" into other modules, e.g. because they are in .cpp files or are
private members and is thus SC (and, as demonstrated by various static
assertions we put into the source code over the years, BC).

The second patch will deal with objects in protected and public APIs,
and thus might be QUIP-6 SiC Type A.

Task-number: QTBUG-132213
Change-Id: If4967f6e563a4e7d74550fad4c6d354fad1beef5
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
(cherry picked from commit 63f1c6fcbab5f36809ffc96ac5ff6cb9e01e70bb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-31 10:12:58 +00:00
Marc Mutz
3ea877a844 QLibraryInfo: de-pessimize prefixFromAppDirHelper()
The local appDir variable was only used to hold the return value of
another function call. But hardly any compiler will be able to look
through the QString atomic ref-counting to turn the non-Darwin code
paths into the tail-calls that they ought to be.

Remove the variable and return the result immediately. This removes
the move-assignment and dtor calls in the two changed lines and lets
RVO kick in, turning these calls into tail-calls on non-Darwin
platforms.

Amends 4ac872639ed0dd3ae6627e05bdda821f7d128500.

Pick-to: 6.8 6.5
Change-Id: Ieeefbd52fc983ab7aebcff6419965b206f374935
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
(cherry picked from commit e57113feac183abd1f5bfcfb633a33e1387b2d3e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-31 10:12:56 +00:00
Toni Saario
60a264ed50 Coin: Tweak VxWorks testrunner
Add crash handling to avoid waiting until 10min timeout on each crash.
Force restart on each crash by killing emulator.

Make health check more robust to allow it to work even when emulator is
down. This is done via wait in separate process which cannot be done
with normal timeout command, as input to pipe that is not being read
by emulator will block forever.

Change-Id: I86c3c86f936cc96d57b38983da48d1d73162399d
Reviewed-by: Simo Fält <simo.falt@qt.io>
(cherry picked from commit 918cbe7601b07fa6db7973ff9a4f76208dae8f22)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-30 11:31:47 +00:00
Samuli Piippo
884c338355 egldevice: allow DRM device path to be overridden
The backend-provided DRM device might not be the right one,
so allow kms config to override it.

Pick-to: 6.8
Task-number: QTBUG-131887
Change-Id: Ied744ae7015eae64f4556f1528e0dbe8ae69d206
Reviewed-by: Pasi Petäjäjärvi <pasi.petajajarvi@qt.io>
(cherry picked from commit c3bbbb22b8bc920e4937cf640fd1d2df3b0f9205)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-30 11:31:47 +00:00
Friedemann Kleint
b06125aa51 uic: Generate fully qualified enumerations for QFormLayout
This is required for Python.

Task-number: PYSIDE-1735
Change-Id: I92108009dd23565adaa2ee77300059cb197a89c5
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
(cherry picked from commit 11d6200d8ad88459a499550b30f5c22f1657719b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-30 04:04:22 +00:00
Ahmad Samir
bbf78c9636 tst_QCryptographicHash: split 4GiB tests to a separate unit test
With those tests split, tst_QCryptographicHash takes about 4ms.
When FEATURE_openssl_hash is enabled those tests take about 15s on
their own, but when openssl_hash is disabled they take about 2 minutes.
That makes running the tests locally a bit of a hassle when hacking
code ... test ... hack ... test.

This is with a debug build, GCC, `-O0 -g` flags.

Change-Id: I8b8f5d1954feb1f9eb8115e27635610a41b42f47
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit fff217824b532da7306af1ac755581e76e098a27)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-29 23:22:56 +00:00
Christian Ehrlicher
6790d8d716 QCommandLinkButton: fix drawing high-dpi icons
QCommandLinkButton was using QIcon::pixmap() without specifying the
current device pixel ratio. Switch to QIcon::paint() to not have to
fiddle around with the dpr at all here.
As a drive-by remove a useless QPainter::save/restore call.

Pick-to: 6.8
Change-Id: I7e2492a09b28cb8a4f4cc60454733e0054fe1e9b
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 785fb89e0aafc25a435d28ff05bf0dc05385b372)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-29 19:35:04 +00:00
Thiago Macieira
d39c493390 3rdparty: patch BLAKE2 sources to not export anything in static builds
This could cause conflicts with other users of these algorithms, notably
libb2 itself. Though if you're using libb2, you shouldn't be using the
un-optimized copy inside QtCore...

I've updated the SHA1 of the last commit in the repository, but there
were no changes to our sources.

[ChangeLog][Third-Party Code] Fixed a bug that caused the BLAKE2 symbols
to be visible from QtCore in a static build. If you need to use the
BLAKE2 hashing algorithm in your own code, either use QCryptographicHash
or import libb2 into your build environment. Using libb2 remains the
recommended solution for all systems, especially those for which it has
optimized (vectorized) implementations.

Fixes: QTBUG-132347
Pick-to: 6.8
Change-Id: I48003b58cef0d8bcc720fffdd89b0f151fd102e3
Reviewed-by: Linus Jahn <lnj@kaidan.im>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit b884fbf10237547e809745f528978942faf0e5f6)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-29 11:40:51 +00:00
Marc Mutz
b79b2edde8 QLibraryInfo: port from manual memory management to unique_ptr
It's safer and clearer.

Also standardize on unique_ptr instead of QScopedPointer, because the
latter is not supposed to be movable, so the assignment in
QLibrarySettings::load() would not compile.

As a drive-by, scope a variable tighter (in an if condition).

Task-number: QTBUG-132213
Pick-to: 6.8
Change-Id: Iecdd910af4d06dbd03d2daf3ccf99dd4822f04ac
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit aa1f2064801b39a26a718703817e197a3e31447e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-29 11:40:51 +00:00
Christian Ehrlicher
e23933e868 QStyleSheetStyle: Honor box settings for QSpinBox
The previous patch to not modify the CT_SpinBox by QStyleSheet when
nothing was added for QStylesheet also removed the additional margins &
paddings handling for the size calculation. This patch re-adds this.

This amends 96adebed606cdbc73c73778917d777dc04c6e93e.

Pick-to: 6.8
Task-number: QTBUG-130642
Fixes: QTBUG-132431
Change-Id: Iff1f0febeca90d3154e61fd80e4b359bc7766b84
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit b2cc8824ec2cdeb6e053a2ff92d7d5b71f8d0ee5)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-29 03:54:57 +00:00
Christian Ehrlicher
314c91d94e Widgets: pass dpr to QIcon::pixmap()
Change the remaining calls to QIcon::pixmap() to pass a valid
devicePixelRatio parameter.

Change-Id: I0e71e20c8109e296446e9e13cddba31d53c05df9
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit efc318e05a2288f3fe62d9d7b2b892906e9263e0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-29 03:54:57 +00:00
Christian Ehrlicher
fba5f806e6 QCommandLinkButton: reload icon on style change
Different styles provide different icons for SP_CommandLink so reload
the icon on every style change.

Pick-to: 6.8
Change-Id: I2d8bd706d4c1bca89b91c90f1bb90a796b38e0d3
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit d4c518b210ad56cb51c17e6e1b4a81b0deb7253c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-29 03:54:57 +00:00
Volker Hilsheimer
843e2e1309 JNI: don't pass jobject by reference
And definitely not by non-const reference.

Discovered during upcoming fixes for native function registration.

Task-number: QTBUG-132410
Pick-to: 6.8
Change-Id: I0ce8519f5a1f9f3caffefc53e6d93b52509bc439
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 1b84970b90c36771bf266f8612dba9585341795a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-28 19:19:03 +00:00
Marc Mutz
5e6fa3dbc5 QTest::toString(QCbor-type): port from const char* to unique_ptr<char[]>
This is more robust and lessens the impedance mismatch as seen by the
old code using std::unique_ptr<char[]>(expr).get().

The new code isn't impedance-mismatch-free, either
(UP{qstrdup(qba.data())}), but short of writing a small string class
whose internal buffer can be release()ed to comply with the archaic
QTest::toString() new[]'ed const char* return value, there's not much
we can do about it atm.

Also separate the internal from the "public" stuff in
QCborValueFormatter by adding private: and public: sections.

Pick-to: 6.8
Change-Id: I09a2ad1a75bb9eab3d01f2b5b60afc2d762da384
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit d9264ee65d6f24e1008b08494b1472a54ac01940)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-26 17:23:30 +00:00
Thiago Macieira
8fdcda4dac Replace qTerminate() with std::terminate() and mark it for removal
It was used by the QT_TERMINATE_ON_EXCEPTION macro, introduced in 2012,
to support pre-C++11 noexcept semantics. That macro was removed for Qt
6.8 in commit 9b2ae564a59656d9cf49b141e70f5958b4fb79a4. This commit
amends that removing the definition of qTerminate() immediately in Qt
6.9 (it was an \internal function).

Change-Id: I9682121c04fafb3676b0fffd9f5ac999e7603c84
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
(cherry picked from commit b8f84fd1e2af38ece89d60619bf93e7af34433ab)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-26 17:23:30 +00:00
Thiago Macieira
09d44fdef3 QSaveFile: make it so flush() errors imply commit() failed
QSaveFile records past write errors in writeData(), but often the
QFileDevice::writeData() calls it places will succeed because the data
is only being buffered. Instead, the failures are noticed only by
flush(), whose actions do not affect QSaveFilePrivate::writeError.

[ChangeLog][QtCore][QSaveFile] Fixed a bug that caused commit() to
return true and overwrite its intended target file even though it failed
to flush buffered data to the storage, which could cause data loss. This
issue can be worked around by calling flush() first and only calling
commit() if that returns success.

[ChangeLog][QtCore][QSaveFile] Fixed a bug that caused commit() to
return true even after a cancelWriting() call had been placed, if
writing directly to the target file (that is, only with
setDirectWriteFallback() set to true). Note that the state of the file
does not change under those conditions, only the value returned by the
function.

Drive-by clarify a comment from 6bf1674f1e51fd8b08783035cda7493ecd63b44
(Qt 4.6 "Don't drop errors from flush on QFile::close") which had me
chasing the wrong lead.

Fixes: QTBUG-132332
Pick-to: 6.8 6.5 5.15
Change-Id: I427df6fd02132d02be91fffd175579c35b9c06cc
Reviewed-by: David Faure <david.faure@kdab.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
(cherry picked from commit 92373d353cf090faa03cbc8aca505d1784b10b54)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-26 17:23:29 +00:00
Lars Schmertmann
e6434a71eb Avoid unused variable warning in qfilesystemmodel.cpp
2135:5: warning: unused variable 'q' [-Wunused-variable]
    2135 |     Q_Q(QFileSystemModel);
         |     ^~~~~~~~~~~~~~~~~~~~~

The variable is only required for the feature filesystemwatcher.

Pick-to: 6.8
Change-Id: I5da48f94118179ec20fec7da7169b7f22cec17fe
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
(cherry picked from commit 46dddcb213eb5080b8f759633a1b025d86f55e36)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-26 16:35:11 +00:00
Marc Mutz
353d22756f Fix a performance regression in QDataStream
Commit e176dd78fd2f253eb2625585b2bd90b5713e5984 replaced a `new
char[n]` with a std::make_unique<char[]>(n), probably on this author's
insistence.

But the two are not equivalent: make_unique() value-initializes, even
arrays, even of built-in type, which means that each buffer resize
writes each byte twice: first nulling out the whole buffer as part of
value-initialization, then in the memcpy() and any following read()s.

For buffers of several MiB, or even GiB in size, this is very costly.

Fix by adding and using a backport of C++20
make_unique_for_overwrite(), which performs the equivalent of the old
code (ie. default-, not value-initialization).

Also add q20::is_(un)bounded_array, which are needed for the
implementation of q20::make_unique_for_overwrite().

Amends e176dd78fd2f253eb2625585b2bd90b5713e5984.

Pick-to: 6.8 6.5
Change-Id: I8865c7369e522ec475df122e3d00d6aba3b24561
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 1a9f8cc0df33195df959cee2e355dde4cbacd754)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-24 23:42:09 +00:00
Marc Mutz
aff082764a tst_QSpan: check QList<int> -> QSpan<const int> doesn't detach the former
It does.

While std::span, does, too, and so users should be using
std::as_const(), it's quite simple to avoid for QSpan, so we'll fix it
in QSpan. This patch adds the reproducer.

Task-number: QTBUG-132133
Pick-to: 6.8
Change-Id: I2e416fb7344830cd5e0d945cce61491cd6f4a7a5
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 05b9a4b2deefd586356e1f36d84372b06e74cfe3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-24 22:24:05 +00:00
Mike Chen
b6108318c2 QFactoryLoader: load extraSearchPath first
Since `QT_QPA_PLATFORM_PLUGIN_PATH` or `-platformpluginpath`
 specifies the path to platform plugins, `extraSearchPath`
 should be loaded first.

Pick-to: 6.8
Change-Id: I2e62fbf2021250ca864c669a7bbd7d56acd67d1e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 457580936ddebc73e8a24fc8af0d342084b3a0b5)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-23 04:08:12 +00:00
Marc Mutz
7b5dbe165d QDecompressHelper: fix compilation with GCC 9
GCC 9 doesn't accept [[unlikely]] between the (condition) and the
compound-statement of an if, in both C++17 and C++20 modes:

  qdecompresshelper.cpp: In member function ‘qsizetype QDecompressHelper::readZLib(char*, qsizetype)’:
  qcompilerdetection.h:1048:31: error: attributes at the beginning of statement are ignored [-Werror=attributes]
   1048 | #    define Q_UNLIKELY_BRANCH [[unlikely]]
        |                               ^~~~~~~~~~~~
  qdecompresshelper.cpp:597:54: note: in expansion of macro ‘Q_UNLIKELY_BRANCH’
    597 |         if (ret == Z_DATA_ERROR && !triedRawDeflate) Q_UNLIKELY_BRANCH {
        |                                                      ^~~~~~~~~~~~~~~~~

See also https://stackoverflow.com/questions/51797959/how-to-use-c20s-likely-unlikely-attribute-in-if-else-statement

Put it into the compound-statement instead, then GCC 9 accepts it. The
two are equivalent, because [[likely]] marks a path, and there is no
selection statement between the two positions.

Amends 5ae84d0afbd3690a2c003d06d920566a5d56dc8c.

Change-Id: Iac1970219c98a1c26e450dfe6bad6583e4d32c29
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 7a7804d4b454021d68d1d5138d134ef62abfcdb3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-22 16:28:52 +00:00
Marc Mutz
fc29f57a17 q23type_traits.h: use is_scoped_enum_v from std
We don't like surprises in qNN, so use the real is_scoped_enum_v from
std instead of adding the _v version outselves, even in C++20.

Amends 03a7be37806a32e9a8ac963b309812d6b8f125f6 and
63a8f657c2236829f16016602d9c0098b089d35e.

Change-Id: I7f9149678b95f7a59643152abf5a627e226cc058
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 40501ffbb441ce48733b3733b7ab781c7db8cca8)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-22 13:50:51 +00:00
Christian Ehrlicher
4354d7797e QDrawUtil: use QPainterStateGuard
Replace the internal PainterStateGuard class with the now public
QPainterStateGuard.

Change-Id: I9c072ce6e45ddfe2d0a8aba789311193788dee5a
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 204df603ef43be921e0eecae4d4af0ae6026787f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-22 09:19:05 +00:00
Christian Ehrlicher
6f7b8ada85 QCommonStyle: use QPainterStateGuard
Replace the internal QPainterStateSaver class with the now public
QPainterStateGuard.

Change-Id: I56285cb469cec43071320e87ac378674fd99c06b
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 7690b6260eac12958c97d642421e27680ca57496)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-22 09:19:04 +00:00
Wladimir Leuschner
4eaaf89db5 QWindows11Style: Adjust Subline for QLineEdit to fit rounded corners
Reduce the size of the subline for QLineEdit to fit the begin and end of
the rounded frame corner.

Task-number: QTBUG-132261
Pick-to: 6.8
Change-Id: I879f30c2bdc6601fef4738aeec71d7ab7bcee22c
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
(cherry picked from commit 5e656b9ea3c192f389b7e4f7aa2ae6b010cec306)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-22 09:19:03 +00:00
Wladimir Leuschner
4c2f439001 QWindows11Style: Align QSpinBox rect to match QLineEdits rect
The content rects for QSpinBoxes were smaller than QLineEdits rects for
UI elements that should have the same size. This patch increases the
content rect for QSpinBoxes.

Task-number: QTBUG-132261
Pick-to: 6.8
Change-Id: I59e752b719399c5845ab3ef81c6e271deda16273
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
(cherry picked from commit a53e095882551caf3684a1f6a205b6c7d76a8913)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-22 09:19:02 +00:00
Alexey Edelev
8f1438b1a8 Avoid creating Plugin targets if the dependencies are missing
The plugin lookup mechanism doesn't handle the situation, when the
plugin is available but it's private dependency(static plugin case)
is missing. In this case we currently silently bypass the dependency
lookup and create targets. So users see the confusing message about
missing linked target, like:

   Qt6QSQLiteDriverPluginTargets.cmake:61 (set_target_properties):
   The link interface of target "Qt6::QSQLiteDriverPlugin" contains:
     SQLite::SQLite3
   but the target was not found.  Possible reasons include:
     * There is a typo in the target name.
     * A find_package call is missing for an IMPORTED target.
     * An ALIAS target is missing.

This indeed should be handled properly and we should omit creating
targets especially if users don't really use the plugin directly.

Also if dependencies are not satisfied it looks logically to set
the <plugin>_FOUND to false as this will be yet another indicator
for user that the plugin is not found.

Task-number: QTBUG-132244
Pick-to: 6.8 6.5
Change-Id: I8685163df0dee3a728c724901f69780569ffcad5
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit 8d0283ad2cae3d8fbd4b1b7ee5c6454f7fcc079c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-21 04:51:58 +00:00
Eskil Abrahamsen Blomfeldt
610ee0c504 Don't include bearing of mid-string characters in max width
When calculating the maximum width of a text layout, we
would add the text width of each substring *after* we had
added the negative right bearing of the last character to it.
But the bearing of the last character in a wrapped substring
does not actually add to the maximum width unless it is the
last character of the *whole* string.

Prior to 250117086ff15bba79df8f0e15ee66192edc9ea9 this was
not noticed, because the last glyph in the substring would
typically be a space and the space does not have any
bearings (when doing wrapping on individual characters it
could still happen). After the change, the previous glyph
for which we get the right bearing will be the last
non-whitespace glyph. If this happened to have a negative
right bearing, we would add this to the max width and
end up with a larger max width than we should.

This caused a test failure in tst_qquicktext.

This test prefers the text width without the bearing (i.e.
the *advance* of the substring) unless the line is manually
wrapped or it is the last line of the layout.

Pick-to: 6.8
Change-Id: Iba1a5ad48d575683672400f0572dfa683a0f2d9c
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
(cherry picked from commit c08a92307d6d9fa9d9d9a1f301e3f2a65374e99a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-21 04:51:43 +00:00
Tor Arne Vestbø
e266949979 Apple: Use automatic rendering mode for icon engine
When requesting symbol icons the OS automatically chooses a rendering
mode per icon. Most icons use the monochrome rendering mode by default,
but some of them use the hierarchical.

We don't want to override this choice by always using hierarchical,
as that doesn't match the look of most icons in the system and may
be surprising to the user.

We still want to support tinted icons, based on the QPalette. For
iOS this is easy via [UIImage withTintColor:] but for macOS we
have to do an extra render pass. Unfortunately we can't use
configurationWithPaletteColors with a single color, as for the
hierarchical icons this will produce a different looking icon
than if we tint the entire icon.

[ChangeLog][macOS/iOS] The Apple icon engine, used for theme
icons on macOS and iOS, will now use the default rendering
mode for icons, typically monochrome, instead of always
using hierarchical icons.

Pick-to: 6.8
Change-Id: I9e66d848222e8ed0f7f20897454f27446bf0fd81
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 9f392c09a1d30e48494b4df0e2f5f531c7e4ec4b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 15:38:18 +00:00
Mårten Nordheim
b91edac40d tst_QHttp2Connection: make settings exchange wait for acknowledgement
Is needed when sending more SETTINGS frames during the test later

Task-number: QTBUG-132277
Pick-to: 6.8
Change-Id: I24b2a5d1b2e7aecd8687db5b24f37233df3b91dd
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit 6e7a15f5c50a94216bcf35241ec008e6c419ba18)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 15:38:18 +00:00
Toni Saario
7ce68e59fd Increase VxWorks stack size
Increases to around 16MB with the format change.
Required by some tests.

Change-Id: Ia41436b4269220f84271b614ea6f2b96ca605c32
Reviewed-by: Simo Fält <simo.falt@qt.io>
(cherry picked from commit 75d87caef70ff79b4db04834d28daa1905f0d5a0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 15:38:18 +00:00
Juha Vuolle
651b515074 Change QImage::mirrored() deprecation from Qt 6.10 to Qt 6.13
The deprecations aren't urgent, and allowing more time for users to
adapt is appropriate. In addition, also suppress the deprecation
warnings when compiling the related autotest.

Resulted from API-review.

Amends: 577946c1f05aaaa2a3f9682001aeb4144386b26b

Task-number: QTBUG-132090
Change-Id: Ia0c07ab510a9a9c8722892fcd94f58f6ec287059
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 0aa07ce77237dacc58de5939d5a239fb8997da7a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 15:38:17 +00:00
Christian Ehrlicher
1319dcf472 QWindows11Style: Adjust position of MDI subwindow icon
The y position for the MDI subwindow icon was not calculated correctly
so the icon was not painted vertically centered.

Pick-to: 6.8
Task-number: QTBUG-130673
Change-Id: I5f9023820a4e4b4288017869ac4088fe2669ce50
Reviewed-by: Wladimir Leuschner <wladimir.leuschner@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 6e29a94b547fbafa69e97ac02aeb33edad63f2ae)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 15:38:17 +00:00
Marc Mutz
9cd2e3ffef qtesttostring.h: standardize on unique_ptr<[]>
... instead of QScopedArrayPointer.

Less Qt code (which we're supposed to test with this library) and more
consistent with the tuple implementation.

Also makes the header clean w.r.t. upcoming QT_NO_SCOPED_POINTER.

Pick-to: 6.8
Task-number: QTBUG-132213
Change-Id: I3705b8db89e909e3f1e37ad6a31aaba6f9af899a
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit f405925829ca37af47ecbb291bdb8a95a606e024)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 15:38:17 +00:00
Christian Ehrlicher
ecc31955f1 QWindows11Style: adjust text rect for CC_TitleBar
The adjustment for the textrect was wrong - the bottomRight point must
be moved by -1/-1, not 1/1.

Pick-to: 6.8
Task-number: QTBUG-130673
Change-Id: I6c099fdd9a03188e7a5c7852b1912ed9b2801f7a
Reviewed-by: Wladimir Leuschner <wladimir.leuschner@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 2c85e5d22215f24bd46d07a1183393e52702493f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 15:38:17 +00:00
Christian Ehrlicher
f349040b39 QDrawUtil: Cleanup qDrawPlainRoundedRect/qDrawPlainRect
Fix the style and use PainterStateGuard instead own save/restore
functionality because PainterStateGuard is already available and used in
those functions.

Pick-to: 6.8
Task-number: QTBUG-132187
Change-Id: Ie454b6cffe03444d88f13d15adb19a7e7783a493
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 1fb86f1f84bb56dab60bc15604c09a14157d6f10)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 15:38:17 +00:00
Volker Hilsheimer
319b31a5a2 QTestLib: Remove logging category declaration from public header
The lcQtGuiTest category is only used in qtestsupport_gui.cpp, so
declare it there as a static logging category.

Addresses header-review comment, amends
5ac4f04325a56d47812f528fe31ceb0d4932f664.

Task-number: QTBUG-132090
Change-Id: I5b2a93822a698f55c52c1be87ebf8a689f49e2a3
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
(cherry picked from commit b957dfc6e06deed64e20e8eee5d2164250b28b95)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 15:38:16 +00:00
Thiago Macieira
1596b5855c QDebug: constrain the new Standard Library op<<
So they be SFINAE-ruled out when either the key or (for associative
containers) value types don't provide their debug-streaming operators
either.

Amends 850d4895be565931d18c92e5e2f9a33b7f26de6d,
0c96528e8d43ad4309bdca14b179a5045984655a,
a9fe57fefaac0cb047e4c02e0b8c8f8327e0a58c.

Fixes: QTBUG-132104
Task-number: QTBUG-130290
Change-Id: I1d6703b1fdf6cfd03799fffd33191d8028ecc123
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 8f958a6e2dcff5bb9b01442a19f5605f357c6e7e)
2024-12-20 08:17:40 -03:00
Christian Ehrlicher
7ab2885594 QSqlQueryModel: add new function to refresh the model data
This function re-executes the query used by QSqlQueryModel and refreshes
the data from the database. The query must not use bound values as these
values are not preserved.

[ChangeLog][QtSql][QSqlQueryModel] Added refresh() to refresh the model
data from the database.

Task-number: QTBUG-123603
Change-Id: I3f1d779e07b88565abe825c31cfc4d7d1b2312c4
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 1bd883dbc15c4016f78d421afac2ac9f31ec4874)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 11:17:40 +00:00
Christian Ehrlicher
fc29afbe1a QSqlDriver: return the connection name of the assoicated QSqlDatabase
A QSqlDriver instance is directly bound to a QSqlDatabase object. But
there was no way to get the QSqlDatabase out of a QSqlQuery/QSqlDriver.
Fix it by storing the connection name also in the driver during
creation and add a getter for it.

[ChangeLog][QtSql][QSqlDriver] Added connectionName() which returns the
connection name of the associated QSqlDatabase instance.

Task-number: QTBUG-123603
Change-Id: If78b85413cf6ca965ff6bf9f3600cb54169b5569
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 5b07e3de3fe5335d9338c65ca40cfe656a389167)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 11:17:39 +00:00
Eskil Abrahamsen Blomfeldt
ed1032975e Include right bearing in width of layouts wrapping on spaces
When we're calculating the width of the layout, we include the
right bearing of the last character in the text line if it is
negative (i.e. it exceeds the advance width). We do this by
storing the last glyph that has been verified to fit in the
line, so that we can retrieve its right bearing when we find
a break.

However, when we were wrapping on spaces this previous glyph
would always be a space, and the right bearing would
subsequently be 0. But then the trailing spaces would be
trimmed and the right bearing of the actual last glyph
would not be recorded and never added to the text width.

This caused a failure in tst_qquicktext on Windows with both
DirectWrite and Freetype: This was purely unlucky, because
the metrics of the Tahoma font happened to be such that the
right bearing on the 'k' was enough to cause a line to
overflow. Since we didn't account for it when setting the
width, we ended up with unexpected line breaks, causing the
test to fail.

This did not happen with GDI, since it rounded the right
bearing of the character down to 0 (which was actually
visible in the layout, in that the k was painted a fraction
of a pixel outside the text layout's width).

In addition, QTBUG-130313 was causing us to pick a different
font when resolving the non-existent font requested by the test,
so therefore the bug was not found immediately when moving to
DirectWrite as the default but only when QTBUG-130313 was fixed.

We fix this by
  1. When adding a chunk of whitespace, we record the previous
     non-whitespace glyph that has been verified to fit.
  2. When adding a chunk of non-whitespace, we only record the
     previous glyph verified to fit *if* it is not whitespace.
	 Otherwise we keep whatever we recorded before adding the
	 spaces.

Pick-to: 6.8
Fixes: QTBUG-132075
Change-Id: I8d9a2f3197068f5f93520d217a6bb89633644e95
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
(cherry picked from commit 250117086ff15bba79df8f0e15ee66192edc9ea9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 07:24:35 +00:00
Eskil Abrahamsen Blomfeldt
51ed0b024b doc: Clarify usage of QFontMetricsF instead of QFontMetrics
A common source of issues is that people do not consider that
fonts can have fractional metrics and use QFontMetrics for UI
purposes, causing bounds and eliding to be inaccurate.

This is not very surprising, since the class name sounds very
much like what you should prefer by default and the docs
didn't even contain links to the QFontMetricsF class.

It might make sense to deprecate the class, since it really
does not serve any useful purpose, but for now we at least
document the issue up-front so that users can easily find
the alternative.

Pick-to: 6.8 6.5
Task-number: QTBUG-132102
Change-Id: I69756c561e5dee448a9d0a7d85af1a9b15ff1ae3
Reviewed-by: Nodir Temirkhodjaev <nodir.temir@gmail.com>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 9a6036dea2cfe0cec555a503445aed93fed3d985)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 07:24:18 +00:00
Yuhang Zhao
d1c0eb2291 Windows theme: don't refresh anything unless theme really changed
Refreshing the global theme may be expensive for large scale applications, and even if Windows sent corresponding message,
it may be triggered by many reasons, not just the system theme,
so no matter what we'd better add an extra check.

Change-Id: I70847aa54fb4af37c81855a62330a4bce31ff104
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
(cherry picked from commit 9b924a4907a4a2b27ee52e807fd419caf219f655)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 07:24:11 +00:00
Ivan Solovev
b2bb9ef0f1 Refactor hasCompareThreeWay check
Use structs derived from std::false_type and std::true_type instead
of boolean constants. This allows us to make use of std::conjunction_v
and std::disjunciton_v in the conditions, thus making use of
short-circuit evaluation and saving unnecessary template
instantiations.

Still keep the constexpr bool *_v constant for the cases when we need
a signle check only.

Amends 678e9f614bc5a05d2ff16cf916397998e7cdfca1.

Pick-to: 6.8
Change-Id: If2ab48ef910e97f241f5922d4108a271bc532f3a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 8784ea16a6bc66ac481d5cbf2dd1ece2d57a836b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 07:23:29 +00:00
Tim Blechmann
9e22277d28 Cocoa: emit config error when using 15.0 as deployment target
QCocoaScreen uses removed APIs, which cause the code no fail compilation
with CMAKE_OSX_DEPLOYMENT_TARGET=15.0.
Adding a compile-time check to detect this early.

Task-number: QTBUG-128900
Pick-to: 6.8 6.5
Change-Id: I7eeb60f5769af6b1622efd1e0637e85a038b7930
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit b6f3695a80f5abfbcfb0ebb5b03358b8e7bbbaf9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 07:23:12 +00:00
Topi Reinio
3b4a7d4881 Doc: Set trademarks page in global configuration
The new \tm command appends a trademark symbol and links to the
trademark documentation page if `navigation.trademarkspage` variable
is set. As we have such a page in qtdoc repository, set the variable
in the global configuration. This works as all Qt module docs have a
dependency to the `qtdoc` documentation set.

Pick-to: 6.8
Task-number: QTBUG-124393
Change-Id: Iabc6e7e5afe5114eac79947f0feb512458f1c4da
Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
(cherry picked from commit 429f565017f7213a91eb0cf43966b2148e0bb651)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-20 07:23:04 +00:00
Volker Hilsheimer
43ab4d5c7b QPainterStateGuard: make movable, add test coverage
There's no real reason not to be able to move a state guard.

Since a moved-from QPainterStateGuard must not have a restore-
level count, we have to implement the move-constructor explicily.
Add a test case, which verifies that we don't end up with an
un-balanced save/restore count, and that verifies that we would
trigger the Q_ASSERT if we do.

Address comment from header review,
amends 9ecf47a8a8d11227ecf192246d7df7c2c4dc9105.

Task-number: QTBUG-132090
Change-Id: I1db135bf48c0fa0a7bac4fdae7b7263c356b5eb6
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
(cherry picked from commit ec3a5f4994a2bafc65fa8e01fb0861219580f622)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-19 22:31:05 +00:00
Thiago Macieira
55a46ec005 QCommandLineParser: include the positional arguments' sizes in --help
We were mostly ignoring them because it looks like most people's options
were longer than their positional arguments. The rest must have just
accepted the enforced wrapping.

But if you have very short options like single-letter only ones or none
at all, the positional argument wrapping is unnecessarily short.

[ChangeLog][QtCore][QCommandLineParser] Made it so the positional
argument descriptions are taken into account in the aligning of text for
helpText().

Pick-to: 6.8
Fixes: QTBUG-131716
Change-Id: Ib1eee62c7cf4462f6a26fffdec233ba849ebf158
Reviewed-by: David Faure <david.faure@kdab.com>
(cherry picked from commit 8928b0fbb9ca4caf9b63a32b3d2a73a6da096755)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-19 20:42:53 +00:00
Assam Boudjelthia
f10b13e469 Android: document androidtestrunner tool
Add documentation and usage of androidtestrunner tool.

Pick-to: 6.8
Fixes: QTBUG-84330
Change-Id: I03aa67ebf0ba807f20595547f2598d905080a878
Reviewed-by: Nicholas Bennett <nicholas.bennett@qt.io>
(cherry picked from commit 5735d7ac861fe99a71d8044977e5f487c401ca12)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-19 20:10:38 +00:00
Tor Arne Vestbø
5051e2b97b Extend blacklisting of tst_QWidget::showMinimizedKeepsFocus to macOS 15
It's flaky on all version.

Pick-to: 6.8
Change-Id: I01b2f0877efc100578c55d69e9f9ed65c02b2aab
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 1ce019815ba62245fd8ae6e8fb5e47f77621c3be)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-19 20:10:38 +00:00
Ahmad Samir
d5cff9be0e QDecompressHelper: add comment for translators in readBrotli()
Spotted by Friedemann Kleint in code review.

Amends 763c47e055376bf6dbd4cd8fe1603b88aa3b72f0.

Change-Id: I3092c51964c167da30b6d1400ab2ba1e2f4df829
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
(cherry picked from commit d983a402a5c7106935439c95d08eaadbf0b26b60)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-19 20:10:38 +00:00
Eirik Aavitsland
a994bc80fe Update bundled libjpeg-turbo to version 3.1.0
[ChangeLog][Third-Party Code] libjpeg-turbo was updated to version 3.1.0

Pick-to: 6.8 6.5 5.15
Change-Id: I321ae095b4ed826ceb940cbf13a63ec1a836acb3
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
(cherry picked from commit 1a5afe625be1ed936d2fc4da98ed1c8fa574ee7b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-19 20:10:37 +00:00
Joerg Bornemann
8c3e5bcd21 Rename qscopedpointer.cpp -> qscopedpointer.qdoc
It only contains qdoc blocks and wasn't even listed in SOURCES.

Also changed the license to be in line with QUIP-18.

Pick-to: 6.8 6.5
Change-Id: I2c90300ddfd47c3f693dc84cb86f326fa185dd84
Reviewed-by: Lucie Gerard <lucie.gerard@qt.io>
(cherry picked from commit 1cdf813e221b5aa133bc85cb928e329ef1dea896)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-19 12:54:39 +00:00
Joerg Bornemann
9834571282 CMake: Split off private module config packages
[ChangeLog][CMake] Private Qt modules have been split off into separate
Qt6FooPrivate CMake config packages. A call to find_package(Qt6Foo) will
now implicitly find_package(Qt6FooPrivate). It's not an error if
Qt6FooPrivate isn't available as it may be the case on certain Linux
distros that split their Qt module packages into private and public
parts.

For every public module Qt6Foo that has an associated Qt6FooPrivate
module, create a separate Qt6FooPrivate CMake config package.

Let Qt6FooPrivate find Qt6Foo. This is a required dependency.

Let Qt6Foo find Qt6FooPrivate if it's available. A message of log level
VERBOSE is issued if Qt6FooPrivate is not found.

Implementation notes: In QtModuleConfig.cmake.in, we pull in the private
module. This is not part of the *Dependencies.cmake file, because

1. The Qt6FooPrivate package references the Qt6::Foo target, therefore
it must be available. And Qt6FooDependencies.cmake is loaded before
creating targets.

2. The dependency needs to be optional, and we don't have facilities for
optional dependencies in Qt6FooDependencies yet.

3. We'd have to avoid recursion, because of the Qt6FooPrivate -> Qt6Foo
dependency.

Fixes: QTBUG-87776
Change-Id: I8f23f07da7ca76486f87b759e197174c11e13534
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
(cherry picked from commit fbbf4ace0188b9718b6d7808021c0b887fd52d9f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-19 11:11:45 +00:00
Marc Mutz
072f2a2241 QXmlStreamReader: use QOffsetStringArray::viewAt()
This auto-computes the string's length without a NUL-byte scan, and
also fixes a GCC 14 unity-build C++23 warning:

  In function ‘constexpr qsizetype QtPrivate::lengthHelperPointer(const Char*) [with Char = char]’,
    inlined from ‘constexpr qsizetype QtPrivate::lengthHelperPointer(const Char*) [with Char = char]’ at qbytearrayview.h:69:28,
    inlined from ‘constexpr QLatin1String::QLatin1String(const char*)’ at qlatin1stringview.h:52:62,
    inlined from ‘constexpr QLatin1StringView contextString(QXmlStreamReaderPrivate::XmlContext)’ at qxmlstream.cpp:814:90,
    inlined from ‘void QXmlStreamReaderPrivate::checkToken()’ at qxmlstream.cpp:4018:85:
  qbytearrayview.h:77:16: warning: ‘strlen’ argument missing terminating nul [-Wstringop-overread]
     77 |     while (data[i] != Char(0))
        |            ~~~~^
  In file included from unity_0_cxx.cxx:412:
  qxmlstream.cpp: In member function ‘void QXmlStreamReaderPrivate::checkToken()’:
  qxmlstream.cpp:769:23: note: referenced argument declared here
    769 | static constexpr auto QXmlStreamReader_XmlContextString = qOffsetStringArray(
        |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Amends c4301be7d5f94852e1b17f2c2989d5ca807855d4, which was picked to
5.15, but didn't use QOffsetStringArray there (and unity-builds exist
only since 6.5), so only picking to 6.5.

Pick-to: 6.8 6.5
Change-Id: Ib50369aed6e8248fb88f43c7569c8a435c2b152e
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 44366d07dca047f096d1366c43ba549c97150074)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-19 11:11:43 +00:00
Marc Mutz
da9ff584d1 Protect QT_ENABLE_STRICT_MODE_UP_TO against predefined individual opt-outs [6.9]
Since some of the Qt opt-outs are defined project-wide by the
buildsystem these days (e.g. QT_NO_QSNPRINF, ...), a module that
attempts to use QT_ENABLE_STRICT_MODE_UP_TO will hit warnings
regarding re-definition of these macros (definition on the compiler
command line, redefinition by qtconfigmacros.h).

To fix, guard the #define QT_NO_FOO's with #ifndef QT_NO_FOO.

Amends bd7d54249e3f2b6a9dd6b759c892d7c97d26c0aa (which was also picked
to 6.8).

Pick-to: 6.8
Change-Id: I88276c9ed01edde1495105cf5bd1e07b1fd244f4
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 752de4a0aabc305af16251a55edf247e043b1b18)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-19 10:44:24 +00:00
Marc Mutz
d328e8eaaf Protect QT_ENABLE_STRICT_MODE_UP_TO against predefined individual opt-outs [6.8]
Since some of the Qt opt-outs are defined project-wide by the
buildsystem these days (e.g. QT_NO_FOREACH, QT_NO_JAVA_STYLE_ITERATOR,
...), a module that attempts to use QT_ENABLE_STRICT_MODE_UP_TO will
hit warnings regarding re-definition of these macros (definition on
the compiler command line, redefinition by qtconfigmacros.h).

To fix, guard the #define QT_NO_FOO's with #ifndef QT_NO_FOO.

Amends 3a6c8e02b6d1b0574da52b0087092d0c74aa92c1.

Pick-to: 6.8
Change-Id: I457457d1e60dbd9362b987157ba089adc67d1d6b
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 0f416cbaaba46ddb039bbf33e1d70dbe80821d57)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-19 10:44:17 +00:00
Marc Mutz
6eb41440cd QTextStream: port from QScopedPointer to unique_ptr
In preparation of adding QT_NO_SCOPED_PONTER, which would be rather
pointless for users if public headers continued to mention the type.

Pick-to: 6.8
Task-number: QTBUG-132213
Change-Id: I6539e83158ab34e4fa4bd22b6d0ac5629a3b6db9
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit b815c6f7fd71086c97fe6e9aa9472154be5fcc57)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-19 10:44:15 +00:00
Robert Löhning
e63884c593 QRadialGradient: Fix crash on huge x values
Credit to OSS-Fuzz

Fixes: QTBUG-130992
Pick-to: 6.8
Change-Id: Iefaa6964966f6828bc23a603f085d283189f1a3b
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 42bd879e2bc6e0d8370d320cca17df36ea68d570)
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2024-12-18 22:08:02 +01:00
Christian Ehrlicher
3c0f08ab70 QBoxLayout: don't crash on passing invalid index
Passing an invalid index gives an assertion in debug mode and crashes in
release mode due to an out-of-bounds access. Fix it by appending the
given widget (same as passing a negative index which is documented).

Pick-to: 6.8 6.5 6.2
Fixes: QTBUG-130275
Change-Id: Id0c245e185acc36e5d07cea1d22619bb0e9eee07
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
(cherry picked from commit 0f9062ec71021c256dba7ee8498f036d7aac0821)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-18 20:17:36 +00:00
Christian Ehrlicher
72f48d0840 Windows11Style: Fix horizontal scrollbar arrows in rtl mode
The arrows for horizontal scrollbars must be swapped in rtl mode.

Pick-to: 6.8
Change-Id: I517fcea19837a6438edc261e066930218b71ce28
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 02920ef05a980d9bb670e1f8a4b84e0b6cef13c1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-18 20:17:36 +00:00
Mårten Nordheim
ab667d881d Schannel: chop off garbage bytes if encryption fails
Because they would break communication (or loop infinitely) otherwise
since we use the presence of bytes in the returned buffer to know if
there is still something we need to transmit.

Amends 4e60a6b556d91ab797aebb7422666a685a726755

Change-Id: If72c1a142d4567f69d78177250b0218c5ca999fd
Reviewed-by: Even Oscar Andersen <even.oscar.andersen@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit 1efcc0df6adab11e7239f5f12a13766a58e2c1ea)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-18 20:17:36 +00:00
Topi Reinio
5fa520a77c Doc: Fix usage instructions for the \youtube macro
The example configuration included a space character that caused a
syntax error parsing the .qdocconf.

Replace the hardcoded qhp `QtDoc` project name with a placeholder.

Pick-to: 6.8
Change-Id: Iadf3a50e030f02182016ed9832f4f59d29f82c57
Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
(cherry picked from commit 4051ec3356bded10cd7ac66dc1149259bc48d36b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-18 20:17:36 +00:00
Shawn Rutledge
019feea9b1 Always send QContextMenuEvent after the contextMenuEventType event
Both widgets and Qt Quick Controls are unable to avoid accepting the
right-click events (press and/or release) in at least some cases.
In the Windows UI pattern of allowing the user to select something by
pressing (and maybe dragging) with the right button and then getting
a QContextMenuEvent afterwards, it's sensible for the code that does
the selection to accept the mouse events, because that code is only
concerned with selection, not the context menu. And in Controls,
Pane is accepting all mouse events just to prevent propagation to
other controls underneath. (That might not be so great, but we don't
have a better way yet.) In legacy Qt Quick, accepting the event results
in an exclusive grab; so in fact, Pane gets the grab, so we can't use
that either, as a way to distinguish "stop propagation" from "this item
is handling it completely, nothing more needs to be done". So it
doesn't make sense for QWindowPrivate::maybeSynthesizeContextMenuEvent
to check the grabber either.

Amends 357c64a99607456133bfabf86d6b67162717cb29 and
84a5f50c7766c99f62b22bb4388137e0aa8dd13d

Task-number: QTBUG-67331
Task-number: QTBUG-93486
Task-number: QTBUG-132066
Fixes: QTBUG-132073
Change-Id: I822cada05cfef27afe6a44faf170585f027061f7
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 70c61b12efe9d1faf24063b63cf5a69414d45cea)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-18 20:17:35 +00:00
Lars Schmertmann
835475873b Avoid linter warning "AndroidGradlePluginVersion"
This is a Qt dependency that the user cannot influence.
We did this in  cfefce57a4ff446305cd1f839e7c5203bac7a6c5
with "GradleDependency"  before. It is a Qt dependency
that the user cannot influence.

Pick-to: 6.8 6.5
Change-Id: I01ef84eab7ab743d5ea9eb15208ef9c567dd2a43
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit ab2a0438ef8b6cc2c73ab0f33d353d00c6599cd9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-18 15:40:50 +00:00
Alexey Edelev
abfaf5189c Remove _qt_internal_find_dependencies
Clean up the dead code according to TODO statement.

Pick-to: 6.8
Change-Id: I9bdf10067d3a1324d584cebc51cf4555f00f717a
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
(cherry picked from commit 64435289027d53c9dace16eaa38087369fee6c4c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-18 14:13:05 +00:00
Mårten Nordheim
2aaaf7cf12 QThread: Link to QThreadPool::(set)serviceLevel
QThreadPool's functions already links to the QThread ones, but they didn't
link back.

From the API review.

Change-Id: I02853d8110806f735b748d022a1cfaea5a72d603
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit bbcf47a07d3ec138016d4f997c9b4849598c2f10)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-18 14:13:03 +00:00
Mårten Nordheim
0a4ff045f1 Http2: Ignore RST frames on already-closed streams
Some http servers like to send RST frames whenever they send their response.
The stream is already closed at that point so it's a little weird, but the
RFC doesn't disallow it, so we'll just ignore the frames.

Fixes: QTBUG-132124
Change-Id: Ic26e249437b739830935e2f3feec572687579b21
Reviewed-by: Øystein Heskestad <oystein.heskestad@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit 2c71fdf043ca94d1c567f169d51245e2702bec19)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-18 14:13:01 +00:00
Marc Mutz
aac98b795d QDebug: make std::optional stream operator SCARY
Piggy-back on the recently-added, type-erased, std::tuple stream
operator to handle std::optional the same way.

While std::optional doesn't support the Tuple Protocol, and we
therefore can't use putTuple() directly, we can still use
putTupleImplImpl() if we set up its arguments manually.

[ChangeLog][Potentially Source-Incompatible Changes][QDebug] The
std::optional streaming operator is now a member of QDebug, not a free
function. This breaks users that rely on the exact definition of the
operator (e.g. `operator<<(d, opt)`). A backwards-compatible fix is to
call the operator with infix notation (d << opt) only, and to avoid
const QDebug objects.

Change-Id: Ib040d65953ca9d3892aee5bdb597d6d30a9694b1
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 08320bfe2b7387d6f488d405dddf9d3aba6434ec)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-18 10:05:26 +00:00
Marc Mutz
94928669c1 QByteArrayView: add a ctor for arrays of unknown bounds
This appears to not have worked, ever, so add it as a new feature, for
view API symmetry, not as a bug-fix.

The new constructor is available for all compatible byte types,
because it is more like the (ptr) constructor (which is available for
all compatible byte types) than the known-size-array constructor
(which is only available for char).

This does not affect QB/QBV overload sets, since they could exist
ambiguity-free only if one of them is a Q_WEAK_OVERLOAD.

The GHS compiler doesn't like the CanConvert static_asserts, so
comment them out for it. The functionality itself is tested by
the fromArrayWithUnknownSize test.

[ChangeLog][QtCore][QByteArrayView] Made construction from arrays of
unknown size compile. Such arrays will use the const Byte*
constructor, determining the size of the array at runtime.

Task-number: QTBUG-112746
Change-Id: I201033656f123b09644e5de447cd5d7b038e5154
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 54d47f8390cb85c5b0f0ac050b5aa5a934d798b0)
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-12-18 08:07:37 +01:00
Friedemann Kleint
6cd5ea15ef Use QPainterStateGuard in examples
Complements 9ecf47a8a8d11227ecf192246d7df7c2c4dc9105.

Change-Id: I65456f8fd34bf9d316b72c4286e1b15789309f7c
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
(cherry picked from commit 1dc15c11db88f96a916258acea80a86bfa7c87cd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 21:18:54 +00:00
Volker Hilsheimer
3339990b4b QPainterStateGuard: make InitialState enum scoped
Address comment from header review,
amends 9ecf47a8a8d11227ecf192246d7df7c2c4dc9105.

Task-number: QTBUG-132090
Change-Id: Idddca104b93ee23f4bac8621f1087a0ae7a1fe24
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
(cherry picked from commit ec011141b8d17a2edc58e0d5b6ebb0f1632fff90)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 21:18:54 +00:00
Christian Ehrlicher
0dd2561d54 QStyleSheetStyle: Fix resetting fonts for subwidgets
When a compound widget is styled with a font through a property and the
default styling has no font settings, the font was not reset to the
parent font but left it the styled state.
Fix it by not resolving the current font when the style rule has no font
settings - use the parent font directly instead.

Fixes: QTBUG-131685
Pick-to: 6.8
Change-Id: I8e79423cfeff24143cd051b282503c4565125b4d
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 5731fe051e48e7a256ef31ae93cfb89ce8d871cc)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 21:18:54 +00:00
Volker Hilsheimer
a8b8a6fd6d QPainterStateGuard: document that restore() asserts when already at 0
Address comment from header review, amends
9ecf47a8a8d11227ecf192246d7df7c2c4dc9105.

Task-number: QTBUG-132090
Change-Id: Ie6eed6f83fcdde0f90514b6016a65905505073e0
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
(cherry picked from commit 8ae4e3efdf80b658f8de19b13bfbea68e1dbd875)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 18:20:00 +00:00
Wladimir Leuschner
ad16cd816a WindowsQPA: Draw custom titlebar with QPainter
- Draw custom titlebars that are requested by setting the
  Qt::ExpandedClientAreaHint with QPainter instead of GdiPlus.
- Draw the application icon, in case it was set, for the custom titlebar
- Add DPI awareness to the custom titlebar

Change-Id: I276e7d8948e5a436f1835d96b59756b7237f63d2
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 438aa1524ee99fd636dc02a7181857ade71bb101)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 15:14:12 +00:00
Timur Pocheptsov
c39a944e74 Revert "qnsview_drag: only ignore key modifier while dragging 'within the application'"
This reverts commit 4332cb313469de1525afe3cddd792d7bc7e08a14.
The original idea of distinguishing between context (outside/within application)
is not working anymore - it's always outside (except the moment when
a mouse pressed inside the window, which is immediately followed by
'outside application' context). So in fact we never ignore key
modifiers.

Fixes: QTBUG-132091
Pick-to: 6.8
Change-Id: I560a48ccf8f8ee1a55f812be6af18b1dd7e25c78
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 7740ac36d27740ff9204cc2626f58620b7e214cb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 14:16:23 +00:00
Ivan Solovev
cc2213ab27 Change QCommandLineParser::showMessageAndExit() argument order
Looking at other similar Qt APIs, the type argument usually comes first.
The typical related examples can be QMessageBox() constructor taking
QIcon as a first parameter, and qFormatLogMessage() function, taking
message type as a first parameter.

This patch changes the order of arguments, so that MessageType enum
comes as a first argument.

Amends bad618606d64e943e3fa78e7d1dbc8e1fab55480.

Found in Qt 6.9 API review.

Change-Id: Ibbdef755a8676a2c556fe7f1c95009ad51320b98
Reviewed-by: David Faure <david.faure@kdab.com>
(cherry picked from commit 56114f4d1ed6ec26ff59a596caf09f5b4e0f5d68)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 14:16:23 +00:00
Ivan Solovev
e69e53de8e Add docs to the new QCommandLineParser::MessageType enum
As a drive-by: move the \since command in the showMessageAndExit() docs
to the right place.

Amends bad618606d64e943e3fa78e7d1dbc8e1fab55480.

Change-Id: I4e6e6d63929029879867624e4007941edfca9cd9
Reviewed-by: David Faure <david.faure@kdab.com>
(cherry picked from commit 6692beace9bb5f461d71935e500e1c6ccfa97fd1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 14:16:23 +00:00
Bartlomiej Moskal
6e3d2ad44f Android: Fix for multi-ABI build in androiddeployqt
7499fd0229d63f969bf6ca58d3b764b96395bed2 commit cleans up the localLibs
to not add dependencies to the libs.xml file as they will not be
satisfied.

Mentioned change created a regression with multi-ABI build. It happens
because in qtDependencies[ARCH] container, some libs just have different
atchitecture prefix.

This commit remove architecture prefix when checking libs in
qtDependencies container.

Fixes: QTBUG-131707
Pick-to: 6.8
Change-Id: Iae54779bfa4bd143ec35353604724d8ec4e35ef2
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit e59308c5119caac5d4f1024c7d8147e9887cb246)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 14:16:23 +00:00
Ivan Solovev
7c332839e0 Specify an underlying type for QCommandLineParser::MessageType
And also add a trailing comma to the last element of the enum to
minimize future diffs.

Amends bad618606d64e943e3fa78e7d1dbc8e1fab55480.

Found in Qt 6.9 API review.

Change-Id: I1a30c344967005c9abc73e59980e56626e09cd7c
Reviewed-by: David Faure <david.faure@kdab.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 14cc2591ac06dbcee01c2b110e014db2993d7a1e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 14:16:23 +00:00
Tor Arne Vestbø
9610a7cbdc QCocoaDrag: Only update m_lastView when it actually changes
The underlying QObjCWeakPointer used to track the view requires
a bit of bookkeeping, so avoid updating its value unless the
view actually changes.

Pick-to: 6.8
Change-Id: I6a1aeaf0e6e0eb221d55de00c8f30259832e58fa
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 2e80e74f37980f62bb915983e61d6734fb416bcd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 14:16:23 +00:00
Tor Arne Vestbø
c8ae8244b4 QObjCWeakPointer: Clear existing associated object on assignment
If the existing m_object is the same as the incoming object the
call to objc_setAssociatedObject in trackObjectLifetime will
release the existing WeakPointerLifetimeTracker after assigning
a new one, which means we'd clear the QObjCWeakPointer's object.

We now reset the state up front.

Fixes: QTBUG-132256
Pick-to: 6.8
Change-Id: If2c08840d465ae6d190c87a4720a537fe9caa8dc
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit 92012333d112dbdf2926117ec3bb123bd30ed9fc)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 14:16:22 +00:00
Christian Ehrlicher
9b2e444811 QAbstractItemView: use 'int' as datatype for updateThreshold
... to sync it with the rest of the api.
This amends ff339819925ab550c48b53d9baaba43e5adebfaa.

Task-number: QTBUG-124173
Change-Id: I0ed4681bf7d3717f84a7e888affb0c8cae877c35
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 15a1ae90f5b6da3ffd50acda63ddd33ca14227f4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 10:52:59 +00:00
Marc Mutz
ee69826054 qthreadstorage.h: fix position of namespace macros
The file contains two implementations of the class template, one for
QT_CONFIG(thread) and one for without. Both are in the QT_NAMESPACE,
but each provided their own QT_{BEGIN,END}_NAMESPACE macro pair.

This is unneeded and may throw off scripts which use the macros as
insertion positions (like includemocs, which, however, operates on
.cpp files, not headers).

To fix, move the namespace macro pair to be around the #if
QT_CONFIG(thread) block.

Pick-to: 6.8 6.5
Change-Id: I56c1f9a4ef7df0fba54c72d8a213fa92573b826c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 8553ffd8d147ecf6a713d12a360027b477dd59c8)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 10:08:46 +00:00
Yuhang Zhao
3c0986a34c Windows: Fix title bar size calculation
The title bar calculation is terribly wrong and was
missed during review.

Change-Id: I0c7a860e747465e6a5e4d8aa5415a9701cf170fd
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
(cherry picked from commit f6af3a581642170f0f4fe0d0563851715e045391)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-17 07:58:48 +00:00
Marc Mutz
9e86f73f82 QStringView: refuse construction from QStringRef
When QStringRef was moved out of QtCore, it was also incorrectly
removed from the if_compatible_container constraint, causing
QStringView{sr} to still match the general container QStringView ctor
overload, which doesn't preserve null'ness if data() doesn't return
null. By refusing to provide a constructor from QStringRef, we force
the compiler to use QStringRef's implicit conversion operators
instead.

This transitively affects QAnyStringView in the same way.

The tests can, naturally, only be in qt5compat, so define a macro to
communicate to tst_QStringRef whether it compiles against a fixed
QtCore or not.

Fixes: QTBUG-122797
Fixes: QTBUG-122798
Pick-to: 6.8 6.5
Change-Id: I64b75a8e421d2b6185615e3288ce3ad7fd8f15f9
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
(cherry picked from commit a0e65398483729259cf58781949133c6055fdc7c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-16 20:44:29 +00:00
Volker Hilsheimer
cdfd686714 QSqlQueryModel test: don't copy a QSqlQuery
Move the query into the model, and use a local scope to make sure that
we don't use the moved-from query later.

Change-Id: I9d216e770733af8b0771280276dba0775209a802
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
Reviewed-by: Dheerendra Purohit <dheerendra@pthinks.com>
(cherry picked from commit af760da54190d96b315ea8edeec00c86871af0d8)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-16 20:18:13 +00:00
Tor Arne Vestbø
78051d03ca Document that QPlatformTheme::standardPixmap should always be a 1x pixmap
This reverts 59bbfb17db563d7e62b9f3158dab3cc6e7e68acd and
c853054910552f5fef04797222dde0d29a0c340d, as that approach
was causing issues for QCommonStyle::iconFromWindowsTheme,
for example in situations where the system has a 1x and 2.5x
screen, and the user requests a 16x16 pixmap or icon via
QStyle::standardPixmap or QStyle::standardIcon. In that
situation our smallest pixmap is 40x40, and we need to
downscale, causing blurred results on a 1x screen.

Change-Id: Ifa6e15d37d15954df689253c32eaa779885c567b
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit d884abaf8bdc1be74ee52306948c0be1986d738d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-16 20:13:30 +00:00
Christian Ehrlicher
eab71ff6b0 Windows11Style: adjust subline color in editable widgets in dark mode
The color of the subline in editable widgets was black in light and dark
mode. Fix it to use white in dark mode to make it visible. Move it out
into own helper function since it's used in at least three places.

Pick-to: 6.8
Task-nubmer: QTBUG-131585
Fixes: QTBUG-131586
Change-Id: Icca2b142a1ce0c3d7f722baa6d3635bae5950e1c
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit 66d42b62b6f01205cf1db72e56ecb5166554e373)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-16 20:13:28 +00:00
Christian Ehrlicher
07ad8c8444 QStyleOptionViewItem: document 'widget' and 'locale' member
These two members were added during Qt4 times but never documented.

Pick-to: 6.8 6.5
Change-Id: Ife4abfc6d8883f4c26ce5b95d5c0cfd3adcbd6bf
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Wladimir Leuschner <wladimir.leuschner@qt.io>
Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch>
(cherry picked from commit a90d9f4823bd6baf4cb660a942c2b1695441dbbd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-16 19:37:58 +00:00
Eskil Abrahamsen Blomfeldt
501f78855e Fix DirectWrite subpixel antialiasing on BGR screens
On monitors where the subpixel arrangement is blue, green, red,
our DirectWrite rendering would give the wrong subppixel
antialiasing, causing color fringes on text.

Like we do with Freetype, we determine subpixel arrangement of the
primary screen and use this as the default.

Pick-to: 6.8
Change-Id: I9ce7025449106a2376bd0ed02ce07b59c79438bd
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
(cherry picked from commit d5cef74d8d71458500f979c0d31a7241b3fef9db)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-16 19:37:56 +00:00
Eskil Abrahamsen Blomfeldt
bfb80b7b45 Support variation selector when emoji segmenter is disabled
This amends cb2633468413d8c2a9e28d4c4a10b25e90dd3116.

The patch excluded the ad hoc parsing of variation selector
except when Qt was built without the emoji segmenter. The
reasoning being that the emoji parsing handles this correctly
now.

However, when setting the QT_DISABLE_EMOJI_SEGMENTER variable
in the environment, this is supposed to work as a fail safe
which gives you the original behavior, in case there are
regressions. Therefore, the variation selector handling needs
to be run also when this environment variable is set.

Change-Id: I2669d29016a552775461aad13e50459baecdc26f
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit aaf7437db3a520ab14220a46cf9427cb9a8d915c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-16 19:37:55 +00:00
Eskil Abrahamsen Blomfeldt
f5e2166bbd DirectWrite: Remove ad hoc font resolution through GDI
In b8612eaa2a17e12e31ee28141cff1fb43e54c00e, we added a fail safe
where failure to find the font name through DirectWrite would
try loading it through GDI instead and if that was successful we
would register the family with the database after all.

However, the code assumed that CreateFontIndirect() would return
NULL if the font did not exist. It does not do this, but instead
selecting the HFONT on the HDC will give us a suitable alternative
instead. The result would be that any missing font family would
be registered with the font database through this mechanism, even
if it really didn't exist.

This code was added in an early version of the patch, however,
and it should not actually be needed anymore, since we in later
versions of the same patch also added logic to populate the
GDI-compatible family names
(DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES etc.). This should
take care of backwards compatibility with the GDI names for fonts.

Since the code has been reported to cause problems on some systems,
it's safest to just remove this hack.

Pick-to: 6.8
Task-number: QTBUG-130313
Change-Id: I7eca893d17796d9cac07391b7b947d28dd7cd920
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 355f54f7d5dd300c73bf203f12e24305d0e227c1)
2024-12-16 15:24:24 +01:00
Andy Shaw
9988cd2469 SQLite: Fix attrition file to have right version number
Pick-to: 6.8 6.5 5.15
Change-Id: I9fea5c8d19209c44b16916645e600735de929d80
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
(cherry picked from commit 311ac55f118dc88add297853318cd0cfd7c1c0d5)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-16 07:13:13 +00:00
Assam Boudjelthia
440dcaca27 Android: handle quotes in hard-coded namespace in build.gradle
Remove quotes from the namespace values if they're set
directly to build.gradle.

Fixes: QTBUG-132150
Pick-to: 6.8
Change-Id: I7f5e132c2600bf5079850c99dc500b1dff7e6a96
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 60f78212379ba2b4a7a9bfadc5088a60309e923c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 18:29:03 +00:00
Magdalena Stojek
7ab145a9ef Output both global and local data tags in benchmark result header
Modified QPlainTestLogger::printBenchmarkResultsHeader() to
concatenate and display both global and local data tags, in
the benchmark result header, in the format `global:local`.
If only one tag is available, it is printed alone.

Pick-to: 6.8 6.5
Fixes: QTBUG-127522
Change-Id: Ic9f3c712ef3f6858aad2546b80d8867ce860b644
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
(cherry picked from commit 95f02adf756d1ae485f39a060c6f23a5af3f64ee)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 18:04:39 +00:00
Michael Weghorn
b5ba125fa0 QMenu: Accept accelerators typed on keypad
Add Qt::KeypadModifier (and the combination with Qt::AltModifier) to the
modifiers that may be set in a key event in order to trigger a menu
action via its accelerator.

Otherwise, an action that has a number set as the accelerator (e.g.
using text "&1 Exit"), cannot be triggered by typing the corresponding
number on the keypad.

Fixes: QTBUG-73390
Pick-to: 6.8
Change-Id: I0fa63b0c5f23823c61e159fcc72f7245215f8aae
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit ca4334bc966c7e5f9997f98b83afe37eb8b1d3ba)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 17:20:11 +00:00
Christian Ehrlicher
c437c6a4f6 Style: pass widget to styleHint() where appropriate
QStyle::styleHint() take the QWidget as optional third parameter. Add
this to calls to styleHint() where appropriate.

Fixes: QTBUG-2501
Pick-to: 6.8
Change-Id: Id4e4158cc889236064f2f618495608736607d457
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit aa341ecca816e3503a834ffde0ec6cb817139427)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 16:46:27 +00:00
Thiago Macieira
ff303c5cd9 QMutex/FreeBSD: mark the functions as noexcept as it always has futex
See qfutex_freebsd_p.h.

Pick-to: 6.8
Change-Id: I7e7bbb8387ae2e7b0c39fffd65c7b03e3a65a853
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit c1bc98da02f0f9335e10f45cc5df4c7e3afcee31)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 16:40:35 +00:00
Fabian Kosmale
510f8005bc moc: Always indentify as moc
External tools might rely on the output of "moc --version" to identify
moc, and, depending on how robust their parsing is, could break if the
reported name does not equal "moc".

Explicitly set the application name to moc, so that even if the moc
binary gets renamed and invoked via a symlink, it will still correctly
identify itself.

This might help with both binaries from the Qt Company's installer, as
well as with distros which rename moc to moc6.

Pick-to: 6.8 6.5
Task-number: QLS-1605
Change-Id: Id85e2ffa17d445213da0b37e7bd038d7b68e2c2a
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit 47be32b761ea6e1f2c1bfa9dd9eb38846ce2fd45)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 16:40:35 +00:00
Thiago Macieira
e9509291ae QSharedMemorySystemV: fix shm vs sem typo
Fixes: QTBUG-132053
Pick-to: 6.8
Change-Id: Ia4f2bdc8edff91020f13fffd79261a9feaf2f496
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 902058e750e67bbfb166db576c538b7add9be08f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 16:40:35 +00:00
Thiago Macieira
7664b826db QMetaType: remove the temporary QMetaTypeTypeFlags compatibility
Amends 44876fb45e702c2554fca98ed19af57feb1c0511.

Change-Id: I5ea354bcb6847e996081fffd012130562999d5c4
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit e48fe10e541c6dec9db4226f8ad02728de7b0e02)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 16:40:34 +00:00
Ivan Solovev
8bd0625f54 [docs] Add QSpan details to overview of C++20 features
Document that QSpan exists because we cannot use std::span, and
explicitly point to the differences between QSpan and std::span.

Task-number: QTBUG-128837
Pick-to: 6.8
Change-Id: I54f406e3306ee1da136107323887f0c87f94ff9b
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
(cherry picked from commit 083ebfa1a5cb16b0b62ae5b5855a602b2f9ba818)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 16:40:34 +00:00
Eirik Aavitsland
4d009678ce Fix in-place conversion of certain QImage formats
In the copying/transcription of the generic converter to the generic
in-place converter, a test for Format_RGB32 destination format was
mistakenly replaced with test of source format. The result was that a
suboptimal pixel store function was selected, and the resulting image
data could end up with non-0xff in the unused alpha field.

Task-number: QTBUG-132051
Pick-to: 6.8
Change-Id: If3ebf5fdd7ab6e377c8ad479ea38ce665f922b7c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 0ace5ba0357b1614b47cb38a16f4afb2fe8e62db)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 16:40:34 +00:00
Edward Welbourne
e2a0ef30da Fix assertion failure on parsing Feb 29 in a non-leap year
If there's no way to resolve an actual date with the data parsed, then
the date-text given is invalid, so don't try to fix it up.

Pick-to: 6.8 6.5
Fixes: QTBUG-132115
Change-Id: Ic6821bd01394d4dba1be1d25806c372800f8176b
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
(cherry picked from commit 72519aeb237a4085aeb6290b0b4088c690fad106)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 16:40:34 +00:00
Mårten Nordheim
d53feb3da2 QHash: fix small performance regression when detaching with resize
There are two QHashPrivate::Data constructors (and two overloads of
::detached()). Initially the Data ctor that takes a new size always
assumed a resize was happening, and any place where there _may_ be a
resize we would usually detach then rehash.

In an effort to avoid the detach+rehash and instead call detach(d, size)
without the performance overhead of rehashing the call to
reallocationHelper() in this overload of the ctor was changed to verify
that a rehash was actually needed. This had the unfortunate side-effect
of making the compiler no longer inline the reallocationHelper()
function, and it no longer expanded the if-expression with the constant
so it was doing a tight copy-loop with a potential branch in the middle.

In this patch we revert that and make the bool a template argument to
highlight that it should be a constant for better performance (but also
leaving a comment.) Also mark it Q_ALWAYS_INLINE, it has two uses and
they both take advantage of the inlining + expanding the expression.

In theory this might have had an impact on QHash::reserve() calls,
though this code is only relevant when reserve() would cause growth so
the performance regression would hopefully be small compared to all the
other work that would also be needed.

Reverts 45c137d797a85c694897e8b1c5099abacc16e2f5

Pick-to: 6.8
Change-Id: I0d2076a9ded8ca816c54d6ce42d472a23bcbc9fd
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 6c8b6acc894e47a37c4fb443316d9c40d35a144c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 16:40:33 +00:00
Edward Welbourne
7baf9d06b5 Fix typos in qstring.cpp (noticed while reviewing other changes)
Pick-to: 6.8
Change-Id: Ief8a9c429b5cdf424e0c3a57d15b1fcb4fdc963c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 5d5c8d277af77cba069b805074551254c0f0d9c7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 16:40:33 +00:00
Mårten Nordheim
9d7fabb6c2 QHash: call the different detached() overloads depending on resize
Instead of using just the detached() overload taking a new size, call
the two un-sized one when not resizing. The unsized overload is faster
because it is inlining the reallocationHelper() function and expanding
a branch by way of a constant.

And drop the call to rehash in the !isDetached case, if we enter this
branch we willfully 'attach' the detach guard to keep the key and values
alive.

Follow-up change will fix the sized detach() to use a constant again.

Amends d9ad2251d9fff85a18ce5afc62bcb1230cd2820d

Change-Id: Ia1640766b898610d12b5df20d83cefe5ca2d4c36
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit ac2b0b958e97c41b38c42c0789d91de724d567ce)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 16:40:33 +00:00
Marc Mutz
51bfc9da41 Q{Any,Utf8}StringView: fix construction from arrays of unknown size
Like QStringView's, these classes' documentation promised
is_constructible<View,Char[]>, but failed to deliver, because neither
the (const Pointer&) nor the (const Container &) compile for arrays of
unkonwn bounds, and the (const Char*) one is just a QDoc fake.

Apply the same fix as for QStringView: Add a ctor specifically for
arrays of unknown bound, delegating to the (ptr) overload.

The GHS compiler doesn't like the CanConvert static_asserts, so
comment them out for it. The functionality itself is tested by
the from*ArrayWithUnknownSize tests.

[ChangeLog][QtCore][QUtf8StringView/QAnyStringView] Made construction
from arrays of unknown size compile. Such arrays will use the const
Char* constructor, determining the size of the array at runtime.

Pick-to: 6.8 6.5
Fixes: QTBUG-112746
Change-Id: I7acdcae3c5bdf80a0bed673e621d53ef34a92a1e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 734bd05d0a6d37d6488cf8d1b2b9f79b9329d966)
2024-12-13 14:31:08 +01:00
Marc Mutz
1f0dc7635e QLatin1StringView: put qstringfwd.h in control of Q_L1S_VIEW_IS_PRIMARY
Less duplication, matches what we do for q_no_char8_t namespaces, too.

Amends 94addad4dd1c89df9c6820d34b9a90424456c492.

Pick-to: 6.8 6.5
Change-Id: I5d98babcb66d1196d3aed31c33289a1b11212a3d
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 2d2ee569421338dbc07a479a7df2531bd37f0ebe)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 11:27:53 +00:00
Marc Mutz
137da0326a QStringView: use qstringfwd.h
... instead of fwd-declaring a bunch of stuff manually.

Also move the fake QDoc decalaration of a "class QUtf8StringView"
over.

Pick-to: 6.8 6.5
Change-Id: I80bc3240d69f69602c127fc0e8fe694dd46765f1
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 8404c21152ed3e28f8e00d683a494a8e1e25a69a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 11:27:47 +00:00
Ulf Hermann
60d28c8c7c Android: Fix some warnings
Use a static logging category where possible, and check the return value
of QFile::open.

Change-Id: Ieda9f7874d1b88d9bfeb593243eb867d0c274e9f
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit e0ef713a2c6a74fe574481e98f0a582819418ed0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 11:27:42 +00:00
Marc Mutz
e076767bfd qstringfwd.h: don't include qglobal.h
qstringfwd.h is supposed to be a lean header, dragging in all of
qglobal.h perverts the purpose.

This also helps with certain circular-dependency issues that
appeared when attempting to use this header in other low-level
headers.

Amends abe3b4c9b947de5e55085b37840e0d1d6f3aae42.

[ChangeLog][Potentially Source-Incompatible Changes][QtCore] The
qstringfwd.h header no longer includes qglobal.h. A
backwards-compatible fix is to include qglobal.h yourself instead of
relying on the transitive include.

Pick-to: 6.8 6.5
Change-Id: I1726fccfd13b3a058abaf800c1bbf02c320143a4
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
(cherry picked from commit 5def8ff180c67f288bdc6e3c05b96940aeae37c0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 11:27:41 +00:00
Kai Köhne
c76b845d90 Doc: Fix links to QIODeviceBase:: flags
Pick-to: 6.8
Task-number: QTBUG-131484
Change-Id: Iee545986d4fb4765086fecce6532092d4b691ae8
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit d3dad28a51743bb408dee1cf997646a89eb6693b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 09:10:52 +00:00
Kai Köhne
604dcc714a Doc: Improve QTemporaryFile::open() descriptions
Explain the behavior of open() in detail, including the edge
cases (reopening a file). Fix links to QIODeviceBase::OpenMode
flags. Use explicit links to make linking more robust. Use
the same parameter name 'mode' as in the base class.

Pick-to: 6.8
Task-number: QTBUG-131484
Change-Id: I5d01b3bb48a7a439b93c144e6d38482607de8d33
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit adaf1fb107ceb7003313ceb67605f986b74763b1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 09:10:46 +00:00
Kai Köhne
b70e61788f Doc: Improve QProcess setStandardOutputFile description
Fix links to OpenMode flags. While at it, make links explicit so
that future changes breaking implicit linking will cause errors.

Pick-to: 6.8
Task-number: QTBUG-131484
Change-Id: I20b80014eadcbcba6ebebab1ff4db4c345dd434a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 4e85a4f401118f2f7330b673e45b4a0399825ef3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 09:10:39 +00:00
Kai Köhne
5d2f40a14b Doc: Improve QBuffer::open description
Explain the method, instead of just linking to the base method.

Call the argument 'mode' instead of 'flags', like it is done in
the base class.

Force the mentioned QIODeviceBase flags to be links. Use fully
qualified name for the first flag mentioned, but use the short form
for the rest to improve readability.

Pick-to: 6.8
Task-number: QTBUG-131484
Change-Id: I8e9668ffc095ec261e2be54a2dcf16a32e4cb441
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 334460407b7cde1cdab5cfe5abe00175893749c3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 09:10:33 +00:00
Kai Köhne
eb44663eaa Doc: Improve QFile::open description
Force the mentioned QIODeviceBase flags to be links. Use fully
qualified name for the first flag mentioned, but use the short form for
the rest to improve readability.

Mark true and false to be written in code style.

Task-number: QTBUG-131484
Pick-to: 6.8
Change-Id: Iebb0f9c6df382327bc5980e9e06c11deb6658291
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 647bee67150dedbd2a9fd2ddcd265d535e8fd8cf)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-13 09:10:27 +00:00
Marc Mutz
83e18b6540 qstringfwd.h: add missing QString fwd decl
qstringfwd.h should probably fwd declare QString, too :o

Amends abe3b4c9b947de5e55085b37840e0d1d6f3aae42.

Pick-to: 6.8 6.5
Change-Id: I80558c92d1144ead0aade410a8b1810713fed701
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit bc4105c843f666eaeaaa44b5a1f897ffa5824ec7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 20:10:54 +00:00
Marc Mutz
df2f31b9bf qsocketnotifier.cpp: un-break -unity-build
qsocketnotifier.cpp is using a #define to activate a second overload
of QSocketNotifier's activated() signal.

In unity-builds, this overload becomes visible to other TUs and breaks
new-style connect()s¹. In PCH builds, the define comes too late (the
qsocketnotifier.h header was already included by the pch header,
without the define).

Fix by adding qsocketnotifier.cpp to NO_PCH_SOURCES (thereby to
NO_UNITY_BUILD_SOURCES, too).

¹ and the signal's use of QPrivateSignal makes disambiguation by
  qOverload(), or assignment to a function pointer, impossible.

Amends 487dd80bce9c6006f349ccb09222e1c308200f0a(!).

Pick-to: 6.8 6.5 5.15
Change-Id: I40ca3b90f7ecc3116ae78dc952583efa299bcedb
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
(cherry picked from commit a38cebfe23674bb459eed6bbbcac965ebf2b6075)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 20:07:29 +00:00
Marc Mutz
e8605372ba qsettings.cpp: really un-break -unity-build
The use of Space was still ambiguous. Says GCC 14:

  qsettings.cpp: In static member function ‘static bool QConfFileSettingsPrivate::readIniLine(QByteArrayView, qsizetype&, qsizetype&, qsizetype&, qsizetype&)’:
  qsettings.cpp:1564:82: error: reference to ‘Space’ is ambiguous
   1564 |     while (lineStart < dataLen && (charTraits[uint(uchar(data.at(lineStart)))] & Space))
        |                                                                                  ^~~~~
  In file included from unity_0_cxx.cxx:277:
  qjsonparser.cpp:217:5: note: candidates are: ‘<unnamed enum> Space’
    217 |     Space = 0x20,
        |     ^~~~~
  qsettings.cpp:1523:8: note:                 ‘SettingsImpl::<unnamed enum> SettingsImpl::Space’
   1523 | enum { Space = 0x1, Special = 0x2 };
        |        ^~~~~
  qsettings.cpp:1605:71: error: reference to ‘Space’ is ambiguous
   1605 |                 while (i < dataLen && charTraits[uchar(data.at(i))] & Space)
        |                                                                       ^~~~~
  qjsonparser.cpp:217:5: note: candidates are: ‘<unnamed enum> Space’
    217 |     Space = 0x20,
        |     ^~~~~
  qsettings.cpp:1523:8: note:                 ‘SettingsImpl::<unnamed enum> SettingsImpl::Space’
   1523 | enum { Space = 0x1, Special = 0x2 };
        |        ^~~~~

Fix by making Space and Special local aliases (contexpr variables)
instead of importing the whole SettingsImpl namespace.

Amends 4ff65f0e5615b1132ec13c6eeba3647162d8dd0f.

Pick-to: 6.8 6.5
Change-Id: I9e8f2422885121fb02938261fbae6231e62ae46d
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
(cherry picked from commit 057defe283f1db5fa9dfb1d8183b94d441c3707b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 20:07:22 +00:00
Marc Mutz
00f6df326f qresource.cpp: fix -unity-build
GCC 14 complains:

  In file included from unity_0_cxx.cxx:121:
  qresource.cpp:283:7: error: ‘QResourcePrivate’ has a field ‘QList<{anonymous}::QResourceRoot*> QResourcePrivate::related’ whose type has internal linkage [-Werror=subobject-linkage]
    283 | class QResourcePrivate {
        |       ^~~~~~~~~~~~~~~~

(Hot-)fix by adding qresource.cpp to NO_UNITY_BUILD_SOURCES.

Amends fe6dda9bb9310878b408b2421f60acb7135bd8ba.

Pick-to: 6.8
Task-number: QTBUG-132114
Change-Id: Ic414d1cf9e4dad94d4263b3657d31df896c4e417
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 57fab6a1c2df8f52b25f6db4017bb3acfa8e0526)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 20:07:16 +00:00
Marc Mutz
06a209384a tst_QString: extend arg() tests with enums w/o explicit underlying_type
The QtDeclarative code causing QTBUG-131906 hits UB, because it tries
to store -666 in an enum {A, B}, which has a valid range of [0,1],
therefore its underlying_type is uint, yet, as per [conv.prom]/3¹,
integer-promotes to _int_ instead, so in Qt 6.8 would cause the
arg(int) overload to be called, outputting -666, while in Qt 6.9, it's
treated (correctly) as an unsigned value, outputting -666's two's
complement, a positive value.

Add a version of the scenario that does not cause UB.

¹ Thanks to Ahmad Samir for digging up the pertinent legalese.

Task-number: QTBUG-131906
Pick-to: 6.8 6.5
Change-Id: Iba1a04de523a0b4cd1c87deea40c643cf16df14f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit e64fd05fecae291c9d7358d2e47d7170995af256)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 20:07:12 +00:00
Thiago Macieira
b143215c54 QString: update docs to prefer "UTF-32" over "UCS-4"
They are now the same, but the name UTF-32 is preferred over UCS-4.

The original ISO-10646 UCS-4 encoding was allowed to use all 31-bit code
units, from 0 to 0x7FFFFFFF[1] including those above 0x10FFFF, which
correspond to UTF-8's five- and six-byte sequences. Unicode doesn't
allow that and restricts the UTF to the range possible in UTF-16.

Renaming the functions is left as an exercise for the reader.

[1] https://en.wikipedia.org/wiki/UTF-32#History

Pick-to: 6.8
Change-Id: I2f29db62b974cb689585fffd9a6434ae252a7651
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
(cherry picked from commit 973d0c4c5160200c188f81da5df064510315f22d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 19:38:25 +00:00
Marc Mutz
31e3012296 tst_QStringView: verify that char16_t[] args aren't ambiguous for QS/QSV overloads
They are not.

Pick-to: 6.8
Task-number: QTBUG-112746
Change-Id: I2a20d68543f5914690acbcb4f214b1d98681de6a
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
(cherry picked from commit 67990c16a6b631c1d809d1ad656fc941293b3f83)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 19:38:23 +00:00
Thiago Macieira
bb91219b26 QString::fromUcs4: use std::char_traits or wcslen() to find the size
... when the user passes size = -1. std::char_traits<char32_t>::length()
doesn't appear to be an any better implementation than our simple loop,
but maybe some compiler will optimize it.

wcslen() is usually optimized in the C libraries, even for Unix
platforms that hardly ever use it (it's used as a fallback in qustrlen()
for non-x86 Windows systems).

Pick-to: 6.8
Change-Id: Ia143270869a3a7cf5754fffdc17e500fc454397b
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
(cherry picked from commit b98cf4fc4afaf55145c34ba06d61fec38fadc25d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 19:38:19 +00:00
Marc Mutz
2dfc0cb6f6 QStringView: fix construction from arrays of unknown size
The original idea (8b5aa7b6c40d70a7ec15b3ea485f28a142fb247c) of the
separation of array and pointer ctors was to determine string literal
sizes at compile-time in C++11's limited constexpr semantics.

But when the scanning for NUL characters was added to the array ctor
in 107ff4c1d6b5da2cb11c65b2bd9106817f7fdb02, the distinction between
the two ctors became meaningless, because we were able to assume
post-C++11 constexpr to make the Char(0) scan a compile-time action.

Finally, 9e1dc1e8a9fda1a7576cc6377c8a36decff631eb removed the array
ctor in favor of the generic Container ctor. I didn't check whether
the old code handled arrays of unknown size, as in

    extern const char16_t str[];
    QStringView sv = str;
    ~~~
    const char16_t str[] = "str";

but std::size() (and therefore if_compatible_container) surely bails
on such arrays, and if_compatible_pointer also SFINAEs out. As a
consequence, such arrays cannot be used to construct QStringViews atm.

Fix by adding a new constructor for arrays of unknown size, delegating
to the existing pointer overload.

The GHS compiler doesn't like the CanConvert static_asserts, so
comment them out for it. The functionality itself is tested by
the from*ArrayWithUnknownSize tests.

[ChangeLog][QtCore][QStringView] Made construction from arrays of
unknown size compile. Such arrays will use the const Char*
constructor, determining the size of the array at runtime.

Pick-to: 6.8 6.5
Task-number: QTBUG-112746
Change-Id: Ifdb217350d93d38f081c99f14661975491d32076
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 56faffd92bf0ac459a921ec043a6f3b3dba51acc)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 19:38:16 +00:00
Ulf Hermann
2a512fd901 Use inline namespaces rather than "using" for logging categories
Amends commit fa4bd30caa079a3b1e5eac1bb4f17365f456b8f9.

Fixes: QTBUG-132111
Change-Id: Iad7969a1841b8cea162e4b0e6624d02313618ef1
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 529ebb31702e8465a9ba42f4c56c749cb7bf7b75)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 19:38:16 +00:00
Marc Mutz
443bdb9620 tst_QAnyStringView: complete Char[] CanConvert sets
Other view tests test Char[N] and const Char[N] separately. Do the
same here.

For many Char types, the array CanConvert test was missing
completely. Add them.

Pick-to: 6.8 6.5
Change-Id: I1d0b6de394d548554a547f190e74cb8cead6ecd4
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 0bbbbfc78beb2393ceea0de0fa85942f71d0a2ed)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 18:21:54 +00:00
Ahmad Samir
149150ab47 QtSql: fix GCC -Wextra-semi warnings after member function definitions
Pick-to: 6.8
Change-Id: I5b65f543d7a36386181e493d8b9ce0267132d686
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
(cherry picked from commit 291c762802a2f5e1edb6bd9a842663ca5689323a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 18:21:51 +00:00
Marc Mutz
29e2695676 tst_QStringApiSymmetry: test QByteArray(weak)/QByteArrayView overloading
Adding it here since this test case already has all the infrastructure
for the overload test.

Pick-to: 6.8 6.5
Change-Id: I2d7fff9d2d82fed3db2446690a354f939c9a37fc
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 140dac92f2a8ee1f54843f69be4026900a049ee7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 18:21:48 +00:00
Ahmad Samir
dbaef86144 Fix GCC -Wextra-semi warnings with Q* macros
Namely, Q_ENUM, Q_DECLAR_FLAGS, Q_FLAG, Q_DECLARE_EQUALITY_COMPARABLE.

The sanitize-commit (from qtrepotools repo) git hook already warns about
these.

Pick-to: 6.8
Change-Id: If53f446c7c19856c4a5be1e0b0156e1892871dae
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
(cherry picked from commit 8d3601dfe8e6a89cbf0ab0ff8089e232f52c21d2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 18:21:44 +00:00
Marc Mutz
9bcbeea2ad tst_QByteArrayView: check conversion from various QSpans
This is supposed to work, so check it.

Pick-to: 6.8
Change-Id: I201033656f123b09644e5de447cd5d7b038e5155
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 8a3ffe7044249bcfb5185bd87a9713685d48de7b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 18:21:41 +00:00
Ivan Solovev
7044c32963 Fix docs for QSet (in)equality operators
The missing '&' prevented qdoc from generating the docs.

Amends f9f3bf79dccbfcabbd5c59c39f9f018d71b7549f.

Change-Id: I1d8d7a4e2f4c46c4c365cb5a5e38877837881c45
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 03389d47902347e858bbafc990de3ab988c07acf)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 18:21:39 +00:00
Ahmad Samir
8472fc2573 Fix GCC -Wextra-semi after member function definitions
Fixes: QTBUG-132101
Pick-to: 6.8
Change-Id: Ia2e13bdaf11c639c5590639717b5d31140352c44
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 6b951f6c0c09b7d7b473a3951e7b6cec41dbec73)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 18:21:37 +00:00
Volker Hilsheimer
3de6c570fb QFontIconEngine: if we can't find the named glyph, try ligatures
Use QTextLayout to layout and shape the text, which will respect
ligatures. Many icon fonts might not name their icons, but have a
replacement ligature for the actual icon name replacing the text with
the respective glyph.

So if for the name of the icon we get a single glyph run with a single
glyph in it, use that to render the icon.

Change-Id: If0e5c528c3ac4cccdbb7df5fb7fd32ca232f2a66
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
(cherry picked from commit d10e9174fecb91b5c366d57aeb19e6410522a807)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 14:28:37 +00:00
Volker Hilsheimer
8b4a8b1e10 QFontIconEngine: always initialize with a non-merging font
The icon engine needs to be able to rely on glyph indices belonging to
the correct font, and we generally don't want the overhead of iterating
through potential fallbacks if a named glyph or unicode code point
wasn't found in the font.

Assert in the QFontIconEngine constructor that the font we get has the
NoFontMerging strategy bit set.

Amends 2af58490b3d33aab8d08610939fe2b7cab4c469c.

Change-Id: Ib38324aebbeda956c8dd053969d6cf08f7ef3c35
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
(cherry picked from commit 9d47233d2cbbae1aa32240688fcc7a8c08c585d3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 14:28:34 +00:00
Tatiana Borisova
609d34d702 [QDomNodePrivate] delete unnecessary pointer check from the statement
- prev pointer never can be null here, so the check can be deleted.

Ammends 948599e7b71f59fd9c9c0f7f3d1987ec93a23490

Pick-to: 6.8
Change-Id: Ie194f5f0432f6da5f6471328193112c970f623b6
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
(cherry picked from commit d991572a45b2bbdcd43e59586f88487837a2927c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 14:27:27 +00:00
Eirik Aavitsland
49cf61f641 QWidget::mapTo()/mapFrom(): Do not crash if parent argument is invalid
These functions iterate through the parent hierarchy until the widget
given as argument is found. If never found, the code would assert (in
debug mode) or just silently crash (in release mode).

No need to bring down the entire application just because some widget
coordinate calculation is off. Instead, just emit a qWarning and
return cleanly.

Task-number: QTBUG-132072
Pick-to: 6.8
Change-Id: I4d13f46037cdcf855f76e040f941a8a7050ab12b
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
(cherry picked from commit 73221d263823d50e525858d613ce93769698454a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 14:27:25 +00:00
Piotr Wierciński
80e581d91b wasm: Link with FETCH library only for MAIN_MODULE
For dynamic linking only the main module should
link with libraries like "FETCH".
When side modules are linking to libraries as well,
it leads to linking errors.

Change-Id: I83e37add867f1ce2cbcab4801f49266a288a9ceb
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
(cherry picked from commit b7419557b1b0cc1a87aa91131329b65aee44ec34)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-12 13:17:02 +00:00
Tor Arne Vestbø
b3c60bd11f iOS: Iterate accessible interface to find window
Many subclasses of QAccessibleInterface implement window(), but
some don't, and the documentation states that the backend (us)
will traverse ancestors until it finds one with a window.

We were not doing that for iOS, which caused a crash for
QAccessibleTabButton, which doesn't have a window.

In case we ever hit the code path where we can't find a
window we also skip adding the nil element to the array
in createAccessibleElement, as that causes an exception.

Amends 7a512d1267442e646bb7942291197b2b03f4d1cd

Pick-to: 6.8 6.5
Change-Id: I9b758423956e845a01b014022f4d3ab6306be94e
Reviewed-by: Doris Verria <doris.verria@qt.io>
(cherry picked from commit 6689921b9da3780676a416324eafcac98ab211a3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-11 10:49:23 +00:00
Shawn Rutledge
8a7ee8d522 Widgets: ignore unhandled right mouse button presses
In many places this was already done; but there was some old code
remaining where mousePressEvent() simply returned without ignoring the
unhandled event.

Task-number: QTBUG-93486
Task-number: QTBUG-132066
Change-Id: I4a876980b7ef88ee478fa8cfd9f68b5be5b217a2
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit a1175255150d27d50f9690d5f8685b31269d9fa1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-11 09:33:35 +00:00
Ivan Solovev
d0a3db5d93 [doc] Clean-up QSpan docs
QSpan docs use \target commands together with the section headers, to
simplify linking to certain parts of the docs. This approach has its
own drawbacks, though, because the \target link is rendered as-is.
This patch improves usage of the \target commands, making the links
look better.
It does the following changes:
* Moves the \target commands before the related \section2 commands, so
  that the section header is visible when following the \target's link.
* Replaces the \target links with the actual section names in the \sa
  and other places of the docs where the links do not have the custom
  text, because otherwise the target names are actually visible in the
  docs instead of the section headers.

Amends 03e78e5d624d9752d76c7448d58c9d9d15a4dc18,
70dc8d3103fade380caec96f7531432cd8e8adb6, and
ef5ac956c755daa9ea84dabfa1314d104e5c62e4.

Pick-to: 6.8
Change-Id: I045824683f342079e33e89e3ee6f8e2e27a0acf5
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit 10c844f0533daf657a1cbbbb96651e20e5d603ec)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-11 00:51:17 +00:00
Marc Mutz
67adc2227d tst_QStringView: add missing CanConvert from char16_t/wchar_t arrays
QChar[N] and ushort[N] are being checked, it's unclear why char16_t[N]
and wchar_t[N] were missing.

Add them.

Pick-to: 6.8 6.5 5.15
Change-Id: I9a2df2a75886b950e8c2bdec843e3e693e536f86
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 89401858696d63b8a13c945d5db63856a3b6f5ba)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-11 00:06:27 +00:00
Marc Mutz
0c054f6844 Confirm QLatin1StringView can be constructed over arrays of unknown bounds
It can (unlike the other views).

Pick-to: 6.8 6.5 5.15
Task-number: QTBUG-112746
Change-Id: Id976429611c53f1c707de1d989c454507b8f4773
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 01f0305dc6f751d3eb4d1681a2f8f9f3165b547c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-11 00:06:21 +00:00
Shawn Rutledge
f329dd4e16 QWidgetWindow: send QContextMenuEvent even after accepted mouse press
It would be more consistent if we could rely on the accepted state of
the original QMouseEvent to decide whether to follow up with a
QContextMenuEvent; but not all Qt widgets call ignore() on unhandled
mouse events, both in Qt and in external libraries and applications
(including some from KDE). So we should at least wait until Qt 7 to
make this a requirement. It seems sensible to move the check into
QWindow::event() rather than trying to distinguish the window type in
maybeSynthesizeContextMenuEvent(). We merely output a categorized log
message to indicate when the legacy behavior is in effect.

Amends 84a5f50c7766c99f62b22bb4388137e0aa8dd13d

[ChangeLog][QtWidgets] If your QWidget subclass depends on receiving
QContextMenuEvent, and also handles mouse events directly, we
recommend that you call ignore() on unhandled mouse events (such as
right-button events). In Qt 7, we plan to stop sending
QContextMenuEvent if the triggering mouse event is accepted.

Fixes: QTBUG-132066
Change-Id: I454813dab4c387112f161fc28a0ee94570013afa
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
(cherry picked from commit 357c64a99607456133bfabf86d6b67162717cb29)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-10 23:51:13 +00:00
Christian Ehrlicher
75cb14deb8 SQLite: Update SQLite to v3.47.2
[ChangeLog][Third-Party Code] Updated SQLite to v3.47.2

Pick-to: 6.8 6.5 5.15
Change-Id: I3f40198db02c7f9599189ec2a0001f1c294616c8
Reviewed-by: Andy Shaw <andy.shaw@qt.io>
(cherry picked from commit f3d5bdf4bcfe26a17b1b3de07a345586c37263c0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-10 19:58:41 +00:00
Dheerendra Purohit
a77b11c548 QToolBar: Update implicit icon size if style changes
Add logic in QToolBar::changeEvent() to update icon size set via
stylesheet.

Fixes: QTBUG-45949
Pick-to: 6.8
Change-Id: I7fce830a969af8774116f0229153668252b55598
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 18733355689fc3ea336631b9c5ff17e3e983fb28)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-10 17:26:03 +00:00
Lars Schmertmann
43f4706ee8 Android: Fix typo in the documentation of the default log pattern
Pick-to: 6.8 6.5
Task-number: QTBUG-94708
Change-Id: I845f193f1b98219be205b8615f817f3315f4d149
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit 3bec93738ea88b6f2f50f1b5eeb2237f6f43c0b6)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-10 17:26:03 +00:00
Marc Mutz
5c3fd55beb QSpan: document slice() and chop()
Needed to use a weird combination of \c and \a here, as qdoc on
one hand insists that all parameters be documented, and OTOH doesn't
support \a within \c.

Writing anything else than the equivalent code in \c to appease qdoc
would be childish. Equivalent code is the best-possible documentation,
as it leaves no question unanswered.

Task-number: QTBUG-131672
Change-Id: I512872360b7eb212001723f2ba12d4c6eac0b6b0
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
(cherry picked from commit 0afe31fa51a26d12be21c1b9c6e886abb9775441)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-10 17:26:02 +00:00
Edward Welbourne
66da88f428 Fix typo in QTZ constructor docs
There is no fromSecondsAfterUtc(), I was thinking of
fromSecondsAheadOfUtc().

Pick-to: 6.8 6.5
Fixes: QTBUG-131913
Change-Id: I6a89a27d678d23043819b93d5e4120d01002da4a
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit 2bdce97480ed66f0e8e9528fbc8f4f9c3d8487bf)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-10 17:26:02 +00:00
Yuhang Zhao
7c3723b2a9 Minor improvements of windows style
1. Make some global constants constexpr.
2. Make some file-scope global constants static.
3. Use QStringLiteral instead of plain const char*
4. Add "u" to QStringLiteral's content.

Pick-to: 6.8
Change-Id: Icbc105366ba40e970b256fe3da41231a6fb5064b
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
(cherry picked from commit ad06099b93d79a954d133d6822517d4d0a10adbc)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-10 08:26:00 +00:00
Wladimir Leuschner
1a737083f1 QWindows11Style: Override alternate base color in darkmode
The alternate base color in darkmode was wrongly set to the accent color
instead of a lighter color. This patch overrides the alternate base
color for the QWindows11Style.

Fixes: QTBUG-131976
Pick-to: 6.8
Change-Id: Ie8f50b0042ca7bf746224275abc0cd255df7a4ad
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
(cherry picked from commit 79aa4269bcbbedef8206d79318c199df7c8a3c9f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-09 21:54:52 +00:00
Allan Sandfeld Jensen
901731ad78 Add primary RGB color points getter
[ChangeLog][QtGui][QColorSpace] Added primary points getter and setter

Change-Id: Ia4e412b3e63584cf88fa632e5c1d47618d07ebf1
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit bde2292247bf4849852355c0dcc71f97c9daace9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2024-12-09 19:46:45 +00:00
2999 changed files with 108773 additions and 267400 deletions

View File

@ -7,7 +7,7 @@ if (NOT DEFINED QT_SUPERBUILD OR DEFINED QT_REPO_MODULE_VERSION)
set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_LEAN_HEADERS=1")
endif()
set(QT_REPO_MODULE_VERSION "6.11.0")
set(QT_REPO_MODULE_VERSION "6.9.0")
set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1")
set(QT_COPYRIGHT "Copyright (C) The Qt Company Ltd. and other contributors.")
@ -51,13 +51,13 @@ set(QT_MAX_NEW_POLICY_CMAKE_VERSION_QT_APPLE "3.21")
set(QT_SUPPORTED_MIN_MACOS_SDK_VERSION "14")
set(QT_SUPPORTED_MAX_MACOS_SDK_VERSION "15")
set(QT_SUPPORTED_MIN_MACOS_XCODE_VERSION "15")
set(QT_SUPPORTED_MIN_MACOS_VERSION "13")
set(QT_SUPPORTED_MIN_MACOS_VERSION "12")
set(QT_SUPPORTED_MAX_MACOS_VERSION_TESTED "15")
set(QT_SUPPORTED_MIN_IOS_SDK_VERSION "17")
set(QT_SUPPORTED_MAX_IOS_SDK_VERSION "18")
set(QT_SUPPORTED_MIN_IOS_XCODE_VERSION "15")
set(QT_SUPPORTED_MIN_IOS_VERSION "17")
set(QT_SUPPORTED_MIN_IOS_VERSION "16")
set(QT_SUPPORTED_MAX_IOS_VERSION_TESTED "18")
set(QT_SUPPORTED_MIN_VISIONOS_SDK_VERSION "1")

View File

@ -1,4 +0,0 @@
[gerrit]
host=codereview.qt-project.org
project=qt/qtbase
defaultbranch=dev

33
.lgtm.yml Normal file
View File

@ -0,0 +1,33 @@
extraction:
cpp:
prepare:
packages:
- libgl-dev
- libglu-dev
- libpcre2-dev
- libz-dev
- libfreetype6-dev
- libpng-dev
- libjpeg-dev
- libsqlite3-dev
after_prepare:
- mkdir $HOME/cmake-3.17 \
\ && wget -qO- "https://cmake.org/files/v3.17/cmake-3.17.3-Linux-x86_64.tar.gz" \
\ | tar -xzf - --strip-components=1 -C $HOME/cmake-3.17
- export PATH=$HOME/cmake-3.17/bin:$PATH
# Pre-analysis step.
configure:
command:
- "./configure -cmake -opensource -confirm-license -debug -no-pch \
\ -nomake tests -nomake examples -no-harfbuzz \
\ -system-pcre -system-zlib -system-freetype -system-libpng \
\ -system-libjpeg -system-sqlite"
# We skip analyzing the bootstrap library, since the same code is
# built with non-standard flags and false-positives are flagged.
- ninja bootstrap_tools
# Actual analysis.
index:
build_command:
- ninja

View File

@ -24,13 +24,9 @@ project(QtBase
VERSION "${QT_REPO_MODULE_VERSION}"
DESCRIPTION "Qt Base Libraries"
HOMEPAGE_URL "https://qt.io/"
LANGUAGES CXX C
LANGUAGES CXX C ASM
)
if(UNIX AND NOT ANDROID)
enable_language(ASM)
endif()
set(QT_BUILD_EXTRA_IDE_FILE_PATTERNS bin/* libexec/*)
qt_internal_qtbase_build_repo()

View File

@ -1,468 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts as the
successor of the GNU Library Public License, version 2, hence the version
number 2.1.]
Preamble
The licenses for most software are designed to take away your freedom to share
and change it. By contrast, the GNU General Public Licenses are intended to
guarantee your freedom to share and change free software--to make sure the
software is free for all its users.
This license, the Lesser General Public License, applies to some specially
designated software packages--typically libraries--of the Free Software Foundation
and other authors who decide to use it. You can use it too, but we suggest
you first think carefully about whether this license or the ordinary General
Public License is the better strategy to use in any particular case, based
on the explanations below.
When we speak of free software, we are referring to freedom of use, not price.
Our General Public Licenses are designed to make sure that you have the freedom
to distribute copies of free software (and charge for this service if you
wish); that you receive source code or can get it if you want it; that you
can change the software and use pieces of it in new free programs; and that
you are informed that you can do these things.
To protect your rights, we need to make restrictions that forbid distributors
to deny you these rights or to ask you to surrender these rights. These restrictions
translate to certain responsibilities for you if you distribute copies of
the library or if you modify it.
For example, if you distribute copies of the library, whether gratis or for
a fee, you must give the recipients all the rights that we gave you. You must
make sure that they, too, receive or can get the source code. If you link
other code with the library, you must provide complete object files to the
recipients, so that they can relink them with the library after making changes
to the library and recompiling it. And you must show them these terms so they
know their rights.
We protect your rights with a two-step method: (1) we copyright the library,
and (2) we offer you this license, which gives you legal permission to copy,
distribute and/or modify the library.
To protect each distributor, we want to make it very clear that there is no
warranty for the free library. Also, if the library is modified by someone
else and passed on, the recipients should know that what they have is not
the original version, so that the original author's reputation will not be
affected by problems that might be introduced by others.
Finally, software patents pose a constant threat to the existence of any free
program. We wish to make sure that a company cannot effectively restrict the
users of a free program by obtaining a restrictive license from a patent holder.
Therefore, we insist that any patent license obtained for a version of the
library must be consistent with the full freedom of use specified in this
license.
Most GNU software, including some libraries, is covered by the ordinary GNU
General Public License. This license, the GNU Lesser General Public License,
applies to certain designated libraries, and is quite different from the ordinary
General Public License. We use this license for certain libraries in order
to permit linking those libraries into non-free programs.
When a program is linked with a library, whether statically or using a shared
library, the combination of the two is legally speaking a combined work, a
derivative of the original library. The ordinary General Public License therefore
permits such linking only if the entire combination fits its criteria of freedom.
The Lesser General Public License permits more lax criteria for linking other
code with the library.
We call this license the "Lesser" General Public License because it does Less
to protect the user's freedom than the ordinary General Public License. It
also provides other free software developers Less of an advantage over competing
non-free programs. These disadvantages are the reason we use the ordinary
General Public License for many libraries. However, the Lesser license provides
advantages in certain special circumstances.
For example, on rare occasions, there may be a special need to encourage the
widest possible use of a certain library, so that it becomes a de-facto standard.
To achieve this, non-free programs must be allowed to use the library. A more
frequent case is that a free library does the same job as widely used non-free
libraries. In this case, there is little to gain by limiting the free library
to free software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free programs
enables a greater number of people to use a large body of free software. For
example, permission to use the GNU C Library in non-free programs enables
many more people to use the whole GNU operating system, as well as its variant,
the GNU/Linux operating system.
Although the Lesser General Public License is Less protective of the users'
freedom, it does ensure that the user of a program that is linked with the
Library has the freedom and the wherewithal to run that program using a modified
version of the Library.
The precise terms and conditions for copying, distribution and modification
follow. Pay close attention to the difference between a "work based on the
library" and a "work that uses the library". The former contains code derived
from the library, whereas the latter must be combined with the library in
order to run.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other program
which contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Lesser General
Public License (also called "this License"). Each licensee is addressed as
"you".
A "library" means a collection of software functions and/or data prepared
so as to be conveniently linked with application programs (which use some
of those functions and data) to form executables.
The "Library", below, refers to any such software library or work which has
been distributed under these terms. A "work based on the Library" means either
the Library or any derivative work under copyright law: that is to say, a
work containing the Library or a portion of it, either verbatim or with modifications
and/or translated straightforwardly into another language. (Hereinafter, translation
is included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for making modifications
to it. For a library, complete source code means all the source code for all
modules it contains, plus any associated interface definition files, plus
the scripts used to control compilation and installation of the library.
Activities other than copying, distribution and modification are not covered
by this License; they are outside its scope. The act of running a program
using the Library is not restricted, and output from such a program is covered
only if its contents constitute a work based on the Library (independent of
the use of the Library in a tool for writing it). Whether that is true depends
on what the Library does and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's complete source
code as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice and disclaimer
of warranty; keep intact all the notices that refer to this License and to
the absence of any warranty; and distribute a copy of this License along with
the Library.
You may charge a fee for the physical act of transferring a copy, and you
may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Library or any portion of it,
thus forming a work based on the Library, and copy and distribute such modifications
or work under the terms of Section 1 above, provided that you also meet all
of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices stating that
you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no charge to all
third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a table of
data to be supplied by an application program that uses the facility, other
than as an argument passed when the facility is invoked, then you must make
a good faith effort to ensure that, in the event an application does not supply
such function or table, the facility still operates, and performs whatever
part of its purpose remains meaningful.
(For example, a function in a library to compute square roots has a purpose
that is entirely well-defined independent of the application. Therefore, Subsection
2d requires that any application-supplied function or table used by this function
must be optional: if the application does not supply it, the square root function
must still compute square roots.)
These requirements apply to the modified work as a whole. If identifiable
sections of that work are not derived from the Library, and can be reasonably
considered independent and separate works in themselves, then this License,
and its terms, do not apply to those sections when you distribute them as
separate works. But when you distribute the same sections as part of a whole
which is a work based on the Library, the distribution of the whole must be
on the terms of this License, whose permissions for other licensees extend
to the entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest your
rights to work written entirely by you; rather, the intent is to exercise
the right to control the distribution of derivative or collective works based
on the Library.
In addition, mere aggregation of another work not based on the Library with
the Library (or with a work based on the Library) on a volume of a storage
or distribution medium does not bring the other work under the scope of this
License.
3. You may opt to apply the terms of the ordinary GNU General Public License
instead of this License to a given copy of the Library. To do this, you must
alter all the notices that refer to this License, so that they refer to the
ordinary GNU General Public License, version 2, instead of to this License.
(If a newer version than version 2 of the ordinary GNU General Public License
has appeared, then you can specify that version instead if you wish.) Do not
make any other change in these notices.
Once this change is made in a given copy, it is irreversible for that copy,
so the ordinary GNU General Public License applies to all subsequent copies
and derivative works made from that copy.
This option is useful when you wish to copy part of the code of the Library
into a program that is not a library.
4. You may copy and distribute the Library (or a portion or derivative of
it, under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you accompany it with the complete corresponding
machine-readable source code, which must be distributed under the terms of
Sections 1 and 2 above on a medium customarily used for software interchange.
If distribution of object code is made by offering access to copy from a designated
place, then offering equivalent access to copy the source code from the same
place satisfies the requirement to distribute the source code, even though
third parties are not compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the Library, but
is designed to work with the Library by being compiled or linked with it,
is called a "work that uses the Library". Such a work, in isolation, is not
a derivative work of the Library, and therefore falls outside the scope of
this License.
However, linking a "work that uses the Library" with the Library creates an
executable that is a derivative of the Library (because it contains portions
of the Library), rather than a "work that uses the library". The executable
is therefore covered by this License. Section 6 states terms for distribution
of such executables.
When a "work that uses the Library" uses material from a header file that
is part of the Library, the object code for the work may be a derivative work
of the Library even though the source code is not. Whether this is true is
especially significant if the work can be linked without the Library, or if
the work is itself a library. The threshold for this to be true is not precisely
defined by law.
If such an object file uses only numerical parameters, data structure layouts
and accessors, and small macros and small inline functions (ten lines or less
in length), then the use of the object file is unrestricted, regardless of
whether it is legally a derivative work. (Executables containing this object
code plus portions of the Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may distribute
the object code for the work under the terms of Section 6. Any executables
containing that work also fall under Section 6, whether or not they are linked
directly with the Library itself.
6. As an exception to the Sections above, you may also combine or link a "work
that uses the Library" with the Library to produce a work containing portions
of the Library, and distribute that work under terms of your choice, provided
that the terms permit modification of the work for the customer's own use
and reverse engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the Library
is used in it and that the Library and its use are covered by this License.
You must supply a copy of this License. If the work during execution displays
copyright notices, you must include the copyright notice for the Library among
them, as well as a reference directing the user to the copy of this License.
Also, you must do one of these things:
a) Accompany the work with the complete corresponding machine-readable source
code for the Library including whatever changes were used in the work (which
must be distributed under Sections 1 and 2 above); and, if the work is an
executable linked with the Library, with the complete machine-readable "work
that uses the Library", as object code and/or source code, so that the user
can modify the Library and then relink to produce a modified executable containing
the modified Library. (It is understood that the user who changes the contents
of definitions files in the Library will not necessarily be able to recompile
the application to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the Library. A
suitable mechanism is one that (1) uses at run time a copy of the library
already present on the user's computer system, rather than copying library
functions into the executable, and (2) will operate properly with a modified
version of the library, if the user installs one, as long as the modified
version is interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at least three years,
to give the same user the materials specified in Subsection 6a, above, for
a charge no more than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy from a designated
place, offer equivalent access to copy the above specified materials from
the same place.
e) Verify that the user has already received a copy of these materials or
that you have already sent this user a copy.
For an executable, the required form of the "work that uses the Library" must
include any data and utility programs needed for reproducing the executable
from it. However, as a special exception, the materials to be distributed
need not include anything that is normally distributed (in either source or
binary form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component itself
accompanies the executable.
It may happen that this requirement contradicts the license restrictions of
other proprietary libraries that do not normally accompany the operating system.
Such a contradiction means you cannot use both them and the Library together
in an executable that you distribute.
7. You may place library facilities that are a work based on the Library side-by-side
in a single library together with other library facilities not covered by
this License, and distribute such a combined library, provided that the separate
distribution of the work based on the Library and of the other library facilities
is otherwise permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work based on the
Library, uncombined with any other library facilities. This must be distributed
under the terms of the Sections above.
b) Give prominent notice with the combined library of the fact that part of
it is a work based on the Library, and explaining where to find the accompanying
uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute the Library
except as expressly provided under this License. Any attempt otherwise to
copy, modify, sublicense, link with, or distribute the Library is void, and
will automatically terminate your rights under this License. However, parties
who have received copies, or rights, from you under this License will not
have their licenses terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not signed
it. However, nothing else grants you permission to modify or distribute the
Library or its derivative works. These actions are prohibited by law if you
do not accept this License. Therefore, by modifying or distributing the Library
(or any work based on the Library), you indicate your acceptance of this License
to do so, and all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the Library),
the recipient automatically receives a license from the original licensor
to copy, distribute, link with or modify the Library subject to these terms
and conditions. You may not impose any further restrictions on the recipients'
exercise of the rights granted herein. You are not responsible for enforcing
compliance by third parties with this License.
11. If, as a consequence of a court judgment or allegation of patent infringement
or for any other reason (not limited to patent issues), conditions are imposed
on you (whether by court order, agreement or otherwise) that contradict the
conditions of this License, they do not excuse you from the conditions of
this License. If you cannot distribute so as to satisfy simultaneously your
obligations under this License and any other pertinent obligations, then as
a consequence you may not distribute the Library at all. For example, if a
patent license would not permit royalty-free redistribution of the Library
by all those who receive copies directly or indirectly through you, then the
only way you could satisfy both it and this License would be to refrain entirely
from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents
or other property right claims or to contest validity of any such claims;
this section has the sole purpose of protecting the integrity of the free
software distribution system which is implemented by public license practices.
Many people have made generous contributions to the wide range of software
distributed through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing to
distribute software through any other system and a licensee cannot impose
that choice.
This section is intended to make thoroughly clear what is believed to be a
consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in certain
countries either by patents or by copyrighted interfaces, the original copyright
holder who places the Library under this License may add an explicit geographical
distribution limitation excluding those countries, so that distribution is
permitted only in or among countries not thus excluded. In such case, this
License incorporates the limitation as if written in the body of this License.
13. The Free Software Foundation may publish revised and/or new versions of
the Lesser General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to address
new problems or concerns.
Each version is given a distinguishing version number. If the Library specifies
a version number of this License which applies to it and "any later version",
you have the option of following the terms and conditions either of that version
or of any later version published by the Free Software Foundation. If the
Library does not specify a license version number, you may choose any version
ever published by the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free programs
whose distribution conditions are incompatible with these, write to the author
to ask for permission. For software which is copyrighted by the Free Software
Foundation, write to the Free Software Foundation; we sometimes make exceptions
for this. Our decision will be guided by the two goals of preserving the free
status of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY
"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES
OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest possible
use to the public, we recommend making it free software that everyone can
redistribute and change. You can do so by permitting redistribution under
these terms (or, alternatively, under the terms of the ordinary General Public
License).
To apply these terms, attach the following notices to the library. It is safest
to attach them to the start of each source file to most effectively convey
the exclusion of warranty; and each file should have at least the "copyright"
line and a pointer to where the full notice is found.
<one line to give the library's name and an idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option)
any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc., 51
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your school,
if any, to sign a "copyright disclaimer" for the library, if necessary. Here
is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in
the library `Frob' (a library for tweaking knobs) written
by James Random Hacker.
< signature of Ty Coon > , 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -26,7 +26,7 @@ path = ["bin/*", "coin/**","libexec/*","**_clang-format", "**.cmake", "**.conf",
"**.pro", "**.pri", "**.yaml", "cmake/**.in", "cmake/ios/LaunchScreen.storyboard",
"cmake/**md", "**.yml", "**.dynlist", "cmake/**.plist",
"src/corelib/global/qconfig.cpp.in", "src/corelib/Qt6CoreConfigureFileTemplate.in",
"**.cfg", "**/Makefile", "**/CMakeLists.txt", "**.qrc", ".tag"]
"**.cfg"]
precedence = "closest"
comment = "build system"
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
@ -39,48 +39,29 @@ SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
SPDX-License-Identifier = "CC0-1.0"
[[annotations]]
path = ["**/.gitattributes", "**.gitignore", "**.gitreview"]
path = [".tag", "**/.gitattributes", "**.gitignore"]
precedence = "closest"
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
SPDX-License-Identifier = "BSD-3-Clause"
[[annotations]]
path = ["**/snippets/**", "examples/**", "src/tools/qlalr/examples/**"]
path = ["**/snippets/**", "**/doc/**/images/**", "examples/**"]
comment = "this must be after the build system table because example and snippets take precedence over build system"
precedence = "closest"
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
[[annotations]]
path = ["tests/manual/examples/**", "**/snippets/**"]
precedence = "closest"
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
[[annotations]]
path = ["**/README*", "src/plugins/**/README*", "examples/**/README*", "tests/**/README*",
"src/widgets/doc/snippets/common-table-model/README", "cmake/README.md",
"lib/README", "coin/instructions/README.md", "src/3rdparty/README",
"**.qdocconf", "**.qdocinc", "config_help.txt",
"doc/global/template/style/*", "**/doc/**/images/**"]
"doc/global/template/style/*"]
comment = "documentation"
precedence = "closest"
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"
[[annotations]]
path = ["src/corelib/global/patches/tlexpected/**", "src/corelib/global/qexpected_p.h"]
precedence = "closest"
SPDX-FileCopyrightText = "To the extent possible under law, Sy Brand has waived all copyright and related or neighboring rights to the expected library. This work is published from: United Kingdom."
SPDX-License-Identifier = "CC0-1.0"
[[annotations]]
path = ["src/gui/doc/snippets/textdocument-images/images.qrc"]
precedence = "closest"
comment = "falls under **/doc/**/images/**, which is wrong"
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
[[annotations]]
path = ["src/assets/icons/**.png", "src/assets/icons/**.svg", "src/android/**.xml",
"src/gui/**.xml",
@ -92,13 +73,6 @@ precedence = "closest"
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"
[[annotations]]
path = ["tests/auto/tools/rcc/data/legal/legal.qrc"]
precedence = "override"
comment = "license in file not referring to the file itself"
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
SPDX-License-Identifier = "BSD-3-Clause"
[[annotations]]
path = ["**/qt_attribution.json"]
precedence = "override"
@ -109,7 +83,7 @@ SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-on
path = ["**.toml", "licenseRule.json"]
precedence = "override"
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"
[[annotations]]
path = ["**LICENSE*", "cmake/3rdparty/**/COPYING-CMAKE-SCRIPTS"]

View File

@ -1,45 +0,0 @@
From cbda7ce74d74539ce0baef4a36198081dfb0265c Mon Sep 17 00:00:00 2001
From: Marc Mutz <marc.mutz@qt.io>
Date: Fri, 14 Mar 2025 18:29:20 +0100
Subject: [PATCH] ECMEnableSanitizers.cmake: fix GCC's "note: variable tracking
size limit exceeded" when using asan
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Set the max-vartrack-size parameter to 0 (= unlimited) to avoid GCC's
"note: variable tracking size limit exceeded with
-fvar-tracking-assignments, retrying without" message you get when you
compile with asan sometimes.
This is reported¹ to speed up compilation, not slow it down.
¹ https://stackoverflow.com/a/75704837/134841
---
modules/ECMEnableSanitizers.cmake | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/modules/ECMEnableSanitizers.cmake b/modules/ECMEnableSanitizers.cmake
index 07db1c80..45236e6d 100644
--- a/modules/ECMEnableSanitizers.cmake
+++ b/modules/ECMEnableSanitizers.cmake
@@ -117,6 +117,16 @@ macro (enable_sanitizer_flags sanitize_option)
set(XSAN_COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls")
set(XSAN_LINKER_FLAGS "asan")
endif()
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+ # fixes "note: variable tracking size limit exceeded with
+ # -fvar-tracking-assignments, retrying without" (which is
+ # another way of saying "I'll go ahead and compile this
+ # thing _twice_") by making it unlimited
+ # Reference:
+ # https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
+ # -> max-vartrack-size
+ string(APPEND XSAN_COMPILE_FLAGS " --param=max-vartrack-size=0")
+ endif ()
elseif (${sanitize_option} MATCHES "thread")
check_compiler_version("4.8" "3.1" "99.99")
set(XSAN_COMPILE_FLAGS "-fsanitize=thread")
--
2.25.1

View File

@ -1,42 +0,0 @@
From 8907023584ea0936893269aee890af5995746af5 Mon Sep 17 00:00:00 2001
From: Marc Mutz <marc.mutz@qt.io>
Date: Mon, 17 Mar 2025 10:15:03 +0100
Subject: [PATCH] ECMEnableSanitizers.cmake: replace tabs with spaces
Amends cbda7ce74d74539ce0baef4a36198081dfb0265c.
---
modules/ECMEnableSanitizers.cmake | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/modules/ECMEnableSanitizers.cmake b/modules/ECMEnableSanitizers.cmake
index 45236e6d..8686384d 100644
--- a/modules/ECMEnableSanitizers.cmake
+++ b/modules/ECMEnableSanitizers.cmake
@@ -118,15 +118,15 @@ macro (enable_sanitizer_flags sanitize_option)
set(XSAN_LINKER_FLAGS "asan")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
- # fixes "note: variable tracking size limit exceeded with
- # -fvar-tracking-assignments, retrying without" (which is
- # another way of saying "I'll go ahead and compile this
- # thing _twice_") by making it unlimited
- # Reference:
- # https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
- # -> max-vartrack-size
- string(APPEND XSAN_COMPILE_FLAGS " --param=max-vartrack-size=0")
- endif ()
+ # fixes "note: variable tracking size limit exceeded with
+ # -fvar-tracking-assignments, retrying without" (which is
+ # another way of saying "I'll go ahead and compile this
+ # thing _twice_") by making it unlimited
+ # Reference:
+ # https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
+ # -> max-vartrack-size
+ string(APPEND XSAN_COMPILE_FLAGS " --param=max-vartrack-size=0")
+ endif ()
elseif (${sanitize_option} MATCHES "thread")
check_compiler_version("4.8" "3.1" "99.99")
set(XSAN_COMPILE_FLAGS "-fsanitize=thread")
--
2.25.1

View File

@ -120,7 +120,7 @@ list(APPEND CMAKE_REQUIRED_LIBRARIES "${EGL_LIBRARY}")
list(APPEND CMAKE_REQUIRED_INCLUDES "${EGL_INCLUDE_DIR}")
list(APPEND CMAKE_REQUIRED_DEFINITIONS "${EGL_DEFINITIONS}")
find_package(PlatformGraphics QUIET)
find_package(PlatformGraphics)
if(TARGET PlatformGraphics::PlatformGraphics)
platform_graphics_extend_check_cxx_source_required_variables()
endif()

View File

@ -145,7 +145,7 @@ endforeach()
set(XCB_XCB_component_deps)
set(XCB_COMPOSITE_component_deps XCB XFIXES)
set(XCB_DAMAGE_component_deps XCB XFIXES)
set(XCB_IMAGE_component_deps XCB SHM AUX)
set(XCB_IMAGE_component_deps XCB SHM)
set(XCB_RENDERUTIL_component_deps XCB RENDER)
set(XCB_XFIXES_component_deps XCB RENDER SHAPE)
set(XCB_XVMC_component_deps XCB XV)

View File

@ -118,16 +118,6 @@ macro (enable_sanitizer_flags sanitize_option)
set(XSAN_COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls")
set(XSAN_LINKER_FLAGS "asan")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
# fixes "note: variable tracking size limit exceeded with
# -fvar-tracking-assignments, retrying without" (which is
# another way of saying "I'll go ahead and compile this
# thing _twice_") by making it unlimited
# Reference:
# https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
# -> max-vartrack-size
string(APPEND XSAN_COMPILE_FLAGS " --param=max-vartrack-size=0")
endif ()
elseif (${sanitize_option} MATCHES "thread")
check_compiler_version("4.8" "3.1" "99.99")
set(XSAN_COMPILE_FLAGS "-fsanitize=thread")

View File

@ -21,31 +21,25 @@
# ``DB2::DB2``
# The db2 client library
if(NOT DEFINED DB2_ROOT)
if(DEFINED ENV{DB2_ROOT})
set(DB2_ROOT "$ENV{DB2_ROOT}")
endif()
endif()
if (NOT DEFINED DB2_INCLUDE_DIR)
find_path(DB2_INCLUDE_DIR
NAMES sqlcli1.h
HINTS "${DB2_ROOT}" ENV DB2_HOME
HINTS ENV DB2_HOME
PATH_SUFFIXES include)
else()
find_path(DB2_INCLUDE_DIR
NAMES sqlcli1.h
HINTS "${DB2_INCLUDE_DIR}")
HINTS ${DB2_INCLUDE_DIR})
endif()
if (NOT DEFINED DB2_LIBRARY_DIR)
find_library(DB2_LIBRARY
NAMES db2 db2cli64
HINTS "${DB2_ROOT}" ENV DB2LIB)
NAMES db2
HINTS ENV DB2LIB)
else()
find_library(DB2_LIBRARY
NAMES db2
HINTS "${DB2_LIBRARY_DIR}")
HINTS ${DB2_LIBRARY_DIR})
endif()
include(FindPackageHandleStandardArgs)

View File

@ -21,7 +21,7 @@ else()
set(_includes "${CMAKE_REQUIRED_INCLUDES}")
list(APPEND CMAKE_REQUIRED_INCLUDES "${GLESv2_INCLUDE_DIR}")
find_package(PlatformGraphics QUIET)
find_package(PlatformGraphics)
if(TARGET PlatformGraphics::PlatformGraphics)
platform_graphics_extend_check_cxx_source_required_variables()
endif()

View File

@ -1,10 +0,0 @@
# Copyright (C) 2025 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
find_package(PkgConfig QUIET)
pkg_check_modules(JeMalloc IMPORTED_TARGET "jemalloc")
if (NOT TARGET PkgConfig::JeMalloc)
set(JeMalloc_FOUND 0)
endif()

View File

@ -37,7 +37,16 @@ if (OpenGL_FOUND)
set(__opengl_fw_path "-framework OpenGL")
endif()
find_library(WrapOpenGL_AGL NAMES AGL)
if(WrapOpenGL_AGL)
set(__opengl_agl_fw_path "${WrapOpenGL_AGL}")
endif()
if(NOT __opengl_agl_fw_path)
set(__opengl_agl_fw_path "-framework AGL")
endif()
target_link_libraries(WrapOpenGL::WrapOpenGL INTERFACE ${__opengl_fw_path})
target_link_libraries(WrapOpenGL::WrapOpenGL INTERFACE ${__opengl_agl_fw_path})
else()
target_link_libraries(WrapOpenGL::WrapOpenGL INTERFACE OpenGL::GL)
endif()

View File

@ -25,22 +25,13 @@ if(LIBRESOLV)
list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBRESOLV}")
endif()
cmake_policy(PUSH)
if(POLICY CMP0067)
cmake_policy(SET CMP0067 NEW)
endif()
if(DEFINED CMAKE_CXX_STANDARD)
set(_WrapResolv_CMAKE_CXX_STANDARD_back ${CMAKE_CXX_STANDARD})
endif()
set(CMAKE_CXX_STANDARD 11)
check_cxx_source_compiles("
#include <netinet/in.h>
#include <resolv.h>
int main(int, char **argv)
{
res_state statep = {};
res_state statep = 0;
int n = res_nmkquery(statep, 0, argv[1], 0, 0, NULL, 0, NULL, NULL, 0);
n = res_nsend(statep, NULL, 0, NULL, 0);
n = dn_expand(NULL, NULL, NULL, NULL, 0);
@ -48,14 +39,6 @@ int main(int, char **argv)
}
" HAVE_LIBRESOLV_FUNCTIONS)
if(DEFINED _WrapResolv_CMAKE_CXX_STANDARD_back)
set(CMAKE_CXX_STANDARD ${_WrapResolv_CMAKE_CXX_STANDARD_back})
unset(_WrapResolv_CMAKE_CXX_STANDARD_back)
else()
unset(CMAKE_CXX_STANDARD)
endif()
cmake_policy(POP)
cmake_pop_check_state()
if(HAVE_LIBRESOLV_FUNCTIONS)

View File

@ -9,6 +9,6 @@ $<1: >
Name: @pkgconfig_name@
Description: @pkgconfig_description@
Version: @PROJECT_VERSION@
Libs: @link_options@
Libs: $<$<NOT:@is_interface_library@>:-L${libdir} -l@pkgconfig_file@> @link_options@
Cflags: @include_dirs@ @compile_defs@
Requires: $<JOIN:$<REMOVE_DUPLICATES:@target_requires@>, >

View File

@ -7,6 +7,9 @@ cmake_minimum_required(VERSION @min_new_policy_version@...@max_new_policy_versio
include(CMakeFindDependencyMacro)
get_filename_component(_import_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_import_prefix "${_import_prefix}" REALPATH)
# Extra cmake code begin
@extra_cmake_code@
# Extra cmake code end

View File

@ -105,30 +105,27 @@ function(qt_internal_add_cmake_library target)
)
endif()
_qt_internal_forward_function_args(
FORWARD_PREFIX arg
FORWARD_OUT_VAR extend_target_args
FORWARD_MULTI
SOURCES
NO_PCH_SOURCES
INCLUDE_DIRECTORIES
SYSTEM_INCLUDE_DIRECTORIES
PUBLIC_INCLUDE_DIRECTORIES
PUBLIC_DEFINES
DEFINES
PUBLIC_LIBRARIES
COMPILE_OPTIONS
PUBLIC_COMPILE_OPTIONS
LINK_OPTIONS
PUBLIC_LINK_OPTIONS
MOC_OPTIONS
ENABLE_AUTOGEN_TOOLS
DISABLE_AUTOGEN_TOOLS
)
qt_internal_extend_target("${target}"
${extend_target_args}
SOURCES ${arg_SOURCES}
INCLUDE_DIRECTORIES
${arg_INCLUDE_DIRECTORIES}
SYSTEM_INCLUDE_DIRECTORIES
${arg_SYSTEM_INCLUDE_DIRECTORIES}
PUBLIC_INCLUDE_DIRECTORIES
${arg_PUBLIC_INCLUDE_DIRECTORIES}
PUBLIC_DEFINES
${arg_PUBLIC_DEFINES}
DEFINES
${arg_DEFINES}
PUBLIC_LIBRARIES ${arg_PUBLIC_LIBRARIES}
LIBRARIES ${arg_LIBRARIES} Qt::PlatformCommonInternal
COMPILE_OPTIONS ${arg_COMPILE_OPTIONS}
PUBLIC_COMPILE_OPTIONS ${arg_PUBLIC_COMPILE_OPTIONS}
LINK_OPTIONS ${arg_LINK_OPTIONS}
PUBLIC_LINK_OPTIONS ${arg_PUBLIC_LINK_OPTIONS}
MOC_OPTIONS ${arg_MOC_OPTIONS}
ENABLE_AUTOGEN_TOOLS ${arg_ENABLE_AUTOGEN_TOOLS}
DISABLE_AUTOGEN_TOOLS ${arg_DISABLE_AUTOGEN_TOOLS}
NO_UNITY_BUILD # Disabled by default
)
endfunction()
@ -230,7 +227,7 @@ function(qt_internal_add_3rdparty_library target)
qt_autogen_tools_initial_setup(${target})
endif()
if(NOT arg_EXCEPTIONS)
if(NOT DEFINED arg_EXCEPTIONS)
qt_internal_set_exceptions_flags("${target}" "DEFAULT")
else()
qt_internal_set_exceptions_flags("${target}" "${arg_EXCEPTIONS}")
@ -382,7 +379,7 @@ function(qt_internal_add_3rdparty_library target)
${__qt_internal_sbom_multi_args}
)
qt_internal_extend_qt_entity_sbom(${target} ${sbom_args})
_qt_internal_extend_sbom(${target} ${sbom_args})
endif()
qt_add_list_file_finalizer(qt_internal_finalize_3rdparty_library ${target})

View File

@ -287,189 +287,3 @@ function(qt_internal_android_dependencies target)
COMPONENT
Devel)
endfunction()
function(qt_internal_set_up_build_host_java_docs)
if("${ANDROID_SDK_ROOT}" STREQUAL "")
message(FATAL_ERROR
"QT_HOST_DOCUMENT_JAVA_SOURCES=ON requires setting ANDROID_SDK_ROOT."
)
endif()
_qt_internal_locate_android_jar()
set(QT_ANDROID_JAR "${QT_ANDROID_JAR}" PARENT_SCOPE)
set(QT_ANDROID_API_USED_FOR_JAVA "${QT_ANDROID_API_USED_FOR_JAVA}" PARENT_SCOPE)
endfunction()
# Collect the Java source files that were recorded by qt_internal_add_jar.
# If we're not building for Android, qt_internal_add_jar is not called, and we simple collect
# all java files under the current directory.
function(qt_internal_collect_jar_sources out_var)
if(NOT ANDROID)
file(GLOB_RECURSE sources LIST_DIRECTORIES FALSE "*.java")
set("${out_var}" "${sources}" PARENT_SCOPE)
return()
endif()
set(no_value_options "")
set(single_value_options DIRECTORY)
set(multi_value_options "")
cmake_parse_arguments(PARSE_ARGV 1 arg
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
)
_qt_internal_validate_all_args_are_parsed(arg)
set(directory_arg "")
if(DEFINED arg_DIRECTORY)
set(directory_arg DIRECTORY ${arg_DIRECTORY})
endif()
get_directory_property(result ${directory_arg} _qt_jar_sources)
get_directory_property(subdirs ${directory_arg} SUBDIRECTORIES)
foreach(subdir IN LISTS subdirs)
qt_internal_collect_jar_sources(subdir_result DIRECTORY ${subdir})
if(NOT "${subdir_result}" STREQUAL "")
list(APPEND result ${subdir_result})
endif()
endforeach()
set("${out_var}" "${result}" PARENT_SCOPE)
endfunction()
function(qt_internal_add_javadoc_target)
set(no_value_options "")
set(single_value_options
MODULE
OUTPUT_DIR
)
set(multi_value_options
SOURCES
)
cmake_parse_arguments(PARSE_ARGV 0 arg
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
)
_qt_internal_validate_all_args_are_parsed(arg)
if(TARGET ${arg_MODULE})
get_target_property(skip ${arg_MODULE} _qt_skip_javadoc)
if(skip)
message(VERBOSE "Skipping generation of Android HTML docs for ${arg_MODULE}.")
return()
endif()
endif()
# Collect source directories from source file paths.
set(source_dirs "")
foreach(source_path IN LISTS arg_SOURCES)
get_filename_component(dir_path "${source_path}" DIRECTORY)
list(APPEND source_dirs "${dir_path}")
endforeach()
list(REMOVE_DUPLICATES source_dirs)
# Retrieve package names from source dirs.
set(package_names "")
foreach(source_dir IN LISTS source_dirs)
string(REGEX MATCH "/(org/qtproject/qt/android(/.*|$))" package_dir "${source_dir}")
if(package_dir STREQUAL "")
message(VERBOSE "Java source dir is not a package directory: ${source_dir}")
continue()
endif()
# Store package_dir without leading slash.
set(package_dir "${CMAKE_MATCH_1}")
# Use dots instead of slashes for the package name.
string(REPLACE "/" "." package_name "${package_dir}")
list(APPEND package_names "${package_name}")
endforeach()
# Strip package paths from the source dirs.
list(TRANSFORM source_dirs REPLACE "/org/qtproject/qt/android.*" "")
list(REMOVE_DUPLICATES source_dirs)
# Use the correct separator for the --source-path argument.
if(NOT CMAKE_HOST_WIN32)
string(REPLACE ";" ":" source_dirs "${source_dirs}")
endif()
# Use a response file to avoid quoting issues with the space-separated package names.
set(javadoc_output_dir "${arg_OUTPUT_DIR}/android")
set(response_file "${CMAKE_CURRENT_BINARY_DIR}/doc/.javadocargs")
string(REPLACE ";" " " package_names_space_separated "${package_names}")
file(CONFIGURE
OUTPUT "${response_file}"
CONTENT "${package_names_space_separated}
--class-path \"${QT_ANDROID_JAR}\"
-d \"${javadoc_output_dir}\"
--source-path \"${source_dirs}\""
)
set(module ${arg_MODULE})
set(javadoc_target android_html_docs_${module})
add_custom_target(${javadoc_target} ${command_args}
COMMAND ${Java_JAVADOC_EXECUTABLE} "@${response_file}"
COMMENT "Generating Java documentation"
VERBATIM
)
add_dependencies(docs_android ${javadoc_target})
if (QT_WILL_INSTALL)
install(DIRECTORY "${arg_OUTPUT_DIR}/"
DESTINATION "${INSTALL_DOCDIR}/${module}"
COMPONENT _install_docs_android_${module}
EXCLUDE_FROM_ALL
)
add_custom_target(install_docs_android_${module}
COMMAND ${CMAKE_COMMAND}
--install "${CMAKE_BINARY_DIR}"
--component _install_docs_android_${module}
COMMENT "Installing Android html docs for ${module}"
)
else()
add_custom_target(install_docs_android_${module})
endif()
add_dependencies(install_docs_android_${module} ${javadoc_target})
add_dependencies(install_docs_android install_docs_android_${module})
endfunction()
function(qt_internal_create_source_jar)
set(no_value_options "")
set(single_value_options MODULE)
set(multi_value_options SOURCES)
cmake_parse_arguments(PARSE_ARGV 0 arg
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
)
_qt_internal_validate_all_args_are_parsed(arg)
set(module ${arg_MODULE})
set(jar_target android_source_jar_${module})
set(jar_name ${CMAKE_INSTALL_NAMESPACE}AndroidSources${module})
add_jar(${jar_target}
SOURCES ${arg_SOURCES}
VERSION ${PROJECT_VERSION}
INCLUDE_JARS "${QT_ANDROID_JAR}"
OUTPUT_NAME ${jar_name}
)
set_target_properties(${jar_target} PROPERTIES EXCLUDE_FROM_ALL ON)
add_dependencies(android_source_jars ${jar_target})
if(QT_WILL_INSTALL)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${jar_name}-${PROJECT_VERSION}.jar"
DESTINATION "${INSTALL_DATADIR}/android/${module}"
COMPONENT _install_android_source_jar_${module}
EXCLUDE_FROM_ALL
)
add_custom_target(install_android_source_jar_${module}
COMMAND ${CMAKE_COMMAND}
--install "${CMAKE_BINARY_DIR}"
--component _install_android_source_jar_${module}
COMMENT "Installing Android source jar for ${module}"
)
else()
add_custom_target(install_android_source_jar_${module})
endif()
add_dependencies(install_android_source_jar_${module} ${jar_target})
add_dependencies(install_android_source_jars install_android_source_jar_${module})
endfunction()

View File

@ -154,7 +154,7 @@ function(qt_internal_add_app target)
${__qt_internal_sbom_multi_args}
)
qt_internal_extend_qt_entity_sbom(${target} ${sbom_args})
_qt_internal_extend_sbom(${target} ${sbom_args})
endif()
qt_add_list_file_finalizer(qt_internal_finalize_app ${target})

View File

@ -65,11 +65,6 @@ function(qt_auto_detect_wasm)
endfunction()
function(qt_auto_detect_android)
# Don't assume an Android build if we're requesting to build Java documentation on the host.
if(QT_BUILD_HOST_JAVA_DOCS)
return()
endif()
# We assume an Android build if any of the ANDROID_* cache variables are set.
if(DEFINED ANDROID_SDK_ROOT
OR DEFINED ANDROID_NDK_ROOT
@ -279,9 +274,6 @@ function(qt_auto_detect_apple)
endif()
endif()
_qt_internal_get_apple_sdk_path(apple_sdk_path)
set(QT_APPLE_SDK_PATH "${apple_sdk_path}" CACHE STRING "Darwin SDK path.")
_qt_internal_get_apple_sdk_version(apple_sdk_version)
set(QT_MAC_SDK_VERSION "${apple_sdk_version}" CACHE STRING "Darwin SDK version.")

View File

@ -123,7 +123,10 @@ function(qt_manual_moc result)
set(dep "${QT_CMAKE_EXPORT_NAMESPACE}::${dep}")
endif()
_qt_internal_dealias_target(dep)
get_target_property(alias_dep ${dep} ALIASED_TARGET)
if(alias_dep)
set(dep ${alias_dep})
endif()
get_target_property(loc ${dep} IMPORTED_LOCATION)
string(REGEX REPLACE "(.*)/Qt[^/]+\\.framework.*" "\\1" loc "${loc}")
@ -166,9 +169,6 @@ function(qt_manual_moc result)
set(metatypes_byproducts "${outfile}.json")
endif()
_qt_internal_get_moc_compiler_flavor_flags(flavor_flags)
list(APPEND moc_parameters ${flavor_flags})
if (TARGET Qt::Platform)
get_target_property(_abi_tag Qt::Platform qt_libcpp_abi_tag)
if (_abi_tag)
@ -199,8 +199,8 @@ function(qt_make_output_file infile prefix suffix source_dir binary_dir result)
get_filename_component(outfilename "${infile}" NAME_WE)
set(base_dir "${source_dir}")
_qt_internal_path_is_prefix(binary_dir "${infile}" in_binary)
if(in_binary)
string(FIND "${infile}" "${binary_dir}/" in_binary)
if (in_binary EQUAL 0)
set(base_dir "${binary_dir}")
endif()
@ -214,50 +214,3 @@ function(qt_make_output_file infile prefix suffix source_dir binary_dir result)
file(MAKE_DIRECTORY "${outpath}")
set("${result}" "${outpath}/${prefix}${outfilename}${suffix}" PARENT_SCOPE)
endfunction()
# Work around AUTOGEN issue when a library is added as a dependency more than once, and the autogen
# library dependency results in being discarded. To mitigate that, add all autogen dependencies
# manually, based on the passed in dependencies.
# CMake 4.0+ has a fix, so we don't need the extra logic.
# See https://gitlab.kitware.com/cmake/cmake/-/issues/26700
function(qt_internal_work_around_autogen_discarded_dependencies target)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.0
OR QT_NO_AUTOGEN_DISCARDED_DEPENDENCIES_WORKAROUND)
return()
endif()
set(libraries ${ARGN})
set(final_libraries "")
foreach(lib IN LISTS libraries)
# Skip non-target dependencies.
if(NOT TARGET "${lib}")
continue()
endif()
# Resolve alias targets, because AUTOGEN_TARGET_DEPENDS doesn't seem to handle them.
_qt_internal_dealias_target(lib)
# Skip imported targets, they don't have sync_headers targets.
get_target_property(imported "${lib}" IMPORTED)
if(imported)
continue()
endif()
# Resolve Qt private modules to their public counterparts.
get_target_property(is_private_module "${lib}" _qt_is_private_module)
get_target_property(public_module_target "${lib}" _qt_public_module_target_name)
if(is_private_module AND public_module_target)
set(lib "${public_module_target}")
endif()
# Another TARGET check, just in case.
if(TARGET "${lib}")
list(APPEND final_libraries "${lib}")
endif()
endforeach()
if(final_libraries)
set_property(TARGET ${target} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS "${final_libraries}")
endif()
endfunction()

View File

@ -187,7 +187,7 @@ function(qt_run_config_test_architecture)
list(APPEND QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT TEST_buildAbi)
set(QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT ${QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT} CACHE INTERNAL "Test variables that should be exported")
list(JOIN sub_architecture_${first_arch} " " subarch_summary)
list(JOIN _sub_architecture " " subarch_summary)
set_property(GLOBAL PROPERTY qt_configure_subarch_summary "${subarch_summary}")
endfunction()
@ -274,7 +274,6 @@ function(qt_internal_print_cmake_darwin_info)
endif()
message(STATUS "CMAKE_OSX_ARCHITECTURES: \"${CMAKE_OSX_ARCHITECTURES}\"${default_osx_arch}")
message(STATUS "CMAKE_OSX_SYSROOT: \"$CACHE{CMAKE_OSX_SYSROOT}\" / \"${CMAKE_OSX_SYSROOT}\"")
message(STATUS "QT_APPLE_SDK_PATH: \"${QT_APPLE_SDK_PATH}\"")
message(STATUS "CMAKE_OSX_DEPLOYMENT_TARGET: \"${CMAKE_OSX_DEPLOYMENT_TARGET}\"")
message(STATUS "QT_MAC_SDK_VERSION: \"${QT_MAC_SDK_VERSION}\"")
message(STATUS "QT_MAC_XCODE_VERSION: \"${QT_MAC_XCODE_VERSION}\"")

View File

@ -55,40 +55,13 @@ qt_install(FILES
DESTINATION "${__build_internals_install_dir}"
COMPONENT Devel
)
qt_path_join(__build_internals_standalone_test_template_path
"${CMAKE_CURRENT_SOURCE_DIR}"
"cmake/QtBuildInternals/${__build_internals_standalone_test_template_dir}")
qt_copy_or_install(
DIRECTORY "${__build_internals_standalone_test_template_path}"
DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtBuildInternals/${__build_internals_standalone_test_template_dir}"
DESTINATION "${__build_internals_install_dir}")
# In prefix builds we also need to copy the files into the build dir.
if(QT_WILL_INSTALL)
file(COPY "${__build_internals_standalone_test_template_path}"
DESTINATION "${__build_internals_install_dir}")
endif()
set(__build_internals_extra_files
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtBuildInternals/QtBuildInternalsHelpers.cmake"
)
qt_copy_or_install(
FILES ${__build_internals_extra_files}
DESTINATION "${__build_internals_install_dir}")
# In prefix builds we also need to copy the files into the build dir.
if(QT_WILL_INSTALL)
foreach(__build_internals_file ${__build_internals_extra_files})
file(COPY "${__build_internals_file}" DESTINATION "${__build_internals_install_dir}")
endforeach()
endif()
_qt_internal_append_cmake_configure_depends(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtBuildInternals/${__build_internals_standalone_test_template_dir}/CMakeLists.txt"
${__build_internals_extra_files}
)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtBuildInternals/${__build_internals_standalone_test_template_dir}/CMakeLists.txt")
qt_internal_create_toolchain_file()
@ -285,24 +258,14 @@ qt_copy_or_install(DIRECTORY
)
# Install qt-internal-strip and qt-internal-ninja files.
set(__qt_internal_strip_wrapper_programs
set(__qt_internal_strip_wrappers
libexec/qt-internal-strip.in
libexec/qt-internal-ninja.in
)
set(__qt_internal_strip_wrapper_files
libexec/qt-internal-strip.bat.in
libexec/qt-internal-ninja.in
libexec/qt-internal-ninja.bat.in
)
set(__qt_internal_strip_wrappers
${__qt_internal_strip_wrapper_programs}
${__qt_internal_strip_wrapper_files}
)
qt_copy_or_install(PROGRAMS
${__qt_internal_strip_wrapper_programs}
DESTINATION "${__GlobalConfig_install_dir}/libexec"
)
qt_copy_or_install(FILES
${__qt_internal_strip_wrapper_files}
${__qt_internal_strip_wrappers}
DESTINATION "${__GlobalConfig_install_dir}/libexec"
)
if(QT_WILL_INSTALL)
@ -423,23 +386,9 @@ if(APPLE)
elseif(WASM)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/wasmtestrunner/qt-wasmtestrunner.py"
"${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-wasmtestrunner.py" @ONLY)
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-wasmtestrunner.py"
DESTINATION "${INSTALL_LIBEXECDIR}")
if(QT_FEATURE_shared)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/preload/preload_qml_imports.py"
"${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qml_imports.py" COPYONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/preload/preload_qt_plugins.py"
"${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qt_plugins.py" COPYONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/preload/generate_default_preloads.sh.in"
"${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/generate_default_preloads.sh.in" COPYONLY)
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qml_imports.py"
DESTINATION "${INSTALL_LIBEXECDIR}")
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qt_plugins.py"
DESTINATION "${INSTALL_LIBEXECDIR}")
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/generate_default_preloads.sh.in"
DESTINATION "${INSTALL_LIBEXECDIR}")
endif()
endif()
# Install CI support files to libexec.

View File

@ -97,8 +97,6 @@ macro(qt_internal_qtbase_pre_project_setup)
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtPublicCMakeVersionHelpers.cmake")
qt_internal_check_and_warn_about_unsuitable_cmake_version()
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtPublicCMakeEarlyPolicyHelpers.cmake")
## Add some paths to check for cmake modules:
list(PREPEND CMAKE_MODULE_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
@ -137,7 +135,7 @@ macro(qt_internal_qtbase_install_mkspecs)
LIST_DIRECTORIES TRUE
"${PROJECT_SOURCE_DIR}/mkspecs/*")
foreach(entry IN LISTS mkspecs_subdirs)
if(IS_DIRECTORY ${entry})
if (IS_DIRECTORY ${entry})
qt_copy_or_install(DIRECTORY "${entry}"
DESTINATION ${mkspecs_install_dir}
USE_SOURCE_PERMISSIONS)
@ -145,70 +143,9 @@ macro(qt_internal_qtbase_install_mkspecs)
qt_copy_or_install(FILES "${entry}"
DESTINATION ${mkspecs_install_dir})
endif()
# In prefix builds we also need to copy the files into the build dir.
if(QT_WILL_INSTALL)
file(COPY "${entry}" DESTINATION "${mkspecs_install_dir}")
endif()
endforeach()
endmacro()
function(qt_internal_qtbase_install_wayland_files)
qt_path_join(wlprotocols_build_dir
${QT_BUILD_DIR}
${INSTALL_QT_SHAREDIR}/wayland/protocols)
qt_path_join(wlprotocols_install_dir
${QT_INSTALL_DIR}
${INSTALL_QT_SHAREDIR}/wayland/protocols)
file(GLOB wlprotocols_subdirs
LIST_DIRECTORIES TRUE
"${PROJECT_SOURCE_DIR}/src/3rdparty/wayland/protocols/*")
foreach(entry IN LISTS wlprotocols_subdirs)
if (IS_DIRECTORY "${entry}")
qt_copy_or_install(DIRECTORY "${entry}"
DESTINATION "${wlprotocols_install_dir}"
USE_SOURCE_PERMISSIONS)
if(QT_WILL_INSTALL)
file(COPY "${entry}" DESTINATION "${wlprotocols_build_dir}")
endif()
else()
qt_copy_or_install(FILES "${entry}"
DESTINATION "${wlprotocols_install_dir}")
if(QT_WILL_INSTALL)
file(COPY "${entry}" DESTINATION "${wlprotocols_build_dir}")
endif()
endif()
endforeach()
qt_path_join(wlextensions_build_dir
${QT_BUILD_DIR}
${INSTALL_QT_SHAREDIR}/wayland/extensions)
qt_path_join(wlextensions_install_dir
${QT_INSTALL_DIR}
${INSTALL_QT_SHAREDIR}/wayland/extensions)
file(GLOB wlextensions_subdirs
LIST_DIRECTORIES TRUE
"${PROJECT_SOURCE_DIR}/src/3rdparty/wayland/extensions/*")
foreach(entry IN LISTS wlextensions_subdirs)
if (IS_DIRECTORY "${entry}")
qt_copy_or_install(DIRECTORY "${entry}"
DESTINATION "${wlextensions_install_dir}"
USE_SOURCE_PERMISSIONS)
if(QT_WILL_INSTALL)
file(COPY "${entry}" DESTINATION "${wlextensions_build_dir}")
endif()
else()
qt_copy_or_install(FILES "${entry}"
DESTINATION "${wlextensions_install_dir}")
if(QT_WILL_INSTALL)
file(COPY "${entry}" DESTINATION "${wlextensions_build_dir}")
endif()
endif()
endforeach()
endfunction()
macro(qt_internal_qtbase_build_repo)
qt_internal_qtbase_pre_project_setup()
@ -245,8 +182,6 @@ macro(qt_internal_qtbase_build_repo)
include(src/corelib/Qt6WasmMacros.cmake)
endif()
include(src/tools/qtwaylandscanner/Qt6WaylandCompositorMacros.cmake)
## Targets for global features, etc.:
include(QtBaseGlobalTargets)
@ -282,7 +217,6 @@ macro(qt_internal_qtbase_build_repo)
endif()
qt_internal_qtbase_install_mkspecs()
qt_internal_qtbase_install_wayland_files()
endif()
qt_build_repo_post_process()

View File

@ -34,23 +34,6 @@ endmacro()
macro(qt_internal_top_level_setup_after_project)
qt_internal_top_level_setup_testing()
qt_internal_top_level_setup_cmake_and_export_namespace()
endmacro()
# Setting QT_CMAKE_EXPORT_NAMESPACE in the top-level scope is needed for any deferred call that is
# run on the top-level scope (CMAKE_BINARY_DIR).
macro(qt_internal_top_level_setup_cmake_and_export_namespace)
# Include the file that defines qt_internal_setup_cmake_and_export_namespace.
# We don't try to call find_package(QtBuildInternals) because that has a lot more side
# effects.
set(__qt6_build_internals_helpers_path
"${__qt6_qtbase_src_path}/cmake/QtBuildInternals/QtBuildInternalsHelpers.cmake")
if(NOT EXISTS "${__qt6_build_internals_helpers_path}")
message(FATAL_ERROR "Required file does not exist: '${__qt6_build_internals_helpers_path}'")
endif()
include("${__qt6_build_internals_helpers_path}")
qt_internal_setup_cmake_and_export_namespace()
endmacro()
macro(qt_internal_top_level_setup_testing)

View File

@ -227,7 +227,6 @@ function(qt_internal_get_qt_build_private_files_to_install out_var)
ModuleDescription.json.in
PkgConfigLibrary.pc.in
Qt3rdPartyLibraryConfig.cmake.in
QtTransitiveExtras.cmake.in
QtBaseTopLevelHelpers.cmake
QtBuild.cmake
QtBuildHelpers.cmake
@ -304,7 +303,6 @@ function(qt_internal_get_qt_build_public_helpers out_var)
QtPublicSbomOpsHelpers
QtPublicSbomPurlHelpers
QtPublicSbomPythonHelpers
QtPublicSbomQtEntityHelpers
QtPublicSbomSystemDepHelpers
QtPublicTargetHelpers
QtPublicTestHelpers
@ -322,7 +320,6 @@ function(qt_internal_get_qt_build_public_files_to_install out_var)
set(${out_var}
QtCopyFileIfDifferent.cmake
QtInitProject.cmake
QtPublicCMakeEarlyPolicyHelpers.cmake
# Public CMake files that are installed next Qt6Config.cmake, but are NOT included by it.
# Instead they are included by the generated CMake toolchain file.
@ -363,8 +360,7 @@ endfunction()
macro(qt_internal_setup_find_host_info_package)
_qt_internal_determine_if_host_info_package_needed(__qt_build_requires_host_info_package)
_qt_internal_find_host_info_package("${__qt_build_requires_host_info_package}"
${INSTALL_CMAKE_NAMESPACE})
_qt_internal_find_host_info_package("${__qt_build_requires_host_info_package}")
endmacro()
macro(qt_internal_setup_poor_mans_scope_finalizer)
@ -446,10 +442,8 @@ macro(qt_internal_setup_build_and_global_variables)
qt_internal_setup_build_examples()
qt_internal_set_qt_host_path()
qt_internal_setup_find_host_info_package()
qt_internal_setup_build_docs()
qt_internal_setup_build_java_docs_on_host()
qt_internal_include_qt_platform_android()
@ -469,6 +463,7 @@ macro(qt_internal_setup_build_and_global_variables)
qt_internal_check_msvc_versions()
qt_internal_check_host_path_set_for_cross_compiling()
qt_internal_setup_android_platform_specifics()
qt_internal_setup_find_host_info_package()
qt_internal_setup_tool_path_command()
qt_internal_setup_default_target_function_options()
qt_internal_set_default_rpath_settings()
@ -493,3 +488,4 @@ macro(qt_internal_setup_build_and_global_variables)
qt_internal_detect_dirty_features()
endmacro()

View File

@ -555,54 +555,11 @@ function(qt_configure_add_report_error error)
qt_configure_add_report_entry(TYPE ERROR MESSAGE "${error}" CONDITION TRUE ${ARGN})
endfunction()
# Goes through each token in given in `CONDITION` or `COMPILE_TESTS_TO_SHOW_ON_ERROR`, checks if
# the token starts with TEST_ which means it represents a Qt compile test, queries its
# compile output if available, and appends it to `out_var`.
# The compile output for a test is only available on first configuration, because we don't cache it
# across cmake invocations.
function(qt_internal_get_try_compile_output_from_tests_in_condition out_var)
set(opt_args "")
set(single_args "")
set(multi_args
CONDITION
COMPILE_TESTS_TO_SHOW_ON_ERROR
)
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
set(content "")
foreach(token IN LISTS arg_CONDITION arg_COMPILE_TESTS_TO_SHOW_ON_ERROR)
if(token MATCHES "TEST_(.+)")
set(name "${CMAKE_MATCH_1}")
get_cmake_property(try_compile_output _qt_run_config_compile_test_output_${name})
if(try_compile_output)
string(APPEND content "\n TEST_${name} output: \n\n${try_compile_output}")
endif()
else()
continue()
endif()
endforeach()
if(content)
string(PREPEND content "\n Compile test outputs:\n")
endif()
set(${out_var} "${content}" PARENT_SCOPE)
endfunction()
function(qt_configure_process_add_report_entry)
set(opt_args "")
set(single_args
TYPE
MESSAGE
)
set(multi_args
CONDITION
COMPILE_TESTS_TO_SHOW_ON_ERROR
)
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
cmake_parse_arguments(PARSE_ARGV 0 arg
""
"TYPE;MESSAGE"
"CONDITION")
_qt_internal_validate_all_args_are_parsed(arg)
set(possible_types NOTE WARNING ERROR FATAL_ERROR)
@ -634,23 +591,6 @@ function(qt_configure_process_add_report_entry)
if("${arg_CONDITION}" STREQUAL "" OR condition_result)
set(new_report "${prefix}${arg_MESSAGE}")
set(compile_test_args "")
if(arg_CONDITION)
list(APPEND compile_test_args CONDITION ${arg_CONDITION})
endif()
if(arg_COMPILE_TESTS_TO_SHOW_ON_ERROR)
list(APPEND compile_test_args
COMPILE_TESTS_TO_SHOW_ON_ERROR ${arg_COMPILE_TESTS_TO_SHOW_ON_ERROR})
endif()
qt_internal_get_try_compile_output_from_tests_in_condition(extra_output
${compile_test_args}
)
if(extra_output)
string(APPEND new_report "\n${extra_output}")
endif()
string(APPEND "${contents_var}" "\n${new_report}")
if(arg_TYPE STREQUAL "ERROR" OR arg_TYPE STREQUAL "FATAL_ERROR")

View File

@ -11,7 +11,18 @@ if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/QtBuildInternalsExtra.cmake")
include(${CMAKE_CURRENT_LIST_DIR}/QtBuildInternalsExtra.cmake)
endif()
include(${CMAKE_CURRENT_LIST_DIR}/QtBuildInternalsHelpers.cmake)
macro(qt_internal_setup_cmake_and_export_namespace)
# The variables might have already been set in QtBuildInternalsExtra.cmake if the file is
# included while building a new module and not QtBase. In that case, stop overriding the value.
if(NOT INSTALL_CMAKE_NAMESPACE)
set(INSTALL_CMAKE_NAMESPACE "Qt${PROJECT_VERSION_MAJOR}"
CACHE STRING "CMake namespace [Qt${PROJECT_VERSION_MAJOR}]")
endif()
if(NOT QT_CMAKE_EXPORT_NAMESPACE)
set(QT_CMAKE_EXPORT_NAMESPACE "Qt${PROJECT_VERSION_MAJOR}"
CACHE STRING "CMake namespace used when exporting targets [Qt${PROJECT_VERSION_MAJOR}]")
endif()
endmacro()
macro(qt_set_up_build_internals_paths)
# Set up the paths for the cmake modules located in the prefix dir. Prepend, so the paths are

View File

@ -1,15 +0,0 @@
# Copyright (C) 2025 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
macro(qt_internal_setup_cmake_and_export_namespace)
# The variables might have already been set in QtBuildInternalsExtra.cmake if the file is
# included while building a new module and not QtBase. In that case, stop overriding the value.
if(NOT INSTALL_CMAKE_NAMESPACE)
set(INSTALL_CMAKE_NAMESPACE "Qt${PROJECT_VERSION_MAJOR}"
CACHE STRING "CMake namespace [Qt${PROJECT_VERSION_MAJOR}]")
endif()
if(NOT QT_CMAKE_EXPORT_NAMESPACE)
set(QT_CMAKE_EXPORT_NAMESPACE "Qt${PROJECT_VERSION_MAJOR}"
CACHE STRING "CMake namespace used when exporting targets [Qt${PROJECT_VERSION_MAJOR}]")
endif()
endmacro()

View File

@ -28,7 +28,7 @@ endif()
# Get the project name base on test directory name
get_filename_component(project_name "${absolute_project_path}" NAME)
project(${project_name} VERSION 6.0.0 LANGUAGES C CXX)
project(${project_name} VERSION 6.0.0 LANGUAGES C CXX ASM)
find_package(Qt6 REQUIRED COMPONENTS BuildInternals Core)

View File

@ -4,9 +4,6 @@
# Includes QtSetup and friends for private CMake API.
set(QT_INTERNAL_IS_STANDALONE_TEST TRUE)
# Make find_package(Qt6 COMPONENTS Foo) pull in FooPrivate too.
set(QT_FIND_PRIVATE_MODULES TRUE)
# Checks minimum CMake version and upgrades policies.
qt_internal_project_setup()

View File

@ -344,9 +344,17 @@ endfunction()
macro(qt_internal_setup_sbom)
qt_internal_compute_sbom_default(_qt_generate_sbom_default)
_qt_internal_setup_sbom(
GENERATE_SBOM_DEFAULT "${_qt_generate_sbom_default}"
)
option(QT_GENERATE_SBOM "Generate SBOM documents in SPDX v2.3 tag:value format."
"${_qt_generate_sbom_default}")
option(QT_SBOM_GENERATE_JSON
"Generate SBOM documents in SPDX v2.3 JSON format if dependencies are available" ON)
option(QT_SBOM_REQUIRE_GENERATE_JSON
"Error out if JSON SBOM generation dependencies are not found." OFF)
option(QT_SBOM_VERIFY "Verify generated SBOM documents." ON)
option(QT_SBOM_REQUIRE_VERIFY
"Error out if SBOM verification dependencies are not found." OFF)
endmacro()
macro(qt_internal_setup_build_examples)
@ -403,16 +411,6 @@ macro(qt_internal_setup_build_docs)
option(QT_BUILD_DOCS "Generate Qt documentation targets" ON)
endmacro()
macro(qt_internal_setup_build_java_docs_on_host)
option(QT_BUILD_HOST_JAVA_DOCS "Generate Java documentation targets on host" OFF)
if(QT_BUILD_HOST_JAVA_DOCS)
find_package(Java)
if(Java_FOUND)
include(UseJava)
endif()
endif()
endmacro()
macro(qt_internal_set_use_ccache)
option(QT_USE_CCACHE "Enable the use of ccache")
if(QT_USE_CCACHE)

View File

@ -160,9 +160,6 @@ macro(qt_internal_setup_configure_install_paths)
qt_configure_process_path(INSTALL_INCLUDEDIR "include" "Header files [PREFIX/include]")
qt_configure_process_path(INSTALL_LIBDIR "lib" "Libraries [PREFIX/lib]")
qt_configure_process_path(INSTALL_MKSPECSDIR "mkspecs" "Mkspecs files [PREFIX/mkspecs]")
qt_configure_process_path(INSTALL_SHAREDIR "share" "Share files [PREFIX/share]")
qt_configure_process_path(INSTALL_QT_SHAREDIR "${INSTALL_SHAREDIR}/qt6"
"Qt namespaced sharedir [SHAREDIR/qt6]")
qt_configure_process_path(INSTALL_ARCHDATADIR "." "Arch-dependent data [PREFIX]")
qt_configure_process_path(INSTALL_PLUGINSDIR
"${INSTALL_ARCHDATADIR}/plugins"
@ -205,15 +202,6 @@ macro(qt_internal_setup_configure_install_paths)
"Module description files directory")
qt_configure_process_path(INSTALL_SBOMDIR "${INSTALL_ARCHDATADIR}/sbom"
"SBOM [PREFIX/sbom]")
# INSTALL_PUBLICBINDIR is processed only if it is not empty
# See usage in qt_internal_generate_user_facing_tools_info
if(NOT "${INSTALL_PUBLICBINDIR}" STREQUAL "")
# A default value is not needed because it is always manually defined
# but as per the documentation it is typically `bin`
qt_configure_process_path(INSTALL_PUBLICBINDIR "bin"
"Symlinked user-facing executables")
endif()
endmacro()
macro(qt_internal_set_cmake_install_libdir)
@ -266,20 +254,3 @@ macro(qt_internal_setup_paths_and_prefixes)
qt_internal_set_qt_apple_support_files_path()
endmacro()
# Returns the prefix for the variables defined by HostInfo package. The prefix
# is based on version information provided by HostInfo. Falls back to current
# project version if ${INSTALL_CMAKE_NAMESPACE}HostInfo_VERSION_MAJOR is not
# defined.
function(qt_internal_get_host_info_var_prefix out_var)
if(${INSTALL_CMAKE_NAMESPACE}HostInfo_VERSION_MAJOR)
set(${out_var} "QT${${INSTALL_CMAKE_NAMESPACE}HostInfo_VERSION_MAJOR}_HOST_INFO"
PARENT_SCOPE)
else()
# This is not a valid way to define the host info versioned prefix, but
# it's backward compatible with Qt versions older than 6.10.
#
# TODO: remove once Qt LTS versions older than 6.10 reach end of life.
set(${out_var} "QT${PROJECT_VERSION_MAJOR}_HOST_INFO" PARENT_SCOPE)
endif()
endfunction()

View File

@ -224,7 +224,7 @@ function(qt_internal_get_example_install_prefix out_var)
# Allow customizing the installation path of the examples. Will be used in CI.
if(QT_INTERNAL_EXAMPLES_INSTALL_PREFIX)
set(qt_example_install_prefix "${QT_INTERNAL_EXAMPLES_INSTALL_PREFIX}")
elseif(QT_BUILD_STANDALONE_EXAMPLES AND NOT QT_NO_FAKE_STANDALONE_EXAMPLE_INSTALL_PREFIX)
elseif(QT_BUILD_STANDALONE_EXAMPLES)
# TODO: We might need to reset and pipe through an empty CMAKE_STAGING_PREFIX if we ever
# try to run standalone examples in the CI when cross-compiling, similar how it's done in
# qt_internal_set_up_fake_standalone_parts_install_prefix.

View File

@ -756,13 +756,6 @@ macro(qt_build_tests)
# Indicates that we are configuring tests now
set(QT_INTERNAL_CONFIGURING_TESTS TRUE)
# Set this as a directory scoped variable, so we can easily check the variable in child
# directories, to prevent certain code from running, like sbom file checks for all targets
# created in tests subdir.
if(NOT QT_BUILD_TESTS_BY_DEFAULT)
set(QT_INTERNAL_TEST_TARGETS_EXCLUDE_FROM_ALL TRUE)
endif()
# Tests are not unity-ready.
set(CMAKE_UNITY_BUILD OFF)

View File

@ -178,10 +178,6 @@ function(qt_internal_configure_qt)
-skip qtactiveqt,qtimageformats,qtlanguageserver,qtsvg
--
-DWARNINGS_ARE_ERRORS=OFF
# When 6.x.y version bumps are not merged in DAG-dependency order, this avoids
# blocking integrations due to mismatch of qtools package version and any of its
# dependencies.
-DQT_NO_PACKAGE_VERSION_INCOMPATIBLE_WARNING=ON
--log-level STATUS
--fresh
-GNinja

View File

@ -1,24 +1,52 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# The common implementation of qt_configure_file functionality.
macro(qt_configure_file_impl)
if(NOT arg_OUTPUT)
message(FATAL_ERROR "No output file provided to qt_configure_file.")
endif()
# We use this check for the cases when the specified CONTENT is empty. The value of arg_CONTENT
# is undefined, but we still want to create a file with empty content.
if(NOT "CONTENT" IN_LIST arg_KEYWORDS_MISSING_VALUES)
if(arg_INPUT)
message(WARNING "Both CONTENT and INPUT are specified. CONTENT will be used to generate"
" output")
endif()
set(template_name "QtFileConfigure.txt.in")
# When building qtbase, use the source template file.
# Otherwise use the installed file (basically wherever Qt6 package is found).
# This should work for non-prefix and superbuilds as well.
if(QtBase_SOURCE_DIR)
set(input_file "${QtBase_SOURCE_DIR}/cmake/${template_name}")
else()
set(input_file "${_qt_6_config_cmake_dir}/${template_name}")
endif()
set(__qt_file_configure_content "${arg_CONTENT}")
elseif(arg_INPUT)
set(input_file "${arg_INPUT}")
else()
message(FATAL_ERROR "No input value provided to qt_configure_file.")
endif()
configure_file("${input_file}" "${arg_OUTPUT}" @ONLY)
endmacro()
# qt_configure_file(OUTPUT output-file <INPUT input-file | CONTENT content>)
# input-file is relative to ${CMAKE_CURRENT_SOURCE_DIR}
# output-file is relative to ${CMAKE_CURRENT_BINARY_DIR}
#
# This function is the universal replacement for file(CONFIGURE CMake command.
# This function is similar to file(GENERATE OUTPUT) except it writes the content
# to the file at configure time, rather than at generate time.
#
# TODO: Once we require 3.18+, this can use file(CONFIGURE) in its implementation,
# or maybe its usage can be replaced by file(CONFIGURE). Until then, it uses
# configure_file() with a generic input file as source, when used with the CONTENT
# signature.
function(qt_configure_file)
cmake_parse_arguments(PARSE_ARGV 0 arg "" "OUTPUT;INPUT;CONTENT" "")
if("CONTENT" IN_LIST ARGV)
if(arg_INPUT)
message(WARNING "Both CONTENT and INPUT are specified. CONTENT will be used to generate"
" output")
endif()
_qt_internal_configure_file(CONFIGURE OUTPUT "${arg_OUTPUT}" CONTENT "${arg_CONTENT}")
elseif(arg_INPUT)
_qt_internal_configure_file(CONFIGURE OUTPUT "${arg_OUTPUT}" INPUT "${arg_INPUT}")
else()
message(FATAL_ERROR "No input value provided to _qt_internal_configure_file.")
endif()
qt_configure_file_impl()
endfunction()
# A version of cmake_parse_arguments that makes sure all arguments are processed and errors out

View File

@ -12,27 +12,12 @@ set(_qt_compiler_warning_flags_off -w)
if (MSVC)
list(APPEND _qt_compiler_warning_flags_on /W3)
# MSVC warns about macros expanding to `defined` when using the
# new preprocessor (so far, default for C11 code, but not C++).
# Suppress the warning, see also the comment below for GCC.
list(APPEND _qt_compiler_warning_flags_on /wd5105)
else()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GHS") # There is no -Wextra flag for GHS compiler.
list(APPEND _qt_compiler_warning_flags_on -Wall)
else()
list(APPEND _qt_compiler_warning_flags_on -Wall -Wextra)
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "17.0.0")
# GCC warns if a macro is expanded to `defined`, but doesn't
# differentiate between object-like and function-like macros.
# The latter generally work everywhere. We don't have fine-grained
# control, so disable the warning (tst_qglobal tests for this
# behavior.)
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118542
list(APPEND _qt_compiler_warning_flags_on -Wno-expansion-to-defined)
endif()
endif()
endif()
set(_qt_compiler_warning_flags_condition

View File

@ -105,7 +105,7 @@ if(MSVC)
if(NOT CLANG)
# -Ob3 was introduced in Visual Studio 2019 version 16.0
# However clang-cl can't recognize it.
string(APPEND QT_CFLAGS_OPTIMIZE " -Ob3")
string(APPEND QT_CFLAGS_OPTIMIZE " -Ob3 ")
endif()
set(QT_CFLAGS_OPTIMIZE_DEBUG "-Od")
set(QT_CFLAGS_OPTIMIZE_SIZE "-O1")

View File

@ -3,10 +3,6 @@
@PACKAGE_INIT@
# This is included before the cmake_minimum_required on purpose.
include("${CMAKE_CURRENT_LIST_DIR}/QtPublicCMakeEarlyPolicyHelpers.cmake")
__qt_internal_save_directory_scope_policy_cmp0156()
cmake_minimum_required(VERSION @min_new_policy_version@...@max_new_policy_version@)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@ConfigExtras.cmake")
@ -43,15 +39,9 @@ if(TARGET @INSTALL_CMAKE_NAMESPACE@::PlatformCommonInternal)
if(NOT _qt_platform_internal_common_target)
set(_qt_platform_internal_common_target @INSTALL_CMAKE_NAMESPACE@::PlatformCommonInternal)
endif()
set(_qt_internal_clang_msvc_frontend FALSE)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
set(_qt_internal_clang_msvc_frontend TRUE)
endif()
set_target_properties(${_qt_platform_internal_common_target}
PROPERTIES
_qt_internal_cmake_generator "${CMAKE_GENERATOR}"
_qt_internal_clang_msvc_frontend "${_qt_internal_clang_msvc_frontend}"
)
unset(_qt_platform_internal_common_target)
endif()
@ -138,12 +128,7 @@ if(QT_DISABLE_NO_DEFAULT_PATH_IN_QT_PACKAGES)
set(__qt_use_no_default_path_for_qt_packages "")
endif()
set(__qt_umbrella_find_components ${@INSTALL_CMAKE_NAMESPACE@_FIND_COMPONENTS})
__qt_internal_handle_find_all_qt_module_packages(__qt_umbrella_find_components
COMPONENTS ${__qt_umbrella_find_components}
)
foreach(module ${__qt_umbrella_find_components})
foreach(module ${@INSTALL_CMAKE_NAMESPACE@_FIND_COMPONENTS})
if(NOT "${QT_HOST_PATH}" STREQUAL ""
AND "${module}" MATCHES "Tools$"
AND NOT "${module}" MATCHES "UiTools$"
@ -154,7 +139,7 @@ foreach(module ${__qt_umbrella_find_components})
# But don't match QtShaderTools and QtTools which are cross-compiled target package names.
# Allow opt out just in case.
get_filename_component(__qt_find_package_host_qt_path
"${@INSTALL_CMAKE_NAMESPACE@HostInfo_DIR}/.." ABSOLUTE)
"${Qt@PROJECT_VERSION_MAJOR@HostInfo_DIR}/.." ABSOLUTE)
set(__qt_backup_cmake_prefix_path "${CMAKE_PREFIX_PATH}")
set(__qt_backup_cmake_find_root_path "${CMAKE_FIND_ROOT_PATH}")
list(PREPEND CMAKE_PREFIX_PATH "${__qt_find_package_host_qt_path}"
@ -165,18 +150,7 @@ foreach(module ${__qt_umbrella_find_components})
_qt_internal_save_find_package_context_for_debugging(@INSTALL_CMAKE_NAMESPACE@${module})
if(@INSTALL_CMAKE_NAMESPACE@${module}_FOUND)
# Tools packages don't usually provide a qt module, so there's no target.
if(TARGET @INSTALL_CMAKE_NAMESPACE@::${module})
get_target_property(__qt_${module}_is_private @INSTALL_CMAKE_NAMESPACE@::${module}
_qt_is_private_module
)
if(__qt_${module}_is_private)
_qt_internal_show_private_module_warning(${module})
endif()
unset(__qt_${module}_is_private)
endif()
else()
if(NOT @INSTALL_CMAKE_NAMESPACE@${module}_FOUND)
find_package(@INSTALL_CMAKE_NAMESPACE@${module}
${@INSTALL_CMAKE_NAMESPACE@_FIND_VERSION}
${_@INSTALL_CMAKE_NAMESPACE@_FIND_PARTS_QUIET}

View File

@ -17,8 +17,7 @@ _qt_internal_setup_qt_host_path(
"${__qt_platform_requires_host_info_package}"
"${__qt_platform_initial_qt_host_path}"
"${__qt_platform_initial_qt_host_path_cmake_dir}")
_qt_internal_find_host_info_package(${__qt_platform_requires_host_info_package}
@INSTALL_CMAKE_NAMESPACE@)
_qt_internal_find_host_info_package(${__qt_platform_requires_host_info_package})
# note: _third_party_deps example: "ICU\\;FALSE\\;1.0\\;i18n uc data;ZLIB\\;FALSE\\;\\;"
set(__qt_third_party_deps "@third_party_deps@")

View File

@ -79,9 +79,4 @@ function(qt_create_qdbusxml2cpp_command target infile)
"${header_file_full}"
"${source_file_full}"
)
set_source_files_properties(
"${header_file_full}"
"${source_file_full}"
PROPERTIES
_qt_syncqt_exclude_from_docs TRUE)
endfunction()

View File

@ -16,43 +16,6 @@ function(qt_internal_add_doc_tool_dependency doc_target tool_name)
endif()
endfunction()
# Adds custom build and install targets to generate documentation for a documentation project
# identified by a cmake target and a path to a .qdocconf file.
#
# Creates custom targets of the form:
# - generate_docs_${target}
# - prepare_docs_${target}
# - html_docs_${target}
# - install_html_docs_${target}
# - etc.
#
# The first two arguments to the function should be <target> <path-to-qdocconf>.
#
# Additional options are:
# INDEX_DIRECTORIES - a list of index directories to pass to qdoc.
#
# DEFINES - extra environment variable assignments of the form ENV_VAR=VALUE, which should be set
# during qdoc execution.
#
# QDOC_EXTRA_ARGS - extra command-line arguments to pass to qdoc in both prepare and generate
# phases.
#
# QDOC_PREPARE_EXTRA_ARGS - extra command-line arguments to pass to qdoc in the prepare phase.
#
# QDOC_GENERATE_EXTRA_ARGS - extra command-line arguments to pass to qdoc in the generate phase.
#
# SHOW_INTERNAL - if set, the --showinternal option is passed to qdoc.
#
# Additional environment variables considered:
# QT_INSTALL_DOCS - directory path where the qt docs were expected to be installed, used for
# linking to other built docs. If not set, defaults to the qtbase or qt5 build directory, or the
# install directory extracted from the BuildInternals package.
#
# QT_QDOC_EXTRA_ARGS, QT_QDOC_PREPARE_EXTRA_ARGS, QT_QDOC_GENERATE_EXTRA_ARGS - same as the options
# but can be set as either environment or cmake variables.
#
# QT_QDOC_SHOW_INTERNAL - same as the option but can be set as either an environment or
# cmake variable.
function(qt_internal_add_docs)
if(NOT QT_BUILD_DOCS)
return()
@ -60,68 +23,39 @@ function(qt_internal_add_docs)
if(${ARGC} EQUAL 1)
# Function called from old generated CMakeLists.txt that was missing the target parameter
if(QT_FEATURE_developer_build)
message(AUTHOR_WARNING
"qt_internal_add_docs called with old signature. Skipping doc generation.")
endif()
return()
endif()
set(error_msg "qt_add_docs called with wrong number of arguments. ")
list(APPEND error_msg
"Should be qt_add_docs\(target_name qdocconf "
"\[INDEX_DIRECTORIES EXTRA_INDEX_DIRS_LIST_TO_ENABLE_QDOC_RESOLVE_LINKS\]\)")
if(NOT ${ARGC} GREATER_EQUAL 2)
message(FATAL_ERROR ${error_msg})
return()
endif()
if(NOT ${ARGC} GREATER_EQUAL 2)
message(FATAL_ERROR
"qt_internal_add_docs called with a wrong number of arguments. "
"The call should be qt_internal_add_docs\(<target> <path-to-qdocconf> [other-options])"
)
endif()
set(target ${ARGV0})
set(qdoc_conf_path ${ARGV1})
set(opt_args
SHOW_INTERNAL
SKIP_JAVADOC
)
set(single_args "")
set(multi_args
INDEX_DIRECTORIES
DEFINES
QDOC_EXTRA_ARGS
QDOC_PREPARE_EXTRA_ARGS
QDOC_GENERATE_EXTRA_ARGS
)
cmake_parse_arguments(PARSE_ARGV 2 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
set(doc_project ${ARGV1})
set(qdoc_extra_args "")
# The INDEX_DIRECTORIES key should enable passing a list of index
# directories as extra command-line arguments to qdoc, in prepare and
# Check if there are more than 2 arguments and pass them
# as extra --indexdir arguments to qdoc in prepare and
# generate phases.
if(arg_INDEX_DIRECTORIES)
foreach(index_directory ${arg_INDEX_DIRECTORIES})
list(APPEND qdoc_extra_args "--indexdir" ${index_directory})
endforeach()
if (${ARGC} GREATER 2)
# The INDEX_DIRECTORIES key should enable passing a list of index
# directories as extra command-line arguments to qdoc.
set(qdocExtraArgs "INDEX_DIRECTORIES;DEFINES")
cmake_parse_arguments(PARSE_ARGV 2 arg "" "" "${qdocExtraArgs}")
if(arg_UNPARSED_ARGUMENTS)
message(FATAL_ERROR ${error_msg})
return()
endif()
if(arg_INDEX_DIRECTORIES)
foreach(index_directory ${arg_INDEX_DIRECTORIES})
list(APPEND qdoc_extra_args "--indexdir" ${index_directory})
endforeach()
endif()
endif()
set(show_internal_env FALSE)
if(DEFINED ENV{QT_QDOC_SHOW_INTERNAL})
set(show_internal_env $ENV{QT_QDOC_SHOW_INTERNAL})
endif()
if(arg_SHOW_INTERNAL OR QT_QDOC_SHOW_INTERNAL OR show_internal_env)
list(APPEND qdoc_extra_args "--showinternal")
endif()
if(arg_QDOC_EXTRA_ARGS)
list(APPEND qdoc_extra_args ${arg_QDOC_EXTRA_ARGS})
endif()
if(QT_QDOC_EXTRA_ARGS)
list(APPEND qdoc_extra_args ${QT_QDOC_EXTRA_ARGS})
endif()
if(DEFINED ENV{QT_QDOC_EXTRA_ARGS})
list(APPEND qdoc_extra_args $ENV{QT_QDOC_EXTRA_ARGS})
endif()
# If a target is not built (which can happen for tools when crosscompiling), we shouldn't try
# to generate docs.
@ -132,9 +66,8 @@ function(qt_internal_add_docs)
set(tool_dependencies_enabled TRUE)
if(NOT "${QT_HOST_PATH}" STREQUAL "")
set(tool_dependencies_enabled FALSE)
qt_internal_get_host_info_var_prefix(host_info_var_prefix)
set(doc_tools_bin "${QT_HOST_PATH}/${${host_info_var_prefix}_BINDIR}")
set(doc_tools_libexec "${QT_HOST_PATH}/${${host_info_var_prefix}_LIBEXECDIR}")
set(doc_tools_bin "${QT_HOST_PATH}/${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_BINDIR}")
set(doc_tools_libexec "${QT_HOST_PATH}/${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_LIBEXECDIR}")
elseif(NOT "${QT_OPTIONAL_TOOLS_PATH}" STREQUAL "")
set(tool_dependencies_enabled FALSE)
set(doc_tools_bin "${QT_OPTIONAL_TOOLS_PATH}/${INSTALL_BINDIR}")
@ -144,8 +77,7 @@ function(qt_internal_add_docs)
set(doc_tools_libexec "${QtBase_BINARY_DIR}/${INSTALL_LIBEXECDIR}")
else()
set(doc_tools_bin "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}")
set(doc_tools_libexec
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_LIBEXECDIR}")
set(doc_tools_libexec "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_LIBEXECDIR}")
endif()
if(CMAKE_HOST_WIN32)
@ -189,18 +121,15 @@ function(qt_internal_add_docs)
set(include_path_args "")
endif()
get_filename_component(doc_target "${qdoc_conf_path}" NAME_WLE)
get_filename_component(doc_target "${doc_project}" NAME_WLE)
if (QT_WILL_INSTALL)
set(qdoc_output_dir "${CMAKE_BINARY_DIR}/${INSTALL_DOCDIR}/${doc_target}")
set(qdoc_qch_output_dir "${CMAKE_BINARY_DIR}/${INSTALL_DOCDIR}")
set(index_dir "${CMAKE_BINARY_DIR}/${INSTALL_DOCDIR}")
else()
set(qdoc_output_dir
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}/${doc_target}")
set(qdoc_qch_output_dir
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
set(index_dir
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
set(qdoc_output_dir "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}/${doc_target}")
set(qdoc_qch_output_dir "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
set(index_dir "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
endif()
# qtattributionsscanner
@ -210,13 +139,12 @@ function(qt_internal_add_docs)
--basedir "${PROJECT_SOURCE_DIR}/.."
--filter "QDocModule=${doc_target}"
-o "${target_bin_dir}/codeattributions.qdoc"
COMMENT "Scanning attributions for ${target}..."
)
# prepare docs target
set(prepare_qdoc_args
-outputdir "${qdoc_output_dir}"
"${target_source_dir}/${qdoc_conf_path}"
"${target_source_dir}/${doc_project}"
-prepare
-indexdir "${index_dir}"
-no-link-errors
@ -229,18 +157,6 @@ function(qt_internal_add_docs)
)
endif()
if(arg_QDOC_PREPARE_EXTRA_ARGS)
list(APPEND prepare_qdoc_args ${arg_QDOC_PREPARE_EXTRA_ARGS})
endif()
if(QT_QDOC_PREPARE_EXTRA_ARGS)
list(APPEND prepare_qdoc_args ${QT_QDOC_PREPARE_EXTRA_ARGS})
endif()
if(DEFINED ENV{QT_QDOC_PREPARE_EXTRA_ARGS})
list(APPEND prepare_qdoc_args $ENV{QT_QDOC_PREPARE_EXTRA_ARGS})
endif()
if(DEFINED ENV{QT_INSTALL_DOCS})
if(NOT EXISTS "$ENV{QT_INSTALL_DOCS}")
message(FATAL_ERROR
@ -251,8 +167,7 @@ function(qt_internal_add_docs)
elseif(QT_SUPERBUILD OR "${PROJECT_NAME}" STREQUAL "QtBase")
set(qt_install_docs_env "${QtBase_BINARY_DIR}/${INSTALL_DOCDIR}")
else()
set(qt_install_docs_env
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
set(qt_install_docs_env "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
endif()
set(qdoc_env_args
@ -272,7 +187,6 @@ function(qt_internal_add_docs)
COMMAND ${CMAKE_COMMAND} -E env ${qdoc_env_args}
${qdoc_bin}
${prepare_qdoc_args}
COMMENT "Running qdoc for ${target}..."
)
add_dependencies(prepare_docs_${target} qattributionsscanner_${target})
@ -284,7 +198,7 @@ function(qt_internal_add_docs)
# generate docs target
set(generate_qdoc_args
-outputdir "${qdoc_output_dir}"
"${target_source_dir}/${qdoc_conf_path}"
"${target_source_dir}/${doc_project}"
-generate
-indexdir "${index_dir}"
"${include_path_args}"
@ -296,18 +210,6 @@ function(qt_internal_add_docs)
)
endif()
if(arg_QDOC_GENERATE_EXTRA_ARGS)
list(APPEND generate_qdoc_args ${arg_QDOC_GENERATE_EXTRA_ARGS})
endif()
if(QT_QDOC_GENERATE_EXTRA_ARGS)
list(APPEND generate_qdoc_args ${QT_QDOC_GENERATE_EXTRA_ARGS})
endif()
if(DEFINED ENV{QT_QDOC_GENERATE_EXTRA_ARGS})
list(APPEND generate_qdoc_args $ENV{QT_QDOC_GENERATE_EXTRA_ARGS})
endif()
foreach(target_prefix generate_top_level_docs generate_repo_docs generate_docs)
set(depends_arg "")
if(tool_dependencies_enabled)
@ -315,9 +217,7 @@ function(qt_internal_add_docs)
endif()
add_custom_target(${target_prefix}_${target}
${depends_arg}
COMMAND ${CMAKE_COMMAND} -E env ${qdoc_env_args} ${qdoc_bin} ${generate_qdoc_args}
COMMENT "Generating documentation for ${target}..."
)
COMMAND ${CMAKE_COMMAND} -E env ${qdoc_env_args} ${qdoc_bin} ${generate_qdoc_args})
endforeach()
add_dependencies(generate_docs_${target} prepare_docs_${target})
@ -343,7 +243,6 @@ function(qt_internal_add_docs)
COMMAND ${qhelpgenerator_bin}
"${qdoc_output_dir}/${doc_target}.qhp"
-o "${qch_file_path}"
COMMENT "Building QtHelp files for ${target}..."
)
endforeach()
add_dependencies(qch_docs_${target} generate_docs_${target})
@ -353,9 +252,9 @@ function(qt_internal_add_docs)
if (QT_WILL_INSTALL)
install(DIRECTORY "${qdoc_output_dir}/"
DESTINATION "${INSTALL_DOCDIR}/${doc_target}"
COMPONENT _install_html_docs_${target}
EXCLUDE_FROM_ALL
DESTINATION "${INSTALL_DOCDIR}/${doc_target}"
COMPONENT _install_html_docs_${target}
EXCLUDE_FROM_ALL
)
add_custom_target(install_html_docs_${target}
@ -366,9 +265,9 @@ function(qt_internal_add_docs)
)
install(FILES "${qch_file_path}"
DESTINATION "${INSTALL_DOCDIR}"
COMPONENT _install_qch_docs_${target}
EXCLUDE_FROM_ALL
DESTINATION "${INSTALL_DOCDIR}"
COMPONENT _install_qch_docs_${target}
EXCLUDE_FROM_ALL
)
add_custom_target(install_qch_docs_${target}
@ -404,73 +303,4 @@ function(qt_internal_add_docs)
qt_internal_add_doc_tool_dependency(prepare_docs_${target} qdoc)
qt_internal_add_doc_tool_dependency(qch_docs_${target} qhelpgenerator)
endif()
_qt_internal_forward_function_args(
FORWARD_PREFIX arg
FORWARD_OUT_VAR add_java_documentation_args
FORWARD_OPTIONS
SKIP_JAVADOC
)
qt_internal_add_java_documentation(${target} ${add_java_documentation_args}
OUTPUT_DIR "${qdoc_output_dir}"
)
endfunction()
function(qt_internal_add_java_documentation target)
if(NOT ANDROID AND NOT QT_BUILD_HOST_JAVA_DOCS)
return()
endif()
set(no_value_options
SKIP_JAVADOC
)
set(single_value_options
OUTPUT_DIR
)
set(multi_value_options "")
cmake_parse_arguments(PARSE_ARGV 1 arg
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
)
_qt_internal_validate_all_args_are_parsed(arg)
# Use a default output directory based on the project name.
if(NOT DEFINED arg_OUTPUT_DIR)
if (QT_WILL_INSTALL)
set(arg_OUTPUT_DIR "${CMAKE_BINARY_DIR}/${INSTALL_DOCDIR}")
else()
set(arg_OUTPUT_DIR "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
endif()
string(APPEND arg_OUTPUT_DIR "/${PROJECT_NAME}")
endif()
qt_internal_collect_jar_sources(sources)
# Bail out if we haven't found relevant sources.
if(sources STREQUAL "")
return()
endif()
if(NOT TARGET docs_android)
add_custom_target(docs_android)
add_custom_target(install_docs_android)
add_dependencies(install_docs_android docs_android)
add_custom_target(android_source_jars)
add_custom_target(install_android_source_jars)
add_dependencies(install_android_source_jars android_source_jars)
endif()
if(NOT ANDROID)
qt_internal_set_up_build_host_java_docs()
endif()
if(NOT arg_SKIP_JAVADOC)
qt_internal_add_javadoc_target(
MODULE ${target}
SOURCES ${sources}
OUTPUT_DIR "${arg_OUTPUT_DIR}"
)
endif()
qt_internal_create_source_jar(SOURCES ${sources} MODULE ${target})
endfunction()

View File

@ -71,12 +71,7 @@ function(qt_internal_add_executable name)
endif()
endif()
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
if(arg_QT_APP
AND QT_FEATURE_debug_and_release
AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.19.0"
AND is_multi_config
)
if(arg_QT_APP AND QT_FEATURE_debug_and_release AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.19.0")
set_property(TARGET "${name}"
PROPERTY EXCLUDE_FROM_ALL "$<NOT:$<CONFIG:${QT_MULTI_CONFIG_FIRST_CONFIG}>>")
endif()
@ -184,18 +179,11 @@ function(qt_internal_add_executable name)
set_target_properties("${name}" PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${arg_OUTPUT_DIRECTORY}"
LIBRARY_OUTPUT_DIRECTORY "${arg_OUTPUT_DIRECTORY}"
WIN32_EXECUTABLE "${arg_GUI}"
MACOSX_BUNDLE "${arg_GUI}"
)
if(arg_GUI)
# Only override if GUI is set. Otherwise leave up to
# CMake defaults, which may be set by the user elsewhere.
set_target_properties("${name}" PROPERTIES
MACOSX_BUNDLE ON
WIN32_EXECUTABLE ON
)
endif()
if(NOT arg_EXCEPTIONS)
if(NOT DEFINED arg_EXCEPTIONS)
qt_internal_set_exceptions_flags("${name}" "DEFAULT")
else()
qt_internal_set_exceptions_flags("${name}" "${arg_EXCEPTIONS}")
@ -206,9 +194,8 @@ function(qt_internal_add_executable name)
set(exclude_from_all FALSE)
if(__qt_exclude_tool_directories)
foreach(absolute_dir ${__qt_exclude_tool_directories})
_qt_internal_path_is_prefix(absolute_dir "${CMAKE_CURRENT_SOURCE_DIR}"
in_current_source)
if(in_current_source)
string(FIND "${CMAKE_CURRENT_SOURCE_DIR}" "${absolute_dir}" dir_starting_pos)
if(dir_starting_pos EQUAL 0)
set(exclude_from_all TRUE)
set_target_properties("${name}" PROPERTIES
EXCLUDE_FROM_ALL TRUE
@ -265,6 +252,23 @@ function(qt_internal_add_executable name)
qt_internal_install_pdb_files(${name} "${arg_INSTALL_DIRECTORY}")
endif()
if(QT_GENERATE_SBOM)
set(sbom_args "")
_qt_internal_forward_function_args(
FORWARD_APPEND
FORWARD_PREFIX arg
FORWARD_OUT_VAR sbom_args
FORWARD_OPTIONS
${__qt_internal_sbom_optional_args}
FORWARD_SINGLE
${__qt_internal_sbom_single_args}
FORWARD_MULTI
${__qt_internal_sbom_multi_args}
)
_qt_internal_extend_sbom(${name} ${sbom_args})
endif()
qt_add_list_file_finalizer(qt_internal_finalize_executable "${name}")
endfunction()

View File

@ -115,263 +115,6 @@ function(qt_feature feature)
set(__QtFeature_internal_features ${__QtFeature_internal_features} PARENT_SCOPE)
endfunction()
# Define an alternative alias for the main feature definition.
#
# If the main feature is defined, it takes precedence and all others are ignored. Otherwise
# only one alias may be defined.
#
# Currently, we need this to be a dedicated function because we are gathering all aliases of
# the main feature and check its real value as part of
# `qt_feature_check_and_save_user_provided_value`
#
# TODO: See how to move this into the main `qt_feature` definition flow.
# TODO: How to add `CONDITION` and how does it interact with the main feature's `EMIT_IF`
#
# Synopsis
#
# qt_feature_alias(<alias_feature>
# {ALIAS_OF_FEATURE <real_feature> | ALIAS_OF_CACHE <cache>}
# [PRIVATE | PUBLIC]
# [LABEL <string>]
# [PURPOSE <string>]
# [SECTION <string>]
# [NEGATE]
# )
#
# Arguments
#
# `<alias_feature>`
# The feature alias to be created.
#
# `ALIAS_OF_FEATURE`
# The true canonical feature to consider.
#
# `ALIAS_OF_CACHE`
# The true cache variable that this value must synchronize with.
#
# `NEGATE`
# Populate the main FEATURE variable with the opposite of the alias's value
#
# `LABEL`, `PURPOSE`, `SECTION`
# Same as in `qt_feature`
#
# `PRIVATE`, `PUBLIC`
# Same as in `qt_feature`. When `ALIAS_OF_FEATURE` is used, these have no effect, instead the
# value of the the true feature is used.
function(qt_feature_alias alias_feature)
set(option_args
NEGATE
PRIVATE
PUBLIC
)
set(single_args
ALIAS_OF_FEATURE
ALIAS_OF_CACHE
LABEL
PURPOSE
SECTION
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 1 arg "${option_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
if(NOT arg_ALIAS_OF_FEATURE AND NOT arg_ALIAS_OF_CACHE)
message(FATAL_ERROR "One of ALIAS_OF_FEATURE,ALIAS_OF_CACHE must be passed.")
endif()
if(arg_ALIAS_OF_FEATURE AND arg_ALIAS_OF_CACHE)
message(FATAL_ERROR "ALIAS_OF_FEATURE and ALIAS_OF_CACHE are mutually exclusive.")
endif()
set(original_name "${alias_feature}")
qt_feature_normalize_name("${alias_feature}" alias_feature)
set_property(GLOBAL PROPERTY QT_FEATURE_ORIGINAL_NAME_${alias_feature} "${original_name}")
set(forward_args "")
if(arg_ALIAS_OF_FEATURE)
qt_feature_normalize_name("${arg_ALIAS_OF_FEATURE}" arg_ALIAS_OF_FEATURE)
if(NOT DEFINED _QT_FEATURE_DEFINITION_${arg_ALIAS_OF_FEATURE})
message(FATAL_ERROR "Primary feature ${arg_ALIAS_OF_FEATURE} was not defined yet.")
endif()
list(APPEND _QT_FEATURE_ALIASES_${arg_ALIAS_OF_FEATURE} "${alias_feature}")
list(APPEND forward_args ALIAS_OF_FEATURE "${arg_ALIAS_OF_FEATURE}")
endif()
if(arg_ALIAS_OF_CACHE)
list(APPEND forward_args ALIAS_OF_CACHE "${arg_ALIAS_OF_CACHE}")
endif()
if(arg_NEGATE)
list(APPEND forward_args ALIAS_NEGATE)
endif()
if(arg_LABEL)
list(APPEND forward_args LABEL "${arg_LABEL}")
endif()
if(arg_PURPOSE)
list(APPEND forward_args PURPOSE "${arg_PURPOSE}")
endif()
if(arg_SECTION)
list(APPEND forward_args SECTION "${arg_SECTION}")
endif()
set(_QT_FEATURE_DEFINITION_${alias_feature} ${forward_args} PARENT_SCOPE)
if(arg_ALIAS_OF_FEATURE)
# Register alias as a feature type similar to the true one
foreach(type IN ITEMS public private internal)
if(arg_ALIAS_OF_FEATURE IN_LIST __QtFeature_${type}_features)
list(APPEND __QtFeature_${type}_features "${alias_feature}")
set(__QtFeature_${type}_features ${__QtFeature_${type}_features} PARENT_SCOPE)
endif()
endforeach()
set(_QT_FEATURE_ALIASES_${arg_ALIAS_OF_FEATURE}
"${_QT_FEATURE_ALIASES_${arg_ALIAS_OF_FEATURE}}" PARENT_SCOPE)
else()
# Otherwise use the same logic as qt_feature
if (arg_PUBLIC)
list(APPEND __QtFeature_public_features "${alias_feature}")
endif()
if (arg_PRIVATE)
list(APPEND __QtFeature_private_features "${alias_feature}")
endif()
if (NOT arg_PUBLIC AND NOT arg_PRIVATE)
list(APPEND __QtFeature_internal_features "${alias_feature}")
endif()
set(__QtFeature_public_features ${__QtFeature_public_features} PARENT_SCOPE)
set(__QtFeature_private_features ${__QtFeature_private_features} PARENT_SCOPE)
set(__QtFeature_internal_features ${__QtFeature_internal_features} PARENT_SCOPE)
endif()
endfunction()
# Create a deprecated feature
#
# Synopsis
#
# qt_feature_deprecated(<feature>
# REMOVE_BY <version>
# [MESSAGE <string>] [VALUE <val>]
# [PRIVATE | PUBLIC]
# [LABEL <string>] [PURPOSE <string>] [SECTION <string>]
# )
#
# Arguments
#
# `<feature>`
# The feature to be created.
#
# `REMOVE_BY`
# Qt version when this feature is going to be removed
#
# `MESSAGE`
# Additional deprecation message to be printed.
#
# `VALUE`
# Value of the `QT_FEATURE_<feature>` that this is forced to. If undefined,
# `QT_FEATURE_<feature>` is not populated
#
# `LABEL`, `PURPOSE`, `SECTION`, `PRIVATE`, `PUBLIC`
# Same as in `qt_feature`
function(qt_feature_deprecated feature)
set(option_args
PRIVATE
PUBLIC
)
set(single_args
REMOVE_BY
MESSAGE
VALUE
LABEL
PURPOSE
SECTION
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 1 arg "${option_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
if(NOT arg_REMOVE_BY)
message(FATAL_ERROR "qt_feature_deprecated requires REMOVE_BY keyword")
elseif(PROJECT_VERSION VERSION_GREATER_EQUAL arg_REMOVE_BY)
message(FATAL_ERROR
"Deprecated feature ${feature} must be removed before Qt version ${arg_REMOVE_BY}"
)
endif()
set(original_name "${feature}")
qt_feature_normalize_name("${feature}" feature)
# Check if the values were manually passed
if(DEFINED FEATURE_${feature})
set(deprecation_msg "FEATURE_${feature} is deprecated. ")
if(arg_VALUE)
string(APPEND deprecation_msg "The value is always: ${arg_VALUE}")
else()
string(APPEND deprecation_msg "The value is not used.")
endif()
if(arg_MESSAGE)
string(APPEND deprecation_msg "\n${arg_MESSAGE}")
endif()
qt_configure_add_report_entry(RECORD_ON_FEATURE_EVALUATION TYPE WARNING
MESSAGE "${deprecation_msg}")
unset(FEATURE_${feature} CACHE)
endif()
# Make sure the `QT_FEATURE_*` value is set/unset accordingly
unset(err_msg)
if(arg_VALUE)
if(DEFINED QT_FEATURE_${feature} AND NOT QT_FEATURE_${feature} STREQUAL arg_VALUE)
string(CONCAT err_msg
"QT_FEATURE_${feature} was manually set to ${QT_FEATURE_${feature}}, but"
"the only supported value is: ${arg_VALUE}\n"
"Overwriting QT_FEATURE_${feature} cache to ${arg_VALUE}"
)
endif()
set(QT_FEATURE_${feature} "${arg_VALUE}" CACHE INTERNAL
"Deprecated: Always ${arg_VALUE}. ${arg_MESSAGE}"
)
else()
if(DEFINED QT_FEATURE_${feature})
string(CONCAT msg
"QT_FEATURE_${feature} was manually set to ${QT_FEATURE_${feature}}, but"
"the value must **NOT** be set.\n"
"Unsetting QT_FEATURE_${feature} cache"
)
unset(QT_FEATURE_${feature} CACHE)
endif()
endif()
# Emit the error message if we have an unexpected `QT_FEATURE_*`
if(err_msg)
if(arg_MESSAGE)
string(APPEND err_msg "\n${arg_MESSAGE}")
endif()
qt_configure_add_report_error("${err_msg}")
endif()
# Register the feature as a normal feature
set(forward_args "")
foreach(arg IN ITEMS LABEL PURPOSE SECTION)
if(arg_${arg})
list(APPEND forward_args ${arg} "${arg_${arg}}")
endif()
endforeach()
set(_QT_FEATURE_DEFINITION_${feature} ${forward_args} PARENT_SCOPE)
# Do the feature register
if (arg_PUBLIC)
list(APPEND __QtFeature_public_features "${feature}")
set(__QtFeature_public_features ${__QtFeature_public_features} PARENT_SCOPE)
endif()
if (arg_PRIVATE)
list(APPEND __QtFeature_private_features "${feature}")
set(__QtFeature_private_features ${__QtFeature_private_features} PARENT_SCOPE)
endif()
if (NOT arg_PUBLIC AND NOT arg_PRIVATE)
list(APPEND __QtFeature_internal_features "${feature}")
set(__QtFeature_internal_features ${__QtFeature_internal_features} PARENT_SCOPE)
endif()
endfunction()
function(qt_evaluate_to_boolean expressionVar)
if(${${expressionVar}})
set(${expressionVar} ON PARENT_SCOPE)
@ -549,146 +292,6 @@ function(_qt_internal_dump_expression_values expression_dump expression)
set(${expression_dump} "${${expression_dump}}" PARENT_SCOPE)
endfunction()
# Check the actual value of a given feature/alias.
# The value can come from `FEATURE_<alias>` being set or from another alias.
# The out_var is sanitized to 0/1 and it is not set if the feature was not defined.
function(_qt_feature_evaluate_alias out_var alias)
# Evaluate the alias against the aliases of the alias
_qt_feature_check_feature_alias(${alias})
if(NOT DEFINED FEATURE_${alias})
# If the alias was not defined, don't set value
return()
endif()
# Check if we need to negate the value to be set or not
set(not_kw)
_qt_internal_parse_feature_definition("${alias}")
if(arg_ALIAS_NEGATE)
set(not_kw "NOT")
endif()
# Evaluate the value and return it
qt_set01(${out_var} ${not_kw} FEATURE_${alias})
set(${out_var} "${${out_var}}" PARENT_SCOPE)
# Also set `not_kw` since it would be reused by the caller
set(not_kw "${not_kw}" PARENT_SCOPE)
endfunction()
# Check that the feature value is consistent with any of its aliases.
# If the feature was not set via `FEATURE_<feature>`, it may be set by the aliases.
function(_qt_feature_check_feature_alias feature)
if(DEFINED "FEATURE_${feature}")
# The main feature was already defined, use the current value.
# Just check if the other aliases have agreeing values.
qt_set01(expected_value FEATURE_${feature})
unset(alias_value)
foreach(alias IN LISTS _QT_FEATURE_ALIASES_${feature})
_qt_feature_evaluate_alias(alias_value ${alias})
if(DEFINED alias_value)
if(NOT expected_value EQUAL alias_value)
string(CONCAT msg
"Alias FEATURE_${alias}(${FEATURE_${alias}}) is an alias of ${not_kw} "
"FEATURE_${feature}(${FEATURE_${alias}}), and their values conflict"
)
qt_configure_add_report_error(${msg})
endif()
unset(alias_value)
endif()
endforeach()
return()
endif()
# Otherwise try to set the `feature` value from the aliases
set(aliases_set "")
set(expected_value "")
set(alias_not_kws "")
unset(value)
foreach(alias IN LISTS _QT_FEATURE_ALIASES_${feature})
_qt_feature_evaluate_alias(value ${alias})
if(DEFINED value)
list(APPEND aliases_set "${alias}")
list(APPEND expected_value "${value}")
list(APPEND alias_not_kws "${not_kw}")
unset(value)
endif()
endforeach()
# If there were no aliases set, do not set the feature either
if(NOT aliases_set)
return()
endif()
# Check if all values are consistent
list(REMOVE_DUPLICATES expected_value)
list(LENGTH expected_value expected_value_length)
if(expected_value_length GREATER 1)
string(CONCAT msg
"Multiple aliases of FEATURE_${feature} were defined, with conflicting values.\n"
"Aliases:"
)
while(aliases_set)
list(POP_FRONT aliases_set alias)
list(POP_FRONT alias_not_kws not_kw)
string(CONCAT msg
"${msg}\n"
" - ${not_kw} FEATURE_${alias}(${FEATURE_${alias}})"
)
endwhile()
qt_configure_add_report_error(${msg})
return()
endif()
# All aliased values are agreeing
set("FEATURE_${feature}" ${expected_value} PARENT_SCOPE)
endfunction()
# Check that the alias value is consistent with its cache source
function(_qt_feature_check_cache_alias feature)
_qt_internal_parse_feature_definition("${feature}")
if(NOT arg_ALIAS_OF_CACHE)
# Not an alias of a cache variable, skip this check
return()
endif()
if(DEFINED "${arg_ALIAS_OF_CACHE}")
# Check if the feature is set by another alias
unset(expected_value)
_qt_feature_evaluate_alias(expected_value "${feature}")
qt_set01(cache_sanitized ${arg_ALIAS_OF_CACHE})
if(NOT DEFINED expected_value)
# If nothing else set the alias value, use the primary cache value
set("FEATURE_${feature}" "${${arg_ALIAS_OF_CACHE}}" PARENT_SCOPE)
return()
endif()
# Otherwise, just check for consistency
if(NOT cache_sanitized EQUAL expected_value)
string(CONCAT msg
"FEATURE_${feature}(${FEATURE_${feature}}) is an alias of ${not_kw} "
"${arg_ALIAS_OF_CACHE}(${${arg_ALIAS_OF_CACHE}}), and their values conflict."
)
qt_configure_add_report_error(${msg})
endif()
endif()
endfunction()
# Make sure all the direct alias values are set after the final evaluation of the feature value.
# Must be run after `_qt_feature_check_feature_alias` which checks for user-defined values and
# any inconsistencies
function(_qt_feature_save_alias feature)
foreach(alias IN LISTS _QT_FEATURE_ALIASES_${feature})
# We only need to set the alias values if they were not explicitly set. The consistency
# check for those was done prior to this function call.
if(NOT DEFINED FEATURE_${alias})
# Evaluate the alias value based on the original
set(not_kw)
_qt_internal_parse_feature_definition("${alias}")
if(arg_ALIAS_NEGATE)
set(not_kw "NOT")
endif()
qt_set01(value ${not_kw} FEATURE_${feature})
qt_evaluate_to_boolean(value)
# Set the values based on the main feature's value
set(FEATURE_${alias} ${value} CACHE BOOL
# Using a temporary docstring that should be overwritten if everything works well
"(temporarily set by _qt_feature_save_alias)"
)
endif()
endforeach()
endfunction()
# Stores the user provided value to FEATURE_${feature} if provided.
# If not provided, stores ${computed} instead.
# ${computed} is also stored when reconfiguring and the condition does not align with the user
@ -696,8 +299,6 @@ endfunction()
#
function(qt_feature_check_and_save_user_provided_value
resultVar feature condition condition_expression computed label)
_qt_feature_check_cache_alias(${feature})
_qt_feature_check_feature_alias(${feature})
if (DEFINED "FEATURE_${feature}")
# Revisit new user provided value
set(user_value "${FEATURE_${feature}}")
@ -750,24 +351,8 @@ function(qt_feature_check_and_save_user_provided_value
# Initial setup:
set(result "${computed}")
set("FEATURE_${feature}" "${result}" CACHE BOOL "${label}")
# Update the HELPSTRING if needed
set_property(CACHE "FEATURE_${feature}" PROPERTY
HELPSTRING "${label}"
)
endif()
# Check for potential typo
get_property(original_name GLOBAL PROPERTY "QT_FEATURE_ORIGINAL_NAME_${feature}")
if(NOT original_name STREQUAL feature AND DEFINED "FEATURE_${original_name}")
unset("FEATURE_${original_name}" CACHE)
qt_configure_add_report_error(
"FEATURE_${original_name} does not exist. Consider using: FEATURE_${feature}"
)
endif()
# Set the values of each direct alias
_qt_feature_save_alias("${feature}")
set("${resultVar}" "${result}" PARENT_SCOPE)
endfunction()
@ -799,8 +384,8 @@ endmacro()
macro(_qt_internal_parse_feature_definition feature)
cmake_parse_arguments(arg
"PRIVATE;PUBLIC;ALIAS_NEGATE"
"LABEL;PURPOSE;SECTION;ALIAS_OF_FEATURE;ALIAS_OF_CACHE"
"PRIVATE;PUBLIC"
"LABEL;PURPOSE;SECTION;"
"AUTODETECT;CONDITION;ENABLE;DISABLE;EMIT_IF"
${_QT_FEATURE_DEFINITION_${feature}})
endmacro()
@ -842,12 +427,6 @@ function(qt_evaluate_feature feature)
_qt_internal_parse_feature_definition("${feature}")
if(arg_ALIAS_OF)
# If the current feature is an alias of another, we have to check the original source first
# in order to be consistent with the original source if set
qt_evaluate_feature("${arg_ALIAS_OF}")
endif()
if("${arg_ENABLE}" STREQUAL "")
set(arg_ENABLE OFF)
endif()
@ -886,17 +465,6 @@ function(qt_evaluate_feature feature)
qt_evaluate_config_expression(emit_if ${arg_EMIT_IF})
endif()
set(actual_label "${arg_LABEL}")
if(arg_ALIAS_OF_FEATURE OR arg_ALIAS_OF_CACHE)
set(not_kw)
if(arg_ALIAS_NEGATE)
set(not_kw "NOT")
endif()
# Only one of ALIAS_OF_FEATURE/ALIAS_OF_CACHE will be set, so we can just combine them
set(alias_source "${not_kw} ${arg_ALIAS_OF_FEATURE}${arg_ALIAS_OF_CACHE}")
string(APPEND actual_label " (alias of ${alias_source})")
endif()
# Warn about a feature which is not emitted, but the user explicitly provided a value for it.
if(NOT emit_if AND DEFINED FEATURE_${feature})
set(msg "")
@ -914,17 +482,17 @@ function(qt_evaluate_feature feature)
if(emit_if)
qt_feature_check_and_save_user_provided_value(
saved_user_value
"${feature}" "${condition}" "${arg_CONDITION}" "${computed}" "${actual_label}")
"${feature}" "${condition}" "${arg_CONDITION}" "${computed}" "${arg_LABEL}")
else()
# Make sure the feature internal value is OFF if not emitted.
set(saved_user_value OFF)
endif()
qt_feature_check_and_save_internal_value(
"${feature}" "${saved_user_value}" "${condition}" "${actual_label}" "${arg_CONDITION}")
"${feature}" "${saved_user_value}" "${condition}" "${arg_LABEL}" "${arg_CONDITION}")
# Store each feature's label for summary info.
set(QT_FEATURE_LABEL_${feature} "${actual_label}" CACHE INTERNAL "")
set(QT_FEATURE_LABEL_${feature} "${arg_LABEL}" CACHE INTERNAL "")
endfunction()
# Collect feature names that ${feature} depends on, by inspecting the given expression.
@ -1233,7 +801,6 @@ function(qt_feature_module_end)
foreach(feature ${all_features})
unset(_QT_FEATURE_DEFINITION_${feature} PARENT_SCOPE)
unset(_QT_FEATURE_ALIASES_${feature} PARENT_SCOPE)
endforeach()
if(NOT arg_ONLY_EVALUATE_FEATURES)
@ -1601,9 +1168,17 @@ function(qt_run_config_compile_test name)
set(_save_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
set(CMAKE_REQUIRED_LIBRARIES "${arg_LIBRARIES}")
_qt_internal_get_check_cxx_source_compiles_out_var(try_compile_output extra_args)
# OUTPUT_VARIABLE is an internal undocumented variable of check_cxx_source_compiles
# since 3.23. Allow an opt out in case this breaks in the future.
set(try_compile_output "")
set(output_var "")
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.23"
AND NOT QT_INTERNAL_NO_TRY_COMPILE_OUTPUT_VARIABLE)
set(output_var OUTPUT_VARIABLE try_compile_output)
endif()
check_cxx_source_compiles(
"${arg_UNPARSED_ARGUMENTS} ${arg_CODE}" HAVE_${name} ${extra_args}
"${arg_UNPARSED_ARGUMENTS} ${arg_CODE}" HAVE_${name} ${output_var}
)
set(CMAKE_REQUIRED_LIBRARIES "${_save_CMAKE_REQUIRED_LIBRARIES}")
@ -1616,14 +1191,7 @@ function(qt_run_config_compile_test name)
endif()
endif()
# Note this is assigned to the parent scope, and is not a CACHE var, which means the value is
# only available on first configuration.
set(TEST_${name}_OUTPUT "${try_compile_output}" PARENT_SCOPE)
# Story the compile output for a test in a global property. It will only be available on first
# configuration, because we don't cache it across cmake invocations.
set_property(GLOBAL PROPERTY _qt_run_config_compile_test_output_${name} "${try_compile_output}")
set(TEST_${name} "${HAVE_${name}}" CACHE INTERNAL "${arg_LABEL}")
endfunction()

View File

@ -162,7 +162,10 @@ macro(qt_find_package)
foreach(qt_find_package_target_name ${arg_PROVIDED_TARGETS})
if(TARGET ${qt_find_package_target_name})
# Allow usage of aliased targets by setting properties on the actual target
_qt_internal_dealias_target(qt_find_package_target_name)
get_target_property(aliased_target ${qt_find_package_target_name} ALIASED_TARGET)
if(aliased_target)
set(qt_find_package_target_name ${aliased_target})
endif()
if("${qt_find_package_target_name}" MATCHES "${QT_CMAKE_EXPORT_NAMESPACE}::"
AND QT_FEATURE_developer_build
@ -384,8 +387,6 @@ endfunction()
# dep_target_name = EntryPointPrivate
# This is just a convenience function that deals with Qt targets and their associated packages
# instead of raw package names.
#
# Deprecated since 6.9.
function(qt_record_extra_qt_package_dependency main_target_name dep_target_name
dep_package_version)
# EntryPointPrivate -> Qt6EntryPointPrivate.
@ -570,26 +571,17 @@ function(qt_internal_get_package_name_of_target target package_name_out_var)
set(${package_name_out_var} "${package_name}" PARENT_SCOPE)
endfunction()
# This function collects the list of Qt targets a library depend on,
# along with their version info, for usage in ${target}Dependencies.cmake file
# Multi-value Arguments:
# PUBLIC
# public dependencies
# PRIVATE
# private dependencies
function(qt_internal_register_target_dependencies target)
cmake_parse_arguments(PARSE_ARGV 1 arg "" "" "PUBLIC;PRIVATE")
# This function stores the list of Qt targets a library depend on,
# along with their version info, for usage in ${target}Depends.cmake file
function(qt_register_target_dependencies target public_libs private_libs)
get_target_property(target_deps "${target}" _qt_target_deps)
if(NOT target_deps)
set(target_deps "")
endif()
set(lib_list "")
if(arg_PUBLIC)
set(lib_list "${arg_PUBLIC}")
endif()
get_target_property(target_type ${target} TYPE)
set(lib_list ${public_libs})
set(target_is_shared FALSE)
set(target_is_static FALSE)
if(target_type STREQUAL "SHARED_LIBRARY")
@ -603,8 +595,8 @@ function(qt_internal_register_target_dependencies target)
#
# Private static library dependencies will become $<LINK_ONLY:> dependencies in
# INTERFACE_LINK_LIBRARIES.
if(target_is_static AND arg_PRIVATE)
list(APPEND lib_list ${arg_PRIVATE})
if(target_is_static)
list(APPEND lib_list ${private_libs})
endif()
foreach(lib IN LISTS lib_list)
@ -630,8 +622,8 @@ function(qt_internal_register_target_dependencies target)
# See QTBUG-86533 for some details.
# We filter out static libraries and common platform targets, but include both SHARED and
# INTERFACE libraries. INTERFACE libraries in most cases will be FooPrivate libraries.
if(target_is_shared AND arg_PRIVATE)
foreach(lib IN LISTS arg_PRIVATE)
if(target_is_shared AND private_libs)
foreach(lib IN LISTS private_libs)
set(lib_namespaced "${lib}")
if("${lib}" MATCHES "^Qt::(.*)")
set(lib "${CMAKE_MATCH_1}")

View File

@ -66,26 +66,7 @@ macro(qt_find_package_system_or_bundled _unique_prefix)
endif()
if(NOT TARGET "${${_unique_prefix}_qt_package_target_to_use}")
if(QT_USE_BUNDLED_${_qfwrap_${_unique_prefix}_BUNDLED_PACKAGE_TARGET})
set(${_unique_prefix}_qt_use_no_default_path_for_qt_packages "NO_DEFAULT_PATH")
if(QT_DISABLE_NO_DEFAULT_PATH_IN_QT_PACKAGES)
set(${_unique_prefix}_qt_use_no_default_path_for_qt_packages "")
endif()
# For bundled targets, we want to limit search paths to the relevant Qt search paths.
find_package("${${_unique_prefix}_qt_package_name_to_use}"
PATHS
${QT_BUILD_CMAKE_PREFIX_PATH}
"${CMAKE_CURRENT_LIST_DIR}/.."
${_qt_cmake_dir}
${_qt_additional_packages_prefix_paths}
${${_unique_prefix}_qt_use_no_default_path_for_qt_packages}
)
else()
# For the non-bundled case we will look for FindWrapSystemFoo.cmake module files,
# which means we should not specify any PATHS.
find_package("${${_unique_prefix}_qt_package_name_to_use}")
endif()
find_package("${${_unique_prefix}_qt_package_name_to_use}")
endif()
if(TARGET "${${_unique_prefix}_qt_package_target_to_use}")

View File

@ -160,21 +160,19 @@ function(qt_internal_add_link_flags_no_undefined target)
return()
endif()
if ((GCC OR CLANG) AND NOT MSVC)
if((GCC OR CLANG) AND QT_FEATURE_sanitizer)
if(CLANG AND QT_FEATURE_sanitizer)
return()
endif()
set(previous_CMAKE_REQUIRED_LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,-undefined,error")
_qt_internal_get_check_cxx_source_compiles_out_var(test_output_undefined_error extra_args)
check_cxx_source_compiles("int main() {}" HAVE_DASH_UNDEFINED_SYMBOLS ${extra_args})
check_cxx_source_compiles("int main() {}" HAVE_DASH_UNDEFINED_SYMBOLS)
if(HAVE_DASH_UNDEFINED_SYMBOLS)
set(no_undefined_flag "-Wl,-undefined,error")
endif()
set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--no-undefined")
_qt_internal_get_check_cxx_source_compiles_out_var(test_output_no_undefined extra_args)
check_cxx_source_compiles("int main() {}" HAVE_DASH_DASH_NO_UNDEFINED ${extra_args})
check_cxx_source_compiles("int main() {}" HAVE_DASH_DASH_NO_UNDEFINED)
if(HAVE_DASH_DASH_NO_UNDEFINED)
set(no_undefined_flag "-Wl,--no-undefined")
endif()
@ -182,10 +180,7 @@ function(qt_internal_add_link_flags_no_undefined target)
set(CMAKE_REQUIRED_LINK_OPTIONS ${previous_CMAKE_REQUIRED_LINK_OPTIONS})
if (NOT HAVE_DASH_UNDEFINED_SYMBOLS AND NOT HAVE_DASH_DASH_NO_UNDEFINED)
message(FATAL_ERROR
"Platform linker doesn't support erroring upon encountering undefined symbols. "
"Target:\"${target}\". "
"Test errors: \n ${test_output_undefined_error} \n ${test_output_no_undefined}")
message(FATAL_ERROR "Platform linker doesn't support erroring upon encountering undefined symbols. Target:\"${target}\".")
endif()
target_link_options("${target}" PRIVATE "${no_undefined_flag}")
endif()
@ -470,21 +465,21 @@ endfunction()
function(qt_internal_print_optimization_flags_values_helper languages configs target_link_types)
foreach(lang ${languages})
set(flag_var_name "CMAKE_${lang}_FLAGS")
message(STATUS "${flag_var_name}: '${${flag_var_name}}'")
message(STATUS "${flag_var_name}: ${${flag_var_name}}")
foreach(config ${configs})
set(flag_var_name "CMAKE_${lang}_FLAGS_${config}")
message(STATUS "${flag_var_name}: '${${flag_var_name}}'")
message(STATUS "${flag_var_name}: ${${flag_var_name}}")
endforeach()
endforeach()
foreach(t ${target_link_types})
set(flag_var_name "CMAKE_${t}_LINKER_FLAGS")
message(STATUS "${flag_var_name}: '${${flag_var_name}}'")
message(STATUS "${flag_var_name}: ${${flag_var_name}}")
foreach(config ${configs})
set(flag_var_name "CMAKE_${t}_LINKER_FLAGS_${config}")
message(STATUS "${flag_var_name}: '${${flag_var_name}}'")
message(STATUS "${flag_var_name}: ${${flag_var_name}}")
endforeach()
endforeach()
endfunction()
@ -718,356 +713,6 @@ function(qt_internal_remove_compiler_flags flags)
endforeach()
endfunction()
# Add a series of compile options as generator expressions
#
# Each condition and compiler requirement are glued by $<AND:> genex.
#
# Synopsis
#
# qt_internal_add_compiler_dependent_flags(<target> <INTERFACE|PUBLIC|PRIVATE>
# COMPILERS <compiler> ...
# [ CONDITIONS <condition> ... ]
# OPTIONS <items> ...
# [ CONDITIONS <condition> ...
# OPTIONS <items> ... ]
# [ COMPILERS ... ]
#
# [LANGUAGES <lang> ...]
# [COMMON_CONDITIONS <condition_genex> ...]
# )
#
# Example
# qt_internal_add_compiler_dependent_flags(tgt PUBLIC
# COMPILERS ALL
# OPTIONS -Werror
# CONDITIONS $<TARGET_PROPERTY:foo> OR $<TARGET_PROPERTY:bar>
# OPTIONS -bar -baz
# COMPILERS GNU
# CONDITIONS VERSION_GREATER_EQUAL 10
# OPTIONS -baz
# )
#
# Is equivalent to:
#
# target_compile_options(tgt PUBLIC
# $<$<AND:$<COMPILE_LANGUAGE:CXX>>:-Werror>
# $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<OR:$<TARGET_PROPERTY:foo>,$<TARGET_PROPERTY:bar>>>:-bar;-baz>
# $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:GNU>,$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,10>>:-baz>
# )
#
# Arguments
#
# `<target>`
# Equivalent to `target_compile_options(<target>)`.
#
# `<INTERFACE|PUBLIC|PRIVATE>`
# Equivalent to `target_compile_options(<INTERFACE|PUBLIC|PRIVATE>)`.
#
# Unlike `target_compile_options`, only one set of target scope is implemented.
#
# `COMPILERS`
# Starts a new set of compiler specific set of options gated by `$<${lang}_COMPILER_ID>`.
# See `LANGUAGES` for how `${lang}` is determined.
#
# Can be any value defined in `CMAKE_<LANG>_COMPILER_ID`, or one of the following shortcuts
# - `ALL`: drops the compiler specific condition
# - `CLANG`: `Clang` and `IntelLLVM` (does not include `AppleClang`)
#
# At least one `COMPILERS` set *must* be defined.
#
# `CONDITIONS`
# Starts a new set of `<condition>` gated options.
#
# `<condition>` can be one of:
# - `VERSION_* <version>`: Equivalent to `$<VERSION_*:$<${lang}_COMPILER_VERSION:>,<version>>`
# See `LANGUAGES` for how `${lang}` is determined.
# - Any genex matching regex: `\$<.*>`
#
# You can use `AND` and `OR` as well as parenthesis `()` to join multiple `<condition>`.
#
# If no `<condition>` is added, the current set only checks for compiler condition and the
# `COMMON_CONDITIONS`.
#
# `OPTIONS`
# Starts the list of compiler options for the current set of `COMPILERS` and `CONDITIONS`
#
# Equivalent to `target_compile_options(<items>)`.
#
# At least one `COMPILERS` set *must* be defined.
#
# `LANGUAGES`
# Language conditions applied to all options.
#
# - If no `LANGUAGES` is passed `$<CXX_COMPILER_*>` is used to compute compiler-dependent
# variables such as `$<CXX_COMPILER_VERSION>`
# - If exactly 1 `LANGUAGES` is passed, this language is used in `$<${lang}_COMPILER_>` like
# variables
#
# `COMMON_CONDITIONS`
# Additional genex conditions to include for all compiler flags.
function(qt_internal_add_compiler_dependent_flags target target_scope)
# We cannot use `cmake_parse_arguments` to parse all the other arguments. We use a special
# parsing for that with the remaining `arg_UNPARSED_ARGUMENTS`
set(option_args "")
set(single_args "")
set(multi_args
LANGUAGES
COMMON_CONDITIONS
)
cmake_parse_arguments(PARSE_ARGV 2 arg
"${option_args}" "${single_args}" "${multi_args}"
)
# For debugging purposes we save the original list of arg_UNPARSED_ARGUMENTS
set(arg_UNPARSED_ARGUMENTS_original ${arg_UNPARSED_ARGUMENTS})
# Set the language for the compiler checks
set(lang CXX)
list(LENGTH arg_LANGUAGES arg_LANGUAGES_length)
if(arg_LANGUAGES_length EQUAL 1)
set(lang ${arg_LANGUAGES})
endif()
# Always add a language genex
set(lang_ex "$<COMPILE_LANGUAGE:${lang}>")
if(arg_LANGUAGES_length GREATER 1)
list(JOIN arg_LANGUAGES "," arg_LANGUAGES_comma_list)
set(lang_ex "$<COMPILE_LANGUAGE:${arg_LANGUAGES_comma_list}>")
endif()
# Helper debugging function
function(_qt_internal_add_compiler_dependent_flags_error msg)
# If you are hitting such a function, something must have gone wrong with
# `qt_internal_add_compiler_flags` implementation.
message(FATAL_ERROR
"${msg}\n"
" curr_arg = ${curr_arg}\n"
" arg_UNPARSED_ARGUMENTS = ${arg_UNPARSED_ARGUMENTS}\n"
" arg_UNPARSED_ARGUMENTS_original = ${arg_UNPARSED_ARGUMENTS_original}"
)
endfunction()
# Helper function finalizing each keyword set
# COMPILERS
function(_qt_internal_add_compiler_dependent_flags_do_COMPILERS)
set(compiler_ex "")
if(NOT curr_COMPILERS)
_qt_internal_add_compiler_dependent_flags_error(
"COMPILERS set cannot be empty"
)
endif()
# If ALL compilers is passed, we can ignore the compiler check
if(NOT "ALL" IN_LIST curr_COMPILERS)
# Check for other aliases
if("CLANG" IN_LIST curr_COMPILERS)
list(REMOVE_ITEM curr_COMPILERS CLANG)
list(APPEND curr_COMPILERS Clang IntelLLVM)
endif()
# Create compiler genex
list(REMOVE_DUPLICATES curr_COMPILERS)
list(JOIN curr_COMPILERS "," compilers)
set(compiler_ex "$<${lang}_COMPILER_ID:${compilers}>" PARENT_SCOPE)
endif()
endfunction()
# CONDITIONS
function(_qt_internal_add_compiler_dependent_flags_do_CONDITIONS)
function(_qt_internal_add_compiler_dependent_flags_do_CONDITIONS_end_stack
stack_in stack_out
)
# Resolve the current stack into a genex list
set(stack_conditions_ex)
set(prev_glue_word)
set(glue_word)
list(POP_FRONT ${stack_in} stack_conditions_ex)
while(${stack_in})
list(POP_FRONT ${stack_in} glue_word)
if(NOT (glue_word STREQUAL "AND" OR glue_word STREQUAL "OR"))
_qt_internal_add_compiler_dependent_flags_error(
"Expected AND/OR glue word, instead got: ${glue_word}"
)
endif()
list(POP_FRONT ${stack_in} next_condition)
if(NOT next_condition)
_qt_internal_add_compiler_dependent_flags_error(
"No other condition provided after ${glue_word}"
)
endif()
if(prev_glue_word STREQUAL glue_word)
# If the glue words are the same, we just add to current genex $<${glue_word}:>
# First trim the last `>` character
string(LENGTH "${stack_conditions_ex}" stack_conditions_ex_length)
math(EXPR stack_conditions_ex_length "${stack_conditions_ex_length} - 1")
string(SUBSTRING "${stack_conditions_ex}" 0 ${stack_conditions_ex_length}
stack_conditions_ex
)
set(stack_conditions_ex "${stack_conditions_ex},${next_condition}>")
else()
# Otherwise create a new $<${glue_word}:>
set(stack_conditions_ex
"$<${glue_word}:${stack_conditions_ex},${next_condition}>"
)
endif()
set(prev_glue_word "${glue_word}")
endwhile()
if(NOT stack_conditions_ex)
_qt_internal_add_compiler_dependent_flags_error(
"Empty parenthesis stack"
)
endif()
# Add the current
list(APPEND ${stack_out} "${stack_conditions_ex}")
set(${stack_out} "${${stack_out}}" PARENT_SCOPE)
endfunction()
set(conditions_ex "")
set(stack_level 0)
set(stack_0)
while(curr_CONDITIONS)
list(POP_FRONT curr_CONDITIONS condition_kw)
# Parenthesis evaluation
if(condition_kw MATCHES "^\\((.*)")
# Start a new stack
math(EXPR stack_level "${stack_level} + 1")
set(stack_${stack_level})
# Check if the parenthesis was glued to another keyword
# Resolve the remaining keyword in the next loop
if(CMAKE_MATCH_1)
list(PREPEND curr_CONDITIONS "${CMAKE_MATCH_1}")
endif()
continue()
elseif(condition_kw MATCHES "(.*)\\)$")
# Check if the parenthesis was glued to another keyword
# Separate them and evaluate each one individually
if(CMAKE_MATCH_1)
set(condition_kw "${CMAKE_MATCH_1}")
list(PREPEND curr_CONDITIONS "${CMAKE_MATCH_1}" ")")
endif()
# Finalize the current stack making it a genex for the next loop
set(curr_stack stack_${stack_level})
math(EXPR stack_level "${stack_level} - 1")
set(prev_stack stack_${stack_level})
_qt_internal_add_compiler_dependent_flags_do_CONDITIONS_end_stack(
${curr_stack} ${prev_stack}
)
if(stack_level LESS 0)
_qt_internal_add_compiler_dependent_flags_error(
"Unbalanced parenthesis."
)
endif()
continue()
endif()
# Glue word evaluation
if(condition_kw STREQUAL "AND" OR condition_kw STREQUAL "OR")
# Insert the operator
list(APPEND stack_${stack_level} "${condition_kw}")
continue()
endif()
# Main condition keyword evaluation
if(condition_kw MATCHES "^VERSION_.*")
# Shortcut for VERSION_* keyword
list(POP_FRONT curr_CONDITIONS version)
list(APPEND stack_${stack_level}
"$<${condition_kw}:$<${lang}_COMPILER_VERSION>,${version}>"
)
continue()
elseif(condition_kw MATCHES "^\\$<.*>$")
# genex expression are added as-is
list(APPEND stack_${stack_level} "${condition_kw}")
continue()
else()
# All other unrecognized forms we do not know how to deal with
_qt_internal_add_compiler_dependent_flags_error(
"Unrecognized condition form: ${condition_kw}"
)
endif()
endwhile()
# Finalize the top-level stack and put it in `conditions_ex`
if(NOT stack_level EQUAL 0)
_qt_internal_add_compiler_dependent_flags_error(
"Unbalanced parenthesis."
)
endif()
_qt_internal_add_compiler_dependent_flags_do_CONDITIONS_end_stack(stack_0 conditions_ex)
set(conditions_ex "${conditions_ex}" PARENT_SCOPE)
endfunction()
# OPTIONS
function(_qt_internal_add_compiler_dependent_flags_do_OPTIONS)
# Check for required keywords
foreach(required_keyword IN ITEMS OPTIONS COMPILERS)
if(curr_${required_keyword} STREQUAL "MISSING")
_qt_internal_add_compiler_dependent_flags_error(
"${required_keyword} keyword was not passed"
)
endif()
endforeach()
# Only handle the current set if the OPTIONS did not evaluate to empty, otherwise
# it is considered a no-op
if(curr_OPTIONS)
# No need to check the length of `all_conditions_ex` because `lang_ex` is
# always defined.
list(JOIN curr_OPTIONS ";" options)
# Combine all conditions in an `AND` statement
set(all_conditions_ex "")
list(APPEND all_conditions_ex
${arg_COMMON_CONDITIONS}
${lang_ex}
${compiler_ex}
${conditions_ex}
)
list(JOIN all_conditions_ex "," all_conditions_ex)
list(APPEND flags
"$<$<AND:${all_conditions_ex}>:${options}>"
)
endif()
# Reset all loop variables
# curr_COMPILERS is inherited from the last loop
set(curr_CONDITIONS "" PARENT_SCOPE)
set(curr_OPTIONS "MISSING" PARENT_SCOPE)
set(conditions_ex "" PARENT_SCOPE)
set(flags "${flags}" PARENT_SCOPE)
endfunction()
# Set initial loop variables
set(compiler_ex "")
set(conditions_ex "")
set(flags "")
# We set (REQUIRED) curr_* loop variables to a special keyword MISSING to identify when
# the keyword was not passed
set(curr_COMPILERS "MISSING")
set(curr_CONDITIONS "")
set(curr_OPTIONS "MISSING")
set(curr_keyword "")
# Parse the remaining arguments
while(arg_UNPARSED_ARGUMENTS)
list(POP_FRONT arg_UNPARSED_ARGUMENTS curr_arg)
# Check for separator keywords
if(curr_arg MATCHES "^(COMPILERS|CONDITIONS|OPTIONS)$")
# Resolve the previous keyword set
# Implicitly we skip the initial loop where curr_keyword == ""
if(curr_keyword STREQUAL "COMPILERS")
_qt_internal_add_compiler_dependent_flags_do_COMPILERS()
elseif(curr_keyword STREQUAL "CONDITIONS")
_qt_internal_add_compiler_dependent_flags_do_CONDITIONS()
elseif(curr_keyword STREQUAL "OPTIONS")
_qt_internal_add_compiler_dependent_flags_do_OPTIONS()
endif()
# Set the new keyword to accumulate the current `curr_*` variable
set(curr_keyword "${curr_arg}")
set(curr_${curr_keyword} "")
continue()
endif()
# If no separator keyword is passed, add the current values to `curr_*` loop variable
# and move on to the next loop
if(NOT curr_keyword)
_qt_internal_add_compiler_dependent_flags_error(
"No keyword was passed: COMPILERS/CONDITIONS/OPTIONS"
)
endif()
list(APPEND curr_${curr_keyword} "${curr_arg}")
endwhile()
# finalize the last set
_qt_internal_add_compiler_dependent_flags_do_OPTIONS()
# Finally add all of the flags to `target_compile_options`
target_compile_options("${target}" ${target_scope} ${flags})
endfunction()
# Adds compiler flags for the given CONFIGS in the calling scope. Can also update the cache
# if asked to do so. The flag variables are always updated in the calling scope, even if they
# did not exist beforehand.

View File

@ -34,12 +34,10 @@ macro(qt_find_apple_system_frameworks)
qt_internal_find_apple_system_framework(FWGameController GameController)
qt_internal_find_apple_system_framework(FWCoreBluetooth CoreBluetooth)
qt_internal_find_apple_system_framework(FWAVFoundation AVFoundation)
qt_internal_find_apple_system_framework(FWPhotos Photos)
qt_internal_find_apple_system_framework(FWContacts Contacts)
qt_internal_find_apple_system_framework(FWEventKit EventKit)
qt_internal_find_apple_system_framework(FWHealthKit HealthKit)
qt_internal_find_apple_system_framework(FWUniformTypeIdentifiers UniformTypeIdentifiers)
qt_internal_find_apple_system_framework(FWNetwork Network)
qt_internal_find_apple_system_framework(FWOpenGL OpenGL)
endif()
endmacro()
@ -172,7 +170,7 @@ function(qt_internal_generate_fake_framework_header target)
file(GENERATE OUTPUT "${fake_header}" CONTENT "// ignore this file\n"
CONDITION "$<CONFIG:${main_config}>")
target_sources(${target} PRIVATE "${fake_header}")
_qt_internal_set_source_file_generated(SOURCES "${fake_header}")
set_source_files_properties("${fake_header}" PROPERTIES GENERATED ON)
set_property(TARGET ${target} APPEND PROPERTY PUBLIC_HEADER "${fake_header}")
endfunction()

View File

@ -239,8 +239,8 @@ function(qt_internal_add_headersclean_target module_target module_headers)
set(possible_base_dirs "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}")
foreach(dir IN LISTS possible_base_dirs)
_qt_internal_path_is_prefix(dir "${input_path}" dir_is_prefix)
if(dir_is_prefix)
string(FIND "${input_path}" "${dir}" idx)
if(idx EQUAL "0")
set(input_base_dir "${dir}")
break()
endif()

View File

@ -18,8 +18,6 @@ set(@var_prefix@SYSCONFDIR "@INSTALL_SYSCONFDIR@")
set(@var_prefix@EXAMPLESDIR "@INSTALL_EXAMPLESDIR@")
set(@var_prefix@TESTSDIR "@INSTALL_TESTSDIR@")
set(@var_prefix@DESCRIPTIONSDIR "@INSTALL_DESCRIPTIONSDIR@")
set(@var_prefix@SHAREDIR "@INSTALL_SHAREDIR@")
set(@var_prefix@QT_SHAREDIR "@INSTALL_QT_SHAREDIR@")
set(@var_prefix@QMAKE_MKSPEC "@QT_QMAKE_TARGET_MKSPEC@")
set(@var_prefix@ARCH "@TEST_architecture_arch@")
set(@var_prefix@SUBARCHS "@TEST_subarch_result@")

View File

@ -93,11 +93,12 @@ handle_type(cpp EXTENSIONS .c .cc .cpp .cxx .h .hh .hxx .hpp MODULES Core TEMPLA
handle_type(qml EXTENSIONS .qml .js .mjs MODULES Gui Qml Quick TEMPLATE
"\n\nqt_add_qml_module(${project_name}
URI ${project_name}
OUTPUT_DIRECTORY qml
VERSION 1.0
RESOURCE_PREFIX /qt/qml
QML_FILES
@files@
)
set_property(TARGET ${project_name} PROPERTY RUNTIME_OUTPUT_NAME \"${project_name}app\")
"
)"
)
handle_type(ui EXTENSIONS .ui MODULES Gui Widgets DEPENDS cpp TEMPLATE
@ -161,7 +162,7 @@ set(content
project(${project_name} LANGUAGES CXX)
find_package(Qt6 REQUIRED COMPONENTS ${packages_string})
qt_standard_project_setup(REQUIRES 6.8)"
qt_standard_project_setup()"
)
set(has_useful_sources FALSE)

View File

@ -14,6 +14,3 @@ set(QT@PROJECT_VERSION_MAJOR@_INSTALL_PLUGINS "@INSTALL_PLUGINSDIR@")
set(QT@PROJECT_VERSION_MAJOR@_INSTALL_QML "@INSTALL_QMLDIR@")
set(QT@PROJECT_VERSION_MAJOR@_INSTALL_TESTS "@INSTALL_TESTSDIR@")
set(QT@PROJECT_VERSION_MAJOR@_INSTALL_TRANSLATIONS "@INSTALL_TRANSLATIONSDIR@")
set(QT@PROJECT_VERSION_MAJOR@_INSTALL_DESCRIPTIONSDIR "@INSTALL_DESCRIPTIONSDIR@")
set(QT@PROJECT_VERSION_MAJOR@_INSTALL_SHAREDIR "@INSTALL_SHAREDIR@")
set(QT@PROJECT_VERSION_MAJOR@_INSTALL_QT_SHAREDIR "@INSTALL_QT_SHAREDIR@")

View File

@ -3,124 +3,85 @@
function(qt_internal_set_warnings_are_errors_flags target target_scope)
# Gate everything by the target property
set(common_conditions "$<NOT:$<BOOL:$<TARGET_PROPERTY:QT_SKIP_WARNINGS_ARE_ERRORS>>>")
set(flags "")
if (CLANG AND NOT MSVC)
list(APPEND flags -Werror -Wno-error=\#warnings -Wno-error=deprecated-declarations)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # as in: not AppleClang
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "10.0.0")
# We do mixed enum arithmetic all over the place:
list(APPEND flags -Wno-error=deprecated-enum-enum-conversion)
endif()
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "14.0.0")
# Clang 14 introduced these two but we are not clean for it.
list(APPEND flags -Wno-error=deprecated-copy-with-user-provided-copy)
list(APPEND flags -Wno-error=unused-but-set-variable)
endif()
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# using GCC
list(APPEND flags -Werror -Wno-error=cpp -Wno-error=deprecated-declarations)
# GCC prints this bogus warning, after it has inlined a lot of code
# error: assuming signed overflow does not occur when assuming that (X + c) < X is always false
list(APPEND flags -Wno-error=strict-overflow)
# GCC 7 includes -Wimplicit-fallthrough in -Wextra, but Qt is not yet free of implicit fallthroughs.
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0.0")
list(APPEND flags -Wno-error=implicit-fallthrough)
endif()
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "9.0.0")
# GCC 9 introduced these but we are not clean for it.
list(APPEND flags -Wno-error=deprecated-copy -Wno-error=redundant-move -Wno-error=init-list-lifetime)
# GCC 9 introduced -Wformat-overflow in -Wall, but it is buggy:
list(APPEND flags -Wno-error=format-overflow)
endif()
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "10.0.0")
# GCC 10 has a number of bugs in -Wstringop-overflow. Do not make them an error.
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92955
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94335
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101134
list(APPEND flags -Wno-error=stringop-overflow)
endif()
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "11.0.0")
# Ditto
list(APPEND flags -Wno-error=stringop-overread)
# We do mixed enum arithmetic all over the place:
list(APPEND flags -Wno-error=deprecated-enum-enum-conversion -Wno-error=deprecated-enum-float-conversion)
endif()
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "11.0.0" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "11.2.0")
# GCC 11.1 has a regression in the integrated preprocessor, so disable it as a workaround (QTBUG-93360)
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100796
# This in turn triggers a fallthrough warning in cborparser.c, so we disable this warning.
list(APPEND flags -no-integrated-cpp -Wno-implicit-fallthrough)
endif()
# Work-around for bug https://code.google.com/p/android/issues/detail?id=58135
if (ANDROID)
list(APPEND flags -Wno-error=literal-suffix)
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# Only enable for versions of MSVC that are known to work
# 1941 is Visual Studio 2022 version 17.11
if(MSVC_VERSION LESS_EQUAL 1941)
list(APPEND flags /WX)
endif()
endif()
set(warnings_are_errors_enabled_genex
"$<NOT:$<BOOL:$<TARGET_PROPERTY:QT_SKIP_WARNINGS_ARE_ERRORS>>>")
# Apparently qmake only adds -Werror to CXX and OBJCXX files, not C files. We have to do the
# same otherwise MinGW builds break when building 3rdparty\md4c\md4c.c (and probably on other
# platforms too).
set(language_args LANGUAGES CXX OBJCXX)
# This property is set to True only if we are using Clang and frontend is MSVC
# Currently we do not set any error flags
set(clang_msvc_frontend_args
"$<NOT:$<BOOL:$<TARGET_PROPERTY:Qt6::PlatformCommonInternal,_qt_internal_clang_msvc_frontend>>>"
)
if(GCC OR CLANG OR WIN32)
# Note: the if check is included to mimic the previous selective gating. These need to
# balance reducing unnecessary compile flags that are evaluated by the genex, and making
# sure the developer has appropriate Werror flags enabled when building a module with
# different environment
qt_internal_add_compiler_dependent_flags("${target}" ${target_scope}
COMPILERS CLANG AppleClang
OPTIONS
-Werror -Wno-error=\#warnings -Wno-error=deprecated-declarations
COMPILERS CLANG
CONDITIONS VERSION_GREATER_EQUAL 10
OPTIONS
# We do mixed enum arithmetic all over the place:
-Wno-error=deprecated-enum-enum-conversion
CONDITIONS VERSION_GREATER_EQUAL 14
OPTIONS
# Clang 14 introduced these two but we are not clean for it.
-Wno-error=deprecated-copy-with-user-provided-copy
-Wno-error=unused-but-set-variable
COMMON_CONDITIONS
${common_conditions}
${clang_msvc_frontend_args}
${language_args}
)
qt_internal_add_compiler_dependent_flags("${target}" ${target_scope}
COMPILERS GNU
OPTIONS
-Werror -Wno-error=cpp -Wno-error=deprecated-declarations
# GCC prints this bogus warning, after it has inlined a lot of code
# error: assuming signed overflow does not occur when assuming that (X + c) < X
# is always false
-Wno-error=strict-overflow
CONDITIONS VERSION_GREATER_EQUAL 7
OPTIONS
# GCC 7 includes -Wimplicit-fallthrough in -Wextra, but Qt is not yet free of
# implicit fallthroughs.
-Wno-error=implicit-fallthrough
CONDITIONS VERSION_GREATER_EQUAL 9
OPTIONS
# GCC 9 introduced these but we are not clean for it.
-Wno-error=deprecated-copy
-Wno-error=redundant-move
-Wno-error=init-list-lifetime
# GCC 9 introduced -Wformat-overflow in -Wall, but it is buggy:
-Wno-error=format-overflow
CONDITIONS VERSION_GREATER_EQUAL 10
OPTIONS
# GCC 10 has a number of bugs in -Wstringop-overflow. Do not make them an error.
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92955
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94335
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101134
-Wno-error=stringop-overflow
CONDITIONS VERSION_GREATER_EQUAL 11
OPTIONS
# Ditto
-Wno-error=stringop-overread
# We do mixed enum arithmetic all over the place:
-Wno-error=deprecated-enum-enum-conversion
-Wno-error=deprecated-enum-float-conversion
CONDITIONS VERSION_GREATER_EQUAL 11.0 AND VERSION_LESS 11.2
OPTIONS
# GCC 11.1 has a regression in the integrated preprocessor, so disable it as a
# workaround (QTBUG-93360)
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100796
# This in turn triggers a fallthrough warning in cborparser.c, so we disable
# this warning.
-no-integrated-cpp -Wno-implicit-fallthrough
CONDITIONS VERSION_LESS 15.1
AND $<BOOL:${QT_FEATURE_sanitize_thread}>
AND $<BOOL:${BUILD_WITH_PCH}>
OPTIONS
# GCC < 15 raises a TSAN warning from Qt's own PCHs, despite the warning
# being suppressed (QTBUG-134415)
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64117
-Wno-error=tsan
COMMON_CONDITIONS
${common_conditions}
${language_args}
)
endif()
# Other options are gated at compile time that are not likely to change between different build
# environments of other modules.
if(ANDROID)
qt_internal_add_compiler_dependent_flags("${target}" ${target_scope}
COMPILERS GNU
CONDITIONS $<PLATFORM_ID:ANDROID>
OPTIONS
# Work-around for bug https://code.google.com/p/android/issues/detail?id=58135
-Wno-error=literal-suffix
COMMON_CONDITIONS
${common_conditions}
${language_args}
)
endif()
if(WIN32)
qt_internal_add_compiler_dependent_flags("${target}" ${target_scope}
COMPILERS MSVC
# Only enable for versions of MSVC that are known to work
# 1941 is Visual Studio 2022 version 17.11
CONDITIONS VERSION_LESS_EQUAL 17.11
OPTIONS
/WX
COMMON_CONDITIONS
${common_conditions}
${language_args}
)
endif()
set(cxx_only_genex "$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:OBJCXX>>")
set(final_condition_genex "$<AND:${warnings_are_errors_enabled_genex},${cxx_only_genex}>")
set(flags_generator_expression "$<${final_condition_genex}:${flags}>")
target_compile_options("${target}" ${target_scope} "${flags_generator_expression}")
endfunction()
# The function adds a global 'definition' to the platform internal targets and the target
@ -136,7 +97,7 @@ endfunction()
# APP - set the definition for all Qt applications
# TODO: Add a tests specific platform target and the definition scope for it.
function(qt_internal_add_global_definition definition)
set(optional_args "")
set(optional_args)
set(single_value_args VALUE)
set(multi_value_args SCOPE)
cmake_parse_arguments(arg
@ -287,13 +248,6 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
"$<$<AND:${not_disabled},${is_xcode15}>:LINKER:-no_warn_duplicate_libraries>")
endif()
if(CYGWIN)
# CYGWIN doesn't define _GNU_SOURCE by default for better support with W32API
target_compile_definitions(PlatformCommonInternal INTERFACE
"_GNU_SOURCE"
)
endif()
if(MSVC)
target_compile_definitions(PlatformCommonInternal INTERFACE
"_CRT_SECURE_NO_WARNINGS"
@ -356,16 +310,6 @@ if (MSVC AND NOT CLANG)
)
endif()
set(_qt_internal_clang_msvc_frontend False)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
set(_qt_internal_clang_msvc_frontend True)
endif()
set_target_properties(PlatformCommonInternal
PROPERTIES
_qt_internal_clang_msvc_frontend "${_qt_internal_clang_msvc_frontend}"
)
if(MINGW)
target_compile_options(PlatformCommonInternal INTERFACE -Wa,-mbig-obj)
endif()
@ -374,22 +318,6 @@ if (GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "9.2")
target_compile_options(PlatformCommonInternal INTERFACE $<$<COMPILE_LANGUAGE:CXX>:-Wsuggest-override>)
endif()
if(QT_FEATURE_stdlib_libcpp)
# Disable transitive C++ inclusions when using libc++, on all
# language versions. See
# https://libcxx.llvm.org/DesignDocs/HeaderRemovalPolicy.html
target_compile_definitions(PlatformCommonInternal INTERFACE _LIBCPP_REMOVE_TRANSITIVE_INCLUDES)
endif()
if(QT_USE_CCACHE AND CLANG AND BUILD_WITH_PCH)
# The ccache man page says we must compile with -fno-pch-timestamp when using clang and pch.
foreach(language IN ITEMS C CXX OBJC OBJCXX)
target_compile_options(PlatformCommonInternal INTERFACE
"$<$<COMPILE_LANGUAGE:${language}>:SHELL:-Xclang -fno-pch-timestamp>"
)
endforeach()
endif()
# Hardening options
qt_internal_apply_intel_cet_harderning(PlatformCommonInternal)

View File

@ -28,7 +28,6 @@ function(qt_internal_add_jar target)
get_filename_component(absolute_path "${path}" ABSOLUTE)
list(APPEND absolute_sources "${absolute_path}")
endforeach()
set_property(DIRECTORY APPEND PROPERTY _qt_jar_sources "${absolute_sources}")
add_jar(${target} SOURCES ${absolute_sources} ${ARGV})

View File

@ -114,8 +114,7 @@ macro(qt_internal_setup_platform_definitions_and_mkspec)
endif()
if(CMAKE_CROSSCOMPILING)
qt_internal_get_host_info_var_prefix(host_info_var_prefix)
set(QT_QMAKE_HOST_MKSPEC "${${host_info_var_prefix}_QMAKE_MKSPEC}")
set(QT_QMAKE_HOST_MKSPEC "${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_QMAKE_MKSPEC}")
else()
set(QT_QMAKE_HOST_MKSPEC "${QT_QMAKE_TARGET_MKSPEC}")
endif()

View File

@ -7,6 +7,9 @@ cmake_minimum_required(VERSION @min_new_policy_version@...@max_new_policy_versio
include(CMakeFindDependencyMacro)
get_filename_component(_import_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_import_prefix "${_import_prefix}" REALPATH)
# Extra cmake code begin
@extra_cmake_code@
# Extra cmake code end
@ -26,42 +29,32 @@ endif()
if (NOT QT_NO_CREATE_TARGETS AND @INSTALL_CMAKE_NAMESPACE@@target@_FOUND)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake"
OPTIONAL)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@ExtraProperties.cmake"
OPTIONAL)
endif()
# Find the private module counterpart.
set(__qt_@target@_always_load_private_module @always_load_private_module@)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@-build.cmake" OPTIONAL)
if (@INSTALL_CMAKE_NAMESPACE@@target@_FOUND
AND NOT @INSTALL_CMAKE_NAMESPACE@@target_private@_FOUND
AND NOT @arg_NO_PRIVATE_MODULE@
AND (
__qt_@target@_always_load_private_module
OR DEFINED QT_REPO_MODULE_VERSION
OR QT_FIND_PRIVATE_MODULES
if (@INSTALL_CMAKE_NAMESPACE@@target@_FOUND AND NOT @arg_NO_PRIVATE_MODULE@)
if(NOT @INSTALL_CMAKE_NAMESPACE@@target_private@_FOUND)
if("${_qt_cmake_dir}" STREQUAL "")
set(_qt_cmake_dir "${QT_TOOLCHAIN_RELOCATABLE_CMAKE_DIR}")
endif()
set(__qt_use_no_default_path_for_qt_packages "NO_DEFAULT_PATH")
if(QT_DISABLE_NO_DEFAULT_PATH_IN_QT_PACKAGES)
set(__qt_use_no_default_path_for_qt_packages "")
endif()
find_package(@INSTALL_CMAKE_NAMESPACE@@target_private@ "@PROJECT_VERSION@" EXACT
QUIET
CONFIG
PATHS
${QT_BUILD_CMAKE_PREFIX_PATH}
"${CMAKE_CURRENT_LIST_DIR}/.."
"${_qt_cmake_dir}"
${_qt_additional_packages_prefix_paths}
${__qt_use_no_default_path_for_qt_packages}
)
)
if("${_qt_cmake_dir}" STREQUAL "")
set(_qt_cmake_dir "${QT_TOOLCHAIN_RELOCATABLE_CMAKE_DIR}")
endif()
set(__qt_use_no_default_path_for_qt_packages "NO_DEFAULT_PATH")
if(QT_DISABLE_NO_DEFAULT_PATH_IN_QT_PACKAGES)
set(__qt_use_no_default_path_for_qt_packages "")
endif()
find_package(@INSTALL_CMAKE_NAMESPACE@@target_private@ "@PROJECT_VERSION@" EXACT
QUIET
CONFIG
PATHS
${QT_BUILD_CMAKE_PREFIX_PATH}
"${CMAKE_CURRENT_LIST_DIR}/.."
"${_qt_cmake_dir}"
${_qt_additional_packages_prefix_paths}
${__qt_use_no_default_path_for_qt_packages}
)
if(NOT @INSTALL_CMAKE_NAMESPACE@@target_private@_FOUND)
get_property(@INSTALL_CMAKE_NAMESPACE@@target_private@_warning_shown GLOBAL PROPERTY
@INSTALL_CMAKE_NAMESPACE@@target_private@_warning_shown
@ -78,7 +71,6 @@ if (@INSTALL_CMAKE_NAMESPACE@@target@_FOUND
endif()
endif()
endif()
unset(__qt_@target@_always_load_private_module)
if (NOT QT_NO_CREATE_TARGETS AND @INSTALL_CMAKE_NAMESPACE@@target@_FOUND)
# DEPRECATED
@ -168,28 +160,18 @@ if (TARGET @QT_CMAKE_EXPORT_NAMESPACE@::@target@)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Plugins.cmake")
endif()
if(NOT "@target@" IN_LIST QT_ALL_MODULES_FOUND_VIA_FIND_PACKAGE)
list(APPEND QT_ALL_MODULES_FOUND_VIA_FIND_PACKAGE "@target@")
list(APPEND QT_ALL_MODULES_VERSIONED_FOUND_VIA_FIND_PACKAGE
"@INSTALL_CMAKE_NAMESPACE@::@target@")
endif()
list(APPEND QT_ALL_MODULES_FOUND_VIA_FIND_PACKAGE "@target@")
get_target_property(_qt_module_target_type "@INSTALL_CMAKE_NAMESPACE@::@target@" TYPE)
if(NOT _qt_module_target_type STREQUAL "INTERFACE_LIBRARY")
get_target_property(_qt_module_plugin_types
@INSTALL_CMAKE_NAMESPACE@::@target@ MODULE_PLUGIN_TYPES)
if(_qt_module_plugin_types)
foreach(_qt_module_plugin_type IN LISTS _qt_module_plugin_types)
if(NOT "${_qt_module_plugin_type}"
IN_LIST QT_ALL_PLUGIN_TYPES_FOUND_VIA_FIND_PACKAGE)
list(APPEND QT_ALL_PLUGIN_TYPES_FOUND_VIA_FIND_PACKAGE
"${_qt_module_plugin_type}")
endif()
endforeach()
unset(_qt_module_plugin_type)
list(APPEND QT_ALL_PLUGIN_TYPES_FOUND_VIA_FIND_PACKAGE "${_qt_module_plugin_types}")
endif()
endif()
# Load Module's BuildInternals should any exist
if (@INSTALL_CMAKE_NAMESPACE@BuildInternals_DIR AND
EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@BuildInternals.cmake")

View File

@ -20,10 +20,6 @@ if(NOT DEFINED "@INSTALL_CMAKE_NAMESPACE@@target_private@_FOUND")
set("@INSTALL_CMAKE_NAMESPACE@@target_private@_FOUND" TRUE)
endif()
if(NOT __qt_@target@_always_load_private_module)
_qt_internal_show_private_module_warning(@target_private@)
endif()
if(NOT QT_NO_CREATE_TARGETS AND @INSTALL_CMAKE_NAMESPACE@@target_private@_FOUND)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@Targets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@AdditionalTargetInfo.cmake")

View File

@ -5,7 +5,6 @@ macro(qt_internal_get_internal_add_module_keywords option_args single_args multi
set(${option_args}
STATIC
EXCEPTIONS
FIND_PRIVATE_MODULE
INTERNAL_MODULE
HEADER_MODULE
DISABLE_TOOLS_EXPORT
@ -82,6 +81,7 @@ endfunction()
# Options:
# NO_ADDITIONAL_TARGET_INFO
# Don't generate a Qt6*AdditionalTargetInfo.cmake file.
# The caller is responsible for creating one.
#
# MODULE_INTERFACE_NAME
# The custom name of the module interface. This name is used as a part of the include paths
@ -131,9 +131,6 @@ endfunction()
# ignored by syncqt. The specifying this directory allows to skip the parsing of the whole
# CMAKE_CURRENT_SOURCE_DIR for the header files that needs to be synced and only parse the
# single subdirectory, that meanwhile can be outside the CMAKE_CURRENT_SOURCE_DIR tree.
#
# FIND_PRIVATE_MODULE
# A call to find_package(Qt6Foo) will imply a call to find_package(Qt6FooPrivate).
function(qt_internal_add_module target)
qt_internal_get_internal_add_module_keywords(
module_option_args
@ -216,17 +213,6 @@ function(qt_internal_add_module target)
"_qt_package_version"
"_qt_package_name"
)
if(CMAKE_VERSION VERSION_LESS 3.30)
# For the CMake versions higher than 3.30 the corresponding INTERFACE_
# properties will be in Qt<Module>Targets.cmake without extra code
# needed.
list(APPEND export_properties
"_qt_transitive_compile_properties"
"_qt_transitive_link_properties"
)
endif()
if(NOT is_internal_module)
set_target_properties(${target} PROPERTIES
_qt_is_public_module TRUE
@ -265,9 +251,10 @@ function(qt_internal_add_module target)
set(module_config_private_header "qt${arg_CONFIG_MODULE_NAME}-config_p.h")
# qt<module>-config.h/-config_p.h header files are not marked as GENERATED automatically
# for old CMake versions. Set the property explicitly here.
_qt_internal_set_source_file_generated(
SOURCES "${module_config_header}" "${module_config_private_header}"
SKIP_AUTOGEN
set_source_files_properties("${module_config_header}" "${module_config_private_header}"
PROPERTIES
GENERATED TRUE
SKIP_AUTOGEN TRUE
)
# Module define needs to take into account the config module name.
@ -340,7 +327,7 @@ function(qt_internal_add_module target)
set_target_properties(${target_private} PROPERTIES
_qt_config_module_name ${arg_CONFIG_MODULE_NAME}_private
_qt_package_version "${PROJECT_VERSION}"
_qt_package_name "${INSTALL_CMAKE_NAMESPACE}${target}Private"
_qt_package_name "${INSTALL_CMAKE_NAMESPACE}${target}"
_qt_is_private_module TRUE
_qt_public_module_target_name "${target}"
)
@ -355,7 +342,7 @@ function(qt_internal_add_module target)
EXPORT_PROPERTIES "${export_properties}")
# Let find_package(Qt6FooPrivate) also find_package(Qt6Foo).
qt_internal_register_target_dependencies("${target_private}" PUBLIC "Qt::${target}")
qt_register_target_dependencies("${target_private}" "Qt::${target}" "")
endif()
# FIXME: This workaround is needed because the deployment logic
@ -458,31 +445,13 @@ function(qt_internal_add_module target)
set(module_depends_header
"${module_build_interface_include_dir}/${module_include_name}Depends")
_qt_internal_set_source_file_generated(SOURCES "${module_depends_header}")
set_source_files_properties("${module_depends_header}" PROPERTIES GENERATED TRUE)
set_target_properties(${target} PROPERTIES _qt_module_depends_header
"${module_depends_header}")
if(NOT arg_HEADER_MODULE)
set(module_header "${module_build_interface_include_dir}/${module_include_name}")
set_property(TARGET "${target}" PROPERTY MODULE_HEADER
"${module_header}")
if(QT_FEATURE_no_prefix)
file(RELATIVE_PATH relative_include_dir
"/${QT_CONFIG_INSTALL_DIR}/${module_include_name}"
"/${module_build_interface_include_dir}"
)
else()
file(RELATIVE_PATH relative_include_dir
"/${QT_CONFIG_INSTALL_DIR}/${module_include_name}"
"/${module_install_interface_include_dir}"
)
endif()
set_property(TARGET "${target}" PROPERTY
_qt_module_relative_include_dir "${relative_include_dir}"
)
set_property(TARGET ${target} APPEND PROPERTY
EXPORT_PROPERTIES _qt_module_relative_include_dir
)
endif()
set(qpa_filter_regex "")
@ -693,7 +662,7 @@ function(qt_internal_add_module target)
# thus we can't use qt_internal_extend_target()'s PUBLIC_DEFINES option.
target_compile_definitions(${target} INTERFACE QT_${module_define_infix}_LIB)
if(NOT arg_EXCEPTIONS)
if(NOT DEFINED arg_EXCEPTIONS)
qt_internal_set_exceptions_flags("${target}" "DEFAULT")
else()
qt_internal_set_exceptions_flags("${target}" "${arg_EXCEPTIONS}")
@ -739,21 +708,6 @@ function(qt_internal_add_module target)
list(APPEND extra_cmake_includes "${INSTALL_CMAKE_NAMESPACE}${target}Macros.cmake")
endif()
if(CMAKE_VERSION VERSION_LESS 3.30)
# For the CMake versions higher than 3.30 the corresponding INTERFACE_
# properties will be in Qt<Module>Targets.cmake without extra code
# needed.
configure_file(
"${QT_CMAKE_DIR}/QtTransitiveExtras.cmake.in"
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}TransitiveExtras.cmake"
@ONLY
)
list(APPEND extra_cmake_files
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}TransitiveExtras.cmake")
list(APPEND extra_cmake_includes
"${INSTALL_CMAKE_NAMESPACE}${target}TransitiveExtras.cmake")
endif()
if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigExtras.cmake.in")
if(target STREQUAL Core)
if(NOT "${QT_NAMESPACE}" STREQUAL "")
@ -794,20 +748,12 @@ set(QT_ALLOW_MISSING_TOOLS_PACKAGES TRUE)")
endif()
foreach(cmake_file IN LISTS arg_EXTRA_CMAKE_FILES)
get_source_file_property(install_path ${cmake_file} QT_INSTALL_PATH)
if(NOT install_path)
# Sanitize the install_path from `NOTFOUND` to ""
set(install_path "")
endif()
file(COPY ${cmake_file} DESTINATION "${config_build_dir}/${install_path}")
qt_install(FILES
${cmake_file}
DESTINATION "${config_install_dir}/${install_path}"
COMPONENT Devel
)
get_filename_component(basename ${cmake_file} NAME)
file(COPY ${cmake_file} DESTINATION ${config_build_dir})
list(APPEND extra_cmake_files "${config_build_dir}/${basename}")
# Make sure touched extra cmake files cause a reconfigure, so they get re-copied.
_qt_internal_append_cmake_configure_depends("${cmake_file}")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${cmake_file}")
endforeach()
list(APPEND extra_cmake_includes ${arg_EXTRA_CMAKE_INCLUDES})
@ -844,22 +790,7 @@ set(QT_ALLOW_MISSING_TOOLS_PACKAGES TRUE)")
qt_internal_get_min_new_policy_cmake_version(min_new_policy_version)
qt_internal_get_max_new_policy_cmake_version(max_new_policy_version)
if(is_static_lib)
set(write_basic_module_package_args IS_STATIC_LIB)
else()
set(write_basic_module_package_args "")
endif()
if(arg_FIND_PRIVATE_MODULE)
set(write_basic_public_module_package_args FIND_PRIVATE_MODULE)
else()
set(write_basic_public_module_package_args "")
endif()
qt_internal_write_basic_module_package("${target}" "${target_private}"
${write_basic_module_package_args}
${write_basic_public_module_package_args}
CONFIG_BUILD_DIR ${config_build_dir}
CONFIG_INSTALL_DIR ${config_install_dir}
)
@ -878,8 +809,7 @@ set(QT_ALLOW_MISSING_TOOLS_PACKAGES TRUE)")
)
if(NOT arg_NO_PRIVATE_MODULE)
qt_internal_write_basic_module_package("${target}" "${target_private}"
${write_basic_module_package_args}
qt_internal_write_basic_module_package(${target} ${target_private}
PRIVATE
CONFIG_BUILD_DIR ${private_config_build_dir}
CONFIG_INSTALL_DIR ${private_config_install_dir}
@ -888,6 +818,11 @@ set(QT_ALLOW_MISSING_TOOLS_PACKAGES TRUE)")
file(COPY ${extra_cmake_files} DESTINATION "${config_build_dir}")
set(targets_to_export ${target})
if(NOT ${arg_NO_PRIVATE_MODULE})
list(APPEND targets_to_export ${target_private})
endif()
_qt_internal_forward_function_args(
FORWARD_PREFIX arg
FORWARD_OUT_VAR export_module_args
@ -1036,7 +971,7 @@ set(QT_ALLOW_MISSING_TOOLS_PACKAGES TRUE)")
${__qt_internal_sbom_multi_args}
)
qt_internal_extend_qt_entity_sbom(${target} ${sbom_args})
_qt_internal_extend_sbom(${target} ${sbom_args})
endif()
qt_add_list_file_finalizer(qt_finalize_module ${target} ${arg_INTERNAL_MODULE} ${arg_NO_PRIVATE_MODULE})
@ -1046,10 +981,11 @@ endfunction()
#
# If PRIVATE is specified, write Qt6FooPrivate.
# Otherwise write its public counterpart.
function(qt_internal_write_basic_module_package target target_private)
#
# Note that this function is supposed to be called from qt_internal_add_module, and depends on
# variables set in the scope of that function, e.g. target and target_private.
function(qt_internal_write_basic_module_package)
set(no_value_options
FIND_PRIVATE_MODULE
IS_STATIC_LIB
PRIVATE
)
set(single_value_options
@ -1061,36 +997,12 @@ function(qt_internal_write_basic_module_package target target_private)
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
)
set(always_load_private_module OFF)
if(arg_PRIVATE)
set(package_name "${INSTALL_CMAKE_NAMESPACE}${target_private}")
set(module_config_input_file "QtModuleConfigPrivate.cmake.in")
else()
set(package_name "${INSTALL_CMAKE_NAMESPACE}${target}")
set(module_config_input_file "QtModuleConfig.cmake.in")
if(arg_FIND_PRIVATE_MODULE)
set(always_load_private_module ON)
endif()
endif()
if((QT_FEATURE_no_prefix OR arg_IS_STATIC_LIB)
AND NOT arg_PRIVATE
AND CMAKE_VERSION VERSION_LESS "3.26")
# We auto-load the private module package from the public module package if we have a
# statically built module or a non-prefix build and CMake's version is < 3.26. This is
# needed for the case "Qt6Foo links against Qt6BarPrivate", because CMake generates a check
# for the target Qt6::BarPrivate in Qt6FooTargets.cmake. Once we can require CMake 3.26, we
# can simply link against $<BUILD_LOCAL_INTERFACE:Qt6BarPrivate> in
# qt_internal_extend_target.
#
# For older CMake versions, we create an additional CMake file that's optionally included by
# Qt6FooConfig.cmake to work around the lack of BUILD_LOCAL_INTERFACE.
file(CONFIGURE
OUTPUT "${arg_CONFIG_BUILD_DIR}/${package_name}-build.cmake"
CONTENT "# This file marks this directory as part of Qt's build tree.
set(__qt_${target}_always_load_private_module ON)
"
)
endif()
configure_package_config_file(
@ -1186,47 +1098,15 @@ function(qt_internal_apply_apple_privacy_manifest target)
endfunction()
function(qt_finalize_module target)
set(no_value_options
INTERNAL_MODULE
NO_PRIVATE_MODULE
)
set(single_value_options "")
set(multi_value_options "")
cmake_parse_arguments(PARSE_ARGV 1 arg
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
)
_qt_internal_validate_all_args_are_parsed(arg)
qt_internal_collect_module_headers(module_headers ${target})
# Issue a warning if we
# - suppressed creation of the private module but have private headers
# - created a private module but don't have any private headers
if(NOT arg_INTERNAL_MODULE)
get_target_property(has_private_headers ${target} _qt_module_has_private_headers)
if(arg_NO_PRIVATE_MODULE AND has_private_headers)
message(AUTHOR_WARNING
"Module ${target} has private headers. "
"Please remove NO_PRIVATE_MODULE from its creation flags."
)
elseif(NOT arg_NO_PRIVATE_MODULE AND NOT has_private_headers)
message(AUTHOR_WARNING
"Module ${target} does not have private headers. "
"Please add NO_PRIVATE_MODULE to its creation flags."
)
endif()
endif()
# qt_internal_install_module_headers needs to be called before
# qt_finalize_framework_headers_copy, because the last uses the QT_COPIED_FRAMEWORK_HEADERS
# property which supposed to be updated inside every qt_internal_install_module_headers
# call.
qt_internal_add_headersclean_target(${target} "${module_headers_public}")
qt_internal_target_sync_headers(${target}
"${module_headers_all}"
"${module_headers_generated}"
"${module_headers_exclude_from_docs}"
)
qt_internal_target_sync_headers(${target} "${module_headers_all}"
"${module_headers_generated}")
get_target_property(module_depends_header ${target} _qt_module_depends_header)
qt_internal_install_module_headers(${target}
PUBLIC ${module_headers_public} "${module_depends_header}"
@ -1440,12 +1320,7 @@ function(qt_describe_module target)
qt_path_join(install_dir ${QT_INSTALL_DIR} ${path_suffix})
set(descfile_in "${QT_CMAKE_DIR}/ModuleDescription.json.in")
# IMPORTANT: If you adjust the file name not to be the exact target name and thus the CMake
# package name, it needs to consider also the code in QtConfig.cmake.in that globs the json
# files.
set(descfile_out "${build_dir}/${target}.json")
string(TOLOWER "${PROJECT_NAME}" lower_case_project_name)
set(extra_module_information "")
set(platforms_information "")
@ -1593,12 +1468,7 @@ function(qt_internal_generate_cpp_global_exports target module_define_infix)
set(${out_public_header} "${generated_header_path}" PARENT_SCOPE)
target_sources(${target} PRIVATE "${generated_header_path}")
_qt_internal_set_source_file_generated(
SOURCES "${generated_header_path}"
CONFIGURE_GENERATED
)
# Make sure the file is installed when processed by `qt_internal_collect_module_headers`
set_source_files_properties("${generated_header_path}" PROPERTIES _qt_syncqt_force_include TRUE)
set_source_files_properties("${generated_header_path}" PROPERTIES GENERATED TRUE)
endfunction()
function(qt_internal_install_module_headers target)
@ -1656,7 +1526,6 @@ endfunction()
function(qt_internal_collect_module_headers out_var target)
set(${out_var}_public "")
set(${out_var}_private "")
set(${out_var}_exclude_from_docs "")
set(${out_var}_qpa "")
set(${out_var}_rhi "")
set(${out_var}_ssg "")
@ -1697,13 +1566,16 @@ function(qt_internal_collect_module_headers out_var target)
get_filename_component(file_path "${file_path}" ABSOLUTE)
_qt_internal_path_is_prefix(source_dir "${file_path}" is_inside_module_source_dir)
string(FIND "${file_path}" "${source_dir}" source_dir_pos)
if(source_dir_pos EQUAL 0)
set(is_outside_module_source_dir FALSE)
else()
set(is_outside_module_source_dir TRUE)
endif()
get_source_file_property(forced_include "${file_path}" _qt_syncqt_force_include)
get_source_file_property(is_generated "${file_path}" GENERATED)
# Skip all header files outside the module source directory, except the generated files,
# or files explicitly marked to be included for syncqt.
if(NOT (forced_include OR is_inside_module_source_dir OR is_generated))
# Skip all header files outside the module source directory, except the generated files.
if(is_outside_module_source_dir AND NOT is_generated)
continue()
endif()
@ -1715,10 +1587,10 @@ function(qt_internal_collect_module_headers out_var target)
"\nCondition:\n ${condition_string}")
endif()
if(is_inside_module_source_dir)
set(base_dir "${source_dir}")
else()
if(is_outside_module_source_dir)
set(base_dir "${binary_dir}")
else()
set(base_dir "${source_dir}")
endif()
file(RELATIVE_PATH file_path_rel "${base_dir}" "${file_path}")
@ -1728,12 +1600,6 @@ function(qt_internal_collect_module_headers out_var target)
set(is_3rdparty_header FALSE)
endif()
list(APPEND ${out_var}_all "${file_path}")
get_source_file_property(exclude_from_docs "${file_path}" _qt_syncqt_exclude_from_docs)
if(exclude_from_docs)
list(APPEND ${out_var}_exclude_from_docs "${file_path}")
endif()
if(qpa_filter AND file_name MATCHES "${qpa_filter}")
list(APPEND ${out_var}_qpa "${file_path}")
elseif(rhi_filter AND file_name MATCHES "${rhi_filter}")
@ -1776,7 +1642,6 @@ function(qt_internal_collect_module_headers out_var target)
endforeach()
set(${out_var}_all "${${out_var}_all}" PARENT_SCOPE)
set(${out_var}_generated "${${out_var}_generated}" PARENT_SCOPE)
set(${out_var}_exclude_from_docs "${${out_var}_exclude_from_docs}" PARENT_SCOPE)
if(has_header_types_properties)
set_target_properties(${target} PROPERTIES ${has_header_types_properties})
@ -1790,100 +1655,3 @@ function(qt_internal_collect_module_headers out_var target)
_qt_module_has_ssg_headers
)
endfunction()
# Set the value of the respective module properties and make the properties
# transitive. The property is not stored as target property, but is set as
# INTERFACE property, so its value is not considered by target itself, but only
# by depending targets. Also this require all properties have the
# INTERFACE_<property_name> name format.
#
# Synopsis
# qt_internal_set_module_transitive_properties(<target>
# PROPERTIES <prop1> <value1> [<prop2> <value2>] ...
# )
#
# Arguments
#
# `target` Qt module target. Unlike CMake set_target_properties this function
# accepts only one target as argument.
#
# `PROPERTIES` List of the property name-value pairs.
#
# `TYPE` The transitive property type: COMPILE or LINK.
function(qt_internal_set_module_transitive_properties target)
cmake_parse_arguments(PARSE_ARGV 1 arg "" "TYPE" "PROPERTIES")
if(NOT arg_PROPERTIES)
message(FATAL_ERROR "PROPERTIES argument is missing.")
endif()
if(NOT arg_TYPE)
message(FATAL_ERROR "TYPE argument is missing.")
endif()
list(LENGTH arg_PROPERTIES count)
math(EXPR even_args_count "${count} % 2")
if(NOT even_args_count EQUAL 0)
message(FATAL_ERROR "Insufficient number of PROPERTIES values.")
endif()
_qt_internal_dealias_target(target)
set(property_names "")
set(internal_property_names "")
math(EXPR last "${count} - 1")
foreach(name_idx RANGE 0 ${last} 2)
list(GET arg_PROPERTIES ${name_idx} interface_property_name)
if(interface_property_name MATCHES "^INTERFACE_(.+)$")
set(property_name "${CMAKE_MATCH_1}")
else()
message(FATAL_ERROR "Incorrect property name ${interface_property_name}. The property"
" name must have the INTERFACE_ prefix. Use regular set_target_properties call to set"
" the non-transitive property.")
endif()
string(TOLOWER "${property_name}" property_name_lower)
list(APPEND property_names ${property_name})
math(EXPR value_idx "${name_idx} + 1")
list(GET arg_PROPERTIES ${value_idx} property_value)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.30)
# The collected interface properties exposed in module build tree and have the
# same transitive capabilities as after the module is installed. Supported for
# CMake version >= 3.30
set_property(TARGET ${target} PROPERTY ${interface_property_name} "${property_value}")
else()
# Internal properties are exported within the Qt module. They have limitations that
# EXPORT_PROPERTIES apply. These properties are exported even if we are building Qt
# with CMake versions that do not support transitive properties. It allows using
# them as transitive properties in user projects if CMake allows this.
list(APPEND internal_property_names _qt_internal_${property_name_lower})
set_property(TARGET ${target} PROPERTY
_qt_internal_${property_name_lower} "${property_value}")
endif()
_qt_internal_add_transitive_property(${target} ${arg_TYPE} ${property_name})
endforeach()
get_target_property(transitive_properties ${target} _qt_transitive_${type_lower}_properties)
if(NOT transitive_properties)
set(transitive_properties "")
endif()
list(APPEND transitive_properties ${property_names})
list(REMOVE_DUPLICATES transitive_properties)
get_target_property(export_properties ${target} EXPORT_PROPERTIES)
if(NOT export_properties)
set(export_properties "")
endif()
list(APPEND export_properties ${internal_property_names})
list(REMOVE_DUPLICATES export_properties)
string(TOLOWER "${arg_TYPE}" type_lower)
set_target_properties(${target} PROPERTIES
EXPORT_PROPERTIES "${export_properties}"
_qt_transitive_${type_lower}_properties "${transitive_properties}"
)
endfunction()

View File

@ -22,7 +22,8 @@ endmacro()
# Create a Qt6*.pc file intended for pkg-config consumption.
function(qt_internal_generate_pkg_config_file module)
# TODO: PkgConfig is supported under MSVC with pkgconf (github.com/pkgconf/pkgconf)
if(NOT UNIX AND NOT MINGW OR CMAKE_VERSION VERSION_LESS "3.20" OR ANDROID)
if((NOT UNIX OR QT_FEATURE_framework)
AND NOT MINGW OR CMAKE_VERSION VERSION_LESS "3.20" OR ANDROID)
return()
endif()
if(NOT BUILD_SHARED_LIBS)
@ -33,6 +34,7 @@ function(qt_internal_generate_pkg_config_file module)
set(pkgconfig_name "${QT_CMAKE_EXPORT_NAMESPACE} ${module}")
set(pkgconfig_description "Qt ${module} module")
set(target "${QT_CMAKE_EXPORT_NAMESPACE}::${module}")
set(is_interface_library "$<STREQUAL:$<TARGET_PROPERTY:${target},TYPE>,INTERFACE_LIBRARY>")
# The flags macro expanded this variables so it's better to set them at
# their corresponding PkgConfig string.
set(includedir "\${includedir}")
@ -48,12 +50,6 @@ function(qt_internal_generate_pkg_config_file module)
get_target_property(loose_include_dirs ${target} INTERFACE_INCLUDE_DIRECTORIES)
list(TRANSFORM loose_include_dirs REPLACE "${INSTALL_INCLUDEDIR}" "\${includedir}")
list(TRANSFORM loose_include_dirs REPLACE "${INSTALL_MKSPECSDIR}" "\${mkspecsdir}")
if(QT_FEATURE_framework)
# Update the include path for framework headers which are located in INSTALL_LIBDIR,
# e.g. this results in -I${libdir}/Qt*.framework/Headers for Qt6*.pc file.
set(libdir "\${libdir}")
list(TRANSFORM loose_include_dirs REPLACE "${INSTALL_LIBDIR}" "\${libdir}")
endif()
# Remove genex wrapping around gc_sections flag because we can't evaluate genexes like
# $<CXX_COMPILER_ID> in file(GENERATE). And given that .pc files don't support dynamic
@ -73,17 +69,6 @@ function(qt_internal_generate_pkg_config_file module)
set(contains_mkspecs TRUE)
endif()
get_target_property(type ${target} TYPE)
if(NOT type STREQUAL "INTERFACE_LIBRARY")
get_target_property(is_framework ${target} FRAMEWORK)
if(is_framework)
qt_internal_get_framework_info(fw ${target})
string(PREPEND link_options "-F\${libdir} -framework ${fw_name} ")
else()
string(PREPEND link_options "-L\${libdir} -l${pkgconfig_file} ")
endif()
endif()
# TODO: Handle macOS framework builds
qt_internal_collect_direct_target_dependencies(${target} loose_target_requires)
foreach(dep IN LISTS loose_target_requires)

View File

@ -23,7 +23,59 @@ if (NOT IS_DIRECTORY "${ANDROID_SDK_ROOT}")
message(FATAL_ERROR "Could not find ANDROID_SDK_ROOT or path is not a directory: ${ANDROID_SDK_ROOT}")
endif()
_qt_internal_locate_android_jar()
function(qt_internal_sort_android_platforms out_var)
if(CMAKE_VERSION GREATER_EQUAL 3.18)
set(platforms ${ARGN})
list(SORT platforms COMPARE NATURAL)
else()
# Simulate natural sorting:
# - prepend every platform with its version as three digits, zero-padded
# - regular sort
# - remove the padded version prefix
set(platforms)
foreach(platform IN LISTS ARGN)
set(version "000")
if(platform MATCHES ".*-([0-9]+)$")
set(version ${CMAKE_MATCH_1})
string(LENGTH "${version}" version_length)
math(EXPR padding_length "3 - ${version_length}")
string(REPEAT "0" ${padding_length} padding)
string(PREPEND version ${padding})
endif()
list(APPEND platforms "${version}~${platform}")
endforeach()
list(SORT platforms)
list(TRANSFORM platforms REPLACE "^.*~" "")
endif()
set("${out_var}" "${platforms}" PARENT_SCOPE)
endfunction()
# This variable specifies the API level used for building Java code, it can be the same as Qt for
# Android's maximum supported Android version or higher.
if(NOT QT_ANDROID_API_USED_FOR_JAVA)
set(QT_ANDROID_API_USED_FOR_JAVA "android-34")
endif()
set(jar_location "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_USED_FOR_JAVA}/android.jar")
if(NOT EXISTS "${jar_location}")
_qt_internal_detect_latest_android_platform(android_platform_latest)
if(android_platform_latest)
message(NOTICE "The default platform SDK ${QT_ANDROID_API_USED_FOR_JAVA} not found, "
"using the latest installed ${android_platform_latest} instead.")
set(QT_ANDROID_API_USED_FOR_JAVA ${android_platform_latest})
endif()
endif()
set(QT_ANDROID_JAR "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_USED_FOR_JAVA}/android.jar")
if(NOT EXISTS "${QT_ANDROID_JAR}")
message(FATAL_ERROR
"No suitable Android SDK platform found in '${ANDROID_SDK_ROOT}/platforms'."
" The minimum version required for building Java code is ${QT_ANDROID_API_USED_FOR_JAVA}"
)
endif()
message(STATUS "Using Android SDK API ${QT_ANDROID_API_USED_FOR_JAVA} from "
"${ANDROID_SDK_ROOT}/platforms")
# Locate Java
include(UseJava)
@ -111,12 +163,10 @@ define_property(TARGET
# Returns test execution arguments for Android targets
function(qt_internal_android_test_runner_arguments target out_test_runner out_test_arguments)
qt_internal_get_host_info_var_prefix(host_info_var_prefix)
set(host_bin_dir "${QT_HOST_PATH}/${${host_info_var_prefix}_BINDIR}")
set(${out_test_runner} "${host_bin_dir}/androidtestrunner" PARENT_SCOPE)
set(deployment_tool "${host_bin_dir}/androiddeployqt")
set(${out_test_runner} "${QT_HOST_PATH}/${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_BINDIR}/androidtestrunner" PARENT_SCOPE)
set(deployment_tool "${QT_HOST_PATH}/${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_BINDIR}/androiddeployqt")
_qt_internal_android_get_target_android_build_dir(android_build_dir ${target})
qt_internal_android_get_target_android_build_dir(${target} android_build_dir)
set(${out_test_arguments}
"--path" "${android_build_dir}"
"--adb" "${ANDROID_SDK_ROOT}/platform-tools/adb"

View File

@ -22,6 +22,9 @@ cmake_minimum_required(VERSION @min_new_policy_version@...@max_new_policy_versio
include(CMakeFindDependencyMacro)
get_filename_component(_import_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_import_prefix "${_import_prefix}" REALPATH)
if (NOT QT_NO_CREATE_TARGETS)
# Find required dependencies, if any.
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake")

View File

@ -115,12 +115,6 @@ function(qt_internal_add_plugin target)
qt_get_sanitized_plugin_type("${plugin_type}" plugin_type_escaped)
if(NOT TARGET qt_${plugin_type_escaped}_plugins_all)
add_custom_target(qt_${plugin_type_escaped}_plugins_all)
endif()
add_dependencies(qt_${plugin_type_escaped}_plugins_all ${target})
set(output_directory_default "${QT_BUILD_DIR}/${INSTALL_PLUGINSDIR}/${plugin_type}")
set(install_directory_default "${INSTALL_PLUGINSDIR}/${plugin_type}")
@ -214,7 +208,10 @@ function(qt_internal_add_plugin target)
set(plugin_install_package_suffix "${qt_module}")
_qt_internal_dealias_target(qt_module_target)
get_target_property(aliased_target ${qt_module_target} ALIASED_TARGET)
if(aliased_target)
set(qt_module_target ${aliased_target})
endif()
get_target_property(is_imported_qt_module ${qt_module_target} IMPORTED)
if(NOT is_imported_qt_module)
@ -232,6 +229,8 @@ function(qt_internal_add_plugin target)
__qt_internal_add_interface_plugin_target(${qt_module_target} ${target})
endif()
set(plugin_target_versioned "${QT_CMAKE_EXPORT_NAMESPACE}::${target}")
get_target_property(type "${plugin_target_versioned}" TYPE)
qt_internal_add_autogen_sync_header_dependencies(${target} ${qt_module_target})
endif()
@ -323,7 +322,7 @@ function(qt_internal_add_plugin target)
qt_internal_add_repo_local_defines("${target}")
if(NOT arg_EXCEPTIONS)
if(NOT DEFINED arg_EXCEPTIONS)
qt_internal_set_exceptions_flags("${target}" "DEFAULT")
else()
qt_internal_set_exceptions_flags("${target}" "${arg_EXCEPTIONS}")
@ -338,16 +337,7 @@ function(qt_internal_add_plugin target)
endif()
endforeach()
set(qt_register_target_dependencies_args "")
if(arg_PUBLIC_LIBRARIES)
list(APPEND qt_register_target_dependencies_args PUBLIC ${arg_PUBLIC_LIBRARIES})
endif()
if(qt_libs_private)
qt_internal_wrap_private_modules(qt_libs_private ${qt_libs_private})
list(APPEND qt_register_target_dependencies_args PRIVATE ${qt_libs_private})
endif()
qt_internal_register_target_dependencies("${target}"
${qt_register_target_dependencies_args})
qt_register_target_dependencies("${target}" "${arg_PUBLIC_LIBRARIES}" "${qt_libs_private}")
if(target_type STREQUAL STATIC_LIBRARY)
if(qt_module_target)
@ -383,8 +373,8 @@ function(qt_internal_add_plugin target)
# when building standalone tests.
if(QT_INTERNAL_CONFIGURING_TESTS OR arg_TEST_PLUGIN)
if(NOT arg_TEST_PLUGIN)
message(WARNING "The installable test plugin ${target} is built as part of a test"
" suite, but is not marked as TEST_PLUGIN using the respective argument."
message(WARNING "The installable test plugin ${target} is built as part of test"
" suite, but is not marked as TEST_PLUGIN using the repsective argument."
"\nThis warning will soon become an error."
)
endif()
@ -480,7 +470,7 @@ endif()"
${__qt_internal_sbom_multi_args}
)
qt_internal_extend_qt_entity_sbom(${target} ${sbom_args})
_qt_internal_extend_sbom(${target} ${sbom_args})
endif()
qt_add_list_file_finalizer(qt_finalize_plugin ${target} ${finalizer_extra_args})

View File

@ -167,11 +167,8 @@ function(qt_internal_create_module_depends_file target)
set(qt_module_dependencies "")
if(NOT is_interface_lib)
# TODO: deprecated code path. QT_EXTRA_PACKAGE_DEPENDENCIES shouldn't be used for the Qt
# packages.
get_target_property(extra_depends "${target}" QT_EXTRA_PACKAGE_DEPENDENCIES)
endif()
if(NOT extra_depends MATCHES "-NOTFOUND$")
list(APPEND target_deps "${extra_depends}")
endif()
@ -432,7 +429,7 @@ endif()")
# to the target CMAKE_INSTALL_DIR, if at all possible to do so in a reliable way.
get_filename_component(qt_host_path_absolute "${QT_HOST_PATH}" ABSOLUTE)
get_filename_component(qt_host_path_cmake_dir_absolute
"${${INSTALL_CMAKE_NAMESPACE}HostInfo_DIR}/.." ABSOLUTE)
"${Qt${PROJECT_VERSION_MAJOR}HostInfo_DIR}/.." ABSOLUTE)
endif()
if(third_party_deps OR platform_requires_host_info_package)
@ -497,8 +494,67 @@ function(qt_internal_create_plugins_auto_inclusion_files)
if(QT_MODULE STREQUAL "Qml")
set(QT_MODULE_PLUGIN_INCLUDES "${QT_MODULE_PLUGIN_INCLUDES}
__qt_internal_include_qml_plugin_packages()
")
# Qml plugin targets might have dependencies on other qml plugin targets, but the Targets.cmake
# files are included in the order that file(GLOB) returns, which means certain targets that are
# referenced might not have been created yet, and \${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE
# might be set to a message saying those targets don't exist.
#
# Postpone checking of which targets don't exist until all Qml PluginConfig.cmake files have been
# included, by including all the files one more time and checking for errors at each step.
#
# TODO: Find a better way to deal with this, perhaps by using find_package() instead of include
# for the Qml PluginConfig.cmake files.
# Distributions should probably change this default.
if(NOT DEFINED QT_SKIP_AUTO_QML_PLUGIN_INCLUSION)
set(QT_SKIP_AUTO_QML_PLUGIN_INCLUSION OFF)
endif()
set(__qt_qml_plugins_config_file_list \"\")
set(__qt_qml_plugins_glob_prefixes \"\${CMAKE_CURRENT_LIST_DIR}\")
# Allow passing additional prefixes where we will glob for PluginConfig.cmake files.
if(QT_ADDITIONAL_QML_PLUGIN_GLOB_PREFIXES)
foreach(__qt_qml_plugin_glob_prefix IN LISTS QT_ADDITIONAL_QML_PLUGIN_GLOB_PREFIXES)
if(__qt_qml_plugin_glob_prefix)
list(APPEND __qt_qml_plugins_glob_prefixes \"\${__qt_qml_plugin_glob_prefix}\")
endif()
endforeach()
endif()
list(REMOVE_DUPLICATES __qt_qml_plugins_glob_prefixes)
foreach(__qt_qml_plugin_glob_prefix IN LISTS __qt_qml_plugins_glob_prefixes)
file(GLOB __qt_qml_plugins_glob_config_file_list
\"\${__qt_qml_plugin_glob_prefix}/QmlPlugins/${INSTALL_CMAKE_NAMESPACE}*Config.cmake\")
if(__qt_qml_plugins_glob_config_file_list)
list(APPEND __qt_qml_plugins_config_file_list \${__qt_qml_plugins_glob_config_file_list})
endif()
endforeach()
if (__qt_qml_plugins_config_file_list AND NOT QT_SKIP_AUTO_QML_PLUGIN_INCLUSION)
# First round of inclusions ensure all qml plugin targets are brought into scope.
foreach(__qt_qml_plugin_config_file \${__qt_qml_plugins_config_file_list})
include(\${__qt_qml_plugin_config_file})
# Temporarily unset any failure markers and mark the Qml package as found.
unset(\${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE)
set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND TRUE)
endforeach()
# For the second round of inclusions, check and bail out early if there are errors.
foreach(__qt_qml_plugin_config_file \${__qt_qml_plugins_config_file_list})
include(\${__qt_qml_plugin_config_file})
if(\${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE)
string(APPEND \${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE
\"\nThe message was set in \${__qt_qml_plugin_config_file} \")
set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
return()
endif()
endforeach()
endif()")
endif()
get_target_property(module_plugin_types "${QT_MODULE}" MODULE_PLUGIN_TYPES)
@ -528,11 +584,6 @@ function(qt_generate_install_prefixes out_var)
INSTALL_PLUGINSDIR INSTALL_LIBEXECDIR INSTALL_QMLDIR INSTALL_DATADIR INSTALL_DOCDIR
INSTALL_TRANSLATIONSDIR INSTALL_SYSCONFDIR INSTALL_EXAMPLESDIR INSTALL_TESTSDIR
INSTALL_DESCRIPTIONSDIR INSTALL_SBOMDIR)
# INSTALL_PUBLICBINDIR is processed only if it is not empty
# See usage in qt_internal_generate_user_facing_tools_info
if(NOT "${INSTALL_PUBLICBINDIR}" STREQUAL "")
list(APPEND vars INSTALL_PUBLICBINDIR)
endif()
foreach(var ${vars})
get_property(docstring CACHE "${var}" PROPERTY HELPSTRING)
@ -566,15 +617,7 @@ function(qt_create_hostinfo_package)
INSTALL_DESTINATION "${install_destination}"
NO_SET_AND_CHECK_MACRO
NO_CHECK_REQUIRED_COMPONENTS_MACRO)
set(version_file "${QT_CONFIG_BUILD_DIR}/${package}/${package}ConfigVersion.cmake")
write_basic_package_version_file(
"${version_file}"
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
ARCH_INDEPENDENT
)
qt_install(FILES "${config_file_path}" "${version_file}" DESTINATION "${install_destination}")
qt_install(FILES "${config_file_path}" DESTINATION "${install_destination}")
endfunction()
function(qt_generate_build_internals_extra_cmake_code)
@ -878,7 +921,6 @@ function(qt_internal_generate_user_facing_tools_info)
if("${INSTALL_PUBLICBINDIR}" STREQUAL "")
return()
endif()
qt_path_join(tool_link_base_dir "${CMAKE_INSTALL_PREFIX}" "${INSTALL_PUBLICBINDIR}")
get_property(user_facing_tool_targets GLOBAL PROPERTY QT_USER_FACING_TOOL_TARGETS)
set(lines "")
foreach(target ${user_facing_tool_targets})
@ -895,7 +937,6 @@ function(qt_internal_generate_user_facing_tools_info)
endif()
qt_path_join(tool_target_path "${CMAKE_INSTALL_PREFIX}" "${INSTALL_BINDIR}" "${filename}")
qt_path_join(tool_link_path "${INSTALL_PUBLICBINDIR}" "${linkname}${PROJECT_VERSION_MAJOR}")
_qt_internal_relative_path(tool_target_path BASE_DIRECTORY ${tool_link_base_dir})
list(APPEND lines "${tool_target_path} ${tool_link_path}")
endforeach()
string(REPLACE ";" "\n" content "${lines}")

View File

@ -3,55 +3,18 @@
function(qt_update_precompiled_header target precompiled_header)
if (precompiled_header AND BUILD_WITH_PCH)
set_property(TARGET "${target}" APPEND PROPERTY "PRECOMPILE_HEADERS" "$<$<COMPILE_LANGUAGE:CXX,OBJCXX>:${precompiled_header}>")
set_property(TARGET "${target}" APPEND PROPERTY "PRECOMPILE_HEADERS" "$<$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:OBJCXX>>:${precompiled_header}>")
endif()
endfunction()
function(qt_update_precompiled_header_with_library target library)
if(NOT TARGET "${library}")
return()
endif()
get_target_property(target_type "${library}" TYPE)
if(target_type STREQUAL "INTERFACE_LIBRARY")
return()
endif()
get_target_property(header_file_path "${library}" MODULE_HEADER)
if(NOT header_file_path)
# The Qt module is imported from the Qt installation prefix.
# Calculate the module header location.
get_target_property(include_name "${library}" _qt_module_include_name)
if(NOT include_name)
message(DEBUG "Property _qt_module_include_name is not set on ${library}.")
return()
endif()
get_target_property(relative_include_dir "${library}" _qt_module_relative_include_dir)
if(NOT relative_include_dir)
message(DEBUG "Property _qt_module_relative_include_dir is not set on ${library}.")
return()
endif()
get_target_property(package_name ${library} _qt_package_name)
if(NOT package_name)
message(DEBUG "No package name found for ${library}.")
return()
endif()
set(package_location "${${package_name}_DIR}")
get_filename_component(absolute_include_dir
"${package_location}/${relative_include_dir}"
ABSOLUTE
)
set(header_file_path "${absolute_include_dir}/${include_name}")
if(NOT EXISTS "${header_file_path}")
message(DEBUG "Module header '${header_file_path}' does not exist.")
return()
if (TARGET "${library}")
get_target_property(TARGET_TYPE "${library}" TYPE)
if (NOT TARGET_TYPE STREQUAL "INTERFACE_LIBRARY")
get_target_property(HEADER "${library}" MODULE_HEADER)
qt_update_precompiled_header("${target}" "${HEADER}")
endif()
endif()
qt_update_precompiled_header("${target}" "${header_file_path}")
endfunction()
function(qt_update_ignore_pch_source target sources)

View File

@ -738,10 +738,9 @@ function(qt_generate_global_config_pri_file)
endif()
if(CMAKE_CROSSCOMPILING)
qt_internal_get_host_info_var_prefix(host_info_var_prefix)
string(APPEND content "host_build {
QT_ARCH = ${${host_info_var_prefix}_ARCH}
QT_BUILDABI = ${${host_info_var_prefix}_BUILDABI}
QT_ARCH = ${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_ARCH}
QT_BUILDABI = ${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_BUILDABI}
QT_TARGET_ARCH = ${TEST_architecture_arch}
QT_TARGET_BUILDABI = ${TEST_buildAbi}
} else {
@ -966,9 +965,8 @@ function(qt_generate_global_module_pri_file)
set(arch "${TEST_architecture_arch}")
list(JOIN TEST_subarch_result " " subarchs)
if(CMAKE_CROSSCOMPILING)
qt_internal_get_host_info_var_prefix(host_info_var_prefix)
set(host_arch "${${host_info_var_prefix}_ARCH}")
list(JOIN ${host_info_var_prefix}_SUBARCHS " " host_subarchs)
set(host_arch "${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_ARCH}")
list(JOIN QT${PROJECT_VERSION_MAJOR}_HOST_INFO_SUBARCHS " " host_subarchs)
string(APPEND content "host_build {
QT_CPU_FEATURES.${host_arch} = ${host_subarchs}
} else {

View File

@ -65,17 +65,9 @@ function(qt_generate_prl_file target install_dir)
set(prefix_for_final_prl_name "$<TARGET_FILE_PREFIX:${target}>")
endif()
# For macOS frameworks, the prl file should be placed under the Resources subdir.
# For iOS, visionOS, watchOS, tvOS, there is no Resources subdir, and the contents needs to
# be placed directly in the framework root, as described at
# https://developer.apple.com/documentation/bundleresources/placing-content-in-a-bundle?language=objc
# For frameworks, the prl file should be placed under the Resources subdir.
get_target_property(is_framework ${target} FRAMEWORK)
if(APPLE AND (NOT CMAKE_SYSTEM_NAME OR CMAKE_SYSTEM_NAME STREQUAL "Darwin"))
set(is_macos TRUE)
else()
set(is_macos FALSE)
endif()
if(is_framework AND is_macos)
if(is_framework)
get_target_property(fw_version ${target} FRAMEWORK_VERSION)
string(APPEND prefix_for_final_prl_name "Versions/${fw_version}/Resources/")
endif()

View File

@ -230,34 +230,6 @@ function(qt_feature feature)
set_property(GLOBAL PROPERTY COMMANDLINE_FEATURE_SECTION_${feature} "${arg_SECTION}")
endfunction()
function(qt_feature_alias feature)
cmake_parse_arguments(arg "NEGATE" "PURPOSE;SECTION;MESSAGE;ALIAS_OF_FEATURE;ALIAS_OF_CACHE" ""
${ARGN})
set_property(GLOBAL APPEND PROPERTY COMMANDLINE_KNOWN_FEATURES "${feature}")
# Mark the feature as aliased
set(alias_note "alias of ")
if(arg_NEGATE)
string(APPEND alias_note "NOT ")
endif()
if(arg_ALIAS_OF_FEATURE)
string(APPEND alias_note "${arg_ALIAS_OF_FEATURE} Feature")
else()
string(APPEND alias_note "${arg_ALIAS_OF_CACHE} Cache")
endif()
set(arg_PURPOSE "(${alias_note}) ${arg_PURPOSE}")
set_property(GLOBAL PROPERTY COMMANDLINE_FEATURE_PURPOSE_${feature} "${arg_PURPOSE}")
set_property(GLOBAL PROPERTY COMMANDLINE_FEATURE_SECTION_${feature} "${arg_SECTION}")
endfunction()
function(qt_feature_deprecated feature)
cmake_parse_arguments(arg "" "PURPOSE;SECTION;MESSAGE" "" ${ARGN})
set_property(GLOBAL APPEND PROPERTY COMMANDLINE_KNOWN_FEATURES "${feature}")
# Mark the feature as deprecated
set(arg_PURPOSE "(DEPRECATED) ${arg_PURPOSE} ${arg_MESSAGE}")
set_property(GLOBAL PROPERTY COMMANDLINE_FEATURE_PURPOSE_${feature} "${arg_PURPOSE}")
set_property(GLOBAL PROPERTY COMMANDLINE_FEATURE_SECTION_${feature} "${arg_SECTION}")
endfunction()
function(find_package)
message(FATAL_ERROR "find_package must not be used directly in configure.cmake. "
"Use qt_find_package or guard the call with an if(NOT QT_CONFIGURE_RUNNING) block.")
@ -316,7 +288,7 @@ endmacro()
function(qt_commandline_option name)
set(options CONTROLS_FEATURE)
set(oneValueArgs TYPE NAME VALUE CMAKE_VARIABLE)
set(oneValueArgs TYPE NAME VALUE)
set(multiValueArgs VALUES MAPPING)
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
@ -327,9 +299,6 @@ function(qt_commandline_option name)
set(input_name ${arg_NAME})
set(commandline_option_${name}_variable "${arg_NAME}" PARENT_SCOPE)
endif()
if(DEFINED arg_CMAKE_VARIABLE)
set_property(GLOBAL PROPERTY INPUTCMAKEVAR_${input_name} "${arg_CMAKE_VARIABLE}")
endif()
set(mapping_type "${arg_TYPE}")
if(arg_CONTROLS_FEATURE)
set(mapping_type "boolean")
@ -348,13 +317,11 @@ endfunction()
# Add the common command line options for every qt repo.
macro(qt_add_common_commandline_options)
qt_commandline_option(headersclean TYPE boolean)
qt_commandline_option(sbom TYPE boolean CMAKE_VARIABLE QT_GENERATE_SBOM)
qt_commandline_option(sbom-json TYPE boolean CMAKE_VARIABLE QT_SBOM_GENERATE_JSON)
qt_commandline_option(sbom-json-required TYPE boolean
CMAKE_VARIABLE QT_SBOM_REQUIRE_GENERATE_JSON
)
qt_commandline_option(sbom-verify TYPE boolean CMAKE_VARIABLE QT_SBOM_VERIFY)
qt_commandline_option(sbom-verify-required TYPE boolean CMAKE_VARIABLE QT_SBOM_REQUIRE_VERIFY)
qt_commandline_option(sbom TYPE boolean)
qt_commandline_option(sbom-json TYPE boolean)
qt_commandline_option(sbom-json-required TYPE boolean)
qt_commandline_option(sbom-verify TYPE boolean)
qt_commandline_option(sbom-verify-required TYPE boolean)
endmacro()
function(qt_commandline_prefix arg var)
@ -538,18 +505,6 @@ function(qt_commandline_string arg val nextok)
endif()
endfunction()
# Handle command line arguments of type "path" exactly like strings.
# They are treated differently by translate_input, however.
function(qt_commandline_path arg val nextok)
qt_commandline_string("${arg}" "${val}" "${nextok}")
endfunction()
# Handle command line arguments of type "stringList" exactly like strings.
# They are treated differently by translate_input, however.
function(qt_commandline_stringList arg val nextok)
qt_commandline_string("${arg}" "${val}" "${nextok}")
endfunction()
function(qt_commandline_optionalString arg val nextok)
if("${val}" STREQUAL "")
if(nextok)
@ -843,10 +798,9 @@ get_property(config_inputs GLOBAL PROPERTY CONFIG_INPUTS)
list(REMOVE_DUPLICATES config_inputs)
foreach(var ${config_inputs})
get_property(INPUT_${var} GLOBAL PROPERTY INPUT_${var})
if("${commandline_input_${var}_type}" STREQUAL "")
if("${commandline_input_type}" STREQUAL "")
get_property(commandline_input_${var}_type GLOBAL PROPERTY INPUTTYPE_${var})
endif()
get_property(commandline_input_${var}_cmake_variable GLOBAL PROPERTY INPUTCMAKEVAR_${var})
endforeach()
macro(drop_input name)
@ -888,24 +842,6 @@ macro(translate_list_input name cmake_var)
endif()
endmacro()
macro(translate_input name cmake_var)
if("${commandline_input_${name}_type}" STREQUAL "boolean")
translate_boolean_input(${name} ${cmake_var})
elseif("${commandline_input_${name}_type}" STREQUAL "path")
translate_path_input(${name} ${cmake_var})
elseif("${commandline_input_${name}_type}" STREQUAL "string")
translate_string_input(${name} ${cmake_var})
elseif("${commandline_input_${name}_type}" STREQUAL "addString"
OR "${commandline_input_${name}_type}" STREQUAL "stringList")
translate_list_input(${name} ${cmake_var})
else()
message(FATAL_ERROR
"translate_input cannot handle input '${name}' "
"of type '${commandline_input_${name}_type}'."
)
endif()
endmacro()
# Check whether to guess the compiler for the given language.
#
# Sets ${out_var} to FALSE if one of the following holds:
@ -935,27 +871,29 @@ function(guess_compiler_from_mkspec)
check_whether_to_guess_compiler(guess_c_compiler CC CMAKE_C_COMPILER)
check_whether_to_guess_compiler(guess_cxx_compiler CXX CMAKE_CXX_COMPILER)
if(NOT guess_c_compiler AND NOT guess_cxx_compiler)
return()
endif()
string(REGEX MATCH "(^|;)-DQT_QMAKE_TARGET_MKSPEC=\([^;]+\)" m "${cmake_args}")
set(mkspec ${CMAKE_MATCH_2})
if(guess_c_compiler OR guess_cxx_compiler)
set(c_compiler "")
set(cxx_compiler "")
if(mkspec MATCHES "-clang-msvc$")
set(c_compiler "clang-cl")
set(cxx_compiler "clang-cl")
elseif(mkspec MATCHES "-clang(-|$)" AND NOT mkspec MATCHES "android")
set(c_compiler "clang")
set(cxx_compiler "clang++")
elseif(mkspec MATCHES "-msvc(-|$)")
set(c_compiler "cl")
set(cxx_compiler "cl")
endif()
if(guess_c_compiler AND NOT c_compiler STREQUAL "")
push("-DCMAKE_C_COMPILER=${c_compiler}")
endif()
if(guess_cxx_compiler AND NOT cxx_compiler STREQUAL "")
push("-DCMAKE_CXX_COMPILER=${cxx_compiler}")
endif()
set(c_compiler "")
set(cxx_compiler "")
if(mkspec MATCHES "-clang-msvc$")
set(c_compiler "clang-cl")
set(cxx_compiler "clang-cl")
elseif(mkspec MATCHES "-clang(-|$)" AND NOT mkspec MATCHES "android")
set(c_compiler "clang")
set(cxx_compiler "clang++")
elseif(mkspec MATCHES "-msvc(-|$)")
set(c_compiler "cl")
set(cxx_compiler "cl")
endif()
if(guess_c_compiler AND NOT c_compiler STREQUAL "")
push("-DCMAKE_C_COMPILER=${c_compiler}")
endif()
if(guess_cxx_compiler AND NOT cxx_compiler STREQUAL "")
push("-DCMAKE_CXX_COMPILER=${cxx_compiler}")
endif()
if(mkspec MATCHES "-libc\\+\\+$")
push("-DFEATURE_stdlib_libcpp=ON")
@ -987,23 +925,47 @@ function(check_qt_build_parts type)
set(cmake_args "${cmake_args}" PARENT_SCOPE)
endfunction()
# Translate command line arguments that have CMAKE_VARIABLE set.
foreach(input IN LISTS config_inputs)
if(NOT "${commandline_input_${input}_cmake_variable}" STREQUAL "")
translate_input("${input}" "${commandline_input_${input}_cmake_variable}")
endif()
endforeach()
drop_input(commercial)
drop_input(confirm-license)
translate_boolean_input(precompile_header BUILD_WITH_PCH)
translate_boolean_input(unity_build QT_UNITY_BUILD)
translate_string_input(unity_build_batch_size QT_UNITY_BUILD_BATCH_SIZE)
translate_boolean_input(ccache QT_USE_CCACHE)
translate_boolean_input(vcpkg QT_USE_VCPKG)
translate_boolean_input(sbom QT_GENERATE_SBOM)
translate_boolean_input(sbom-json QT_SBOM_GENERATE_JSON)
translate_boolean_input(sbom-json-required QT_SBOM_REQUIRE_GENERATE_JSON)
translate_boolean_input(sbom-verify QT_SBOM_VERIFY)
translate_boolean_input(sbom-verify-required QT_SBOM_REQUIRE_VERIFY)
translate_boolean_input(shared BUILD_SHARED_LIBS)
translate_boolean_input(warnings_are_errors WARNINGS_ARE_ERRORS)
translate_boolean_input(qtinlinenamespace QT_INLINE_NAMESPACE)
translate_string_input(qt_namespace QT_NAMESPACE)
translate_string_input(qt_libinfix QT_LIBINFIX)
translate_string_input(qreal QT_COORD_TYPE)
translate_path_input(prefix CMAKE_INSTALL_PREFIX)
translate_path_input(extprefix CMAKE_STAGING_PREFIX)
foreach(kind bin lib archdata libexec qml data doc sysconf examples tests)
string(TOUPPER ${kind} uc_kind)
translate_path_input(${kind}dir INSTALL_${uc_kind}DIR)
endforeach()
translate_path_input(headerdir INSTALL_INCLUDEDIR)
translate_path_input(plugindir INSTALL_PLUGINSDIR)
translate_path_input(translationdir INSTALL_TRANSLATIONSDIR)
translate_path_input(sbomdir INSTALL_SBOMDIR)
if(NOT "${INPUT_device}" STREQUAL "")
push("-DQT_QMAKE_TARGET_MKSPEC=devices/${INPUT_device}")
drop_input(device)
endif()
translate_string_input(platform QT_QMAKE_TARGET_MKSPEC)
translate_string_input(xplatform QT_QMAKE_TARGET_MKSPEC)
guess_compiler_from_mkspec()
translate_string_input(qpa_default_platform QT_QPA_DEFAULT_PLATFORM)
translate_list_input(qpa_platforms QT_QPA_PLATFORMS)
translate_path_input(android-sdk ANDROID_SDK_ROOT)
translate_path_input(android-ndk ANDROID_NDK_ROOT)
if(DEFINED INPUT_android-ndk-platform)
drop_input(android-ndk-platform)
push("-DANDROID_PLATFORM=${INPUT_android-ndk-platform}")
@ -1015,9 +977,14 @@ if(DEFINED INPUT_android-abis)
endif()
translate_string_input(android-abis ANDROID_ABI)
endif()
translate_string_input(android-javac-source QT_ANDROID_JAVAC_SOURCE)
translate_string_input(android-javac-target QT_ANDROID_JAVAC_TARGET)
translate_string_input(sdk QT_APPLE_SDK)
drop_input(make)
drop_input(nomake)
translate_boolean_input(install-examples-sources QT_INSTALL_EXAMPLES_SOURCES)
check_qt_build_parts(nomake)
check_qt_build_parts(make)
@ -1082,7 +1049,10 @@ if("${INPUT_ltcg}" STREQUAL "yes")
endforeach()
endif()
# Handle -D, -I and friends.
translate_path_input(ffmpeg-dir FFMPEG_DIR)
translate_boolean_input(ffmpeg-deploy QT_DEPLOY_FFMPEG)
translate_list_input(device-option QT_QMAKE_DEVICE_OPTIONS)
translate_list_input(defines QT_EXTRA_DEFINES)
translate_list_input(fpaths QT_EXTRA_FRAMEWORKPATHS)
translate_list_input(includes QT_EXTRA_INCLUDEPATHS)

View File

@ -10,7 +10,7 @@ function(_qt_internal_detect_latest_android_platform out_var)
# If list is not empty
if(android_platforms)
_qt_internal_sort_android_platforms(android_platforms ${android_platforms})
qt_internal_sort_android_platforms(android_platforms ${android_platforms})
list(REVERSE android_platforms)
list(GET android_platforms 0 android_platform_latest)
set(${out_var} "${android_platform_latest}" PARENT_SCOPE)
@ -18,63 +18,3 @@ function(_qt_internal_detect_latest_android_platform out_var)
set(${out_var} "${out_var}-NOTFOUND" PARENT_SCOPE)
endif()
endfunction()
function(_qt_internal_sort_android_platforms out_var)
if(CMAKE_VERSION GREATER_EQUAL 3.18)
set(platforms ${ARGN})
list(SORT platforms COMPARE NATURAL)
else()
# Simulate natural sorting:
# - prepend every platform with its version as three digits, zero-padded
# - regular sort
# - remove the padded version prefix
set(platforms)
foreach(platform IN LISTS ARGN)
set(version "000")
if(platform MATCHES ".*-([0-9]+)$")
set(version ${CMAKE_MATCH_1})
string(LENGTH "${version}" version_length)
math(EXPR padding_length "3 - ${version_length}")
string(REPEAT "0" ${padding_length} padding)
string(PREPEND version ${padding})
endif()
list(APPEND platforms "${version}~${platform}")
endforeach()
list(SORT platforms)
list(TRANSFORM platforms REPLACE "^.*~" "")
endif()
set("${out_var}" "${platforms}" PARENT_SCOPE)
endfunction()
function(_qt_internal_locate_android_jar)
# This variable specifies the API level used for building Java code, it can be the same as Qt
# for Android's maximum supported Android version or higher.
if(NOT QT_ANDROID_API_USED_FOR_JAVA)
set(QT_ANDROID_API_USED_FOR_JAVA "android-35")
endif()
set(jar_location "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_USED_FOR_JAVA}/android.jar")
if(NOT EXISTS "${jar_location}")
_qt_internal_detect_latest_android_platform(android_platform_latest)
if(android_platform_latest)
message(NOTICE "The default platform SDK ${QT_ANDROID_API_USED_FOR_JAVA} not found, "
"using the latest installed ${android_platform_latest} instead.")
set(QT_ANDROID_API_USED_FOR_JAVA ${android_platform_latest})
endif()
endif()
set(QT_ANDROID_JAR "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_USED_FOR_JAVA}/android.jar")
if(NOT EXISTS "${QT_ANDROID_JAR}")
message(FATAL_ERROR
"No suitable Android SDK platform found in '${ANDROID_SDK_ROOT}/platforms'."
" The minimum version required for building Java code is ${QT_ANDROID_API_USED_FOR_JAVA}"
)
endif()
message(STATUS "Using Android SDK API ${QT_ANDROID_API_USED_FOR_JAVA} from "
"${ANDROID_SDK_ROOT}/platforms")
set(QT_ANDROID_JAR "${QT_ANDROID_JAR}" PARENT_SCOPE)
set(QT_ANDROID_API_USED_FOR_JAVA "${QT_ANDROID_API_USED_FOR_JAVA}" PARENT_SCOPE)
endfunction()

View File

@ -97,9 +97,9 @@ function(_qt_internal_handle_ios_launch_screen target)
endif()
endfunction()
function(_qt_internal_find_apple_development_team_id out_var)
function(_qt_internal_find_ios_development_team_id out_var)
get_property(team_id GLOBAL PROPERTY _qt_internal_ios_development_team_id)
get_property(team_id_computed GLOBAL PROPERTY _qt_internal_apple_development_team_id_computed)
get_property(team_id_computed GLOBAL PROPERTY _qt_internal_ios_development_team_id_computed)
if(team_id_computed)
# Just in case if the value is non-empty but still booly FALSE.
if(NOT team_id)
@ -109,31 +109,17 @@ function(_qt_internal_find_apple_development_team_id out_var)
return()
endif()
set_property(GLOBAL PROPERTY _qt_internal_apple_development_team_id_computed "TRUE")
set_property(GLOBAL PROPERTY _qt_internal_ios_development_team_id_computed "TRUE")
set(home_dir "$ENV{HOME}")
set(xcode_preferences_path "${home_dir}/Library/Preferences/com.apple.dt.Xcode.plist")
# Extract the first account name (email) from the user's Xcode preferences
message(DEBUG "Trying to extract an Xcode development team id from '${xcode_preferences_path}'")
# Try Xcode 16.2 format first
_qt_internal_plist_buddy("${xcode_preferences_path}"
COMMANDS "print IDEProvisioningTeamByIdentifier"
EXTRA_ARGS -x
OUTPUT_VARIABLE teams_xml
ERROR_VARIABLE plist_error
)
# Then fall back to older format
if(plist_error OR NOT teams_xml)
_qt_internal_plist_buddy("${xcode_preferences_path}"
COMMANDS "print IDEProvisioningTeams"
EXTRA_ARGS -x
OUTPUT_VARIABLE teams_xml
ERROR_VARIABLE plist_error
)
endif()
execute_process(COMMAND "/usr/libexec/PlistBuddy"
-x -c "print IDEProvisioningTeams" "${xcode_preferences_path}"
OUTPUT_VARIABLE teams_xml
ERROR_VARIABLE plist_error)
# Parsing state.
set(is_free "")
@ -166,16 +152,6 @@ function(_qt_internal_find_apple_development_team_id out_var)
# ...
# </dict>
# </array>
# <key>AAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE</key>
# <array>
# <dict>
# <key>isFreeProvisioningTeam</key>
# <false/>
# <key>teamID</key>
# <string>CCC</string>
# ...
# </dict>
# </array>
#</dict>
#</plist>
if(teams_xml AND NOT plist_error)
@ -294,7 +270,7 @@ function(_qt_internal_get_default_apple_bundle_identifier target out_var)
# For a better out-of-the-box experience, try to create a unique prefix by appending
# the sha1 of the team id, if one is found.
_qt_internal_find_apple_development_team_id(team_id)
_qt_internal_find_ios_development_team_id(team_id)
if(team_id)
string(SHA1 hash "${team_id}")
string(SUBSTRING "${hash}" 0 8 infix)
@ -402,7 +378,7 @@ function(_qt_internal_set_xcode_development_team_id target)
if(NOT CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM AND NOT QT_NO_SET_XCODE_DEVELOPMENT_TEAM_ID)
get_target_property(existing_team_id "${target}" XCODE_ATTRIBUTE_DEVELOPMENT_TEAM)
if(NOT existing_team_id)
_qt_internal_find_apple_development_team_id(team_id)
_qt_internal_find_ios_development_team_id(team_id)
set_target_properties("${target}"
PROPERTIES XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${team_id}")
endif()
@ -659,10 +635,10 @@ endfunction()
function(_qt_internal_plist_buddy plist_file)
cmake_parse_arguments(PARSE_ARGV 1 arg
"" "OUTPUT_VARIABLE;ERROR_VARIABLE;EXTRA_ARGS" "COMMANDS")
"" "OUTPUT_VARIABLE;ERROR_VARIABLE" "COMMANDS")
foreach(command ${arg_COMMANDS})
execute_process(COMMAND "/usr/libexec/PlistBuddy"
${arg_EXTRA_ARGS} -c "${command}" "${plist_file}"
-c "${command}" "${plist_file}"
OUTPUT_VARIABLE plist_buddy_output
ERROR_VARIABLE plist_buddy_error)
string(STRIP "${plist_buddy_output}" plist_buddy_output)
@ -754,25 +730,6 @@ function(_qt_internal_set_ios_simulator_arch target)
"x86_64")
endfunction()
function(_qt_internal_set_xcode_entrypoint_attribute target entrypoint)
if(CMAKE_XCODE_ATTRIBUTE_LD_ENTRY_POINT
OR QT_NO_SET_XCODE_LD_ENTRY_POINT)
return()
endif()
get_target_property(existing_entrypoint
"${target}" XCODE_ATTRIBUTE_LD_ENTRY_POINT)
if(NOT existing_entrypoint MATCHES "-NOTFOUND")
return()
endif()
set_target_properties("${target}"
PROPERTIES
"XCODE_ATTRIBUTE_LD_ENTRY_POINT"
"${entrypoint}")
endfunction()
# Export Apple platform sdk and xcode version requirements to Qt6ConfigExtras.cmake.
# Always exported, even on non-Apple platforms, so that we can use them when building
# documentation.
@ -811,141 +768,38 @@ endif()")
set(${out_var} "${assignments}" PARENT_SCOPE)
endfunction()
# Returns the active apple sdk name that was either explicitly set by the user via QT_APPLE_SDK or
# or CMAKE_OSX_SYSROOT, or return the default approximated value, based on what CMake does
# internally.
#
# TODO: Handle case when CMAKE_OSX_SYSROOT is set to an sdk path, from which we need to retrieve the
# sdk name.
function(_qt_internal_get_apple_sdk_name out_var)
if(NOT APPLE)
set(${out_var} "" PARENT_SCOPE)
return()
endif()
# If CMake or the user has set an explicit sdk name, consider it.
if(QT_APPLE_SDK)
set(explicit_sdk_name "${QT_APPLE_SDK}")
elseif(CMAKE_OSX_SYSROOT)
set(explicit_sdk_name "${CMAKE_OSX_SYSROOT}")
else()
set(explicit_sdk_name "")
endif()
set(output_sdk_name "")
# Detect (or check if already set) that the sdk name is one that Qt knows about.
if(CMAKE_SYSTEM_NAME STREQUAL iOS)
if(explicit_sdk_name STREQUAL "iphoneos" OR explicit_sdk_name STREQUAL "iphonesimulator")
set(output_sdk_name "${explicit_sdk_name}")
else()
# Default case.
set(output_sdk_name "iphoneos")
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL visionOS)
if(explicit_sdk_name STREQUAL "xros" OR explicit_sdk_name STREQUAL "xrsimulator")
set(output_sdk_name "${explicit_sdk_name}")
else()
# Default case.
set(output_sdk_name "xros")
endif()
else()
# Default case.
set(output_sdk_name "macosx")
endif()
set(${out_var} "${output_sdk_name}" PARENT_SCOPE)
endfunction()
function(_qt_internal_execute_xcrun out_var)
set(opt_args "")
set(single_args "")
set(multi_args
XCRUN_ARGS
OUT_ERROR_VAR
)
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
set(output "")
set(xcrun_error "")
if(NOT APPLE)
message(FATAL_ERROR
"Executing xcrun should only happen happen when targeting Apple plaforms")
endif()
find_program(QT_XCRUN xcrun)
if(NOT QT_XCRUN)
message(FATAL_ERROR "Can't find xcrun in PATH")
endif()
execute_process(COMMAND "${QT_XCRUN}" ${arg_XCRUN_ARGS}
OUTPUT_VARIABLE output
ERROR_VARIABLE xcrun_error)
if(arg_OUT_ERROR_VAR)
set(${arg_OUT_ERROR_VAR} "${xcrun_error}" PARENT_SCOPE)
endif()
set(${out_var} "${output}" PARENT_SCOPE)
endfunction()
function(_qt_internal_get_apple_sdk_path out_var)
set(sdk_path "")
if(APPLE)
_qt_internal_get_apple_sdk_name(sdk_name)
_qt_internal_execute_xcrun(sdk_path
XCRUN_ARGS --sdk ${sdk_name} --show-sdk-path
OUT_ERROR_VAR xcrun_error
)
if(NOT sdk_path)
message(FATAL_ERROR
"Can't determine darwin ${sdk_name} SDK path. Error: ${xcrun_error}")
endif()
string(STRIP "${sdk_path}" sdk_path)
endif()
set(${out_var} "${sdk_path}" PARENT_SCOPE)
endfunction()
function(_qt_internal_get_apple_sdk_version out_var)
set(sdk_version "")
if(APPLE)
_qt_internal_get_apple_sdk_name(sdk_name)
_qt_internal_execute_xcrun(sdk_version
XCRUN_ARGS --sdk ${sdk_name} --show-sdk-version
OUT_ERROR_VAR xcrun_error
)
if(CMAKE_SYSTEM_NAME STREQUAL iOS)
set(sdk_name "iphoneos")
elseif(CMAKE_SYSTEM_NAME STREQUAL visionOS)
set(sdk_name "xros")
else()
# Default to macOS
set(sdk_name "macosx")
endif()
set(xcrun_version_arg "--show-sdk-version")
execute_process(COMMAND /usr/bin/xcrun --sdk ${sdk_name} ${xcrun_version_arg}
OUTPUT_VARIABLE sdk_version
ERROR_VARIABLE xcrun_error)
if(NOT sdk_version)
message(FATAL_ERROR
"Can't determine darwin ${sdk_name} SDK version. Error: ${xcrun_error}")
endif()
string(STRIP "${sdk_version}" sdk_version)
set(${out_var} "${sdk_version}" PARENT_SCOPE)
endif()
set(${out_var} "${sdk_version}" PARENT_SCOPE)
endfunction()
function(_qt_internal_get_xcode_version_raw out_var)
set(xcode_version "")
if(APPLE)
_qt_internal_execute_xcrun(xcode_version
XCRUN_ARGS xcodebuild -version
OUT_ERROR_VAR xcrun_error
)
execute_process(COMMAND /usr/bin/xcrun xcodebuild -version
OUTPUT_VARIABLE xcode_version
ERROR_VARIABLE xcrun_error)
string(REPLACE "\n" " " xcode_version "${xcode_version}")
string(STRIP "${xcode_version}" xcode_version)
if(NOT xcode_version)
message(FATAL_ERROR
"Can't determine Xcode version. Is Xcode installed?"
" Error details:\n${xcrun_error}")
endif()
set(${out_var} "${xcode_version}" PARENT_SCOPE)
endif()
set(${out_var} "${xcode_version}" PARENT_SCOPE)
endfunction()
function(_qt_internal_get_xcode_version out_var)
@ -1144,8 +998,6 @@ function(_qt_internal_finalize_ios_app target)
_qt_internal_set_xcode_targeted_device_family("${target}")
_qt_internal_set_xcode_bitcode_enablement("${target}")
_qt_internal_set_ios_simulator_arch("${target}")
_qt_internal_set_xcode_entrypoint_attribute("${target}" "_qt_main_wrapper")
endfunction()
function(_qt_internal_finalize_macos_app target)

View File

@ -1,24 +0,0 @@
# Copyright (C) 2025 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# Save the current value of the CMP0156 policy in a propert of the current directory scope.
function(__qt_internal_save_directory_scope_policy_cmp0156)
if(NOT POLICY CMP0156)
return()
endif()
# Exit early if we already saved the policy value for this directory scope.
get_property(policy_value_set DIRECTORY PROPERTY _qt_internal_policy_cmp0156_value_set)
if(policy_value_set)
return()
endif()
cmake_policy(GET CMP0156 policy_value)
set_property(DIRECTORY PROPERTY _qt_internal_policy_cmp0156_value "${policy_value}")
set_property(DIRECTORY PROPERTY _qt_internal_policy_cmp0156_value_set "TRUE")
endfunction()
function(__qt_internal_get_directory_scope_policy_cmp0156 out_var)
get_property(policy_value DIRECTORY PROPERTY _qt_internal_policy_cmp0156_value)
set(${out_var} "${policy_value}" PARENT_SCOPE)
endfunction()

View File

@ -153,7 +153,7 @@ function(__qt_internal_collect_additional_module_paths)
if(is_path_to_cmake)
list(APPEND CMAKE_MODULE_PATH "${prefix_path}/${QT_CMAKE_EXPORT_NAMESPACE}")
else()
__qt_internal_get_possible_cmake_dirs(additional_cmake_dirs "${prefix_path}")
__qt_internal_get_possible_cmake_dirs(additional_cmake_dirs "${additional_path}")
list(TRANSFORM additional_cmake_dirs APPEND "/${QT_CMAKE_EXPORT_NAMESPACE}")
list(APPEND CMAKE_MODULE_PATH ${additional_cmake_dirs})
endif()
@ -174,21 +174,6 @@ function(__qt_internal_prefix_paths_to_roots out_var prefix_paths)
set("${out_var}" "${result}" PARENT_SCOPE)
endfunction()
function(_qt_internal_get_check_cxx_source_compiles_out_var out_output_var out_func_args)
# This just resets the output var in the parent scope to an empty string.
set(${out_output_var} "" PARENT_SCOPE)
# OUTPUT_VARIABLE is an internal undocumented variable of check_cxx_source_compiles
# since 3.23. Allow an opt out in case this breaks in the future.
set(extra_func_args "")
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.23"
AND NOT QT_INTERNAL_NO_TRY_COMPILE_OUTPUT_VARIABLE)
set(extra_func_args OUTPUT_VARIABLE ${out_output_var})
endif()
set(${out_func_args} "${extra_func_args}" PARENT_SCOPE)
endfunction()
# This function gets all targets below this directory
#
# Multi-value Arguments:
@ -551,14 +536,8 @@ endfunction()
# Takes a list of path components and joins them into one path separated by forward slashes "/",
# and saves the path in out_var.
# Filters out any path parts that are bare "."s.
function(_qt_internal_path_join out_var)
set(args ${ARGN})
# Remove any bare ".", to avoid any CMP0177 warnings for paths passed to install().
list(REMOVE_ITEM args ".")
string(JOIN "/" path ${args})
string(JOIN "/" path ${ARGN})
set(${out_var} ${path} PARENT_SCOPE)
endfunction()
@ -618,45 +597,6 @@ function(_qt_internal_remove_args out_var)
set(${out_var} "${result}" PARENT_SCOPE)
endfunction()
function(__qt_internal_handle_find_all_qt_module_packages out_var)
set(opt_args "")
set(single_args "")
set(multi_args
COMPONENTS
)
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
if(NOT arg_COMPONENTS)
return()
endif()
set(components ${arg_COMPONENTS})
if("ALL_QT_MODULES" IN_LIST components)
list(FIND components "ALL_QT_MODULES" all_qt_modules_index)
list(REMOVE_AT components ${all_qt_modules_index})
# Find the path to dir with module.json files. # We consider each file name to be a
# Qt package (component) name that contains a target with the same name.
set(json_modules_path "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_DESCRIPTIONSDIR}")
file(GLOB json_modules "${json_modules_path}/*.json")
set(all_qt_modules "")
foreach(json_module IN LISTS json_modules)
get_filename_component(module_name "${json_module}" NAME_WE)
list(APPEND all_qt_modules ${module_name})
endforeach()
if(all_qt_modules)
list(INSERT components "${all_qt_modules_index}" ${all_qt_modules})
endif()
endif()
set(${out_var} "${components}" PARENT_SCOPE)
endfunction()
# Append ${ARGN} to ${target}'s ${property_name} property, removing duplicates.
function(_qt_internal_append_to_target_property_without_duplicates target property_name)
get_target_property(property "${target}" "${property_name}")
@ -750,7 +690,6 @@ function(_qt_internal_add_transitive_property target type property)
message(FATAL_ERROR "Attempt to assign unknown TRANSITIVE_${type}_PROPERTIES property")
endif()
_qt_internal_dealias_target(target)
get_target_property(transitive_properties ${target}
TRANSITIVE_${type}_PROPERTIES)
if(NOT "${property}" IN_LIST transitive_properties)
@ -758,225 +697,3 @@ function(_qt_internal_add_transitive_property target type property)
APPEND PROPERTY TRANSITIVE_${type}_PROPERTIES ${property})
endif()
endfunction()
# Compatibility of `cmake_path(RELATIVE_PATH)`
#
# In order to be compatible with `file(RELATIVE_PATH)`, path normalization of the result is
# always performed, with the trailing slash stripped.
#
# Synopsis
#
# _qt_internal_relative_path(<path-var>
# [BASE_DIRECTORY <input>]
# [OUTPUT_VARIABLE <out-var>]
# )
#
# Arguments
#
# `path-var`
# Equivalent to `cmake_path(RELATIVE_PATH <path-var>)`.
#
# `BASE_DIRECTORY`
# Equivalent to `cmake_path(RELATIVE_PATH BASE_DIRECTORY)`.
#
# `OUTPUT_VARIABLE`
# Equivalent to `cmake_path(RELATIVE_PATH OUTPUT_VARIABLE)`.
function(_qt_internal_relative_path path_var)
set(option_args "")
set(single_args
BASE_DIRECTORY
OUTPUT_VARIABLE
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 1 arg "${option_args}" "${single_args}" "${multi_args}")
if(NOT arg_BASE_DIRECTORY)
set(arg_BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endif()
if(NOT arg_OUTPUT_VARIABLE)
set(arg_OUTPUT_VARIABLE ${path_var})
endif()
if(CMAKE_VERSION VERSION_LESS 3.20)
file(RELATIVE_PATH ${arg_OUTPUT_VARIABLE}
"${arg_BASE_DIRECTORY}"
"${${path_var}}")
else()
cmake_path(RELATIVE_PATH ${path_var}
BASE_DIRECTORY "${arg_BASE_DIRECTORY}"
OUTPUT_VARIABLE ${arg_OUTPUT_VARIABLE}
)
cmake_path(NORMAL_PATH ${arg_OUTPUT_VARIABLE})
string(REGEX REPLACE "/$" "" ${arg_OUTPUT_VARIABLE}
"${${arg_OUTPUT_VARIABLE}}")
endif()
set(${arg_OUTPUT_VARIABLE} "${${arg_OUTPUT_VARIABLE}}" PARENT_SCOPE)
endfunction()
# Compatibility of `cmake_path(IS_PREFIX)`
#
# NORMALIZE keyword is not supported
#
# Synopsis
#
# _qt_internal_path_is_prefix(<path-var> <input> <out-var>)
#
# Arguments
#
# `path-var`
# Equivalent to `cmake_path(IS_PREFIX <path-var>)`.
#
# `input`
# Equivalent to `cmake_path(IS_PREFIX <input>)`.
#
# `out-var`
# Equivalent to `cmake_path(IS_PREFIX <out-var>)`.
function(_qt_internal_path_is_prefix path_var input out_var)
# Make sure the path ends with `/`
if(NOT ${path_var} MATCHES "/$")
set(${path_var} "${${path_var}}/")
endif()
# For the case input == path_var, we need to also include a trailing `/` to match the
# previous change. We discard the actual path for input so we can add it unconditionally
set(input "${input}/")
if(CMAKE_VERSION VERSION_LESS 3.20)
string(FIND "${input}" "${${path_var}}" find_pos)
if(find_pos EQUAL 0)
# input starts_with path_var
set(${out_var} ON)
else()
set(${out_var} OFF)
endif()
else()
cmake_path(IS_PREFIX ${path_var} ${input} ${out_var})
endif()
set(${out_var} "${${out_var}}" PARENT_SCOPE)
endfunction()
function(qt_set01 result)
if (${ARGN})
set("${result}" 1 PARENT_SCOPE)
else()
set("${result}" 0 PARENT_SCOPE)
endif()
endfunction()
# Configures the file using either the input template or the CONTENT.
# Behaves as either file(CONFIGURE or configure_file( command, but do not depend
# on CMake version.
#
# Synopsis
# _qt_internal_configure_file(<CONFIGURE|GENERATE>
# OUTPUT <path>
# <INPUT path|CONTENT data>
# )
#
# Arguments
# `CONFIGURE` Run in pure CONFIGURE mode.
#
# `GENERATE` Configure CONTENT and generate file with the generator expression
# support.
#
# `OUTPUT` The output file name to generate.
#
# `INPUT` The input template file name.
#
# `CONTENT` The template content. If both INPUT and CONTENT are specified, INPUT
# argument is ignored.
function(_qt_internal_configure_file mode)
cmake_parse_arguments(PARSE_ARGV 1 arg "" "OUTPUT;INPUT;CONTENT" "")
if(NOT arg_OUTPUT)
message(FATAL_ERROR "No OUTPUT file provided to _qt_internal_configure_file.")
endif()
# Substitute the '@' wrapped variables and generate the file with the
# the generator expressions evaluation inside the resulting CONTENT.
if(mode STREQUAL "GENERATE")
if(arg_INPUT)
configure_file("${arg_INPUT}" "${arg_OUTPUT}.tmp" @ONLY)
file(GENERATE OUTPUT "${arg_OUTPUT}" INPUT "${arg_OUTPUT}.tmp")
else()
string(CONFIGURE "${arg_CONTENT}" arg_CONTENT @ONLY)
file(GENERATE OUTPUT "${arg_OUTPUT}" CONTENT "${arg_CONTENT}")
endif()
return()
endif()
# We use this check for the cases when the specified CONTENT is empty. The value of arg_CONTENT
# is undefined, but we still want to create a file with empty content.
if("CONTENT" IN_LIST ARGV)
if(arg_INPUT)
message(WARNING "Both CONTENT and INPUT are specified. CONTENT will be used to generate"
" output")
endif()
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.18)
file(CONFIGURE OUTPUT "${arg_OUTPUT}" CONTENT "${arg_CONTENT}" @ONLY)
return()
endif()
set(template_name "QtFileConfigure.txt.in")
# When building qtbase, use the source template file.
# Otherwise use the installed file (basically wherever Qt6 package is found).
# This should work for non-prefix and superbuilds as well.
if(QtBase_SOURCE_DIR)
set(input_file "${QtBase_SOURCE_DIR}/cmake/${template_name}")
else()
set(input_file "${_qt_6_config_cmake_dir}/${template_name}")
endif()
set(__qt_file_configure_content "${arg_CONTENT}")
elseif(arg_INPUT)
set(input_file "${arg_INPUT}")
else()
message(FATAL_ERROR "No input value provided to _qt_internal_configure_file.")
endif()
configure_file("${input_file}" "${arg_OUTPUT}" @ONLY)
endfunction()
# The function checks if `value` is a valid C indentifier.
#
# Synopsis
#
# _qt_internal_is_c_identifier(<out_var> <value>)
#
# Arguments
#
# `out_var`
# Variable name for the evaluation result.
#
# `value`
# The string for the evaluation.
function(_qt_internal_is_c_identifier out_var value)
string(MAKE_C_IDENTIFIER "${value}" value_valid)
if(value AND "${value}" STREQUAL "${value_valid}")
set(${out_var} "TRUE" PARENT_SCOPE)
else()
set(${out_var} "FALSE" PARENT_SCOPE)
endif()
endfunction()
# Makes appending of the CMake configure time dependencies unique.
function(_qt_internal_append_cmake_configure_depends)
get_property(configure_depends DIRECTORY PROPERTY CMAKE_CONFIGURE_DEPENDS)
foreach(path IN LISTS ARGN)
get_filename_component(abs_path "${path}" REALPATH)
if(NOT "${abs_path}" IN_LIST configure_depends)
list(APPEND configure_depends "${abs_path}")
endif()
endforeach()
set_property(DIRECTORY PROPERTY CMAKE_CONFIGURE_DEPENDS "${configure_depends}")
endfunction()
function(_qt_internal_get_moc_compiler_flavor_flags out_var)
set(flags "")
if(WIN32)
list(APPEND flags -DWIN32)
endif()
if(MSVC)
list(APPEND flags --compiler-flavor=msvc)
endif()
set(${out_var} "${flags}" PARENT_SCOPE)
endfunction()

View File

@ -104,88 +104,21 @@ function(__qt_internal_require_suitable_cmake_version_for_using_qt)
endif()
endfunction()
# Handle force-assignment of CMP0156 policy when using CMake 3.29+.
#
# For Apple-platforms we set it to NEW, to avoid duplicate linker issues when using -ObjC flag.
#
# For non-Apple platforms we set it to OLD, because we haven't done the necessary testing to
# see which platforms / linkers can handle the new deduplication behavior, without breaking the
# various linking techniques that Qt uses for object library propagation.
function(__qt_internal_set_cmp0156)
# Exit early if not using CMake 3.29+
if(NOT POLICY CMP0156)
return()
endif()
# Honor this variable if it's set and TRUE. It was previously introduced to allow working around
# the forced OLD value.
if(QT_FORCE_CMP0156_TO_NEW)
get_cmake_property(debug_message_shown _qt_internal_cmp0156_debug_message_shown)
if(NOT debug_message_shown)
message(DEBUG "Force setting the CMP0156 policy to user provided value: NEW")
set_property(GLOBAL PROPERTY _qt_internal_cmp0156_debug_message_shown TRUE)
if(POLICY CMP0156)
if(QT_FORCE_CMP0156_TO_NEW)
cmake_policy(SET CMP0156 "NEW")
else()
cmake_policy(GET CMP0156 policy_value)
if(NOT "${policy_value}" STREQUAL "OLD")
if("${policy_value}" STREQUAL "NEW" AND NOT QT_BUILDING_QT)
message(WARNING "CMP0156 is set to '${policy_value}'. Qt forces the 'OLD'"
" behavior of this policy by default. Set QT_FORCE_CMP0156_TO_NEW=ON to"
" force the 'NEW' behavior for the Qt commands that create either"
" library or executable targets.")
endif()
cmake_policy(SET CMP0156 "OLD")
endif()
endif()
cmake_policy(SET CMP0156 "NEW")
return()
endif()
# Allow forcing to OLD / NEW or empty behavior due the default being NEW for Apple platforms.
if(QT_FORCE_CMP0156_TO_VALUE)
cmake_policy(SET CMP0156 "${QT_FORCE_CMP0156_TO_VALUE}")
message(DEBUG "Force setting the CMP0156 policy to user provided value: "
"${QT_FORCE_CMP0156_TO_VALUE}")
return()
endif()
# Get the current value of the policy, as saved by the Qt6 package as soon as it is found.
# We can't just do cmake_policy(GET CMP0156 policy_value) here, because our Qt6Config.cmake and
# Qt6FooConfig.cmake files use cmake_minimum_required, which reset the policy value that
# might have been set by the project developer or the user.
# And a function uses the policy values that were set when the function was defined, not when
# it is called.
__qt_internal_get_directory_scope_policy_cmp0156(policy_value)
# Apple linkers (legacy Apple ld64, as well as the new ld-prime) don't care about the
# link line order when linking static libraries, compared to Linux GNU ld.
# But they care about duplicate static frameworks (not libraries) when used in conjunction with
# the -ObjC flag, which force loads all static libraries / frameworks that contain Objective-C
# categories or classes. This can cause duplicate symbol errors.
# To avoid the issue, we want to enable the policy, so we de-duplicate the libraries.
if(APPLE)
set(default_policy_value NEW)
set(unsupported_policy_value OLD)
set(platform_string "Apple")
else()
# For non-Apple linkers, we keep the previous behavior of not deduplicating libraries,
# because we haven't done the necessary testing to identify on which platforms
# it is safe to deduplicate.
set(default_policy_value OLD)
set(unsupported_policy_value NEW)
set(platform_string "non-Apple")
endif()
# Force set the default policy value for the given platform, even if the policy value is
# the same or empty. That's because in the calling function scope, the value can be empty
# due to the cmake_minimum_required call in Qt6Config.cmake resetting the policy value.
get_cmake_property(debug_message_shown _qt_internal_cmp0156_debug_message_shown)
if(NOT debug_message_shown)
message(DEBUG "Force setting the CMP0156 policy to '${default_policy_value}' "
"for ${platform_string} platforms.")
set_property(GLOBAL PROPERTY _qt_internal_cmp0156_debug_message_shown TRUE)
endif()
cmake_policy(SET CMP0156 "${default_policy_value}")
# If the policy is explicitly set to a value other than the default, issue a warning.
# Don't show the warning if the policy is unset, which would be the default for most
# projects, because it's too much noise. Also don't show it for Qt builds.
if("${policy_value}" STREQUAL "${unsupported_policy_value}" AND NOT QT_BUILDING_QT)
message(WARNING
"CMP0156 is set to '${policy_value}'. Qt forces the '${default_policy_value}'"
" behavior of this policy for ${platform_string} platforms by default."
" Set QT_FORCE_CMP0156_TO_VALUE=${unsupported_policy_value} to force"
" the '${unsupported_policy_value}' behavior for Qt commands that create"
" library or executable targets.")
endif()
endfunction()

View File

@ -86,15 +86,15 @@ macro(_qt_internal_find_tool_dependencies target target_dep_list)
"${_qt_additional_host_packages_root_paths}")
endif()
unset(__qt_${target}_find_package_args)
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY)
list(APPEND __qt_${target}_find_package_args QUIET)
endif()
foreach(__qt_${target}_target_dep IN LISTS ${target_dep_list})
list(GET __qt_${target}_target_dep 0 __qt_${target}_pkg)
list(GET __qt_${target}_target_dep 1 __qt_${target}_version)
unset(__qt_${target}_find_package_args)
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY)
list(APPEND __qt_${target}_find_package_args QUIET)
endif()
_qt_internal_save_find_package_context_for_debugging(${target})
find_package(${__qt_${target}_pkg}
@ -127,19 +127,24 @@ endmacro()
# contain preformed dependencies. See foreach block for reference.
# The same applies for find_dependency_path_list.
macro(_qt_internal_find_qt_dependencies target target_dep_list find_dependency_path_list)
list(APPEND __qt_${target}_find_qt_dependencies_save_QT_NO_PRIVATE_MODULE_WARNING
${QT_NO_PRIVATE_MODULE_WARNING}
)
set(QT_NO_PRIVATE_MODULE_WARNING ON)
foreach(__qt_${target}_target_dep IN LISTS ${target_dep_list})
list(GET __qt_${target}_target_dep 0 __qt_${target}_pkg)
list(GET __qt_${target}_target_dep 1 __qt_${target}_version)
if (NOT ${__qt_${target}_pkg}_FOUND)
# TODO: Remove Private handling once sufficient time has passed, aka all developers
# updated their builds not to contain stale FooDependencies.cmake files without the
# _qt_package_name property.
set(__qt_${target}_pkg_names ${__qt_${target}_pkg})
if(__qt_${target}_pkg MATCHES "(.*)Private$")
set(__qt_${target}_pkg_names "${CMAKE_MATCH_1};${__qt_${target}_pkg}")
endif()
_qt_internal_save_find_package_context_for_debugging(${target})
find_dependency(${__qt_${target}_pkg} ${__qt_${target}_version}
NAMES
${__qt_${target}_pkg_names}
PATHS
${QT_BUILD_CMAKE_PREFIX_PATH}
${${find_dependency_path_list}}
@ -151,10 +156,6 @@ macro(_qt_internal_find_qt_dependencies target target_dep_list find_dependency_p
endif()
endif()
endforeach()
list(POP_BACK __qt_${target}_find_qt_dependencies_save_QT_NO_PRIVATE_MODULE_WARNING
QT_NO_PRIVATE_MODULE_WARNING
)
endmacro()
# If a dependency package was not found, provide some hints in the error message on how to debug
@ -238,9 +239,9 @@ function(_qt_internal_determine_if_host_info_package_needed out_var)
set(${out_var} "${needed}" PARENT_SCOPE)
endfunction()
macro(_qt_internal_find_host_info_package platform_requires_host_info install_namespace)
macro(_qt_internal_find_host_info_package platform_requires_host_info)
if(${platform_requires_host_info})
find_package(${install_namespace}HostInfo
find_package(Qt6HostInfo
CONFIG
REQUIRED
PATHS "${QT_HOST_PATH}"
@ -321,23 +322,3 @@ macro(_qt_internal_setup_qt_host_path
endif()
endif()
endmacro()
function(_qt_internal_show_private_module_warning module)
if(DEFINED QT_REPO_MODULE_VERSION OR QT_NO_PRIVATE_MODULE_WARNING OR QT_FIND_PRIVATE_MODULES)
return()
endif()
get_cmake_property(warning_shown __qt_private_module_${module}_warning_shown)
if(warning_shown)
return()
endif()
message(WARNING
"This project is using headers of the ${module} module and will therefore be tied "
"to this specific Qt module build version. "
"Running this project against other versions of the Qt modules may crash at any arbitrary "
"point. This is not a bug, but a result of using Qt internals. You have been warned! "
"\nYou can disable this warning by setting QT_NO_PRIVATE_MODULE_WARNING to ON."
)
set_property(GLOBAL PROPERTY __qt_private_module_${module}_warning_shown TRUE)
endfunction()

View File

@ -49,16 +49,6 @@ function(_qt_internal_query_git_version)
set(git_version "${version_git_head}+${version_git_branch}")
endif()
if(QT_SBOM_FAKE_GIT_VERSION)
set(version_git_head "fakegithead")
set(version_git_hash "fakegithash")
set(version_git_branch "fakegitbranch")
set(version_git_tag "fakegittag")
set(git_version "${version_git_head}+${version_git_branch}")
_qt_internal_set_git_query_variables()
return()
endif()
if(NOT Git_FOUND)
message(STATUS "Git not found, skipping querying git version.")
_qt_internal_set_git_query_variables()

View File

@ -248,7 +248,10 @@ function(__qt_internal_add_static_plugin_init_object_library
CONTENT "${import_content}"
)
_qt_internal_set_source_file_generated(SOURCES "${generated_qt_plugin_file_name}")
# CMake versions earlier than 3.18.0 can't find the generated file for some reason,
# failing at generation phase.
# Explicitly marking the file as GENERATED fixes the issue.
set_source_files_properties("${generated_qt_plugin_file_name}" PROPERTIES GENERATED TRUE)
__qt_internal_get_static_plugin_init_target_name("${plugin_target}" plugin_init_target)
@ -413,6 +416,46 @@ function(__qt_internal_collect_plugin_targets_from_dependencies_of_plugins targe
set("${out_var}" "${plugin_targets}" PARENT_SCOPE)
endfunction()
# Generate plugin information files for deployment
#
# Arguments:
# OUT_PLUGIN_TARGETS - Variable name to store the plugin targets that were collected with
# __qt_internal_collect_plugin_targets_from_dependencies.
function(__qt_internal_generate_plugin_deployment_info target)
set(no_value_options "")
set(single_value_options "OUT_PLUGIN_TARGETS")
set(multi_value_options "")
cmake_parse_arguments(PARSE_ARGV 0 arg
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
)
__qt_internal_collect_plugin_targets_from_dependencies("${target}" plugin_targets)
if(NOT "${arg_OUT_PLUGIN_TARGETS}" STREQUAL "")
set("${arg_OUT_PLUGIN_TARGETS}" "${plugin_targets}" PARENT_SCOPE)
endif()
get_target_property(marked_for_deployment ${target} _qt_marked_for_deployment)
if(NOT marked_for_deployment)
return()
endif()
__qt_internal_collect_plugin_library_files(${target} "${plugin_targets}" plugins_files)
set(plugins_files "$<FILTER:${plugins_files},EXCLUDE,^$>")
_qt_internal_get_deploy_impl_dir(deploy_impl_dir)
set(file_path "${deploy_impl_dir}/${target}-plugins")
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
if(is_multi_config)
string(APPEND file_path "-$<CONFIG>")
endif()
string(APPEND file_path ".cmake")
file(GENERATE
OUTPUT ${file_path}
CONTENT "set(__QT_DEPLOY_PLUGINS ${plugins_files})"
)
endfunction()
# Main logic of finalizer mode.
function(__qt_internal_apply_plugin_imports_finalizer_mode target)
# Process a target only once.
@ -421,6 +464,9 @@ function(__qt_internal_apply_plugin_imports_finalizer_mode target)
return()
endif()
__qt_internal_generate_plugin_deployment_info(${target}
OUT_PLUGIN_TARGETS plugin_targets)
# By default if the project hasn't explicitly opted in or out, use finalizer mode.
# The precondition for this is that qt_finalize_target was called (either explicitly by the user
# or auto-deferred by CMake 3.19+).
@ -434,7 +480,6 @@ function(__qt_internal_apply_plugin_imports_finalizer_mode target)
return()
endif()
__qt_internal_collect_plugin_targets_from_dependencies("${target}" plugin_targets)
__qt_internal_collect_plugin_init_libraries("${plugin_targets}" init_libraries)
__qt_internal_collect_plugin_libraries("${plugin_targets}" plugin_libraries)
@ -473,20 +518,6 @@ function(__qt_internal_add_interface_plugin_target plugin_module_target plugin_t
APPEND PROPERTY INTERFACE_QT_PLUGIN_TARGETS ${plugin_target_name_wrapped})
endfunction()
# TODO: Figure out how to do this more reliably, instead of parsing the file name to get
# the target name.
function(__qt_internal_get_target_name_from_plugin_config_file_name
config_file_path
package_prefix_regex
out_var)
string(REGEX REPLACE
"^.*/${QT_CMAKE_EXPORT_NAMESPACE}(${package_prefix_regex})Config.cmake$"
"\\1"
target "${config_file_path}")
set(${out_var} "${target}" PARENT_SCOPE)
endfunction()
# Include CMake plugin packages that belong to the Qt module ${target} and initialize automatic
# linkage of the plugins in static builds.
# The variables inside the macro have to be named unique to the module because an included Plugin
@ -498,7 +529,10 @@ macro(__qt_internal_include_plugin_packages target)
# Properties can't be set on aliased targets, so make sure to unalias the target. This is needed
# when Qt examples are built as part of the Qt build itself.
_qt_internal_dealias_target(__qt_${target}_plugin_module_target)
get_target_property(_aliased_target ${__qt_${target}_plugin_module_target} ALIASED_TARGET)
if(_aliased_target)
set(__qt_${target}_plugin_module_target ${_aliased_target})
endif()
# Ensure that QT_PLUGIN_TARGETS is a known transitive compile property. Works with CMake
# versions >= 3.30.
@ -512,14 +546,11 @@ macro(__qt_internal_include_plugin_packages target)
file(GLOB __qt_${target}_plugin_config_files
"${CMAKE_CURRENT_LIST_DIR}/${QT_CMAKE_EXPORT_NAMESPACE}*PluginConfig.cmake")
foreach(__qt_${target}_plugin_config_file ${__qt_${target}_plugin_config_files})
string(REGEX REPLACE
"^.*/${QT_CMAKE_EXPORT_NAMESPACE}(.*Plugin)Config.cmake$"
"\\1"
__qt_${target}_qt_plugin "${__qt_${target}_plugin_config_file}")
include("${__qt_${target}_plugin_config_file}")
__qt_internal_get_target_name_from_plugin_config_file_name(
"${__qt_${target}_plugin_config_file}"
"(.*Plugin)"
__qt_${target}_qt_plugin
)
if(TARGET "${QT_CMAKE_EXPORT_NAMESPACE}::${__qt_${target}_qt_plugin}")
list(APPEND __qt_${target}_plugins ${__qt_${target}_qt_plugin})
__qt_internal_add_interface_plugin_target(${__qt_${target}_plugin_module_target}
@ -550,34 +581,10 @@ macro(__qt_internal_include_plugin_packages target)
continue()
endif()
set(plugin_target_versioned "${QT_CMAKE_EXPORT_NAMESPACE}::${plugin_target}")
if(NOT "${plugin_target}"
IN_LIST QT_ALL_PLUGINS_FOUND_VIA_FIND_PACKAGE)
# Old compatibility name.
# TODO: Remove once all usages are ported.
list(APPEND QT_ALL_PLUGINS_FOUND_BY_FIND_PACKAGE "${plugin_target}")
# New name consistent with other such variables.
list(APPEND QT_ALL_PLUGINS_FOUND_VIA_FIND_PACKAGE "${plugin_target}")
list(APPEND QT_ALL_PLUGINS_VERSIONED_FOUND_VIA_FIND_PACKAGE
"${plugin_target_versioned}")
endif()
if(NOT "${plugin_target}" IN_LIST QT_ALL_PLUGINS_FOUND_VIA_FIND_PACKAGE_${__plugin_type})
# Old compatibility name.
# TODO: Remove once all usages are ported.
list(APPEND QT_ALL_PLUGINS_FOUND_BY_FIND_PACKAGE_${__plugin_type} "${plugin_target}")
# New name consistent with other such variables.
list(APPEND QT_ALL_PLUGINS_FOUND_VIA_FIND_PACKAGE_${__plugin_type} "${plugin_target}")
list(APPEND
QT_ALL_PLUGINS_VERSIONED_FOUND_VIA_FIND_PACKAGE_${__plugin_type}
"${plugin_target_versioned}")
endif()
list(APPEND "QT_ALL_PLUGINS_FOUND_BY_FIND_PACKAGE_${__plugin_type}" "${plugin_target}")
# Auto-linkage should be set up only for static plugins.
set(plugin_target_versioned "${QT_CMAKE_EXPORT_NAMESPACE}::${plugin_target}")
get_target_property(type "${plugin_target_versioned}" TYPE)
if(type STREQUAL STATIC_LIBRARY)
__qt_internal_add_static_plugin_linkage(
@ -590,87 +597,3 @@ macro(__qt_internal_include_plugin_packages target)
set_target_properties(
${__qt_${target}_plugin_module_target} PROPERTIES __qt_internal_plugins_added TRUE)
endmacro()
# Include Qt Qml plugin CMake packages that are present under the Qml package directory.
# TODO: Consider moving this to qtdeclarative somehow.
macro(__qt_internal_include_qml_plugin_packages)
# Qml plugin targets might have dependencies on other qml plugin targets, but the Targets.cmake
# files are included in the order that file(GLOB) returns, which means certain targets that are
# referenced might not have been created yet, and ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE
# might be set to a message saying those targets don't exist.
#
# Postpone checking of which targets don't exist until all Qml PluginConfig.cmake files have
# been included, by including all the files one more time and checking for errors at each step.
#
# TODO: Find a better way to deal with this, perhaps by using find_package() instead of include
# for the Qml PluginConfig.cmake files.
# Distributions should probably change this default.
if(NOT DEFINED QT_SKIP_AUTO_QML_PLUGIN_INCLUSION)
set(QT_SKIP_AUTO_QML_PLUGIN_INCLUSION OFF)
endif()
set(__qt_qml_plugins_config_file_list "")
set(__qt_qml_plugins_glob_prefixes "${CMAKE_CURRENT_LIST_DIR}")
# Allow passing additional prefixes where we will glob for PluginConfig.cmake files.
if(QT_ADDITIONAL_QML_PLUGIN_GLOB_PREFIXES)
foreach(__qt_qml_plugin_glob_prefix IN LISTS QT_ADDITIONAL_QML_PLUGIN_GLOB_PREFIXES)
if(__qt_qml_plugin_glob_prefix)
list(APPEND __qt_qml_plugins_glob_prefixes "${__qt_qml_plugin_glob_prefix}")
endif()
endforeach()
endif()
list(REMOVE_DUPLICATES __qt_qml_plugins_glob_prefixes)
foreach(__qt_qml_plugin_glob_prefix IN LISTS __qt_qml_plugins_glob_prefixes)
file(GLOB __qt_qml_plugins_glob_config_file_list
"${__qt_qml_plugin_glob_prefix}/QmlPlugins/${INSTALL_CMAKE_NAMESPACE}*Config.cmake")
if(__qt_qml_plugins_glob_config_file_list)
list(APPEND __qt_qml_plugins_config_file_list ${__qt_qml_plugins_glob_config_file_list})
endif()
endforeach()
if (__qt_qml_plugins_config_file_list AND NOT QT_SKIP_AUTO_QML_PLUGIN_INCLUSION)
# First round of inclusions ensure all qml plugin targets are brought into scope.
foreach(__qt_qml_plugin_config_file ${__qt_qml_plugins_config_file_list})
include(${__qt_qml_plugin_config_file})
# Temporarily unset any failure markers and mark the Qml package as found.
unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE)
set(${CMAKE_FIND_PACKAGE_NAME}_FOUND TRUE)
endforeach()
# For the second round of inclusions, check and bail out early if there are errors.
foreach(__qt_qml_plugin_config_file ${__qt_qml_plugins_config_file_list})
include(${__qt_qml_plugin_config_file})
__qt_internal_get_target_name_from_plugin_config_file_name(
"${__qt_qml_plugin_config_file}"
"(.*)"
__qt_qml_plugin_target
)
set(__qt_qml_plugin_target_versioned
"${QT_CMAKE_EXPORT_NAMESPACE}::${__qt_qml_plugin_target}")
if(TARGET "${__qt_qml_plugin_target_versioned}"
AND NOT "${__qt_qml_plugin_target}"
IN_LIST QT_ALL_QML_PLUGINS_FOUND_VIA_FIND_PACKAGE)
list(APPEND QT_ALL_QML_PLUGINS_FOUND_VIA_FIND_PACKAGE "${__qt_qml_plugin_target}")
list(APPEND QT_ALL_QML_PLUGINS_VERSIONED_FOUND_VIA_FIND_PACKAGE
"${__qt_qml_plugin_target_versioned}")
endif()
unset(__qt_qml_plugin_target)
unset(__qt_qml_plugin_target_versioned)
if(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE)
string(APPEND ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE
"\nThe message was set in ${__qt_qml_plugin_config_file} ")
set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
return()
endif()
endforeach()
endif()
endmacro()

View File

@ -25,8 +25,12 @@ function(_qt_internal_sbom_handle_qt_attribution_files out_prefix_outer)
return()
endif()
set(opt_args "")
set(single_args "")
set(opt_args
CREATE_SBOM_FOR_EACH_ATTRIBUTION
)
set(single_args
PARENT_TARGET
)
set(multi_args "")
_qt_internal_get_sbom_specific_options(sbom_opt_args sbom_single_args sbom_multi_args)
@ -53,22 +57,15 @@ function(_qt_internal_sbom_handle_qt_attribution_files out_prefix_outer)
math(EXPR attribution_file_count "${attribution_file_count} + 1")
endforeach()
# If CREATE_SBOM_FOR_EACH_ATTRIBUTION is set, that means the parent target is likely not a
# 3rd party library, so each attribution entry should create a separate attribution target.
# If CREATE_SBOM_FOR_EACH_ATTRIBUTION is set, that means the parent target was a qt entity,
# and not a 3rd party library.
# In which case we don't want to proagate options like CPE to the child attribution targets,
# because the CPE is meant for the parent target.
set(propagate_sbom_options_to_new_attribution_targets TRUE)
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_ATTRIBUTION_FILES)
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
if(is_qt_entity_type)
set(arg_CREATE_SBOM_FOR_EACH_ATTRIBUTION TRUE)
endif()
endif()
if(arg_CREATE_SBOM_FOR_EACH_ATTRIBUTION)
set(propagate_sbom_options_to_new_attribution_targets FALSE)
if(NOT arg_ATTRIBUTION_PARENT_TARGET)
message(FATAL_ERROR "ATTRIBUTION_PARENT_TARGET must be set")
if(NOT arg_PARENT_TARGET)
message(FATAL_ERROR "PARENT_TARGET must be set")
endif()
endif()
@ -79,12 +76,6 @@ function(_qt_internal_sbom_handle_qt_attribution_files out_prefix_outer)
)
endif()
set(ids_to_add "")
set(ids_found "")
if(arg_ATTRIBUTION_IDS)
set(ids_to_add ${arg_ATTRIBUTION_IDS})
endif()
set(file_index 0)
set(first_attribution_processed FALSE)
foreach(attribution_file_path IN LISTS attribution_files)
@ -127,17 +118,6 @@ function(_qt_internal_sbom_handle_qt_attribution_files out_prefix_outer)
FILE_PATH "${attribution_file_path}"
)
# Check if we need to filter for specific ids.
if(ids_to_add AND ${out_prefix}_attribution_id)
if("${${out_prefix}_attribution_id}" IN_LIST ids_to_add)
list(APPEND ids_found "${${out_prefix}_attribution_id}")
else()
# Skip to next entry.
math(EXPR entry_index "${entry_index} + 1")
continue()
endif()
endif()
# Propagate the values to the outer scope.
foreach(variable_name IN LISTS variable_names)
set(${out_prefix}_${variable_name} "${${out_prefix}_${variable_name}}"
@ -175,63 +155,25 @@ function(_qt_internal_sbom_handle_qt_attribution_files out_prefix_outer)
FILE_PATH "${attribution_file_path}"
)
# Check if we need to filter for specific ids
if(ids_to_add AND ${out_prefix}_attribution_id)
if("${${out_prefix}_attribution_id}" IN_LIST ids_to_add)
list(APPEND ids_found "${${out_prefix}_attribution_id}")
else()
# Skip to next entry.
math(EXPR entry_index "${entry_index} + 1")
continue()
endif()
endif()
# If no Id was retrieved, just add a numeric one, to make the sbom target
# unique.
set(attribution_target "${arg_ATTRIBUTION_PARENT_TARGET}_Attribution_")
set(attribution_target "${arg_PARENT_TARGET}_Attribution_")
if(NOT ${out_prefix}_attribution_id)
string(APPEND attribution_target "${file_index}_${entry_index}")
else()
string(APPEND attribution_target "${${out_prefix}_attribution_id}")
endif()
# Sanitize the target name, to avoid issues with slashes and other unsupported chars
# in target names.
string(REGEX REPLACE "[^a-zA-Z0-9_-]" "_"
attribution_target "${attribution_target}")
set(sbom_args "")
# Always propagate the package supplier, because we assume the supplier for 3rd
# party libs is the same as the current project supplier.
# Also propagate the internal qt entity type values like CPE, supplier, PURL
# handling options, attribution file values, if set.
_qt_internal_forward_function_args(
FORWARD_APPEND
FORWARD_PREFIX arg
FORWARD_OUT_VAR sbom_args
FORWARD_OPTIONS
USE_ATTRIBUTION_FILES
__QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_CPE
__QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_SUPPLIER
__QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL
__QT_INTERNAL_HANDLE_QT_ENTITY_ATTRIBUTION_FILES
FORWARD_SINGLE
SUPPLIER
)
if(propagate_sbom_options_to_new_attribution_targets)
# Filter out the attributtion options, they will be passed mnaually
# depending on which file and index is currently being processed.
_qt_internal_get_sbom_specific_options(
sbom_opt_args sbom_single_args sbom_multi_args)
list(REMOVE_ITEM sbom_opt_args
NO_CURRENT_DIR_ATTRIBUTION
CREATE_SBOM_FOR_EACH_ATTRIBUTION
)
list(REMOVE_ITEM sbom_opt_args NO_CURRENT_DIR_ATTRIBUTION)
list(REMOVE_ITEM sbom_single_args ATTRIBUTION_ENTRY_INDEX)
list(REMOVE_ITEM sbom_multi_args
ATTRIBUTION_IDS
ATTRIBUTION_FILE_PATHS
ATTRIBUTION_FILE_DIR_PATHS
)
@ -256,22 +198,16 @@ function(_qt_internal_sbom_handle_qt_attribution_files out_prefix_outer)
# Create another sbom target with the id as a hint for the target name,
# the attribution file passed, and make the new target a dependency of the
# parent one.
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_ATTRIBUTION_FILES)
set(attribution_entity_type QT_THIRD_PARTY_SOURCES)
else()
set(attribution_entity_type THIRD_PARTY_SOURCES)
endif()
_qt_internal_add_sbom("${attribution_target}"
IMMEDIATE_FINALIZATION
TYPE "${attribution_entity_type}"
TYPE QT_THIRD_PARTY_SOURCES
ATTRIBUTION_FILE_PATHS "${attribution_file_path}"
ATTRIBUTION_ENTRY_INDEX "${entry_index}"
NO_CURRENT_DIR_ATTRIBUTION
${sbom_args}
)
_qt_internal_extend_sbom_dependencies(${arg_ATTRIBUTION_PARENT_TARGET}
_qt_internal_extend_sbom_dependencies(${arg_PARENT_TARGET}
SBOM_DEPENDENCIES ${attribution_target}
)
endif()
@ -281,22 +217,6 @@ function(_qt_internal_sbom_handle_qt_attribution_files out_prefix_outer)
math(EXPR file_index "${file_index} + 1")
endforeach()
# Show an error if an id is unaccounted for, it might be it has moved to a different file, that
# is not referenced.
if(ids_to_add)
set(attribution_ids_diff ${ids_to_add})
list(REMOVE_ITEM attribution_ids_diff ${ids_found})
if(attribution_ids_diff)
set(error_message
"The following required attribution ids were not found in the attribution files")
if(arg_ATTRIBUTION_PARENT_TARGET)
string(APPEND error_message " for target: ${arg_ATTRIBUTION_PARENT_TARGET}")
endif()
string(APPEND error_message " ids: ${attribution_ids_diff}")
message(FATAL_ERROR "${error_message}")
endif()
endif()
endfunction()
# Helper to parse a qt_attribution.json file and do various operations:
@ -415,10 +335,10 @@ function(_qt_internal_sbom_read_qt_attribution out_prefix)
endif()
if(arg_GET_DEFAULT_KEYS)
_qt_internal_sbom_get_attribution_key(Id attribution_id "${out_prefix}")
# Some calls are currently commented out, to save on json parsing time because we don't have
# a usage for them yet.
# _qt_internal_sbom_get_attribution_key(License license)
_qt_internal_sbom_get_attribution_key(LicenseId license_id "${out_prefix}")
_qt_internal_sbom_get_attribution_key(License license "${out_prefix}")
_qt_internal_sbom_get_attribution_key(LicenseFile license_file "${out_prefix}")
_qt_internal_sbom_get_attribution_key(Version version "${out_prefix}")
_qt_internal_sbom_get_attribution_key(Homepage homepage "${out_prefix}")
_qt_internal_sbom_get_attribution_key(Name attribution_name "${out_prefix}")
@ -524,9 +444,6 @@ endfunction()
macro(_qt_internal_sbom_get_attribution_key json_key out_var out_prefix)
cmake_parse_arguments(arg "IS_MULTI_VALUE" "" "" ${ARGN})
# Reset any leftover value that might have been set in a previous iteration.
set(${out_prefix}_${out_var} "" PARENT_SCOPE)
string(JSON "${out_var}" ERROR_VARIABLE get_error GET "${contents}" ${indices} "${json_key}")
if(NOT "${${out_var}}" STREQUAL "" AND NOT get_error)
set(extracted_value "${${out_var}}")

View File

@ -76,7 +76,7 @@ function(_qt_internal_sbom_handle_target_dependencies target)
list(REMOVE_DUPLICATES all_direct_libraries)
set(spdx_dependencies "")
set(external_spdx_dependencies "")
set(relationships "")
# Go through each direct linked lib.
foreach(direct_lib IN LISTS all_direct_libraries)
@ -84,13 +84,63 @@ function(_qt_internal_sbom_handle_target_dependencies target)
continue()
endif()
# Check for Qt-specific system library targets. These are marked via qt_find_package calls.
get_target_property(is_system_library "${direct_lib}" _qt_internal_sbom_is_system_library)
if(is_system_library)
# Some targets are Qt modules, even though they are not prefixed with Qt::, targets
# like Bootstrap and QtLibraryInfo. We use the property to differentiate them.
get_target_property(is_marked_as_qt_module "${direct_lib}" _qt_sbom_is_qt_module)
# We need to check if the dependency is a FindWrap dependency that points either to a
# system library or a vendored / bundled library. We need to depend on whichever one
# the FindWrap script points to.
# Custom sbom targets created by _qt_internal_create_sbom_target are always imported, so we
# need to differentiate them via this property.
get_target_property(is_custom_sbom_target "${direct_lib}" _qt_sbom_is_custom_sbom_target)
if("${direct_lib}" MATCHES "^(Qt::.*)|(${QT_CMAKE_EXPORT_NAMESPACE}::.*)")
set(is_qt_prefixed TRUE)
else()
set(is_qt_prefixed FALSE)
endif()
# is_qt_dependency is not strictly only a qt dependency, it applies to custom sbom
# targets as well. But I'm having a hard time to come up with a better name.
if(is_marked_as_qt_module OR is_custom_sbom_target OR is_qt_prefixed)
set(is_qt_dependency TRUE)
else()
set(is_qt_dependency FALSE)
endif()
# Regular Qt dependency, depend on the relevant package, either within the current
# document or via an external document.
if(is_qt_dependency)
_qt_internal_sbom_is_external_target_dependency("${direct_lib}"
OUT_VAR is_dependency_in_external_document
)
if(is_dependency_in_external_document)
# External document case.
_qt_internal_sbom_add_external_target_dependency(
"${package_spdx_id}" "${direct_lib}"
extra_spdx_dependencies
extra_spdx_relationships
)
if(extra_spdx_dependencies)
list(APPEND spdx_dependencies "${extra_spdx_dependencies}")
endif()
if(extra_spdx_relationships)
list(APPEND relationships "${extra_spdx_relationships}")
endif()
else()
# Dependency is part of current repo build.
_qt_internal_sbom_get_spdx_id_for_target("${direct_lib}" dep_spdx_id)
if(dep_spdx_id)
list(APPEND spdx_dependencies "${dep_spdx_id}")
else()
message(DEBUG "Could not add target dependency on ${direct_lib} "
"because no spdx id could be found")
endif()
endif()
else()
# If it's not a Qt dependency, then it's most likely a 3rd party dependency.
# If we are looking at a FindWrap dependency, we need to depend on either
# the system or vendored lib, whichever one the FindWrap script points to.
# If we are looking at a non-Wrap dependency, it's 99% a system lib.
__qt_internal_walk_libs(
"${direct_lib}"
lib_walked_targets
@ -112,59 +162,50 @@ function(_qt_internal_sbom_handle_target_dependencies target)
set(bundled_targets_found TRUE)
endif()
endforeach()
if(bundled_targets_found)
# If we handled a bundled target, we can move on to process the next direct_lib.
continue()
endif()
endif()
# If no bundled libs were found as a result of walking the Wrap lib, we consider this
# a system lib, and add a dependency on it directly.
if(NOT bundled_targets_found)
# If we haven't found a bundled target, then it's a regular system library
# dependency. Make sure to mark the system library as consumed, so that we later
# generate an sbom for it.
# Also fall through to the code that actually adds the dependency on the target.
_qt_internal_append_to_cmake_property_without_duplicates(
_qt_internal_sbom_consumed_system_library_targets
"${direct_lib}"
_qt_internal_sbom_get_spdx_id_for_target("${direct_lib}" lib_spdx_id)
_qt_internal_sbom_is_external_target_dependency("${direct_lib}"
SYSTEM_LIBRARY
OUT_VAR is_dependency_in_external_document
)
endif()
endif()
# Get the spdx id of the dependency.
_qt_internal_sbom_get_spdx_id_for_target("${direct_lib}" lib_spdx_id)
if(NOT lib_spdx_id)
message(DEBUG "Could not add target dependency on target ${direct_lib} "
"because no spdx id for it could be found.")
continue()
endif()
if(lib_spdx_id)
if(NOT is_dependency_in_external_document)
list(APPEND spdx_dependencies "${lib_spdx_id}")
# Check if the target sbom is defined in an external document.
_qt_internal_sbom_is_external_target_dependency("${direct_lib}"
OUT_VAR is_dependency_in_external_document
)
if(NOT is_dependency_in_external_document)
# If the target is not in the external document, it must be one built as part of the
# current project.
list(APPEND spdx_dependencies "${lib_spdx_id}")
else()
# Refer to the package in the external document. This can be the case
# in a top-level build, where a system library is reused across repos, or for any
# regular dependency that was built as part of a different project.
_qt_internal_sbom_add_external_target_dependency("${direct_lib}"
extra_spdx_dependencies
)
if(extra_spdx_dependencies)
list(APPEND external_spdx_dependencies ${extra_spdx_dependencies})
# Mark the system library is used, so that we later generate an sbom for it.
_qt_internal_append_to_cmake_property_without_duplicates(
_qt_internal_sbom_consumed_system_library_targets
"${direct_lib}"
)
else()
# Refer to the package in the external document. This can be the case
# in a top-level build, where a system library is reused across repos.
_qt_internal_sbom_add_external_target_dependency(
"${package_spdx_id}" "${direct_lib}"
extra_spdx_dependencies
extra_spdx_relationships
)
if(extra_spdx_dependencies)
list(APPEND spdx_dependencies "${extra_spdx_dependencies}")
endif()
if(extra_spdx_relationships)
list(APPEND relationships "${extra_spdx_relationships}")
endif()
endif()
else()
message(DEBUG "Could not add target dependency on system library ${direct_lib} "
"because no spdx id could be found")
endif()
endif()
endif()
endforeach()
set(relationships "")
# Keep the external dependencies first, so they are neatly ordered.
foreach(dep_spdx_id IN LISTS external_spdx_dependencies spdx_dependencies)
foreach(dep_spdx_id IN LISTS spdx_dependencies)
set(relationship
"${package_spdx_id} DEPENDS_ON ${dep_spdx_id}"
)
@ -201,22 +242,41 @@ function(_qt_internal_sbom_is_external_target_dependency target)
set(part_of_other_repo FALSE)
endif()
set(${arg_OUT_VAR} "${part_of_other_repo}" PARENT_SCOPE)
# A target is in an external document if
# 1) it is imported, and not a custom sbom target, and not a system library
# 2) it was created as part of another repo in a top-level build
if((is_imported AND NOT is_custom_sbom_target AND NOT arg_SYSTEM_LIBRARY)
OR part_of_other_repo)
set(is_dependency_in_external_document TRUE)
else()
set(is_dependency_in_external_document FALSE)
endif()
set(${arg_OUT_VAR} "${is_dependency_in_external_document}" PARENT_SCOPE)
endfunction()
# Handles generating an external document reference SDPX element for each target package that is
# located in a different spdx document.
function(_qt_internal_sbom_add_external_target_dependency target out_spdx_dependencies)
function(_qt_internal_sbom_add_external_target_dependency
current_package_spdx_id
target_dep
out_spdx_dependencies
out_spdx_relationships
)
set(target "${target_dep}")
_qt_internal_sbom_get_spdx_id_for_target("${target}" dep_spdx_id)
if(NOT dep_spdx_id)
message(DEBUG "Could not add external target dependency on ${target} "
"because no spdx id could be found")
set(${out_spdx_dependencies} "" PARENT_SCOPE)
set(${out_spdx_relationships} "" PARENT_SCOPE)
return()
endif()
set(spdx_dependencies "")
set(spdx_relationships "")
# Get the external document path and the repo it belongs to for the given target.
get_property(relative_installed_repo_document_path TARGET ${target}
@ -232,9 +292,10 @@ function(_qt_internal_sbom_add_external_target_dependency target out_spdx_depend
get_cmake_property(known_external_document
_qt_known_external_documents_${external_document_ref})
set(dependency "${external_document_ref}:${dep_spdx_id}")
set(relationship
"${current_package_spdx_id} DEPENDS_ON ${external_document_ref}:${dep_spdx_id}")
list(APPEND spdx_dependencies "${dependency}")
list(APPEND spdx_relationships "${relationship}")
# Only add a reference to the external document package, if we haven't done so already.
if(NOT known_external_document)
@ -257,9 +318,10 @@ function(_qt_internal_sbom_add_external_target_dependency target out_spdx_depend
_qt_known_external_documents "${external_document_ref}")
endif()
else()
message(AUTHOR_WARNING
"Missing spdx document path for external target dependency: ${target}")
message(WARNING "Missing spdx document path for external ref: "
"package_name_for_spdx_id ${package_name_for_spdx_id} direct_lib ${direct_lib}")
endif()
set(${out_spdx_dependencies} "${spdx_dependencies}" PARENT_SCOPE)
set(${out_spdx_relationships} "${spdx_relationships}" PARENT_SCOPE)
endfunction()

View File

@ -29,12 +29,6 @@ function(_qt_internal_sbom_handle_target_binary_files target)
return()
endif()
if(QT_SBOM_SKIP_BINARY_FILES)
message(DEBUG "Skipping sbom target file processing ${target} because "
"QT_SBOM_SKIP_BINARY_FILES is set")
return()
endif()
set(supported_types
QT_MODULE
QT_PLUGIN
@ -51,7 +45,6 @@ function(_qt_internal_sbom_handle_target_binary_files target)
# This will be meant for user projects, and are not currently used by Qt's sbom.
THIRD_PARTY_LIBRARY
THIRD_PARTY_LIBRARY_WITH_FILES
THIRD_PARTY_SOURCES
EXECUTABLE
LIBRARY
TRANSLATIONS
@ -72,7 +65,6 @@ function(_qt_internal_sbom_handle_target_binary_files target)
QT_CUSTOM_NO_INFIX
SYSTEM_LIBRARY
THIRD_PARTY_LIBRARY
THIRD_PARTY_SOURCES
TRANSLATIONS
RESOURCES
CUSTOM
@ -93,8 +85,8 @@ function(_qt_internal_sbom_handle_target_binary_files target)
return()
endif()
get_target_property(excluded_via_property ${target} _qt_internal_excluded_from_default_target)
if(excluded_via_property OR QT_INTERNAL_TEST_TARGETS_EXCLUDE_FROM_ALL)
get_target_property(excluded ${target} _qt_internal_excluded_from_default_target)
if(excluded)
message(DEBUG "Target ${target} has no binary files to reference in the SBOM "
"because it was excluded from the default 'all' target.")
return()
@ -273,14 +265,9 @@ function(_qt_internal_sbom_add_binary_file target file_path)
set(relationships "${arg_PACKAGE_SPDX_ID} CONTAINS ${spdx_id}")
# Add source file relationships from which the binary file was generated.
if(NOT QT_SBOM_SKIP_SOURCE_FILES)
_qt_internal_sbom_add_target_source_files("${target}" "${spdx_id}" source_relationships)
if(source_relationships)
list(APPEND relationships "${source_relationships}")
endif()
else()
message(DEBUG "Skipping sbom source file processing for file '${file_path}' because "
"QT_SBOM_SKIP_SOURCE_FILES is set")
_qt_internal_sbom_add_target_source_files("${target}" "${spdx_id}" source_relationships)
if(source_relationships)
list(APPEND relationships "${source_relationships}")
endif()
set(glue "\nRelationship: ")
@ -378,12 +365,6 @@ function(_qt_internal_sbom_handle_target_custom_files target)
return()
endif()
if(QT_SBOM_SKIP_CUSTOM_FILES)
message(DEBUG "Skipping sbom custom file processing ${target} because "
"QT_SBOM_SKIP_BINARY_FILES is set")
return()
endif()
if(NOT arg_PACKAGE_SPDX_ID)
message(FATAL_ERROR "PACKAGE_SPDX_ID must be set")
endif()
@ -426,7 +407,7 @@ endfunction()
# options are the same as in _qt_internal_sbom_handle_target_custom_files, and are actually
# forwarded from that function, because they might be set at the target level.
#
# In addition, more options can be passed when called via qt_internal_sbom_add_files:
# In addition, more options can be passed when called via qt_internal_sbom_add_custom_files:
#
# They are:
#
@ -434,10 +415,7 @@ endfunction()
# _qt_internal_sbom_get_spdx_v2_3_file_type_for_file().
# Some examples are QT_TRANSLATION, QT_TRANSLATIONS_CATALOG, QT_RESOURCE.
#
# FILES - a list of file paths to include in the SBOM.
#
# DIRECTORIES - a list of directories which will be file(GLOB_RECURSE)d to find files to include in
# the SBOM.
# FILES - a list of file paths to include in the SBOM. Only the file name is currently used.
#
# SOURCE_FILES - which source files were used to generate the custom files. All source files apply
# to each input file.
@ -467,7 +445,6 @@ function(_qt_internal_sbom_handle_target_custom_file_set target)
set(multi_args
COPYRIGHTS
FILES
DIRECTORIES
SOURCE_FILES
SOURCE_FILES_PER_INPUT_FILE
)
@ -482,19 +459,16 @@ function(_qt_internal_sbom_handle_target_custom_file_set target)
_qt_internal_validate_all_args_are_parsed(arg)
# No custom files to process.
if(NOT arg_FILES AND NOT arg_DIRECTORIES)
if(NOT arg_FILES)
return()
endif()
# Don't forward the FILES and DIRECTORIES options.
# Don't forward the FILES option.
set(multi_args_without_files "${multi_args}")
list(REMOVE_ITEM multi_args_without_files FILES DIRECTORIES)
list(REMOVE_ITEM multi_args_without_files FILES)
# Handle the case where we have one source file per input file.
if(arg_SOURCE_FILES_PER_INPUT_FILE)
if(NOT arg_FILES)
message(FATAL_ERROR "SOURCE_FILES_PER_INPUT_FILE can only be set if FILES is set.")
endif()
list(LENGTH arg_FILES files_count)
list(LENGTH arg_SOURCE_FILES_PER_INPUT_FILE source_files_count)
if(NOT files_count EQUAL source_files_count)
@ -515,45 +489,16 @@ function(_qt_internal_sbom_handle_target_custom_file_set target)
${multi_args_without_files}
)
set(files "")
if(arg_FILES)
list(APPEND files ${arg_FILES})
endif()
set(directories "")
if(arg_DIRECTORIES)
list(APPEND directories ${arg_DIRECTORIES})
endif()
set(relative_file_paths "")
# For each file in FILES, we only add the file name as a suffix, and not the path relative to
# the current source dir, because that's how install(FILES) behaves. The final installed
# destination is ${arg_INSTALL_PATH}/${file_name}.
foreach(file_path IN LISTS files)
get_filename_component(relative_file_path "${file_path}" NAME)
list(APPEND relative_file_paths "${relative_file_path}")
endforeach()
# For each file globbed in DIRECTORIES, we add the file path relative to the current source dir
# + all components of the given DIRECTORY except for the last one.
# That's how install(DIRECTORY) behaves.
# So the final installed destination is
# ${arg_INSTALL_PATH}/${directory_without_last_component}/${path_to_file}.
foreach(directory IN LISTS directories)
file(GLOB_RECURSE files_in_directory "${directory}/*")
set(directory_abs_path "${CMAKE_CURRENT_SOURCE_DIR}/${directory}")
get_filename_component(parent_dir "${directory_abs_path}" DIRECTORY)
foreach(file_path IN LISTS files_in_directory)
file(RELATIVE_PATH relative_file_path "${parent_dir}" "${file_path}")
list(APPEND relative_file_paths "${relative_file_path}")
endforeach()
endforeach()
set(file_index 0)
foreach(relative_file_path IN LISTS relative_file_paths)
foreach(file_path IN LISTS arg_FILES)
set(per_file_forward_args "")
# We don't currently use the file path for anything other than getting the file name, to
# embed it into the spdx document entry.
# What matters in the end is the location where the file is installed, which is handled
# by the PATH_KIND option.
get_filename_component(file_name "${file_path}" NAME)
if(arg_SOURCE_FILES_PER_INPUT_FILE)
list(GET arg_SOURCE_FILES_PER_INPUT_FILE "${file_index}" source_file)
list(APPEND per_file_forward_args SOURCE_FILES "${source_file}")
@ -567,7 +512,7 @@ function(_qt_internal_sbom_handle_target_custom_file_set target)
# the parsing gets confused by what's the option and what's the value.
_qt_internal_sbom_handle_multi_config_custom_file(${target}
PATH_KIND "INSTALL_PATH"
PATH_SUFFIX "${relative_file_path}"
PATH_SUFFIX "${file_name}"
OPTIONS
${forward_args}
${per_file_forward_args}
@ -677,12 +622,7 @@ function(_qt_internal_sbom_add_custom_file target installed_file_relative_path)
set(file_type "OTHER")
endif()
# Append a short hash based on the installed relative path of the file, to avoid spdx id
# clashes for files with the same name installed into different dirs.
get_filename_component(file_name "${installed_file_relative_path}" NAME)
string(SHA1 rel_path_hash "${installed_file_relative_path}")
string(SUBSTRING "${rel_path_hash}" 0 4 short_hash)
set(file_name "${file_name}-${short_hash}")
_qt_internal_sbom_get_package_infix("${arg_PACKAGE_TYPE}" package_infix)
@ -699,17 +639,11 @@ function(_qt_internal_sbom_add_custom_file target installed_file_relative_path)
set(sources_option SOURCES ${arg_SOURCE_FILES})
endif()
# Add source file relationships from which the binary file was generated.
if(NOT QT_SBOM_SKIP_SOURCE_FILES)
_qt_internal_sbom_add_source_files(
${sources_option}
SPDX_ID "${spdx_id}"
OUT_RELATIONSHIPS_VAR source_relationships
)
else()
message(DEBUG "Skipping sbom source file processing for file "
"'${installed_file_relative_path}' because QT_SBOM_SKIP_SOURCE_FILES is set")
endif()
_qt_internal_sbom_add_source_files(
${sources_option}
SPDX_ID "${spdx_id}"
OUT_RELATIONSHIPS_VAR source_relationships
)
if(source_relationships)
list(APPEND relationships "${source_relationships}")
@ -814,9 +748,13 @@ function(_qt_internal_sbom_map_path_to_reproducible_relative_path out_var)
if(IS_ABSOLUTE "${path}")
set(path_in "${path}")
_qt_internal_path_is_prefix(PROJECT_SOURCE_DIR "${path}" is_in_source_dir)
if(NOT is_in_source_dir)
_qt_internal_path_is_prefix(PROJECT_BINARY_DIR "${path}" is_in_build_dir)
string(FIND "${path}" "${PROJECT_SOURCE_DIR}/" src_idx)
string(FIND "${path}" "${PROJECT_BINARY_DIR}/" dest_idx)
if(src_idx EQUAL "0")
set(is_in_source_dir TRUE)
elseif(dest_idx EQUAL "0")
set(is_in_build_dir TRUE)
endif()
else()
# We consider relative paths to be relative to the current source dir.

View File

@ -3,7 +3,7 @@
# SPDX-License-Identifier: MIT AND BSD-3-Clause
# Helper to set a single arg option to a default value if not set.
function(_qt_internal_sbom_set_default_option_value option_name default)
function(qt_internal_sbom_set_default_option_value option_name default)
if(NOT arg_${option_name})
set(arg_${option_name} "${default}" PARENT_SCOPE)
endif()
@ -11,8 +11,8 @@ endfunction()
# Helper to set a single arg option to a default value if not set.
# Errors out if the end value is empty. Including if the default value was empty.
function(_qt_internal_sbom_set_default_option_value_and_error_if_empty option_name default)
_qt_internal_sbom_set_default_option_value("${option_name}" "${default}")
function(qt_internal_sbom_set_default_option_value_and_error_if_empty option_name default)
qt_internal_sbom_set_default_option_value("${option_name}" "${default}")
if(NOT arg_${option_name})
message(FATAL_ERROR "Specifying a non-empty ${option_name} is required")
endif()
@ -73,15 +73,10 @@ function(_qt_internal_sbom_begin_project_generate)
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
if(QT_SBOM_FAKE_TIMESTAMP)
set(current_utc "2590-01-01T11:33:55Z")
set(current_year "2590")
else()
string(TIMESTAMP current_utc UTC)
string(TIMESTAMP current_year "%Y" UTC)
endif()
string(TIMESTAMP current_utc UTC)
string(TIMESTAMP current_year "%Y" UTC)
_qt_internal_sbom_set_default_option_value(PROJECT "${PROJECT_NAME}")
qt_internal_sbom_set_default_option_value(PROJECT "${PROJECT_NAME}")
_qt_internal_sbom_get_git_version_vars()
@ -90,17 +85,17 @@ function(_qt_internal_sbom_begin_project_generate)
set(default_install_sbom_path
"\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/${default_sbom_file_name}")
_qt_internal_sbom_set_default_option_value(OUTPUT "${default_install_sbom_path}")
_qt_internal_sbom_set_default_option_value(OUTPUT_RELATIVE_PATH
qt_internal_sbom_set_default_option_value(OUTPUT "${default_install_sbom_path}")
qt_internal_sbom_set_default_option_value(OUTPUT_RELATIVE_PATH
"${default_sbom_file_name}")
_qt_internal_sbom_set_default_option_value(LICENSE "NOASSERTION")
_qt_internal_sbom_set_default_option_value(PROJECT_FOR_SPDX_ID "Package-${arg_PROJECT}")
_qt_internal_sbom_set_default_option_value_and_error_if_empty(SUPPLIER "")
_qt_internal_sbom_set_default_option_value(COPYRIGHT "${current_year} ${arg_SUPPLIER}")
_qt_internal_sbom_set_default_option_value_and_error_if_empty(SUPPLIER_URL
qt_internal_sbom_set_default_option_value(LICENSE "NOASSERTION")
qt_internal_sbom_set_default_option_value(PROJECT_FOR_SPDX_ID "Package-${arg_PROJECT}")
qt_internal_sbom_set_default_option_value_and_error_if_empty(SUPPLIER "")
qt_internal_sbom_set_default_option_value(COPYRIGHT "${current_year} ${arg_SUPPLIER}")
qt_internal_sbom_set_default_option_value_and_error_if_empty(SUPPLIER_URL
"${PROJECT_HOMEPAGE_URL}")
_qt_internal_sbom_set_default_option_value(NAMESPACE
qt_internal_sbom_set_default_option_value(NAMESPACE
"${arg_SUPPLIER}/spdxdocs/${arg_PROJECT}-${QT_SBOM_GIT_VERSION}")
if(arg_CPE)
@ -128,7 +123,7 @@ function(_qt_internal_sbom_begin_project_generate)
set(cmake_configs "${CMAKE_BUILD_TYPE}")
endif()
_qt_internal_sbom_set_default_option_value(DOWNLOAD_LOCATION "NOASSERTION")
qt_internal_sbom_set_default_option_value(DOWNLOAD_LOCATION "NOASSERTION")
set(cmake_version "Built by CMake ${CMAKE_VERSION}")
set(system_name_and_processor "${CMAKE_SYSTEM_NAME} (${CMAKE_SYSTEM_PROCESSOR})")
@ -213,10 +208,9 @@ Relationship: SPDXRef-DOCUMENT DESCRIBES ${project_spdx_id}
set(computed_sbom_file_name_without_ext "${output_file_name_without_ext}${multi_config_suffix}")
set(computed_sbom_file_name "${output_file_name_without_ext}${output_file_ext}")
# In a super build and in a no-prefix build, put all the build time sboms into the same dir in,
# in the qtbase build dir.
if(QT_BUILDING_QT AND (QT_SUPERBUILD OR (NOT QT_WILL_INSTALL)))
set(build_sbom_root_dir "${QT_BUILD_DIR}")
# In a super build, put all the build time sboms into the same dir in qtbase.
if(QT_SUPERBUILD)
set(build_sbom_root_dir "${QtBase_BINARY_DIR}/qt_sbom")
else()
set(build_sbom_root_dir "${sbom_dir}")
endif()
@ -245,11 +239,6 @@ Relationship: SPDXRef-DOCUMENT DESCRIBES ${project_spdx_id}
")
file(GENERATE OUTPUT "${create_staging_file}" CONTENT "${content}")
set_property(GLOBAL PROPERTY _qt_sbom_project_supplier "${arg_SUPPLIER}")
set_property(GLOBAL PROPERTY _qt_sbom_project_supplier_url "${arg_SUPPLIER_URL}")
set_property(GLOBAL PROPERTY _qt_sbom_project_namespace "${arg_NAMESPACE}")
set_property(GLOBAL PROPERTY _qt_sbom_project_name "${arg_PROJECT}")
set_property(GLOBAL PROPERTY _qt_sbom_project_spdx_id "${project_spdx_id}")
@ -449,7 +438,7 @@ function(_qt_internal_sbom_end_project_generate)
# Allow skipping checksum computation for testing purposes, while installing just the sbom
# documents, without requiring to build and install all the actual files.
if(QT_SBOM_FAKE_CHECKSUM)
if(QT_INTERNAL_SBOM_FAKE_CHECKSUM)
string(APPEND extra_code_begin "
set(QT_SBOM_FAKE_CHECKSUM TRUE)")
endif()
@ -555,8 +544,8 @@ function(_qt_internal_sbom_generate_add_file)
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_sbom_set_default_option_value_and_error_if_empty(FILENAME "")
_qt_internal_sbom_set_default_option_value_and_error_if_empty(FILETYPE "")
qt_internal_sbom_set_default_option_value_and_error_if_empty(FILENAME "")
qt_internal_sbom_set_default_option_value_and_error_if_empty(FILETYPE "")
set(check_option "")
if(arg_SPDXID)
@ -569,8 +558,8 @@ function(_qt_internal_sbom_generate_add_file)
HINTS "SPDXRef-${arg_FILENAME}"
)
_qt_internal_sbom_set_default_option_value(LICENSE "NOASSERTION")
_qt_internal_sbom_set_default_option_value(COPYRIGHT "NOASSERTION")
qt_internal_sbom_set_default_option_value(LICENSE "NOASSERTION")
qt_internal_sbom_set_default_option_value(COPYRIGHT "NOASSERTION")
get_property(sbom_project_spdx_id GLOBAL PROPERTY _qt_sbom_project_spdx_id)
if(NOT sbom_project_spdx_id)
@ -713,7 +702,7 @@ function(_qt_internal_sbom_generate_add_external_reference)
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_sbom_set_default_option_value_and_error_if_empty(EXTERNAL_DOCUMENT_FILE_PATH "")
qt_internal_sbom_set_default_option_value_and_error_if_empty(EXTERNAL_DOCUMENT_FILE_PATH "")
if(NOT arg_EXTERNAL_DOCUMENT_SPDX_ID)
get_property(spdx_id_count GLOBAL PROPERTY _qt_sbom_spdx_id_count)
@ -814,7 +803,7 @@ function(_qt_internal_sbom_generate_add_external_reference)
string(REGEX REPLACE \"^.*[\\r\\n]DocumentNamespace:[ \\t]*([^#\\r\\n]*).*$\"
\"\\\\1\" ext_ns \"\${ext_content}\")
string(APPEND QT_SBOM_EXTERNAL_DOC_REFS \"
list(APPEND QT_SBOM_EXTERNAL_DOC_REFS \"
ExternalDocumentRef: ${arg_EXTERNAL_DOCUMENT_SPDX_ID} \${ext_ns} SHA1: \${ext_sha1}\")
${relationship_content}
@ -852,7 +841,7 @@ function(_qt_internal_sbom_generate_add_package)
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_sbom_set_default_option_value_and_error_if_empty(PACKAGE "")
qt_internal_sbom_set_default_option_value_and_error_if_empty(PACKAGE "")
set(check_option "")
if(arg_SPDXID)
@ -865,13 +854,13 @@ function(_qt_internal_sbom_generate_add_package)
HINTS "SPDXRef-${arg_PACKAGE}"
)
_qt_internal_sbom_set_default_option_value(DOWNLOAD_LOCATION "NOASSERTION")
_qt_internal_sbom_set_default_option_value(VERSION "unknown")
_qt_internal_sbom_set_default_option_value(SUPPLIER "Person: Anonymous")
_qt_internal_sbom_set_default_option_value(LICENSE_DECLARED "NOASSERTION")
_qt_internal_sbom_set_default_option_value(LICENSE_CONCLUDED "NOASSERTION")
_qt_internal_sbom_set_default_option_value(COPYRIGHT "NOASSERTION")
_qt_internal_sbom_set_default_option_value(PURPOSE "OTHER")
qt_internal_sbom_set_default_option_value(DOWNLOAD_LOCATION "NOASSERTION")
qt_internal_sbom_set_default_option_value(VERSION "unknown")
qt_internal_sbom_set_default_option_value(SUPPLIER "Person: Anonymous")
qt_internal_sbom_set_default_option_value(LICENSE_DECLARED "NOASSERTION")
qt_internal_sbom_set_default_option_value(LICENSE_CONCLUDED "NOASSERTION")
qt_internal_sbom_set_default_option_value(COPYRIGHT "NOASSERTION")
qt_internal_sbom_set_default_option_value(PURPOSE "OTHER")
set(fields "")
@ -995,7 +984,7 @@ function(_qt_internal_sbom_generate_add_project_relationship)
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_sbom_set_default_option_value_and_error_if_empty(RELATIONSHIPS "")
qt_internal_sbom_set_default_option_value_and_error_if_empty(RELATIONSHIPS "")
_qt_internal_get_staging_area_spdx_file_path(staging_area_spdx_file)
@ -1096,7 +1085,7 @@ function(_qt_internal_sbom_generate_add_license)
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_sbom_set_default_option_value_and_error_if_empty(LICENSE_ID "")
qt_internal_sbom_set_default_option_value_and_error_if_empty(LICENSE_ID "")
set(check_option "")
if(arg_SPDXID)
@ -1149,7 +1138,7 @@ function(_qt_internal_sbom_get_and_check_spdx_id)
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_sbom_set_default_option_value_and_error_if_empty(VARIABLE "")
qt_internal_sbom_set_default_option_value_and_error_if_empty(VARIABLE "")
if(NOT arg_CHECK)
get_property(spdx_id_count GLOBAL PROPERTY _qt_sbom_spdx_id_count)

View File

@ -25,11 +25,8 @@ function(_qt_internal_sbom_begin_project)
return()
endif()
_qt_internal_sbom_setup_fake_deterministic_build()
set(opt_args
USE_GIT_VERSION
__QT_INTERNAL_HANDLE_QT_REPO
QT_CPE
)
set(single_args
INSTALL_PREFIX
@ -83,10 +80,9 @@ function(_qt_internal_sbom_begin_project)
_qt_internal_sbom_get_root_project_name_for_spdx_id(repo_project_name_for_spdx_id)
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
set(repo_supplier_url "")
if(arg_SUPPLIER_URL)
set(repo_supplier_url "${arg_SUPPLIER_URL}")
elseif(arg___QT_INTERNAL_HANDLE_QT_REPO)
else()
_qt_internal_sbom_get_default_supplier_url(repo_supplier_url)
endif()
@ -97,7 +93,7 @@ function(_qt_internal_sbom_begin_project)
set(QT_SBOM_GIT_HASH "") # empty on purpose, no source of info
set(QT_SBOM_GIT_HASH_SHORT "") # empty on purpose, no source of info
set(non_git_version "${arg_VERSION}")
elseif(arg_USE_GIT_VERSION)
else()
# Query git version info.
_qt_internal_find_git_package()
_qt_internal_query_git_version(
@ -128,10 +124,17 @@ function(_qt_internal_sbom_begin_project)
if(arg_DOCUMENT_NAMESPACE)
set(repo_spdx_namespace "${arg_DOCUMENT_NAMESPACE}")
else()
_qt_internal_sbom_compute_project_namespace(repo_spdx_namespace
PROJECT_NAME "${repo_project_name_lowercase}"
SUPPLIER_URL "${repo_supplier_url}"
)
# Used in external refs, either URI + UUID or URI + checksum. We use git version for now
# which is probably not conformat to spec.
set(repo_name_and_version "${repo_project_name_lowercase}-${QT_SBOM_GIT_VERSION}")
set(repo_spdx_namespace
"${repo_supplier_url}/spdxdocs/${repo_name_and_version}")
endif()
if(non_git_version)
set(version_suffix "-${non_git_version}")
else()
set(version_suffix "")
endif()
if(arg_INSTALL_SBOM_DIR)
@ -150,13 +153,8 @@ function(_qt_internal_sbom_begin_project)
set(install_prefix "\${CMAKE_INSTALL_PREFIX}")
endif()
_qt_internal_sbom_compute_project_file_name(repo_project_file_name
PROJECT_NAME "${repo_project_name_lowercase}"
VERSION_SUFFIX "${non_git_version}"
)
set(repo_spdx_relative_install_path
"${arg_INSTALL_SBOM_DIR}/${repo_project_file_name}")
"${arg_INSTALL_SBOM_DIR}/${repo_project_name_lowercase}${version_suffix}.spdx")
# Prepend DESTDIR, to allow relocating installed sbom. Needed for CI.
set(repo_spdx_install_path
@ -179,19 +177,19 @@ function(_qt_internal_sbom_begin_project)
if(arg_COPYRIGHTS)
list(JOIN arg_COPYRIGHTS "\n" arg_COPYRIGHTS)
set(repo_copyright "<text>${arg_COPYRIGHTS}</text>")
elseif(arg___QT_INTERNAL_HANDLE_QT_REPO)
else()
_qt_internal_sbom_get_default_qt_copyright_header(repo_copyright)
endif()
if(arg_SUPPLIER)
set(repo_supplier "${arg_SUPPLIER}")
elseif(arg___QT_INTERNAL_HANDLE_QT_REPO)
else()
_qt_internal_sbom_get_default_supplier(repo_supplier)
endif()
if(arg_CPE)
set(qt_cpe "${arg_CPE}")
elseif(arg___QT_INTERNAL_HANDLE_QT_REPO)
elseif(arg_QT_CPE)
_qt_internal_sbom_get_cpe_qt_repo(qt_cpe)
else()
set(qt_cpe "")
@ -199,25 +197,17 @@ function(_qt_internal_sbom_begin_project)
if(arg_DOWNLOAD_LOCATION)
set(download_location "${arg_DOWNLOAD_LOCATION}")
elseif(arg___QT_INTERNAL_HANDLE_QT_REPO)
else()
_qt_internal_sbom_get_qt_repo_source_download_location(download_location)
endif()
set(project_comment "")
if(arg___QT_INTERNAL_HANDLE_QT_REPO)
_qt_internal_get_configure_line(configure_line)
if(configure_line)
set(configure_line_comment
"\n${repo_project_name_lowercase} was configured with:\n ${configure_line}\n")
string(APPEND project_comment "${configure_line_comment}")
endif()
endif()
if(project_comment)
# Escape any potential semicolons.
string(REPLACE ";" "\\;" project_comment "${project_comment}")
set(project_comment PROJECT_COMMENT "${project_comment}")
_qt_internal_get_configure_line(configure_line)
if(configure_line)
set(configure_line_comment
"\n${repo_project_name_lowercase} was configured with:\n ${configure_line}\n")
string(APPEND project_comment "${configure_line_comment}")
endif()
_qt_internal_sbom_begin_project_generate(
@ -229,7 +219,7 @@ function(_qt_internal_sbom_begin_project)
SUPPLIER_URL "${repo_supplier_url}"
DOWNLOAD_LOCATION "${download_location}"
PROJECT "${repo_project_name_lowercase}"
${project_comment}
PROJECT_COMMENT "${project_comment}"
PROJECT_FOR_SPDX_ID "${repo_project_name_for_spdx_id}"
NAMESPACE "${repo_spdx_namespace}"
CPE "${qt_cpe}"
@ -256,7 +246,7 @@ function(_qt_internal_sbom_begin_project)
# Collect project licenses.
set(license_dirs "")
if(arg___QT_INTERNAL_HANDLE_QT_REPO AND EXISTS "${PROJECT_SOURCE_DIR}/LICENSES")
if(EXISTS "${PROJECT_SOURCE_DIR}/LICENSES")
list(APPEND license_dirs "${PROJECT_SOURCE_DIR}/LICENSES")
endif()
@ -352,46 +342,6 @@ function(_qt_internal_sbom_setup_project_ops)
_qt_internal_sbom_setup_project_ops_generation(${options})
endfunction()
# Sets up SBOM generation and verification options.
# By default SBOM generation is disabled.
# By default JSON generation and SBOM verification are enabled by default, if the dependencies
# are present, otherwise they will be silently skipped. Unless the user explicitly requests to
# fail the build if the dependencies are not found.
#
# The QT_GENERATE_SBOM_DEFAULT option can be set by a project to change the default value.
function(_qt_internal_setup_sbom)
set(opt_args "")
set(single_args
GENERATE_SBOM_DEFAULT
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
set(default_value "OFF")
if(NOT "${arg_GENERATE_SBOM_DEFAULT}" STREQUAL "")
set(default_value "${arg_GENERATE_SBOM_DEFAULT}")
endif()
option(QT_GENERATE_SBOM "Generate SBOM documents in SPDX v2.3 tag:value format."
"${default_value}")
string(CONCAT help_string
"Generate SBOM documents in SPDX v2.3 JSON format if required python dependency "
"spdx-tools is available"
)
option(QT_SBOM_GENERATE_JSON
"${help_string}" ON)
option(QT_SBOM_REQUIRE_GENERATE_JSON
"Error out if JSON SBOM generation depdendency is not found." OFF)
option(QT_SBOM_VERIFY "Verify generated SBOM documents using python spdx-tools package." ON)
option(QT_SBOM_REQUIRE_VERIFY
"Error out if SBOM verification dependencies are not found." OFF)
endfunction()
# Ends repo sbom project generation.
# Should be called after all relevant targets are added to the sbom.
# Handles registering sbom info for recorded system libraries and then creates the sbom build
@ -432,7 +382,8 @@ function(_qt_internal_sbom_end_project)
# Add configure-time dependency on project attribution files.
get_property(attribution_files GLOBAL PROPERTY _qt_internal_project_attribution_files)
_qt_internal_append_cmake_configure_depends(${attribution_files})
list(REMOVE_DUPLICATES attribution_files)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${attribution_files}")
endfunction()
# Automatically begins sbom generation for a qt git repo unless QT_SKIP_SBOM_AUTO_PROJECT is TRUE.
@ -482,8 +433,7 @@ function(_qt_internal_sbom_begin_qt_repo_project)
_qt_internal_sbom_begin_project(
INSTALL_SBOM_DIR "${INSTALL_SBOMDIR}"
USE_GIT_VERSION
__QT_INTERNAL_HANDLE_QT_REPO
QT_CPE
${sbom_project_args}
)
endfunction()
@ -499,38 +449,20 @@ function(_qt_internal_sbom_auto_end_qt_repo_project)
_qt_internal_sbom_end_qt_repo_project()
endfunction()
# Ends sbom generation for a qt git repo or qt-git-repo-sub-project.
# Endssbom generation for a qt git repo or qt-git-repo-sub-project.
function(_qt_internal_sbom_end_qt_repo_project)
_qt_internal_sbom_end_project()
endfunction()
# Enables a fake deterministic SBOM build, for easier inter-diffs between sbom files. Useful
# for local development.
function(_qt_internal_sbom_setup_fake_deterministic_build)
if(NOT DEFINED QT_SBOM_FAKE_DETERMINISTIC_BUILD)
return()
endif()
if(QT_SBOM_FAKE_DETERMINISTIC_BUILD)
set(value "ON")
elseif()
set(value "OFF")
endif()
set(QT_SBOM_FAKE_GIT_VERSION "${value}" CACHE BOOL "SBOM fake git version")
set(QT_SBOM_FAKE_TIMESTAMP "${value}" CACHE BOOL "SBOM fake timestamp")
set(QT_SBOM_FAKE_CHECKSUM "${value}" CACHE BOOL "SBOM fake checksums")
endfunction()
# Helper to get purl entry-specific options.
# Helper to get purl parsing options.
macro(_qt_internal_get_sbom_purl_parsing_options opt_args single_args multi_args)
set(${opt_args}
NO_PURL
NO_DEFAULT_QT_PURL
PURL_USE_PACKAGE_VERSION
)
set(${single_args}
PURL_ID
PURL_TYPE
PURL_NAMESPACE
PURL_NAME
@ -543,27 +475,31 @@ macro(_qt_internal_get_sbom_purl_parsing_options opt_args single_args multi_args
)
endmacro()
# Helper to get the purl options that should be recongized by sbom functions like
# Helper to get the purl variant option names that should be recongized by sbom functions like
# _qt_internal_sbom_add_target.
macro(_qt_internal_get_sbom_purl_add_target_options opt_args single_args multi_args)
set(${opt_args}
__QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL
)
set(${opt_args} "")
set(${single_args} "")
set(${multi_args}
PURLS
PURL_VALUES
PURL_QT_ARGS
PURL_3RDPARTY_UPSTREAM_ARGS
PURL_MIRROR_ARGS
PURL_QT_VALUES
PURL_3RDPARTY_UPSTREAM_VALUES
PURL_MIRROR_VALUES
)
endmacro()
# Helper to get purl options that should be forwarded from _qt_internal_sbom_add_target to
# _qt_internal_sbom_handle_purl_values.
macro(_qt_internal_get_sbom_purl_handling_options opt_args single_args multi_args)
set(${opt_args} "")
set(${opt_args}
IS_QT_ENTITY_TYPE
)
set(${single_args}
SUPPLIER
TYPE
PACKAGE_VERSION
VERSION
)
set(${multi_args} "")
@ -589,27 +525,16 @@ macro(_qt_internal_get_sbom_add_target_common_options opt_args single_args multi
NO_DEFAULT_QT_SUPPLIER
SBOM_INCOMPLETE_3RD_PARTY_DEPENDENCIES
IS_QT_3RD_PARTY_HEADER_MODULE
USE_ATTRIBUTION_FILES
CREATE_SBOM_FOR_EACH_ATTRIBUTION
__QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PACKAGE_VERSION
__QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_SUPPLIER
__QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_DOWNLOAD_LOCATION
__QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_LICENSE
__QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_COPYRIGHTS
__QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_CPE
__QT_INTERNAL_HANDLE_QT_ENTITY_ATTRIBUTION_FILES
)
set(${single_args}
PACKAGE_VERSION
FRIENDLY_PACKAGE_NAME
SUPPLIER
CPE_VENDOR
CPE_PRODUCT
LICENSE_EXPRESSION
QT_LICENSE_ID
DOWNLOAD_LOCATION
ATTRIBUTION_ENTRY_INDEX
ATTRIBUTION_PARENT_TARGET
SBOM_PACKAGE_COMMENT
)
set(${multi_args}
@ -618,7 +543,6 @@ macro(_qt_internal_get_sbom_add_target_common_options opt_args single_args multi
SBOM_DEPENDENCIES
ATTRIBUTION_FILE_PATHS
ATTRIBUTION_FILE_DIR_PATHS
ATTRIBUTION_IDS
SBOM_RELATIONSHIPS
)
@ -698,6 +622,9 @@ function(_qt_internal_sbom_add_target target)
set(project_package_options "")
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
_qt_internal_sbom_is_qt_3rd_party_entity_type("${arg_TYPE}" is_qt_3rd_party_entity_type)
if(arg_FRIENDLY_PACKAGE_NAME)
set(package_name_for_spdx_id "${arg_FRIENDLY_PACKAGE_NAME}")
else()
@ -716,18 +643,6 @@ function(_qt_internal_sbom_add_target target)
string(APPEND package_comment "${arg_SBOM_PACKAGE_COMMENT}\n")
endif()
string(APPEND package_comment "CMake target name: ${target}\n")
get_target_property(qt_package_name "${target}" _qt_package_name)
if(qt_package_name)
get_target_property(qt_module_interface_name "${target}" _qt_module_interface_name)
set(namespaced_target_name "${QT_CMAKE_EXPORT_NAMESPACE}::${qt_module_interface_name}")
string(APPEND package_comment
"CMake exported target name: ${namespaced_target_name}\n")
string(APPEND package_comment "Contained in CMake package: ${qt_package_name}\n")
endif()
# Record the target spdx id right now, so we can refer to it in later attribution targets
# if needed.
_qt_internal_sbom_record_target_spdx_id(${target}
@ -736,37 +651,39 @@ function(_qt_internal_sbom_add_target target)
OUT_VAR package_spdx_id
)
if(arg_USE_ATTRIBUTION_FILES)
set(attribution_args
ATTRIBUTION_PARENT_TARGET "${target}"
)
set(attribution_args
PARENT_TARGET "${target}"
)
# Forward the sbom specific options when handling attribution files because those might
# create other sbom targets that need to inherit the parent ones.
_qt_internal_get_sbom_specific_options(sbom_opt_args sbom_single_args sbom_multi_args)
_qt_internal_forward_function_args(
FORWARD_APPEND
FORWARD_PREFIX arg
FORWARD_OUT_VAR attribution_args
FORWARD_OPTIONS
${sbom_opt_args}
FORWARD_SINGLE
${sbom_single_args}
FORWARD_MULTI
${sbom_multi_args}
)
if(NOT arg_NO_CURRENT_DIR_ATTRIBUTION
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/qt_attribution.json")
list(APPEND attribution_args
ATTRIBUTION_FILE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/qt_attribution.json"
)
endif()
_qt_internal_sbom_handle_qt_attribution_files(qa ${attribution_args})
if(is_qt_entity_type)
list(APPEND attribution_args CREATE_SBOM_FOR_EACH_ATTRIBUTION)
endif()
# Forward the sbom specific options when handling attribution files because those might
# create other sbom targets that need to inherit the parent ones.
_qt_internal_get_sbom_specific_options(sbom_opt_args sbom_single_args sbom_multi_args)
_qt_internal_forward_function_args(
FORWARD_APPEND
FORWARD_PREFIX arg
FORWARD_OUT_VAR attribution_args
FORWARD_OPTIONS
${sbom_opt_args}
FORWARD_SINGLE
${sbom_single_args}
FORWARD_MULTI
${sbom_multi_args}
)
if(NOT arg_NO_CURRENT_DIR_ATTRIBUTION
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/qt_attribution.json")
list(APPEND attribution_args
ATTRIBUTION_FILE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/qt_attribution.json"
)
endif()
_qt_internal_sbom_handle_qt_attribution_files(qa ${attribution_args})
# Collect license expressions, but in most cases, each expression needs to be abided, so we
# AND the accumulated license expressions.
set(license_expression "")
@ -775,21 +692,59 @@ function(_qt_internal_sbom_add_target target)
set(license_expression "${arg_LICENSE_EXPRESSION}")
endif()
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_LICENSE)
_qt_internal_sbom_forward_sbom_add_target_options(sbom_add_target_args)
_qt_internal_sbom_handle_qt_entity_license_expression(${target} ${sbom_add_target_args}
OUT_VAR qt_entity_license_expression)
if(qt_entity_license_expression)
_qt_internal_sbom_join_two_license_ids_with_op(
"${license_expression}" "AND" "${qt_entity_license_expression}"
license_expression)
# For Qt entities, we have some special handling.
if(is_qt_entity_type AND NOT arg_NO_DEFAULT_QT_LICENSE AND NOT arg_QT_LICENSE_ID)
if(arg_TYPE STREQUAL "QT_TOOL" OR arg_TYPE STREQUAL "QT_APP")
if(QT_SBOM_DEFAULT_QT_LICENSE_ID_EXECUTABLES
AND NOT arg_NO_DEFAULT_QT_LICENSE_ID_EXECUTABLES)
# A repo might contain only the "gpl3" license variant as the default for all
# executables, so allow setting it at the repo level to avoid having to repeat it
# for each target.
_qt_internal_sbom_get_spdx_license_expression(
"${QT_SBOM_DEFAULT_QT_LICENSE_ID_EXECUTABLES}" qt_license_expression)
else()
# For tools and apps, we use the gpl exception variant by default.
_qt_internal_sbom_get_spdx_license_expression("QT_COMMERCIAL_OR_GPL3_WITH_EXCEPTION"
qt_license_expression)
endif()
elseif(QT_SBOM_DEFAULT_QT_LICENSE_ID_LIBRARIES
AND NOT arg_NO_DEFAULT_QT_LICENSE_ID_LIBRARIES)
# A repo might contain only the "gpl3" license variant as the default for all modules
# and plugins, so allow setting it at the repo level to avoid having to repeat it
# for each target.
_qt_internal_sbom_get_spdx_license_expression(
"${QT_SBOM_DEFAULT_QT_LICENSE_ID_LIBRARIES}" qt_license_expression)
else()
# Otherwise, for modules and plugins we use the default qt license.
_qt_internal_sbom_get_spdx_license_expression("QT_DEFAULT" qt_license_expression)
endif()
_qt_internal_sbom_join_two_license_ids_with_op(
"${license_expression}" "AND" "${qt_license_expression}"
license_expression)
endif()
# Some Qt entities might request a specific license from the subset that we usually use.
if(arg_QT_LICENSE_ID)
_qt_internal_sbom_get_spdx_license_expression("${arg_QT_LICENSE_ID}"
requested_license_expression)
_qt_internal_sbom_join_two_license_ids_with_op(
"${license_expression}" "AND" "${requested_license_expression}"
license_expression)
endif()
# Allow setting a license expression string per directory scope via a variable.
if(is_qt_entity_type AND QT_SBOM_LICENSE_EXPRESSION AND NOT arg_NO_DEFAULT_DIRECTORY_QT_LICENSE)
set(qt_license_expression "${QT_SBOM_LICENSE_EXPRESSION}")
_qt_internal_sbom_join_two_license_ids_with_op(
"${license_expression}" "AND" "${qt_license_expression}"
license_expression)
endif()
# Read a license expression from the attribution json file.
if(arg_USE_ATTRIBUTION_FILES
AND qa_license_id
AND NOT arg_NO_ATTRIBUTION_LICENSE_ID)
if(qa_license_id AND NOT arg_NO_ATTRIBUTION_LICENSE_ID)
if(NOT qa_license_id MATCHES "urn:dje:license")
_qt_internal_sbom_join_two_license_ids_with_op(
"${license_expression}" "AND" "${qa_license_id}"
@ -806,18 +761,10 @@ function(_qt_internal_sbom_add_target target)
if(license_expression)
list(APPEND project_package_options LICENSE_CONCLUDED "${license_expression}")
endif()
if(license_expression AND
arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_LICENSE)
_qt_internal_sbom_forward_sbom_add_target_options(sbom_add_target_args)
_qt_internal_sbom_handle_qt_entity_license_declared_expression(${target}
${sbom_add_target_args}
LICENSE_CONCLUDED_EXPRESSION "${license_expression}"
OUT_VAR qt_entity_license_declared_expression)
if(qt_entity_license_declared_expression)
list(APPEND project_package_options
LICENSE_DECLARED "${qt_entity_license_declared_expression}")
# For qt entities we know the license we provide, so we mark it as declared as well.
if(is_qt_entity_type)
list(APPEND project_package_options LICENSE_DECLARED "${license_expression}")
endif()
endif()
@ -826,17 +773,13 @@ function(_qt_internal_sbom_add_target target)
if(arg_COPYRIGHTS)
list(APPEND copyrights "${arg_COPYRIGHTS}")
endif()
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_COPYRIGHTS)
_qt_internal_sbom_forward_sbom_add_target_options(sbom_add_target_args)
_qt_internal_sbom_handle_qt_entity_copyrights(${target} ${sbom_add_target_args}
OUT_VAR qt_copyrights)
if(qt_copyrights)
list(APPEND copyrights ${qt_copyrights})
if(is_qt_entity_type AND NOT arg_NO_DEFAULT_QT_COPYRIGHTS)
_qt_internal_sbom_get_default_qt_copyright_header(qt_default_copyright)
if(qt_default_copyright)
list(APPEND copyrights "${qt_default_copyright}")
endif()
endif()
if(arg_USE_ATTRIBUTION_FILES AND qa_copyrights)
if(qa_copyrights)
list(APPEND copyrights "${qa_copyrights}")
endif()
if(copyrights)
@ -847,37 +790,20 @@ function(_qt_internal_sbom_add_target target)
set(package_version "")
if(arg_PACKAGE_VERSION)
set(package_version "${arg_PACKAGE_VERSION}")
elseif(arg_USE_ATTRIBUTION_FILES AND qa_version)
elseif(is_qt_entity_type AND NOT arg_NO_DEFAULT_QT_PACKAGE_VERSION)
_qt_internal_sbom_get_default_qt_package_version(package_version)
elseif(qa_version)
set(package_version "${qa_version}")
endif()
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PACKAGE_VERSION)
_qt_internal_sbom_forward_sbom_add_target_options(sbom_add_target_args)
_qt_internal_sbom_handle_qt_entity_package_version(${target} ${sbom_add_target_args}
OUT_VAR qt_entity_package_version)
if(qt_entity_package_version)
set(package_version "${qt_entity_package_version}")
endif()
endif()
if(package_version)
list(APPEND project_package_options VERSION "${package_version}")
endif()
set(supplier "")
if(arg_SUPPLIER)
set(supplier "${arg_SUPPLIER}")
if((is_qt_entity_type OR is_qt_3rd_party_entity_type)
AND NOT arg_NO_DEFAULT_QT_SUPPLIER)
_qt_internal_sbom_get_default_supplier(supplier)
endif()
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_SUPPLIER)
_qt_internal_sbom_forward_sbom_add_target_options(sbom_add_target_args)
_qt_internal_sbom_handle_qt_entity_supplier(${target} ${sbom_add_target_args}
OUT_VAR qt_entity_supplier)
if(qt_entity_supplier)
set(supplier "${qt_entity_supplier}")
endif()
endif()
if(supplier)
list(APPEND project_package_options SUPPLIER "Organization: ${supplier}")
endif()
@ -885,26 +811,15 @@ function(_qt_internal_sbom_add_target target)
set(download_location "")
if(arg_DOWNLOAD_LOCATION)
set(download_location "${arg_DOWNLOAD_LOCATION}")
endif()
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_DOWNLOAD_LOCATION)
_qt_internal_sbom_forward_sbom_add_target_options(sbom_add_target_args)
_qt_internal_sbom_handle_qt_entity_download_location(${target} ${sbom_add_target_args}
OUT_VAR qt_entity_download_location)
if(qt_entity_download_location)
set(download_location "${qt_entity_download_location}")
endif()
endif()
if(arg_USE_ATTRIBUTION_FILES)
elseif(is_qt_entity_type)
_qt_internal_sbom_get_qt_repo_source_download_location(download_location)
elseif(arg_TYPE STREQUAL "QT_THIRD_PARTY_MODULE" OR arg_TYPE STREQUAL "QT_THIRD_PARTY_SOURCES")
if(qa_download_location)
set(download_location "${qa_download_location}")
elseif(qa_homepage)
set(download_location "${qa_homepage}")
endif()
endif()
if(arg_TYPE STREQUAL "SYSTEM_LIBRARY")
elseif(arg_TYPE STREQUAL "SYSTEM_LIBRARY")
# Try to get package url that was set using CMake's set_package_properties function.
# Relies on querying the internal global property name that CMake sets in its
# implementation.
@ -912,9 +827,7 @@ function(_qt_internal_sbom_add_target target)
if(target_url)
set(download_location "${target_url}")
endif()
if(NOT download_location
AND arg_USE_ATTRIBUTION_FILES
AND qa_download_location)
if(NOT download_location AND qa_download_location)
set(download_location "${qa_download_location}")
endif()
endif()
@ -926,10 +839,10 @@ function(_qt_internal_sbom_add_target target)
_qt_internal_sbom_get_package_purpose("${arg_TYPE}" package_purpose)
list(APPEND project_package_options PURPOSE "${package_purpose}")
set(cpe_values "")
set(cpe_args "")
if(arg_CPE)
list(APPEND cpe_values "${arg_CPE}")
list(APPEND cpe_args CPE "${arg_CPE}")
endif()
if(arg_CPE_VENDOR AND arg_CPE_PRODUCT)
@ -937,34 +850,27 @@ function(_qt_internal_sbom_add_target target)
VENDOR "${arg_CPE_VENDOR}"
PRODUCT "${arg_CPE_PRODUCT}"
VERSION "${package_version}")
list(APPEND cpe_values "${custom_cpe}")
list(APPEND cpe_args CPE "${custom_cpe}")
endif()
if(arg_USE_ATTRIBUTION_FILES AND qa_cpes)
set(placeholder_args "")
if(package_version)
list(APPEND placeholder_args VERSION "${package_version}")
endif()
if(qa_cpes)
_qt_internal_sbom_replace_qa_placeholders(
VALUES ${qa_cpes}
${placeholder_args}
VERSION "${package_version}"
OUT_VAR qa_cpes_replaced
)
list(APPEND cpe_values "${qa_cpes_replaced}")
list(APPEND cpe_args CPE "${qa_cpes_replaced}")
endif()
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_CPE)
_qt_internal_sbom_forward_sbom_add_target_options(sbom_add_target_args)
_qt_internal_sbom_handle_qt_entity_cpe(${target} ${sbom_add_target_args}
CPE "${cpe_values}"
OUT_VAR qt_cpe_list)
if(qt_cpe_list)
list(APPEND cpe_values ${qt_cpe_list})
endif()
# Add the qt-specific CPE if the target is a Qt entity type, or if it's a 3rd party entity type
# without any CPE specified.
if(is_qt_entity_type OR (is_qt_3rd_party_entity_type AND NOT cpe_args))
_qt_internal_sbom_compute_security_cpe_for_qt(cpe_list)
list(APPEND cpe_args CPE "${cpe_list}")
endif()
if(cpe_values)
list(APPEND project_package_options CPE ${cpe_values})
if(cpe_args)
list(APPEND project_package_options ${cpe_args})
endif()
# Assemble arguments to forward to the function that handles purl options.
@ -988,21 +894,21 @@ function(_qt_internal_sbom_add_target target)
endif()
if(package_version)
list(APPEND purl_args PACKAGE_VERSION "${package_version}")
list(APPEND purl_args VERSION "${package_version}")
endif()
if(arg_USE_ATTRIBUTION_FILES AND qa_purls)
set(placeholder_args "")
if(package_version)
list(APPEND placeholder_args VERSION "${package_version}")
endif()
if(is_qt_entity_type)
list(APPEND purl_args IS_QT_ENTITY_TYPE)
endif()
if(qa_purls)
_qt_internal_sbom_replace_qa_placeholders(
VALUES ${qa_purls}
${placeholder_args}
VERSION "${package_version}"
OUT_VAR qa_purls_replaced
)
list(APPEND purl_args PURL_VALUES ${qa_purls_replaced})
list(APPEND purl_args PURL_3RDPARTY_UPSTREAM_VALUES "${qa_purls_replaced}")
endif()
list(APPEND purl_args OUT_VAR purl_package_options)
@ -1012,24 +918,11 @@ function(_qt_internal_sbom_add_target target)
list(APPEND project_package_options ${purl_package_options})
endif()
if(arg_USE_ATTRIBUTION_FILES)
if(qa_chosen_attribution_file_path)
_qt_internal_sbom_map_path_to_reproducible_relative_path(relative_attribution_path
PATH "${qa_chosen_attribution_file_path}"
)
string(APPEND package_comment
" Information extracted from:\n ${relative_attribution_path}\n")
endif()
if(NOT "${qa_chosen_attribution_entry_index}" STREQUAL "")
string(APPEND package_comment
" Entry index: ${qa_chosen_attribution_entry_index}\n")
endif()
if(qa_attribution_id)
string(APPEND package_comment " Id: ${qa_attribution_id}\n")
endif()
if(is_qt_3rd_party_entity_type
OR arg_TYPE STREQUAL "SYSTEM_LIBRARY"
OR arg_TYPE STREQUAL "THIRD_PARTY_LIBRARY"
OR arg_TYPE STREQUAL "THIRD_PARTY_LIBRARY_WITH_FILES"
)
if(qa_attribution_name)
string(APPEND package_comment " Name: ${qa_attribution_name}\n")
endif()
@ -1042,12 +935,17 @@ function(_qt_internal_sbom_add_target target)
string(APPEND package_comment " Qt usage: ${qa_qt_usage}\n")
endif()
if(qa_license)
string(APPEND package_comment " License: ${qa_license}\n")
if(qa_chosen_attribution_file_path)
_qt_internal_sbom_map_path_to_reproducible_relative_path(relative_attribution_path
PATH "${qa_chosen_attribution_file_path}"
)
string(APPEND package_comment
" Information extracted from:\n ${relative_attribution_path}\n")
endif()
if(qa_license_file)
string(APPEND package_comment " License file: ${qa_license_file}\n")
if(NOT "${qa_chosen_attribution_entry_index}" STREQUAL "")
string(APPEND package_comment
" Entry index: ${qa_chosen_attribution_entry_index}\n")
endif()
endif()
@ -1521,7 +1419,10 @@ function(_qt_internal_sbom_save_spdx_id_for_target target spdx_id)
message(DEBUG "Saving spdx id for target ${target}: ${spdx_id}")
set(target_unaliased "${target}")
_qt_internal_dealias_target(target_unaliased)
get_target_property(aliased_target "${target}" ALIASED_TARGET)
if(aliased_target)
set(target_unaliased ${aliased_target})
endif()
set_target_properties(${target_unaliased} PROPERTIES
_qt_sbom_spdx_id "${spdx_id}")
@ -1667,8 +1568,6 @@ function(_qt_internal_sbom_get_package_infix type out_infix)
set(package_infix "3rdparty-library")
elseif(type STREQUAL "THIRD_PARTY_LIBRARY_WITH_FILES")
set(package_infix "3rdparty-library-with-files")
elseif(type STREQUAL "THIRD_PARTY_SOURCES")
set(package_infix "3rdparty-sources")
elseif(type STREQUAL "TRANSLATIONS")
set(package_infix "translations")
elseif(type STREQUAL "RESOURCES")
@ -1718,8 +1617,6 @@ function(_qt_internal_sbom_get_package_purpose type out_purpose)
set(package_purpose "LIBRARY")
elseif(type STREQUAL "THIRD_PARTY_LIBRARY_WITH_FILES")
set(package_purpose "LIBRARY")
elseif(type STREQUAL "THIRD_PARTY_SOURCES")
set(package_purpose "LIBRARY")
elseif(type STREQUAL "TRANSLATIONS")
set(package_purpose "OTHER")
elseif(type STREQUAL "RESOURCES")
@ -1734,6 +1631,41 @@ function(_qt_internal_sbom_get_package_purpose type out_purpose)
set(${out_purpose} "${package_purpose}" PARENT_SCOPE)
endfunction()
# Get the default qt copyright.
function(_qt_internal_sbom_get_default_qt_copyright_header out_var)
set(${out_var}
"Copyright (C) The Qt Company Ltd. and other contributors."
PARENT_SCOPE)
endfunction()
# Get the default qt package version.
function(_qt_internal_sbom_get_default_qt_package_version out_var)
set(${out_var} "${QT_REPO_MODULE_VERSION}" PARENT_SCOPE)
endfunction()
# Get the default qt supplier.
function(_qt_internal_sbom_get_default_supplier out_var)
set(${out_var} "TheQtCompany" PARENT_SCOPE)
endfunction()
# Get the default qt supplier url.
function(_qt_internal_sbom_get_default_supplier_url out_var)
set(${out_var} "https://qt.io" PARENT_SCOPE)
endfunction()
# Get the default qt download location.
# If git info is available, includes the hash.
function(_qt_internal_sbom_get_qt_repo_source_download_location out_var)
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
set(download_location "git://code.qt.io/qt/${repo_project_name_lowercase}.git")
_qt_internal_sbom_get_git_version_vars()
if(QT_SBOM_GIT_HASH)
string(APPEND download_location "@${QT_SBOM_GIT_HASH}")
endif()
set(${out_var} "${download_location}" PARENT_SCOPE)
endfunction()
# Queries the current project git version variables and sets them in the parent scope.
function(_qt_internal_sbom_get_git_version_vars)
get_cmake_property(QT_SBOM_GIT_VERSION QT_SBOM_GIT_VERSION)
@ -1784,84 +1716,3 @@ function(_qt_internal_get_configure_line out_var)
set(${out_var} "${content}" PARENT_SCOPE)
endfunction()
function(_qt_internal_sbom_compute_project_namespace out_var)
set(opt_args "")
set(single_args
SUPPLIER_URL
PROJECT_NAME
VERSION_SUFFIX
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
if(NOT arg_PROJECT_NAME)
message(FATAL_ERROR "PROJECT_NAME must be set")
endif()
if(NOT arg_SUPPLIER_URL)
message(FATAL_ERROR "SUPPLIER_URL must be set")
endif()
string(TOLOWER "${arg_PROJECT_NAME}" project_name_lowercase)
set(version_suffix "")
if(arg_VERSION_SUFFIX)
set(version_suffix "-${arg_VERSION_SUFFIX}")
else()
_qt_internal_sbom_get_git_version_vars()
if(QT_SBOM_GIT_VERSION)
set(version_suffix "-${QT_SBOM_GIT_VERSION}")
endif()
endif()
# Used in external refs, it should be either aa URI + UUID or a URI + checksum.
# We currently use a URI + git version, which is probably not conformant to the spec.
set(repo_name_and_version "${project_name_lowercase}${version_suffix}")
set(repo_spdx_namespace
"${arg_SUPPLIER_URL}/spdxdocs/${repo_name_and_version}")
set(${out_var} "${repo_spdx_namespace}" PARENT_SCOPE)
endfunction()
function(_qt_internal_sbom_compute_project_file_name out_var)
set(opt_args
EXTENSION_JSON
)
set(single_args
PROJECT_NAME
VERSION_SUFFIX
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
if(NOT arg_PROJECT_NAME)
message(FATAL_ERROR "PROJECT_NAME must be set")
endif()
string(TOLOWER "${arg_PROJECT_NAME}" project_name_lowercase)
set(version_suffix "")
if(arg_VERSION_SUFFIX)
set(version_suffix "-${arg_VERSION_SUFFIX}")
elseif(QT_REPO_MODULE_VERSION)
set(version_suffix "-${QT_REPO_MODULE_VERSION}")
endif()
if(arg_EXTENSION_JSON)
set(extension "spdx.json")
else()
set(extension "spdx")
endif()
set(result
"${project_name_lowercase}${version_suffix}.${extension}")
set(${out_var} "${result}" PARENT_SCOPE)
endfunction()

View File

@ -153,13 +153,6 @@ function(_qt_internal_sbom_find_and_handle_sbom_op_dependencies)
_qt_internal_sbom_find_python_and_dependency_helper_lambda()
endif()
# Always save the python interpreter path if it is found, even if the dependencies are not
# found. This improves the error message workflow.
if(python_found AND NOT QT_INTERNAL_SBOM_PYTHON_EXECUTABLE)
set(QT_INTERNAL_SBOM_PYTHON_EXECUTABLE "${python_path}" CACHE INTERNAL
"Python interpeter used for SBOM generation.")
endif()
if(NOT everything_found)
if(arg_REQUIRED)
set(message_type "FATAL_ERROR")
@ -184,6 +177,11 @@ function(_qt_internal_sbom_find_and_handle_sbom_op_dependencies)
else()
message(DEBUG "Using Python ${python_path} for running SBOM ops.")
if(NOT QT_INTERNAL_SBOM_PYTHON_EXECUTABLE)
set(QT_INTERNAL_SBOM_PYTHON_EXECUTABLE "${python_path}" CACHE INTERNAL
"Python interpeter used for SBOM generation.")
endif()
set(QT_INTERNAL_SBOM_DEPS_FOUND_FOR_${arg_OP_KEY} "TRUE" CACHE INTERNAL
"All dependencies found to run SBOM OP ${arg_OP_KEY}")
endif()
@ -194,184 +192,15 @@ function(_qt_internal_sbom_find_and_handle_sbom_op_dependencies)
endif()
endfunction()
# Helper that checks a variable for truthiness, and sets the OUT_VAR_DEPS_FOUND and
# OUT_VAR_REASON_FAILURE_MESSAGE variables based on what was passed in.
function(_qt_internal_sbom_handle_sbom_op_missing_dependency)
set(opt_args "")
set(single_args
VAR_TO_CHECK
OUT_VAR_DEPS_FOUND
OUT_VAR_REASON_FAILURE_MESSAGE
)
set(multi_args
FAILURE_MESSAGE
)
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
if(NOT arg_VAR_TO_CHECK)
message(FATAL_ERROR "VAR_TO_CHECK is required")
endif()
set(reason "")
set(value "${${arg_VAR_TO_CHECK}}")
if(NOT value)
if(arg_FAILURE_MESSAGE)
list(JOIN arg_FAILURE_MESSAGE " " reason)
endif()
set(deps_found FALSE)
else()
set(deps_found TRUE)
endif()
if(arg_OUT_VAR_DEPS_FOUND)
set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
endif()
if(arg_OUT_VAR_REASON_FAILURE_MESSAGE)
set(${arg_OUT_VAR_REASON_FAILURE_MESSAGE} "${reason}" PARENT_SCOPE)
endif()
endfunction()
# Helper to query whether the sbom python interpreter is available, and also the error message if it
# is not available.
function(_qt_internal_sbom_check_python_interpreter_available)
set(opt_args "")
set(single_args
OUT_VAR_DEPS_FOUND
OUT_VAR_REASON_FAILURE_MESSAGE
)
set(multi_args
FAILURE_MESSAGE_PREFIX
)
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
set(failure_message
"QT_INTERNAL_SBOM_PYTHON_EXECUTABLE is missing a valid path to a python interpreter")
if(arg_FAILURE_MESSAGE_PREFIX)
list(PREPEND failure_message ${arg_FAILURE_MESSAGE_PREFIX})
endif()
_qt_internal_sbom_handle_sbom_op_missing_dependency(
VAR_TO_CHECK QT_INTERNAL_SBOM_PYTHON_EXECUTABLE
FAILURE_MESSAGE ${failure_message}
OUT_VAR_DEPS_FOUND deps_found
OUT_VAR_REASON_FAILURE_MESSAGE reason
)
if(arg_OUT_VAR_DEPS_FOUND)
set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
endif()
if(arg_OUT_VAR_REASON_FAILURE_MESSAGE)
set(${arg_OUT_VAR_REASON_FAILURE_MESSAGE} "${reason}" PARENT_SCOPE)
endif()
endfunction()
# Helper to assert that the python interpreter is available.
function(_qt_internal_sbom_assert_python_interpreter_available error_message_prefix)
_qt_internal_sbom_check_python_interpreter_available(
FAILURE_MESSAGE_PREFIX ${error_message_prefix}
OUT_VAR_DEPS_FOUND deps_found
OUT_VAR_REASON_FAILURE_MESSAGE reason
)
if(NOT deps_found)
message(FATAL_ERROR ${reason})
endif()
endfunction()
# Helper to query whether an sbom python dependency is available, and also the error message if it
# is not available.
function(_qt_internal_sbom_check_python_dependency_available)
set(opt_args "")
set(single_args
OUT_VAR_DEPS_FOUND
OUT_VAR_REASON_FAILURE_MESSAGE
VAR_TO_CHECK
)
set(multi_args
FAILURE_MESSAGE_PREFIX
FAILURE_MESSAGE_SUFFIX
)
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
set(failure_message
"Required Python dependencies not found: ")
if(arg_FAILURE_MESSAGE_PREFIX)
list(PREPEND failure_message ${arg_FAILURE_MESSAGE_PREFIX})
endif()
if(arg_FAILURE_MESSAGE_SUFFIX)
list(APPEND failure_message ${arg_FAILURE_MESSAGE_SUFFIX})
endif()
_qt_internal_sbom_handle_sbom_op_missing_dependency(
VAR_TO_CHECK ${arg_VAR_TO_CHECK}
FAILURE_MESSAGE ${failure_message}
OUT_VAR_DEPS_FOUND deps_found
OUT_VAR_REASON_FAILURE_MESSAGE reason
)
if(arg_OUT_VAR_DEPS_FOUND)
set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
endif()
if(arg_OUT_VAR_REASON_FAILURE_MESSAGE)
set(${arg_OUT_VAR_REASON_FAILURE_MESSAGE} "${reason}" PARENT_SCOPE)
endif()
endfunction()
# Helper to assert that an sbom python dependency is available.
function(_qt_internal_sbom_assert_python_dependency_available key dep error_message_prefix)
_qt_internal_sbom_check_python_dependency_available(
VAR_TO_CHECK QT_INTERNAL_SBOM_DEPS_FOUND_FOR_${key}
FAILURE_MESSAGE_PREFIX ${error_message_prefix}
FAILURE_MESSAGE_SUFFIX ${dep}
OUT_VAR_DEPS_FOUND deps_found
OUT_VAR_REASON_FAILURE_MESSAGE reason
)
if(NOT deps_found)
message(FATAL_ERROR ${reason})
endif()
endfunction()
# Helper to query whether the json sbom generation dependency is available, and also the error
# message if it is not available.
function(_qt_internal_sbom_check_generate_json_dependency_available)
set(opt_args "")
set(single_args
OUT_VAR_DEPS_FOUND
OUT_VAR_REASON_FAILURE_MESSAGE
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_sbom_check_python_dependency_available(
VAR_TO_CHECK QT_INTERNAL_SBOM_DEPS_FOUND_FOR_GENERATE_JSON
FAILURE_MESSAGE_SUFFIX "spdx_tools.spdx.clitools.pyspdxtools"
OUT_VAR_DEPS_FOUND deps_found
OUT_VAR_REASON_FAILURE_MESSAGE reason
)
if(arg_OUT_VAR_DEPS_FOUND)
set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
endif()
if(arg_OUT_VAR_REASON_FAILURE_MESSAGE)
set(${arg_OUT_VAR_REASON_FAILURE_MESSAGE} "${reason}" PARENT_SCOPE)
endif()
endfunction()
# Helper to generate a SPDX JSON file from a tag/value format file.
# This also implies some additional validity checks, useful to ensure a proper sbom file.
function(_qt_internal_sbom_generate_json)
set(error_message_prefix "Failed to generate an SBOM json file.")
_qt_internal_sbom_assert_python_interpreter_available("${error_message_prefix}")
_qt_internal_sbom_assert_python_dependency_available(GENERATE_JSON
"spdx_tools.spdx.clitools.pyspdxtools" ${error_message_prefix})
if(NOT QT_INTERNAL_SBOM_PYTHON_EXECUTABLE)
message(FATAL_ERROR "Python interpreter not found for generating SBOM json file.")
endif()
if(NOT QT_INTERNAL_SBOM_DEPS_FOUND_FOR_GENERATE_JSON)
message(FATAL_ERROR "Python dependencies not found for generating SBOM json file.")
endif()
set(content "
message(STATUS \"Generating JSON: \${QT_SBOM_OUTPUT_PATH}.json\")
@ -392,50 +221,6 @@ function(_qt_internal_sbom_generate_json)
set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_verify_include_files "${verify_sbom}")
endfunction()
# Helper to query whether the all required dependencies are available to generate a tag / value
# document from a json one.
function(_qt_internal_sbom_verify_deps_for_generate_tag_value_spdx_document)
set(opt_args "")
set(single_args
OUT_VAR_DEPS_FOUND
OUT_VAR_REASON_FAILURE_MESSAGE
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
# First try to find dependencies, because they might not have been found yet.
_qt_internal_sbom_find_and_handle_sbom_op_dependencies(
OP_KEY "GENERATE_JSON"
)
_qt_internal_sbom_check_python_interpreter_available(
OUT_VAR_DEPS_FOUND python_found
OUT_VAR_REASON_FAILURE_MESSAGE python_error
)
_qt_internal_sbom_check_generate_json_dependency_available(
OUT_VAR_DEPS_FOUND dep_found
OUT_VAR_REASON_FAILURE_MESSAGE dep_error
)
set(reasons "")
if(python_error)
string(APPEND reasons "${python_error}\n")
endif()
if(dep_error)
string(APPEND reasons "${dep_error}\n")
endif()
if(python_found AND dep_found)
set(deps_found "TRUE")
else()
set(deps_found "FALSE")
endif()
set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
set(${arg_OUT_VAR_REASON_FAILURE_MESSAGE} "${reasons}" PARENT_SCOPE)
endfunction()
# Helper to generate a tag/value SPDX file from a SPDX JSON format file.
#
# Will be used by WebEngine to convert the Chromium JSON file to a tag/value SPDX file.
@ -465,20 +250,12 @@ endfunction()
# OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH - output variable where to store the output file path.
# Note that the path will contain an unresolved '${QT_SBOM_OUTPUT_DIR}' which only has a value at
# install time. So the path can't be used sensibly during configure time.
#
# OPTIONAL - whether the operation should return early, if the required python dependencies are
# not found. OUT_VAR_DEPS_FOUND is still set in that case.
#
# OUT_VAR_DEPS_FOUND - output variable where to store whether the python dependencies for the
# operation were found, and thus the conversion will be attempted.
function(_qt_internal_sbom_generate_tag_value_spdx_document)
if(NOT QT_GENERATE_SBOM)
return()
endif()
set(opt_args
OPTIONAL
)
set(opt_args "")
set(single_args
OPERATION_ID
INPUT_JSON_FILE_PATH
@ -486,40 +263,19 @@ function(_qt_internal_sbom_generate_tag_value_spdx_document)
OUTPUT_FILE_NAME
OUT_VAR_OUTPUT_FILE_NAME
OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH
OUT_VAR_DEPS_FOUND
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
# First try to find dependencies, because they might not have been found yet.
_qt_internal_sbom_find_and_handle_sbom_op_dependencies(
OP_KEY "GENERATE_JSON"
OUT_VAR_DEPS_FOUND deps_found
)
if(arg_OPTIONAL)
set(deps_are_required FALSE)
else()
set(deps_are_required TRUE)
if(NOT QT_INTERNAL_SBOM_PYTHON_EXECUTABLE)
message(FATAL_ERROR "Python interpreter not found for generating tag/value file from JSON.")
endif()
# If the operation has to succeed, then the deps are required. Assert they are available.
if(deps_are_required)
set(error_message_prefix "Failed to generate a tag/value SBOM file from a json SBOM file.")
_qt_internal_sbom_assert_python_interpreter_available("${error_message_prefix}")
_qt_internal_sbom_assert_python_dependency_available(GENERATE_JSON
"spdx_tools.spdx.clitools.pyspdxtools" ${error_message_prefix})
# If the operation is optional, don't error out if the deps are not found, but silently return
# and mention that the deps are not found.
elseif(NOT deps_found)
set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
return()
if(NOT QT_INTERNAL_SBOM_DEPS_FOUND_FOR_GENERATE_JSON)
message(FATAL_ERROR
"Python dependencies not found for generating tag/value file from JSON.")
endif()
set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
if(NOT arg_OPERATION_ID)
message(FATAL_ERROR "OPERATION_ID is required")
endif()
@ -573,10 +329,13 @@ endfunction()
# Helper to verify the generated sbom is valid.
function(_qt_internal_sbom_verify_valid)
set(error_message_prefix "Failed to verify SBOM file syntax.")
_qt_internal_sbom_assert_python_interpreter_available("${error_message_prefix}")
_qt_internal_sbom_assert_python_dependency_available(VERIFY_SBOM
"spdx_tools.spdx.clitools.pyspdxtools" ${error_message_prefix})
if(NOT QT_INTERNAL_SBOM_PYTHON_EXECUTABLE)
message(FATAL_ERROR "Python interpreter not found for verifying SBOM file.")
endif()
if(NOT QT_INTERNAL_SBOM_DEPS_FOUND_FOR_VERIFY_SBOM)
message(FATAL_ERROR "Python dependencies not found for verifying SBOM file")
endif()
set(content "
message(STATUS \"Verifying: \${QT_SBOM_OUTPUT_PATH}\")
@ -599,10 +358,13 @@ endfunction()
# Helper to verify the generated sbom is NTIA compliant.
function(_qt_internal_sbom_verify_ntia_compliant)
set(error_message_prefix "Failed to run NTIA checker on SBOM file.")
_qt_internal_sbom_assert_python_interpreter_available("${error_message_prefix}")
_qt_internal_sbom_assert_python_dependency_available(RUN_NTIA
"ntia_conformance_checker.main" ${error_message_prefix})
if(NOT QT_INTERNAL_SBOM_PYTHON_EXECUTABLE)
message(FATAL_ERROR "Python interpreter not found for verifying SBOM file.")
endif()
if(NOT QT_INTERNAL_SBOM_DEPS_FOUND_FOR_RUN_NTIA)
message(FATAL_ERROR "Python dependencies not found for running the SBOM NTIA checker.")
endif()
set(content "
message(STATUS \"Checking for NTIA compliance: \${QT_SBOM_OUTPUT_PATH}\")
@ -612,7 +374,7 @@ function(_qt_internal_sbom_verify_ntia_compliant)
RESULT_VARIABLE res
)
if(NOT res EQUAL 0)
message(FATAL_ERROR \"SBOM NTIA verification failed: \${res}\")
message(FATAL_ERROR \"SBOM NTIA verification failed: \{res}\")
endif()
")
@ -737,59 +499,15 @@ function(_qt_internal_sbom_generate_reuse_source_sbom)
endif()
set(source_sbom_path "\${QT_SBOM_OUTPUT_PATH_WITHOUT_EXT}.source.spdx")
file(TO_CMAKE_PATH "$ENV{QT_QA_LICENSE_TEST_DIR}/$ENV{QT_SOURCE_SBOM_TEST_SCRIPT}"
full_path_to_license_test)
set(verify_source_sbom "
if(res EQUAL 0)
message(STATUS \"Verifying source SBOM ${source_sbom_path} using qtqa tst_licenses.pl ${full_path_to_license_test}\")
if(NOT EXISTS \"${full_path_to_license_test}\")
message(FATAL_ERROR \"Source SBOM check has failed: The tst_licenses.pl script could not be found at ${full_path_to_license_test}\")
endif()
execute_process(
COMMAND perl \"\$ENV{QT_SOURCE_SBOM_TEST_SCRIPT}\" -sbomonly -sbom \"${source_sbom_path}\"
WORKING_DIRECTORY \"\$ENV{QT_QA_LICENSE_TEST_DIR}\"
RESULT_VARIABLE res
COMMAND_ECHO STDOUT
)
if(NOT res EQUAL 0)
message(FATAL_ERROR \"Source SBOM check has failed: \${res}\")
endif()
endif()
")
set(extra_reuse_args "")
get_property(project_supplier GLOBAL PROPERTY _qt_sbom_project_supplier)
if(project_supplier)
get_property(project_supplier_url GLOBAL PROPERTY _qt_sbom_project_supplier_url)
# Add the supplier url if available. Add it in parenthesis to stop reuse from adding its
# own empty parenthesis.
if(project_supplier_url)
set(project_supplier "${project_supplier} (${project_supplier_url})")
endif()
# Unfortunately there's no way to silence the addition of the 'Creator: Person' field,
# even though 'Creator: Organization' is supplied.
list(APPEND extra_reuse_args --creator-organization "${project_supplier}")
endif()
set(content "
message(STATUS \"Generating source SBOM using reuse tool: ${source_sbom_path}\")
set(extra_reuse_args \"${extra_reuse_args}\")
execute_process(
COMMAND
${QT_SBOM_PROGRAM_REUSE}
--root \"${PROJECT_SOURCE_DIR}\"
spdx
-o ${source_sbom_path}
\${extra_reuse_args}
COMMAND ${QT_SBOM_PROGRAM_REUSE} --root \"${PROJECT_SOURCE_DIR}\" spdx
-o ${source_sbom_path}
RESULT_VARIABLE res
)
${handle_error}
if(\"\$ENV{VERIFY_SOURCE_SBOM}\")
${verify_source_sbom}
endif()
")
file(GENERATE OUTPUT "${file_op}" CONTENT "${content}")

View File

@ -1,91 +1,89 @@
# Copyright (C) 2024 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# Parse purl arguments for a specific purl entry.
# Parse purl arguments for a specific purl variant, e.g. for parsing all values of arg_PURL_QT_ARGS.
# arguments_var_name is the variable name that contains the args.
# prefix is the prefix passed to cmake_parse_arguments.
macro(_qt_internal_sbom_parse_purl_entry_options prefix arguments_var_name)
macro(_qt_internal_sbom_parse_purl_variant_options prefix arguments_var_name)
_qt_internal_get_sbom_purl_parsing_options(purl_opt_args purl_single_args purl_multi_args)
cmake_parse_arguments(${prefix} "${purl_opt_args}" "${purl_single_args}" "${purl_multi_args}"
cmake_parse_arguments(arg "${purl_opt_args}" "${purl_single_args}" "${purl_multi_args}"
${${arguments_var_name}})
_qt_internal_validate_all_args_are_parsed(${prefix})
_qt_internal_validate_all_args_are_parsed(arg)
endmacro()
# Helper macro to prepare forwarding all set purl options to some other function.
# Expects the options names to be set in the parent scope by calling
# _qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
macro(_qt_internal_sbom_forward_purl_handling_options args_var_name)
if(NOT opt_args)
message(FATAL_ERROR
"Expected opt_args to be set by _qt_internal_get_sbom_purl_handling_options")
endif()
if(NOT single_args)
message(FATAL_ERROR
"Expected single_args to be set by _qt_internal_get_sbom_purl_handling_options")
endif()
if(NOT multi_args)
message(FATAL_ERROR
"Expected multi_args to be set by _qt_internal_get_sbom_purl_handling_options")
endif()
_qt_internal_forward_function_args(
FORWARD_PREFIX arg
FORWARD_OUT_VAR ${args_var_name}
FORWARD_OPTIONS
${opt_args}
FORWARD_SINGLE
${single_args}
FORWARD_MULTI
${multi_args}
# Returns a vcs url where for purls where qt entities of the current repo are hosted.
function(_qt_internal_sbom_get_qt_entity_vcs_url target)
set(opt_args "")
set(single_args
REPO_NAME
VERSION
OUT_VAR
)
endmacro()
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
if(NOT arg_REPO_NAME)
message(FATAL_ERROR "REPO_NAME must be set")
endif()
if(NOT arg_OUT_VAR)
message(FATAL_ERROR "OUT_VAR must be set")
endif()
set(version_part "")
if(arg_VERSION)
set(version_part "@${arg_VERSION}")
endif()
set(vcs_url "https://code.qt.io/qt/${arg_REPO_NAME}.git${version_part}")
set(${arg_OUT_VAR} "${vcs_url}" PARENT_SCOPE)
endfunction()
# Returns a relative path to the source where the target was created, to be embedded into a
# mirror purl as a subpath.
function(_qt_internal_sbom_get_qt_entity_repo_source_dir target)
set(opt_args "")
set(single_args
OUT_VAR
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
if(NOT arg_OUT_VAR)
message(FATAL_ERROR "OUT_VAR must be set")
endif()
get_target_property(repo_source_dir "${target}" SOURCE_DIR)
# Get the path relative to the PROJECT_SOURCE_DIR
file(RELATIVE_PATH relative_repo_source_dir "${PROJECT_SOURCE_DIR}" "${repo_source_dir}")
set(sub_path "${relative_repo_source_dir}")
set(${arg_OUT_VAR} "${sub_path}" PARENT_SCOPE)
endfunction()
# Handles purl arguments specified to functions like qt_internal_add_sbom.
# Currently accepts arguments for 3 variants of purls, each of which will generate a separate purl.
# If no arguments are specified, for qt entity types, default values will be chosen.
#
# Synopsis
#
# qt_internal_add_sbom(<target>
# PURLS
# [[PURL_ENTRY
# PURL_ID <id>
# PURL_TYPE <type>
# PURL_NAMESPACE <namespace>
# PURL_NAME <name>
# PURL_VERSION <version>]...]
# PURL_VALUES
# [purl-string...]
# )
#
# Example
#
# qt_internal_add_sbom(<target>
# PURLS
# PURL_ENTRY
# PURL_ID "UPSTREAM"
# PURL_TYPE "github"
# PURL_NAMESPACE "harfbuzz"
# PURL_NAME "harfbuzz"
# PURL_VERSION "v8.5.0"
# PURL_ENTRY
# PURL_ID "MIRROR"
# PURL_TYPE "git"
# PURL_NAMESPACE "harfbuzz"
# PURL_NAME "harfbuzz"
# PURL_QUALIFIERS "vcs_url=https://code.qt.io/qt/qtbase"
# ....
# PURL_VALUES
# pkg:git/harfbuzz/harfbuzz@v8.5.0
# pkg:github/harfbuzz/harfbuzz@v8.5.0
# ....
#
#
# PURLS accepts multiple purl entries, each starting with the PURL_ENTRY keyword.
# PURL_VALUES takes a list of pre-built purl strings.
#
# If no arguments are specified, for qt entity types (e.g. libraries built as part of Qt repos),
# default purls will be generated.
#
# There is no limit to the number of purls that can be added to a target.
# Purl variants:
# - PURL_QT_ARGS
# args to override Qt's generic purl for Qt modules or patched 3rd party libs
# defaults to something like pkg:generic/TheQtCompany/${repo_name}-${target}@SHA1
# - PURL_MIRROR_ARGS
# args to override Qt's mirror purl, which is hosted on github
# defaults to something like pkg:github/qt/${repo_name}@SHA1
# - PURL_3RDPARTY_UPSTREAM_ARGS
# args to specify a purl pointing to an upstream repo, usually to github or another forge
# no defaults, but could look like: pkg:github/harfbuzz/harfbuzz@v8.5.0
# Example values for harfbuzz:
# PURL_3RDPARTY_UPSTREAM_ARGS
# PURL_TYPE "github"
# PURL_NAMESPACE "harfbuzz"
# PURL_NAME "harfbuzz"
# PURL_VERSION "v8.5.0" # tag
function(_qt_internal_sbom_handle_purl_values target)
_qt_internal_get_sbom_purl_handling_options(opt_args single_args multi_args)
list(APPEND single_args OUT_VAR)
@ -97,118 +95,261 @@ function(_qt_internal_sbom_handle_purl_values target)
message(FATAL_ERROR "OUT_VAR must be set")
endif()
# List of purl variants to process.
set(purl_variants "")
_qt_internal_sbom_get_git_version_vars()
set(third_party_types
QT_THIRD_PARTY_MODULE
QT_THIRD_PARTY_SOURCES
)
if(arg_IS_QT_ENTITY_TYPE)
# Qt entities have two purls by default, a QT generic one and a MIRROR hosted on github.
list(APPEND purl_variants MIRROR QT)
elseif(arg_TYPE IN_LIST third_party_types)
# Third party libraries vendored in Qt also have at least two purls, like regular Qt
# libraries, but might also have an upstream one.
# The order in which the purls are generated matters for tools that consume the SBOM. Some
# tools can only handle one PURL per package, so the first one should be the important one.
# For now, I deem that the upstream one if present. Otherwise the github mirror.
if(arg_PURL_3RDPARTY_UPSTREAM_ARGS)
list(APPEND purl_variants 3RDPARTY_UPSTREAM)
endif()
list(APPEND purl_variants MIRROR QT)
else()
# If handling another entity type, handle based on whether any of the purl arguments are
# set.
set(known_purl_variants QT MIRROR 3RDPARTY_UPSTREAM)
foreach(known_purl_variant IN LISTS known_purl_variants)
if(arg_PURL_${known_purl_variant}_ARGS)
list(APPEND purl_variants ${known_purl_variant})
endif()
endforeach()
endif()
if(arg_IS_QT_ENTITY_TYPE
OR arg_TYPE STREQUAL "QT_THIRD_PARTY_MODULE"
OR arg_TYPE STREQUAL "QT_THIRD_PARTY_SOURCES"
)
set(is_qt_purl_entity_type TRUE)
else()
set(is_qt_purl_entity_type FALSE)
endif()
_qt_internal_get_sbom_purl_parsing_options(purl_opt_args purl_single_args purl_multi_args)
set(project_package_options "")
# Collect each PURL_ENTRY args into a separate variable.
set(purl_idx -1)
set(purl_entry_indices "")
foreach(purl_arg IN LISTS arg_PURLS)
if(purl_arg STREQUAL "PURL_ENTRY")
math(EXPR purl_idx "${purl_idx}+1")
list(APPEND purl_entry_indices "${purl_idx}")
elseif(purl_idx GREATER_EQUAL 0)
list(APPEND purl_${purl_idx}_args "${purl_arg}")
else()
message(FATAL_ERROR "Missing PURL_ENTRY keyword.")
endif()
endforeach()
# Validate the args for each collected entry.
foreach(purl_idx IN LISTS purl_entry_indices)
list(LENGTH purl_${purl_idx}_args num_args)
if(num_args LESS 1)
message(FATAL_ERROR "Empty PURL_ENTRY encountered.")
endif()
_qt_internal_sbom_parse_purl_entry_options(arg purl_${purl_idx}_args)
endforeach()
# Append qt specific placeholder entries when handling Qt entities.
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL)
_qt_internal_sbom_forward_purl_handling_options(purl_handling_args)
_qt_internal_sbom_handle_qt_entity_purl_entries(${purl_handling_args}
OUT_VAR_IDS qt_purl_ids
)
if(qt_purl_ids)
# Create purl placeholder indices for each qt purl id.
foreach(qt_purl_id IN LISTS qt_purl_ids)
math(EXPR purl_idx "${purl_idx}+1")
list(APPEND purl_entry_indices "${purl_idx}")
list(APPEND purl_${purl_idx}_args PURL_ID "${qt_purl_id}")
endforeach()
endif()
endif()
foreach(purl_idx IN LISTS purl_entry_indices)
foreach(purl_variant IN LISTS purl_variants)
# Clear previous values.
foreach(option_name IN LISTS purl_opt_args purl_single_args purl_multi_args)
unset(arg_${option_name})
endforeach()
_qt_internal_sbom_parse_purl_entry_options(arg purl_${purl_idx}_args)
_qt_internal_sbom_parse_purl_variant_options(arg arg_PURL_${purl_variant}_ARGS)
set(purl_args "")
# Override the purl version with the package version.
if(arg_PURL_USE_PACKAGE_VERSION AND arg_PACKAGE_VERSION)
set(arg_PURL_VERSION "${arg_PACKAGE_VERSION}")
# Check if custom purl args were specified.
set(purl_args_available FALSE)
if(arg_PURL_${purl_variant}_ARGS)
set(purl_args_available TRUE)
endif()
# Append a vcs_url to the qualifiers if specified.
if(arg_PURL_VCS_URL)
list(APPEND arg_PURL_QUALIFIERS "vcs_url=${arg_PURL_VCS_URL}")
# We want to create a purl either if it's one of Qt's entities and one of it's default
# purl types, or if custom args were specified.
set(consider_purl_processing FALSE)
if((purl_args_available OR is_qt_purl_entity_type) AND NOT arg_NO_PURL)
set(consider_purl_processing TRUE)
endif()
_qt_internal_forward_function_args(
FORWARD_APPEND
FORWARD_PREFIX arg
FORWARD_OUT_VAR purl_args
FORWARD_OPTIONS
${purl_opt_args}
FORWARD_SINGLE
${purl_single_args}
FORWARD_MULTI
${purl_multi_args}
)
if(consider_purl_processing)
set(purl_args "")
# Qt entity types get special treatment to gather the required args.
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL
AND arg_PURL_ID
AND arg_PURL_ID IN_LIST qt_purl_ids)
_qt_internal_sbom_handle_qt_entity_purl("${target}"
${purl_handling_args}
PURL_ID "${arg_PURL_ID}"
OUT_PURL_ARGS qt_purl_args
)
if(qt_purl_args)
list(APPEND purl_args "${qt_purl_args}")
# Override the purl version with the package version.
if(arg_PURL_USE_PACKAGE_VERSION AND arg_VERSION)
set(arg_PURL_VERSION "${arg_VERSION}")
endif()
endif()
_qt_internal_sbom_assemble_purl(${target}
${purl_args}
OUT_VAR package_manager_external_ref
)
list(APPEND project_package_options ${package_manager_external_ref})
# Append a vcs_url to the qualifiers if specified.
if(arg_PURL_VCS_URL)
list(APPEND arg_PURL_QUALIFIERS "vcs_url=${arg_PURL_VCS_URL}")
endif()
_qt_internal_forward_function_args(
FORWARD_APPEND
FORWARD_PREFIX arg
FORWARD_OUT_VAR purl_args
FORWARD_OPTIONS
${purl_opt_args}
FORWARD_SINGLE
${purl_single_args}
FORWARD_MULTI
${purl_multi_args}
)
# Qt entity types get special treatment purl.
if(is_qt_purl_entity_type AND NOT arg_NO_DEFAULT_QT_PURL AND
(purl_variant STREQUAL "QT" OR purl_variant STREQUAL "MIRROR"))
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
# Add a vcs_url to the generic QT variant.
if(purl_variant STREQUAL "QT")
set(entity_vcs_url_version_option "")
# Can be empty.
if(QT_SBOM_GIT_HASH_SHORT)
set(entity_vcs_url_version_option VERSION "${QT_SBOM_GIT_HASH_SHORT}")
endif()
_qt_internal_sbom_get_qt_entity_vcs_url(${target}
REPO_NAME "${repo_project_name_lowercase}"
${entity_vcs_url_version_option}
OUT_VAR vcs_url)
list(APPEND purl_args PURL_QUALIFIERS "vcs_url=${vcs_url}")
endif()
# Add the subdirectory path where the target was created as a custom qualifier.
_qt_internal_sbom_get_qt_entity_repo_source_dir(${target} OUT_VAR sub_path)
if(sub_path)
list(APPEND purl_args PURL_SUBPATH "${sub_path}")
endif()
# Add the target name as a custom qualifer.
list(APPEND purl_args PURL_QUALIFIERS "library_name=${target}")
# Can be empty.
if(QT_SBOM_GIT_HASH_SHORT)
list(APPEND purl_args VERSION "${QT_SBOM_GIT_HASH_SHORT}")
endif()
# Get purl args the Qt entity type, taking into account defaults.
_qt_internal_sbom_get_qt_entity_purl_args(${target}
NAME "${repo_project_name_lowercase}-${target}"
REPO_NAME "${repo_project_name_lowercase}"
SUPPLIER "${arg_SUPPLIER}"
PURL_VARIANT "${purl_variant}"
${purl_args}
OUT_VAR purl_args
)
endif()
_qt_internal_sbom_assemble_purl(${target}
${purl_args}
OUT_VAR package_manager_external_ref
)
list(APPEND project_package_options ${package_manager_external_ref})
endif()
endforeach()
foreach(purl_value IN LISTS arg_PURL_VALUES)
_qt_internal_sbom_get_purl_value_extref(
VALUE "${purl_value}" OUT_VAR package_manager_external_ref)
set(direct_values
PURL_QT_VALUES
PURL_MIRROR_VALUES
PURL_3RDPARTY_UPSTREAM_VALUES
)
# The order in which the purls are generated, matters for tools that consume the SBOM.
# Some tools can only handle one PURL per package, so the first one should be the
# important one.
# For now, I deem that the directly specified ones (probably via a qt_attribution.json
# file) are the more important ones. So we prepend them.
list(PREPEND project_package_options ${package_manager_external_ref})
foreach(direct_value IN LISTS direct_values)
if(arg_${direct_value})
set(direct_values_per_type "")
foreach(direct_value IN LISTS arg_${direct_value})
_qt_internal_sbom_get_purl_value_extref(
VALUE "${direct_value}" OUT_VAR package_manager_external_ref)
list(APPEND direct_values_per_type ${package_manager_external_ref})
endforeach()
# The order in which the purls are generated, matters for tools that consume the SBOM.
# Some tools can only handle one PURL per package, so the first one should be the
# important one.
# For now, I deem that the directly specified ones (probably via a qt_attribution.json
# file) are the more important ones. So we prepend them.
list(PREPEND project_package_options ${direct_values_per_type})
endif()
endforeach()
set(${arg_OUT_VAR} "${project_package_options}" PARENT_SCOPE)
endfunction()
# Gets a list of arguments to pass to _qt_internal_sbom_assemble_purl when handling a Qt entity
# type. The purl for Qt entity types have Qt-specific defaults, but can be overridden per purl
# component.
# The arguments are saved in OUT_VAR.
function(_qt_internal_sbom_get_qt_entity_purl_args target)
set(opt_args "")
set(single_args
NAME
REPO_NAME
SUPPLIER
VERSION
PURL_VARIANT
OUT_VAR
)
set(multi_args "")
_qt_internal_get_sbom_purl_parsing_options(purl_opt_args purl_single_args purl_multi_args)
list(APPEND opt_args ${purl_opt_args})
list(APPEND single_args ${purl_single_args})
list(APPEND multi_args ${purl_multi_args})
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
set(supported_purl_variants QT MIRROR)
if(NOT arg_PURL_VARIANT IN_LIST supported_purl_variants)
message(FATAL_ERROR "PURL_VARIANT unknown: ${arg_PURL_VARIANT}")
endif()
if(arg_PURL_VARIANT STREQUAL "QT")
set(purl_type "generic")
set(purl_namespace "${arg_SUPPLIER}")
set(purl_name "${arg_NAME}")
set(purl_version "${arg_VERSION}")
elseif(arg_PURL_VARIANT STREQUAL "MIRROR")
set(purl_type "github")
set(purl_namespace "qt")
set(purl_name "${arg_REPO_NAME}")
set(purl_version "${arg_VERSION}")
endif()
if(arg_PURL_TYPE)
set(purl_type "${arg_PURL_TYPE}")
endif()
if(arg_PURL_NAMESPACE)
set(purl_namespace "${arg_PURL_NAMESPACE}")
endif()
if(arg_PURL_NAME)
set(purl_name "${arg_PURL_NAME}")
endif()
if(arg_PURL_VERSION)
set(purl_version "${arg_PURL_VERSION}")
endif()
set(purl_version_option "")
if(purl_version)
set(purl_version_option PURL_VERSION "${purl_version}")
endif()
set(purl_args
PURL_TYPE "${purl_type}"
PURL_NAMESPACE "${purl_namespace}"
PURL_NAME "${purl_name}"
${purl_version_option}
)
if(arg_PURL_QUALIFIERS)
list(APPEND purl_args PURL_QUALIFIERS "${arg_PURL_QUALIFIERS}")
endif()
if(arg_PURL_SUBPATH)
list(APPEND purl_args PURL_SUBPATH "${arg_PURL_SUBPATH}")
endif()
set(${arg_OUT_VAR} "${purl_args}" PARENT_SCOPE)
endfunction()
# Assembles an external reference purl identifier.
# PURL_TYPE and PURL_NAME are required.
# Stores the result in the OUT_VAR.

View File

@ -1,492 +0,0 @@
# Copyright (C) 2024 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# Helper macro to prepare forwarding all set sbom options to some other function.
# Expects the options names to be set in the parent scope by calling
# _qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
macro(_qt_internal_sbom_forward_sbom_add_target_options args_var_name)
if(NOT opt_args)
message(FATAL_ERROR
"Expected opt_args to be set by _qt_internal_get_sbom_add_target_options")
endif()
if(NOT single_args)
message(FATAL_ERROR
"Expected single_args to be set by _qt_internal_get_sbom_add_target_options")
endif()
if(NOT multi_args)
message(FATAL_ERROR
"Expected multi_args to be set by _qt_internal_get_sbom_add_target_options")
endif()
_qt_internal_forward_function_args(
FORWARD_PREFIX arg
FORWARD_OUT_VAR ${args_var_name}
FORWARD_OPTIONS
${opt_args}
FORWARD_SINGLE
${single_args}
FORWARD_MULTI
${multi_args}
)
endmacro()
# Helper function to add a default supplier for a qt entity type.
function(_qt_internal_sbom_handle_qt_entity_supplier target)
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
list(APPEND single_args OUT_VAR)
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
_qt_internal_sbom_is_qt_3rd_party_entity_type("${arg_TYPE}" is_qt_3rd_party_entity_type)
set(supplier "")
if(NOT arg_SUPPLIER
AND (is_qt_entity_type OR is_qt_3rd_party_entity_type)
AND NOT arg_NO_DEFAULT_QT_SUPPLIER)
_qt_internal_sbom_get_default_supplier(supplier)
endif()
if(supplier)
set(${arg_OUT_VAR} "${supplier}" PARENT_SCOPE)
endif()
endfunction()
# Helper function to add a default package for a qt entity type.
function(_qt_internal_sbom_handle_qt_entity_package_version target)
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
list(APPEND single_args OUT_VAR)
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
set(package_version "")
if(NOT arg_PACKAGE_VERSION
AND is_qt_entity_type
AND NOT arg_NO_DEFAULT_QT_PACKAGE_VERSION)
_qt_internal_sbom_get_default_qt_package_version(package_version)
endif()
if(package_version)
set(${arg_OUT_VAR} "${package_version}" PARENT_SCOPE)
endif()
endfunction()
# Helper function to add a default repo download location for a qt entity type.
function(_qt_internal_sbom_handle_qt_entity_download_location target)
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
list(APPEND single_args OUT_VAR)
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
set(download_location "")
if(NOT arg_DOWNLOAD_LOCATION AND is_qt_entity_type)
_qt_internal_sbom_get_qt_repo_source_download_location(download_location)
endif()
if(download_location)
set(${arg_OUT_VAR} "${download_location}" PARENT_SCOPE)
endif()
endfunction()
# Helper function to add a default license expression for a qt entity type.
function(_qt_internal_sbom_handle_qt_entity_license_expression target)
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
list(APPEND single_args OUT_VAR)
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
set(license_expression "")
# For Qt entities, we have some special handling.
if(is_qt_entity_type AND NOT arg_NO_DEFAULT_QT_LICENSE AND NOT arg_QT_LICENSE_ID)
if(arg_TYPE STREQUAL "QT_TOOL" OR arg_TYPE STREQUAL "QT_APP")
if(QT_SBOM_DEFAULT_QT_LICENSE_ID_EXECUTABLES
AND NOT arg_NO_DEFAULT_QT_LICENSE_ID_EXECUTABLES)
# A repo might contain only the "gpl3" license variant as the default for all
# executables, so allow setting it at the repo level to avoid having to repeat it
# for each target.
_qt_internal_sbom_get_spdx_license_expression(
"${QT_SBOM_DEFAULT_QT_LICENSE_ID_EXECUTABLES}" license_expression)
else()
# For tools and apps, we use the gpl exception variant by default.
_qt_internal_sbom_get_spdx_license_expression("QT_COMMERCIAL_OR_GPL3_WITH_EXCEPTION"
license_expression)
endif()
elseif(QT_SBOM_DEFAULT_QT_LICENSE_ID_LIBRARIES
AND NOT arg_NO_DEFAULT_QT_LICENSE_ID_LIBRARIES)
# A repo might contain only the "gpl3" license variant as the default for all modules
# and plugins, so allow setting it at the repo level to avoid having to repeat it
# for each target.
_qt_internal_sbom_get_spdx_license_expression(
"${QT_SBOM_DEFAULT_QT_LICENSE_ID_LIBRARIES}" license_expression)
else()
# Otherwise, for modules and plugins we use the default qt license.
_qt_internal_sbom_get_spdx_license_expression("QT_DEFAULT" license_expression)
endif()
endif()
# Some Qt entities might request a specific license from the subset that we usually use.
if(arg_QT_LICENSE_ID)
_qt_internal_sbom_get_spdx_license_expression("${arg_QT_LICENSE_ID}"
requested_license_expression)
_qt_internal_sbom_join_two_license_ids_with_op(
"${license_expression}" "AND" "${requested_license_expression}"
license_expression)
endif()
# Allow setting a license expression string per directory scope via a variable.
if(is_qt_entity_type AND QT_SBOM_LICENSE_EXPRESSION AND NOT arg_NO_DEFAULT_DIRECTORY_QT_LICENSE)
set(qt_license_expression "${QT_SBOM_LICENSE_EXPRESSION}")
_qt_internal_sbom_join_two_license_ids_with_op(
"${license_expression}" "AND" "${qt_license_expression}"
license_expression)
endif()
if(license_expression)
set(${arg_OUT_VAR} "${license_expression}" PARENT_SCOPE)
endif()
endfunction()
# Helper function to add a default license declared expression for a qt entity type.
function(_qt_internal_sbom_handle_qt_entity_license_declared_expression target)
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
list(APPEND single_args OUT_VAR LICENSE_CONCLUDED_EXPRESSION)
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
set(license_expression "")
# For qt entities we know the license we provide, so we mark it as declared as well.
if(is_qt_entity_type AND arg_LICENSE_CONCLUDED_EXPRESSION)
set(license_expression "${arg_LICENSE_CONCLUDED_EXPRESSION}")
endif()
if(license_expression)
set(${arg_OUT_VAR} "${license_expression}" PARENT_SCOPE)
endif()
endfunction()
# Get the default qt copyright.
function(_qt_internal_sbom_get_default_qt_copyright_header out_var)
set(${out_var}
"Copyright (C) The Qt Company Ltd. and other contributors."
PARENT_SCOPE)
endfunction()
# Helper function to add default copyrights for a qt entity type.
function(_qt_internal_sbom_handle_qt_entity_copyrights target)
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
list(APPEND single_args OUT_VAR)
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
set(qt_default_copyright "")
if(is_qt_entity_type AND NOT arg_NO_DEFAULT_QT_COPYRIGHTS)
_qt_internal_sbom_get_default_qt_copyright_header(qt_default_copyright)
endif()
if(qt_default_copyright)
set(${arg_OUT_VAR} "${qt_default_copyright}" PARENT_SCOPE)
endif()
endfunction()
# Helper function to add default CPEs for a qt entity type.
function(_qt_internal_sbom_handle_qt_entity_cpe target)
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
list(APPEND single_args OUT_VAR)
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
_qt_internal_sbom_is_qt_3rd_party_entity_type("${arg_TYPE}" is_qt_3rd_party_entity_type)
set(cpe_list "")
# Add the qt-specific CPE if the target is a Qt entity type, or if it's a 3rd party entity type
# without any CPE specified.
if(is_qt_entity_type OR (is_qt_3rd_party_entity_type AND NOT arg_CPE))
_qt_internal_sbom_compute_security_cpe_for_qt(cpe_list)
endif()
if(cpe_list)
set(${arg_OUT_VAR} "${cpe_list}" PARENT_SCOPE)
endif()
endfunction()
# Returns a vcs url for purls where qt entities of the current repo are hosted.
function(_qt_internal_sbom_get_qt_entity_vcs_url target)
set(opt_args "")
set(single_args
REPO_NAME
VERSION
OUT_VAR
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
if(NOT arg_REPO_NAME)
message(FATAL_ERROR "REPO_NAME must be set")
endif()
if(NOT arg_OUT_VAR)
message(FATAL_ERROR "OUT_VAR must be set")
endif()
set(version_part "")
if(arg_VERSION)
set(version_part "@${arg_VERSION}")
endif()
set(vcs_url "https://code.qt.io/qt/${arg_REPO_NAME}.git${version_part}")
set(${arg_OUT_VAR} "${vcs_url}" PARENT_SCOPE)
endfunction()
# Returns a relative path to the source where the target was created, to be embedded into a
# mirror purl as a subpath.
function(_qt_internal_sbom_get_qt_entity_repo_source_dir target)
set(opt_args "")
set(single_args
OUT_VAR
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
if(NOT arg_OUT_VAR)
message(FATAL_ERROR "OUT_VAR must be set")
endif()
get_target_property(repo_source_dir "${target}" SOURCE_DIR)
# Get the path relative to the PROJECT_SOURCE_DIR
file(RELATIVE_PATH relative_repo_source_dir "${PROJECT_SOURCE_DIR}" "${repo_source_dir}")
set(sub_path "${relative_repo_source_dir}")
set(${arg_OUT_VAR} "${sub_path}" PARENT_SCOPE)
endfunction()
# Gets a list of arguments to pass to _qt_internal_sbom_assemble_purl when handling a Qt entity
# type. The purl for Qt entity types have Qt-specific defaults, but can be overridden per purl
# component.
# The arguments are saved in OUT_VAR.
function(_qt_internal_sbom_get_qt_entity_purl_args target)
set(opt_args "")
set(single_args
NAME
REPO_NAME
SUPPLIER
VERSION
OUT_VAR
)
set(multi_args "")
_qt_internal_get_sbom_purl_parsing_options(purl_opt_args purl_single_args purl_multi_args)
list(APPEND opt_args ${purl_opt_args})
list(APPEND single_args ${purl_single_args})
list(APPEND multi_args ${purl_multi_args})
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
if(arg_VERSION)
set(purl_version "${arg_VERSION}")
endif()
if(arg_PURL_ID STREQUAL "GENERIC")
set(purl_type "generic")
set(purl_namespace "${arg_SUPPLIER}")
set(purl_name "${arg_NAME}")
elseif(arg_PURL_ID STREQUAL "GITHUB")
set(purl_type "github")
set(purl_namespace "qt")
set(purl_name "${arg_REPO_NAME}")
endif()
if(arg_PURL_TYPE)
set(purl_type "${arg_PURL_TYPE}")
endif()
if(arg_PURL_NAMESPACE)
set(purl_namespace "${arg_PURL_NAMESPACE}")
endif()
if(arg_PURL_NAME)
set(purl_name "${arg_PURL_NAME}")
endif()
if(arg_PURL_VERSION)
set(purl_version "${arg_PURL_VERSION}")
endif()
set(purl_version_option "")
if(purl_version)
set(purl_version_option PURL_VERSION "${purl_version}")
endif()
set(purl_args
PURL_TYPE "${purl_type}"
PURL_NAMESPACE "${purl_namespace}"
PURL_NAME "${purl_name}"
${purl_version_option}
)
if(arg_PURL_QUALIFIERS)
list(APPEND purl_args PURL_QUALIFIERS "${arg_PURL_QUALIFIERS}")
endif()
if(arg_PURL_SUBPATH)
list(APPEND purl_args PURL_SUBPATH "${arg_PURL_SUBPATH}")
endif()
set(${arg_OUT_VAR} "${purl_args}" PARENT_SCOPE)
endfunction()
# Helper to get the list of default purl ids for a qt entity.
#
# Qt entities have two purls by default:
# - a GITHUB one pointing to the qt github mirror
# - a GENERIC one pointing to code.qt.io via vcs_url
#
# Third party libraries vendored in Qt also have the same purls, like regular Qt
# libraries, but might also have an upstream one which is specified explicitly.
function(_qt_internal_sbom_get_qt_entity_default_purl_ids out_var)
set(supported_purl_ids GITHUB GENERIC)
set(${out_var} "${supported_purl_ids}" PARENT_SCOPE)
endfunction()
# Helper function to decide which purl ids to add for a qt entity.
# Returns either a list of qt purl ids, or an empty list if it's not a qt entity type or qt 3rd
# party type.
function(_qt_internal_sbom_handle_qt_entity_purl_entries)
_qt_internal_get_sbom_purl_handling_options(opt_args single_args multi_args)
list(APPEND single_args
OUT_VAR # This is unused, but added by the calling function.
OUT_VAR_IDS
)
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
set(purl_ids "")
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
_qt_internal_sbom_is_qt_3rd_party_entity_type("${arg_TYPE}" is_qt_3rd_party_entity_type)
if(is_qt_entity_type OR is_qt_3rd_party_entity_type)
_qt_internal_sbom_get_qt_entity_default_purl_ids(purl_ids)
endif()
if(purl_ids)
set(${arg_OUT_VAR_IDS} "${purl_ids}" PARENT_SCOPE)
endif()
endfunction()
# Helper function to add purl values for a specific purl entry of a qt entity type.
function(_qt_internal_sbom_handle_qt_entity_purl target)
_qt_internal_get_sbom_purl_handling_options(opt_args single_args multi_args)
list(APPEND single_args
OUT_VAR # This is unused, but added by the calling function.
OUT_PURL_ARGS
PURL_ID
)
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
set(purl_args "")
_qt_internal_sbom_get_git_version_vars()
# Return early if not handling one of the default qt purl ids, or if requested not to add a
# default purl.
_qt_internal_sbom_get_qt_entity_default_purl_ids(default_purl_ids)
if(arg_NO_DEFAULT_QT_PURL OR (NOT arg_PURL_ID IN_LIST default_purl_ids))
set(${arg_OUT_PURL_ARGS} "${purl_args}" PARENT_SCOPE)
return()
endif()
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
# Add a vcs_url to the GENERIC purl entry.
if(arg_PURL_ID STREQUAL "GENERIC")
set(entity_vcs_url_version_option "")
# Can be empty.
if(QT_SBOM_GIT_HASH_SHORT)
set(entity_vcs_url_version_option VERSION "${QT_SBOM_GIT_HASH_SHORT}")
endif()
_qt_internal_sbom_get_qt_entity_vcs_url(${target}
REPO_NAME "${repo_project_name_lowercase}"
${entity_vcs_url_version_option}
OUT_VAR vcs_url)
list(APPEND purl_args PURL_QUALIFIERS "vcs_url=${vcs_url}")
endif()
# Add the subdirectory path where the target was created as a custom qualifier.
_qt_internal_sbom_get_qt_entity_repo_source_dir(${target} OUT_VAR sub_path)
if(sub_path)
list(APPEND purl_args PURL_SUBPATH "${sub_path}")
endif()
# Add the target name as a custom qualifer.
list(APPEND purl_args PURL_QUALIFIERS "library_name=${target}")
# Can be empty.
if(QT_SBOM_GIT_HASH_SHORT)
list(APPEND purl_args VERSION "${QT_SBOM_GIT_HASH_SHORT}")
endif()
# Get purl args the Qt entity type, taking into account defaults.
_qt_internal_sbom_get_qt_entity_purl_args(${target}
NAME "${repo_project_name_lowercase}-${target}"
REPO_NAME "${repo_project_name_lowercase}"
SUPPLIER "${arg_SUPPLIER}"
PURL_ID "${arg_PURL_ID}"
${purl_args}
OUT_VAR purl_args
)
if(purl_args)
set(${arg_OUT_PURL_ARGS} "${purl_args}" PARENT_SCOPE)
endif()
endfunction()
# Get the default qt package version.
function(_qt_internal_sbom_get_default_qt_package_version out_var)
set(${out_var} "${QT_REPO_MODULE_VERSION}" PARENT_SCOPE)
endfunction()
# Get the default qt supplier.
function(_qt_internal_sbom_get_default_supplier out_var)
set(${out_var} "TheQtCompany" PARENT_SCOPE)
endfunction()
# Get the default qt supplier url.
function(_qt_internal_sbom_get_default_supplier_url out_var)
set(${out_var} "https://qt.io" PARENT_SCOPE)
endfunction()
# Get the default qt download location.
# If git info is available, includes the hash.
function(_qt_internal_sbom_get_qt_repo_source_download_location out_var)
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
set(download_location "git://code.qt.io/qt/${repo_project_name_lowercase}.git")
_qt_internal_sbom_get_git_version_vars()
if(QT_SBOM_GIT_HASH)
string(APPEND download_location "@${QT_SBOM_GIT_HASH}")
endif()
set(${out_var} "${download_location}" PARENT_SCOPE)
endfunction()

View File

@ -77,7 +77,10 @@ function(_qt_internal_sbom_record_system_library_spdx_ids)
# kind of zstd build was done. Make sure to check if the target exists before recording it.
if(TARGET "${target}")
set(target_unaliased "${target}")
_qt_internal_dealias_target(target_unaliased)
get_target_property(aliased_target "${target}" ALIASED_TARGET)
if(aliased_target)
set(target_unaliased ${aliased_target})
endif()
_qt_internal_sbom_record_system_library_spdx_id(${target_unaliased} ${args})
else()
@ -97,8 +100,6 @@ function(_qt_internal_sbom_record_system_library_spdx_id target)
message(FATAL_ERROR "Could not generate spdx id for system library target: ${target}")
endif()
set_target_properties("${target}" PROPERTIES _qt_internal_sbom_is_system_library TRUE)
set_property(GLOBAL PROPERTY
_qt_internal_sbom_recorded_system_library_package_${target} "${package_spdx_id}")
endfunction()
@ -113,18 +114,14 @@ function(_qt_internal_sbom_add_recorded_system_libraries)
set(unconsumed_targets "${recorded_targets}")
set(generated_package_names "")
message(DEBUG
"System libraries that were marked consumed "
"(some target linked to them): ${consumed_targets}")
message(DEBUG
"System libraries that were recorded "
"(they were marked with qt_find_package()): ${recorded_targets}")
foreach(target IN LISTS consumed_targets)
# Some system targets like qtspeech SpeechDispatcher::SpeechDispatcher might be aliased,
# and we can't set properties on them, so unalias the target name.
set(target_original "${target}")
_qt_internal_dealias_target(target)
get_target_property(aliased_target "${target}" ALIASED_TARGET)
if(aliased_target)
set(target ${aliased_target})
endif()
get_property(args GLOBAL PROPERTY
_qt_internal_sbom_recorded_system_library_options_${target})

View File

@ -62,7 +62,10 @@ function(__qt_internal_set_link_order_matters target link_order_matters)
message(FATAL_ERROR "Unable to set _qt_link_order_matters flag. ${target} is not a target.")
endif()
_qt_internal_dealias_target(target)
get_target_property(aliased_target ${target} ALIASED_TARGET)
if(aliased_target)
set(target "${aliased_target}")
endif()
if(link_order_matters)
set(link_order_matters TRUE)
@ -98,7 +101,10 @@ endfunction()
function(__qt_internal_check_cmp0099_available)
set(platform_target ${QT_CMAKE_EXPORT_NAMESPACE}::Platform)
_qt_internal_dealias_target(platform_target)
get_target_property(aliased_target ${platform_target} ALIASED_TARGET)
if(aliased_target)
set(platform_target "${aliased_target}")
endif()
__qt_internal_get_cmp0099_genex_check(cmp0099_check)
set_target_properties(${platform_target} PROPERTIES
@ -218,7 +224,10 @@ function(__qt_internal_collect_object_libraries_recursively out_var target initi
set(lib "${CMAKE_MATCH_1}")
endif()
if(TARGET ${lib})
_qt_internal_dealias_target(lib)
get_target_property(aliased_target ${lib} ALIASED_TARGET)
if(aliased_target)
set(lib ${aliased_target})
endif()
if(${lib} IN_LIST processed_object_libraries)
continue()
@ -415,109 +424,3 @@ function(_qt_internal_warn_about_example_add_subdirectory)
)
endif()
endfunction()
# Mark source files as generated.
#
# This sets `GENERATED` property to TRUE, along with other Qt relevant properties,
# e.g. `SKIP_LINTING`.
#
# Synopsis
#
# _qt_internal_set_source_file_generated(SOURCE <src1> ...
# [CONFIGURE_GENERATED]
# [SKIP_AUTOGEN]
# [DIRECTORY <dirs> ...]
# [TARGET_DIRECTORY <targets> ...]
# )
#
# Arguments
#
# `SOURCES`
# Source files that are generated.
#
# Equivalent to `set_source_files_properties(<files>)`.
#
# `DIRECTORY`
# Equivalent to `set_source_files_properties(DIRECTORY)`.
#
# `TARGET_DIRECTORY`
# Equivalent to `set_source_files_properties(TARGET_DIRECTORY)`.
#
# `SKIP_AUTOGEN`
# Set SKIP_AUTOGEN property to True as well.
#
# `CONFIGURE_GENERATED`
# Files are generated with `configure_file`.
# Does not set `GENERATED TRUE` property. This is needed to avoid removing the file when
# running the clean target.
function(_qt_internal_set_source_file_generated)
set(option_args
SKIP_AUTOGEN
CONFIGURE_GENERATED
)
set(single_args "")
set(multi_args
SOURCES
DIRECTORY
TARGET_DIRECTORY
)
cmake_parse_arguments(PARSE_ARGV 0 arg
"${option_args}" "${single_args}" "${multi_args}"
)
# Parse required variables
if(NOT arg_SOURCES AND QT_FEATURE_developer_build)
message(WARNING
"Unexpected call _qt_internal_set_source_file_generated with empty `SOURCES`."
)
endif()
# Prepend again the appropriate keywords to pass to `set_source_files_properties`
if(arg_DIRECTORY)
list(PREPEND arg_DIRECTORY DIRECTORY)
endif()
if(arg_TARGET_DIRECTORY)
list(PREPEND arg_TARGET_DIRECTORY TARGET_DIRECTORY)
endif()
# Construct the properties list
set(properties "")
if(NOT arg_CONFIGURE_GENERATED)
list(APPEND properties
GENERATED TRUE
)
endif()
if(arg_SKIP_AUTOGEN)
list(APPEND properties
SKIP_AUTOGEN TRUE
)
endif()
# Add SKIP_LINTING if possible. We do not add it unconditionally here to avoid
# confusion when CMake ignores this variable.
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.27" AND NOT QT_FEATURE_lint_generated_code)
list(APPEND properties
SKIP_LINTING TRUE
)
endif()
set_source_files_properties(${arg_SOURCES}
${arg_DIRECTORY}
${arg_TARGET_DIRECTORY}
PROPERTIES ${properties}
)
endfunction()
# Get the real target checking for ALIASED_TARGET
function(_qt_internal_get_real_target out_var target)
get_target_property(aliased_target "${target}" ALIASED_TARGET)
if(aliased_target)
set(${out_var} "${aliased_target}" PARENT_SCOPE)
else()
set(${out_var} "${target}" PARENT_SCOPE)
endif()
endfunction()
# Helpful shortcut to `_qt_internal_get_real_target` if we just need to dealias
function(_qt_internal_dealias_target target_var)
_qt_internal_get_real_target(${target_var} ${${target_var}})
set(${target_var} "${${target_var}}" PARENT_SCOPE)
endfunction()

View File

@ -121,35 +121,3 @@ endfunction()
function(_qt_internal_test_batch_target_name out)
set(${out} "test_batch" PARENT_SCOPE)
endfunction()
# Create a *_check target of the ctest execution for alternative execution
# Arguments:
# : CTEST_TEST_NAME: (default: ${testname})
# name of the ctest test used
function(_qt_internal_make_check_target testname)
set(options "")
set(singleOpts CTEST_TEST_NAME)
set(multiOpts "")
cmake_parse_arguments(PARSE_ARGV 1 arg
"${options}" "${singleOpts}" "${multiOpts}"
)
if(NOT arg_CTEST_TEST_NAME)
set(arg_CTEST_TEST_NAME ${testname})
endif()
set(test_config_options "")
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
if(is_multi_config)
set(test_config_options -C $<CONFIG>)
endif()
# Note: By default the working directory here is CMAKE_CURRENT_BINARY_DIR, which will
# work as long as this is called anywhere up or down the path where the equivalent
# `add_test` is called (not down a different branch path).
add_custom_target(${testname}_check
VERBATIM
COMMENT "Running ctest -V -R \"^${arg_CTEST_TEST_NAME}$\" ${test_config_options}"
COMMAND
"${CMAKE_CTEST_COMMAND}" -V -R "^${arg_CTEST_TEST_NAME}$" ${test_config_options}
)
endfunction()

View File

@ -139,7 +139,7 @@ macro(_qt_internal_execute_proccess_in_qt_env execute_process_args_var)
# We avoid escaping issues this way.
execute_process(${${execute_process_args_var}})
if(CMAKE_HOST_WIN32)
set(ENV{PATH} "${_qt_internal_execute_proccess_in_qt_env_path_backup}")
set(ENV{PATH} "${path_backup}")
unset(_qt_internal_execute_proccess_in_qt_env_path_backup)
endif()
endmacro()

View File

@ -153,16 +153,9 @@ function(__qt_internal_walk_libs
lib "${lib}")
endwhile()
# Skip processing static plugins.
# There are some abuses of this genex marker, because the more generic one below did
# not exist yet.
# Skip static plugins.
set(_is_plugin_marker_genex "\\$<BOOL:QT_IS_PLUGIN_GENEX>")
# Skip any genex expressions that contain the marker. Useful in cases like processing
# link expressions for prl file generation, where some link expressions should be
# skipped either because they don't make sense or they are handled differently.
set(_is_skip_marker_genex "\\$<BOOL:QT_SKIP_WALK_LIBS_PROCESSING>")
if(lib MATCHES "${_is_plugin_marker_genex}" OR lib MATCHES "${_is_skip_marker_genex}")
if(lib MATCHES "${_is_plugin_marker_genex}")
continue()
endif()
@ -179,24 +172,10 @@ function(__qt_internal_walk_libs
if(lib MATCHES "^\\$<TARGET_OBJECTS:")
# Skip object files.
continue()
endif()
set(lib_target "${lib}")
# Unwrap targets like $<LINK_ONLY:$<BUILD_INTERFACE:Qt6::CorePrivate>>
while(lib_target
MATCHES "^\\$<(LINK_ONLY|BUILD_INTERFACE|BUILD_LOCAL_INTERFACE):(.*)>$")
set(lib_target "${CMAKE_MATCH_2}")
endwhile()
# If one of the values is "$<LINK_ONLY:$<BUILD_LOCAL_INTERFACE:Foo>>", this will be
# exported by cmake as "$<LINK_ONLY:>", which will become an empty value after the
# unwrapping above.
# In that case, skip the processing. Otherwise in some weird unknown conditions,
# CMake might consider the empty name to be a valid target, and cause errors further
# down.
if("${lib_target}" STREQUAL "")
continue()
elseif(lib MATCHES "^\\$<LINK_ONLY:(.*)>$")
set(lib_target ${CMAKE_MATCH_1})
else()
set(lib_target ${lib})
endif()
# Skip CMAKE_DIRECTORY_ID_SEP. If a target_link_libraries is applied to a target
@ -261,7 +240,10 @@ function(__qt_internal_walk_libs
endif()
if(operation STREQUAL "promote_3rd_party_global")
set(lib_target_unaliased "${lib_target}")
_qt_internal_dealias_target(lib_target_unaliased)
get_target_property(aliased_target ${lib_target} ALIASED_TARGET)
if(aliased_target)
set(lib_target_unaliased ${aliased_target})
endif()
get_property(is_imported TARGET ${lib_target_unaliased} PROPERTY IMPORTED)

View File

@ -53,7 +53,7 @@ endfunction()
function(__qt_internal_get_emcc_recommended_version out_var)
# This version of Qt needs this version of emscripten.
set(QT_EMCC_RECOMMENDED_VERSION "3.1.70")
set(QT_EMCC_RECOMMENDED_VERSION "3.1.56")
set(${out_var} "${QT_EMCC_RECOMMENDED_VERSION}" PARENT_SCOPE)
endfunction()

View File

@ -33,10 +33,11 @@ function(qt6_add_win_app_sdk target)
set(generated_headers_path "${CMAKE_CURRENT_BINARY_DIR}/winrt_includes")
set(winappsdk_generated_include_dir "${generated_headers_path}/winrt")
find_path(WINAPPSDK_GENERATED_INCLUDE_DIR
NAMES winrt/Microsoft.UI.h
HINTS "${generated_headers_path}")
# If headers are not already generated
if(NOT EXISTS "${winappsdk_generated_include_dir}")
if(NOT WINAPPSDK_GENERATED_INCLUDE_DIR)
if(CPP_WIN_RT_PATH)
set(cpp_win_rt_path "${CPP_WIN_RT_PATH}")
elseif(DEFINED ENV{CPP_WIN_RT_PATH})
@ -52,26 +53,23 @@ function(qt6_add_win_app_sdk target)
message(FATAL_ERROR "cppwinrt.exe could not be found")
endif()
find_path(winappsdk_include_dir
find_path(WINAPPSDK_INCLUDE_DIR
NAMES MddBootstrap.h
HINTS ${win_app_sdk_root}/include
NO_CACHE)
HINTS ${win_app_sdk_root}/include)
find_library(winappsdk_library
find_library(WINAPPSDK_LIBRARY
NAMES Microsoft.WindowsAppRuntime
HINTS ${WINAPPSDK_LIBRARY_DIR} "${win_app_sdk_root}"
"${win_app_sdk_root}/lib"
"${win_app_sdk_root}/lib/win10-${win_app_sdk_arch}"
NO_CACHE)
"${win_app_sdk_root}/lib/win10-${win_app_sdk_arch}")
find_library(winappsdk_bootstrap_library
find_library(WINAPPSDK_BOOTSTRAP_LIBRARY
NAMES Microsoft.WindowsAppRuntime.Bootstrap
HINTS ${WINAPPSDK_LIBRARY_DIR} "${win_app_sdk_root}"
"${win_app_sdk_root}/lib"
"${win_app_sdk_root}/lib/win10-${win_app_sdk_arch}"
NO_CACHE)
"${win_app_sdk_root}/lib/win10-${win_app_sdk_arch}")
if(winappsdk_include_dir AND winappsdk_library AND winappsdk_bootstrap_library)
if(WINAPPSDK_INCLUDE_DIR AND WINAPPSDK_LIBRARY AND WINAPPSDK_BOOTSTRAP_LIBRARY)
execute_process(COMMAND
${cpp_win_rt_path} -out "${generated_headers_path}" -ref sdk
-in "${win_app_sdk_root}/lib/uap10.0"
@ -79,8 +77,12 @@ function(qt6_add_win_app_sdk target)
-in "${win_app_sdk_root}/lib/uap10.0.18362"
-in "${web_view_root}/lib")
if(NOT EXISTS "${winappsdk_generated_include_dir}")
message(FATAL_ERROR "Windows App SDK library headers generation failed.")
find_path(WINAPPSDK_GENERATED_INCLUDE_DIR
NAMES winrt/Microsoft.UI.h
HINTS "${generated_headers_path}")
if(NOT WINAPPSDK_GENERATED_INCLUDE_DIR)
message(FATAL_ERROR "Windows App SDK library headers generation failed")
endif()
else()
message(FATAL_ERROR "Windows App SDK library not found")

View File

@ -125,7 +125,6 @@ Prefix=${prefix}
endif()
endif()
qt_internal_get_host_info_var_prefix(host_info_var_prefix)
string(APPEND content
"[Paths]
Prefix=${ext_prefix_relative_to_conf_file}
@ -143,9 +142,9 @@ Examples=${INSTALL_EXAMPLESDIR}
Tests=${INSTALL_TESTSDIR}
Settings=${INSTALL_SYSCONFDIR}
HostPrefix=${host_prefix_relative_to_conf_file}
HostBinaries=${${host_info_var_prefix}_BINDIR}
HostLibraries=${${host_info_var_prefix}_LIBDIR}
HostLibraryExecutables=${${host_info_var_prefix}_LIBEXECDIR}
HostBinaries=${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_BINDIR}
HostLibraries=${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_LIBDIR}
HostLibraryExecutables=${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_LIBEXECDIR}
HostData=${ext_datadir_relative_to_host_prefix}
Sysroot=${sysroot}
SysrootifyPrefix=${sysrootify_prefix}
@ -170,7 +169,7 @@ HostSpec=${QT_QMAKE_HOST_MKSPEC}
set(wrapper_prefix "host-")
endif()
set(host_qt_bindir "${host_prefix}/${${host_info_var_prefix}_BINDIR}")
set(host_qt_bindir "${host_prefix}/${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_BINDIR}")
file(TO_NATIVE_PATH "${host_qt_bindir}" host_qt_bindir)
if(QT_CREATE_VERSIONED_HARD_LINK AND QT_WILL_INSTALL)

View File

@ -1,15 +1,10 @@
# Copyright (C) 2024 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# These internal sbom functions are meant to be used in qt repo CMakeLists.txt files.
function(qt_internal_add_sbom target)
if(NOT QT_GENERATE_SBOM)
return()
endif()
qt_internal_sbom_get_default_sbom_args("${target}" sbom_extra_args ${ARGN})
_qt_internal_add_sbom(${target} ${ARGN} ${sbom_extra_args})
# For now these are simple internal forwarding wrappers for the public counterparts, which are
# meant to be used in qt repo CMakeLists.txt files.
function(qt_internal_add_sbom)
_qt_internal_add_sbom(${ARGN})
endfunction()
function(qt_internal_extend_sbom)
@ -59,7 +54,6 @@ function(qt_internal_sbom_generate_tag_value_spdx_document)
set(single_args
OUT_VAR_OUTPUT_FILE_NAME
OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH
OUT_VAR_DEPS_FOUND
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
@ -72,31 +66,6 @@ function(qt_internal_sbom_generate_tag_value_spdx_document)
set(${arg_OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH} "${${arg_OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH}}"
PARENT_SCOPE)
endif()
if(arg_OUT_VAR_DEPS_FOUND)
set(${arg_OUT_VAR_DEPS_FOUND} "${${arg_OUT_VAR_DEPS_FOUND}}" PARENT_SCOPE)
endif()
endfunction()
function(qt_internal_sbom_verify_deps_for_generate_tag_value_spdx_document)
_qt_internal_sbom_verify_deps_for_generate_tag_value_spdx_document(${ARGN})
set(opt_args "")
set(single_args
OUT_VAR_DEPS_FOUND
OUT_VAR_REASON_FAILURE_MESSAGE
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
if(arg_OUT_VAR_DEPS_FOUND)
set(${arg_OUT_VAR_DEPS_FOUND} "${${arg_OUT_VAR_DEPS_FOUND}}" PARENT_SCOPE)
endif()
if(arg_OUT_VAR_REASON_FAILURE_MESSAGE)
set(${arg_OUT_VAR_REASON_FAILURE_MESSAGE}
"${${arg_OUT_VAR_REASON_FAILURE_MESSAGE}}" PARENT_SCOPE)
endif()
endfunction()
function(qt_internal_sbom_get_project_spdx_id out_var)
@ -136,61 +105,3 @@ endfunction()
macro(qt_internal_sbom_get_git_version_vars)
_qt_internal_sbom_get_git_version_vars()
endmacro()
function(qt_internal_sbom_get_project_supplier out_var)
get_property(result GLOBAL PROPERTY _qt_sbom_project_supplier)
set(${out_var} "${result}" PARENT_SCOPE)
endfunction()
function(qt_internal_sbom_get_project_supplier_url out_var)
get_property(result GLOBAL PROPERTY _qt_sbom_project_supplier_url)
set(${out_var} "${result}" PARENT_SCOPE)
endfunction()
function(qt_internal_sbom_get_project_namespace out_var)
get_property(result GLOBAL PROPERTY _qt_sbom_project_namespace)
set(${out_var} "${result}" PARENT_SCOPE)
endfunction()
function(qt_internal_sbom_compute_project_namespace out_var)
_qt_internal_sbom_compute_project_namespace(result ${ARGN})
set(${out_var} "${result}" PARENT_SCOPE)
endfunction()
function(qt_internal_sbom_compute_project_file_name out_var)
_qt_internal_sbom_compute_project_file_name(result ${ARGN})
set(${out_var} "${result}" PARENT_SCOPE)
endfunction()
function(qt_internal_sbom_get_sanitized_spdx_id out_var hint)
_qt_internal_sbom_get_sanitized_spdx_id(result "${hint}")
set(${out_var} "${result}" PARENT_SCOPE)
endfunction()
# Gets a list of default sbom args to use when processing qt entity types.
function(qt_internal_sbom_get_default_sbom_args target out_var)
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
list(APPEND opt_args IMMEDIATE_FINALIZATION)
cmake_parse_arguments(PARSE_ARGV 2 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
set(sbom_args "")
list(APPEND sbom_args USE_ATTRIBUTION_FILES)
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PACKAGE_VERSION)
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_SUPPLIER)
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_DOWNLOAD_LOCATION)
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_LICENSE)
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_COPYRIGHTS)
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_CPE)
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL)
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_ATTRIBUTION_FILES)
set(${out_var} "${sbom_args}" PARENT_SCOPE)
endfunction()
function(qt_internal_extend_qt_entity_sbom target)
qt_internal_sbom_get_default_sbom_args("${target}" sbom_extra_args ${ARGN})
_qt_internal_extend_sbom(${target} ${ARGN} ${sbom_extra_args})
endfunction()

View File

@ -270,7 +270,7 @@ function(qt_enable_separate_debug_info target installDestination)
if(QNX)
set(debug_info_suffix sym)
set(debug_info_keep --keep-file-symbols)
set(strip_args --strip-debug -R.ident)
set(strip_args "--strip-debug -R.ident")
else()
set(debug_info_suffix debug)
set(debug_info_keep --only-keep-debug)

View File

@ -6,11 +6,7 @@
# QT_REPO_PUBLIC_NAMESPACE_REGEX cache variable, that can be set by repository in .cmake.conf file.
# The variable tells the syncqt program, what namespaces are treated as public. Symbols in public
# namespaces are considered when generating CaMeL case header files.
function(qt_internal_target_sync_headers target
module_headers
module_headers_generated
module_headers_exclude_from_docs
)
function(qt_internal_target_sync_headers target module_headers module_headers_generated)
if(NOT TARGET ${QT_CMAKE_EXPORT_NAMESPACE}::syncqt)
message(FATAL_ERROR "${QT_CMAKE_EXPORT_NAMESPACE}::syncqt is not a target.")
endif()
@ -84,13 +80,6 @@ function(qt_internal_target_sync_headers target
# std::filesystem API
get_filename_component(source_dir_real "${sync_source_directory}" REALPATH)
get_filename_component(binary_dir_real "${CMAKE_CURRENT_BINARY_DIR}" REALPATH)
if(QT6_INSTALL_PREFIX)
get_filename_component(install_dir_real "${QT6_INSTALL_PREFIX}" REALPATH)
set(install_include_dir_argument
-installIncludeDir "${install_dir_real}/${QT6_INSTALL_HEADERS}")
else()
set(install_include_dir_argument "")
endif()
if(QT_REPO_PUBLIC_NAMESPACE_REGEX)
set(public_namespaces_filter -publicNamespaceFilter "${QT_REPO_PUBLIC_NAMESPACE_REGEX}")
@ -120,7 +109,6 @@ function(qt_internal_target_sync_headers target
-binaryDir "${binary_dir_real}"
-privateHeadersFilter "${private_filter_regex}"
-includeDir "${module_build_interface_include_dir}"
${install_include_dir_argument}
-privateIncludeDir "${module_build_interface_private_include_dir}"
-qpaIncludeDir "${module_build_interface_qpa_include_dir}"
-rhiIncludeDir "${module_build_interface_rhi_include_dir}"
@ -158,13 +146,6 @@ function(qt_internal_target_sync_headers target
list(FILTER module_headers EXCLUDE REGEX
"(.+/(ui_)[^/]+\\.h|${CMAKE_CURRENT_SOURCE_DIR}(/.+)?/doc/+\\.h)")
# Filter out all headers that should be excluded from documentation generation.
# Documentation generation shouldn't depend on headers like the dbus-generated ones.
set(module_headers_for_docs "${module_headers}")
if(module_headers_exclude_from_docs)
list(REMOVE_ITEM module_headers_for_docs ${module_headers_exclude_from_docs})
endif()
set(syncqt_staging_dir "${module_build_interface_include_dir}/.syncqt_staging")
set(syncqt_args "${common_syncqt_arguments}")
@ -244,16 +225,10 @@ function(qt_internal_target_sync_headers target
"@${syncqt_all_args_rsp}"
${external_headers_dir_copy_cmd}
DEPENDS
# Note, we don't depend anymore on ${target}_sync_headers so that we don't bring
# in the headers that are usually excluded from docs.
# This means if someone manually calls
# `ninja sync_all_public_headers Gui_sync_headers` it will cause havoc due to two
# syncqt calls accessing the same files concurrently. This is an edge case that should
# not happen, but it ends up happening, we will have to implement some kind of lock
# file mechanism.
${module_headers_for_docs}
${module_headers}
${syncqt_all_args_rsp}
${QT_CMAKE_EXPORT_NAMESPACE}::syncqt
${target}_sync_headers
VERBATIM
)

View File

@ -148,7 +148,6 @@ function(qt_internal_extend_target target)
list(TRANSFORM arg_PUBLIC_LIBRARIES REPLACE "^Qt::" "${QT_CMAKE_EXPORT_NAMESPACE}::")
list(TRANSFORM arg_LIBRARIES REPLACE "^Qt::" "${QT_CMAKE_EXPORT_NAMESPACE}::")
qt_internal_wrap_private_modules(arg_LIBRARIES ${arg_LIBRARIES})
# Set-up the target
@ -195,11 +194,9 @@ function(qt_internal_extend_target target)
${private_visibility_option} ${arg_LINK_OPTIONS})
if(NOT is_interface_lib)
_qt_internal_get_moc_compiler_flavor_flags(flavor_flags)
set_property(TARGET "${target}" APPEND PROPERTY
AUTOMOC_MOC_OPTIONS "${arg_MOC_OPTIONS}" ${flavor_flags}
AUTOMOC_MOC_OPTIONS "${arg_MOC_OPTIONS}"
)
# Plugin types associated to a module
if(NOT "x${arg_PLUGIN_TYPES}" STREQUAL "x")
qt_internal_add_plugin_types("${target}" "${arg_PLUGIN_TYPES}")
@ -234,9 +231,6 @@ function(qt_internal_extend_target target)
)
endif()
set(all_libraries ${arg_LIBRARIES} ${arg_PUBLIC_LIBRARIES})
qt_internal_work_around_autogen_discarded_dependencies(${target} ${all_libraries})
if(QT_GENERATE_SBOM)
set(sbom_args "")
_qt_internal_forward_function_args(
@ -263,9 +257,6 @@ function(qt_internal_extend_target target)
if(TARGET "${target_private}")
target_link_libraries("${target_private}"
INTERFACE ${arg_PRIVATE_MODULE_INTERFACE})
qt_internal_register_target_dependencies("${target_private}"
PUBLIC ${arg_PRIVATE_MODULE_INTERFACE}
)
elseif(arg_PRIVATE_MODULE_INTERFACE)
set(warning_message "")
string(APPEND warning_message
@ -275,18 +266,10 @@ function(qt_internal_extend_target target)
"Ensure the target exists or remove the option.")
message(AUTHOR_WARNING "${warning_message}")
endif()
qt_register_target_dependencies("${target}"
"${arg_PUBLIC_LIBRARIES};${arg_PRIVATE_MODULE_INTERFACE}"
"${qt_libs_private};${arg_LIBRARIES}")
set(qt_register_target_dependencies_args "")
if(arg_PUBLIC_LIBRARIES)
list(APPEND qt_register_target_dependencies_args
PUBLIC ${arg_PUBLIC_LIBRARIES})
endif()
if(qt_libs_private OR arg_LIBRARIES)
list(APPEND qt_register_target_dependencies_args
PRIVATE ${qt_libs_private} ${arg_LIBRARIES})
endif()
qt_internal_register_target_dependencies("${target}"
${qt_register_target_dependencies_args})
qt_autogen_tools(${target}
ENABLE_AUTOGEN_TOOLS ${arg_ENABLE_AUTOGEN_TOOLS}
@ -346,43 +329,6 @@ function(qt_internal_extend_target target)
endif()
endfunction()
# Takes an output variable and a list of libraries.
#
# Every library that is a private module is wrapped in $<BUILD_INTERFACE> or
# $<BUILD_LOCAL_INTERFACE> if CMake is new enough.
#
# This is necessary for static builds, because if Qt6Foo links to Qt6BarPrivate, this link
# dependency is purely internal. If we don't do this, CMake adds a target check for Qt6BarPrivate
# in Qt6FooTargets.cmake. This breaks if Qt6BarPrivate is not find_package'ed before.
function(qt_internal_wrap_private_modules out_var)
set(result "")
if(CMAKE_VERSION VERSION_LESS "3.26")
set(wrapper_genex "BUILD_INTERFACE")
else()
set(wrapper_genex "BUILD_LOCAL_INTERFACE")
endif()
foreach(lib IN LISTS ARGN)
if(TARGET "${lib}")
get_target_property(lib_is_private_module ${lib} _qt_is_private_module)
if(lib_is_private_module)
# Add the public module as non-wrapped link dependency. This is necessary for
# targets that link only to the private module. Consumers of this target would then
# get a linker error about missing symbols from that Qt module.
get_target_property(lib_public_module_target ${lib} _qt_public_module_target_name)
list(APPEND result "${INSTALL_CMAKE_NAMESPACE}::${lib_public_module_target}")
# Wrap the private module in BUILD_LOCAL_INTERFACE.
set(lib "$<${wrapper_genex}:${lib}>")
endif()
endif()
list(APPEND result "${lib}")
endforeach()
set("${out_var}" "${result}" PARENT_SCOPE)
endfunction()
# Given CMAKE_CONFIG and ALL_CMAKE_CONFIGS, determines if a directory suffix needs to be appended
# to each destination, and sets the computed install target destination arguments in OUT_VAR.
# Defaults used for each of the destination types, and can be configured per destination type.
@ -1241,10 +1187,9 @@ function(qt_internal_create_tracepoints name tracepoints_file)
endif()
if(NOT "${QT_HOST_PATH}" STREQUAL "")
qt_internal_get_host_info_var_prefix(host_info_var_prefix)
qt_path_join(tracegen
"${QT_HOST_PATH}"
"${${host_info_var_prefix}_LIBEXECDIR}"
"${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_LIBEXECDIR}"
"tracegen")
else()
set(tracegen "${QT_CMAKE_EXPORT_NAMESPACE}::tracegen")
@ -1279,10 +1224,9 @@ function(qt_internal_generate_tracepoints name provider)
endforeach()
if(NOT "${QT_HOST_PATH}" STREQUAL "")
qt_internal_get_host_info_var_prefix(host_info_var_prefix)
qt_path_join(tracepointgen
"${QT_HOST_PATH}"
"${${host_info_var_prefix}_LIBEXECDIR}"
"${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_LIBEXECDIR}"
"tracepointgen")
else()
set(tracepointgen "${QT_CMAKE_EXPORT_NAMESPACE}::tracepointgen")
@ -1313,10 +1257,9 @@ function(qt_internal_generate_tracepoints name provider)
endif()
if(NOT "${QT_HOST_PATH}" STREQUAL "")
qt_internal_get_host_info_var_prefix(host_info_var_prefix)
qt_path_join(tracegen
"${QT_HOST_PATH}"
"${${host_info_var_prefix}_LIBEXECDIR}"
"${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_LIBEXECDIR}"
"tracegen")
else()
set(tracegen "${QT_CMAKE_EXPORT_NAMESPACE}::tracegen")

View File

@ -100,10 +100,6 @@ function(qt_internal_add_manual_test target)
qt_internal_add_test(${ARGV} MANUAL)
endfunction()
macro(qt_internal_skip_docker_compose)
set(QT_SKIP_DOCKER_COMPOSE ON CACHE BOOL "Skip setting docker on Linux." FORCE)
endmacro()
# This function will configure the fixture for the network tests that require docker network services
# qmake counterpart: qtbase/mkspecs/features/unsupported/testserver.prf
function(qt_internal_setup_docker_test_fixture name)
@ -123,7 +119,6 @@ function(qt_internal_setup_docker_test_fixture name)
find_program(QT_DOCKER_COMPOSE docker-compose)
if (NOT QT_DOCKER_COMPOSE)
message(WARNING "docker-compose was not found. Docker network tests will not be run.")
qt_internal_skip_docker_compose()
return()
endif()
if (NOT DEFINED QT_DOCKER_COMPOSE_VERSION)
@ -135,7 +130,6 @@ function(qt_internal_setup_docker_test_fixture name)
find_program(QT_DOCKER docker)
if (NOT QT_DOCKER)
message(WARNING "docker was not found. Docker network tests will not be run.")
qt_internal_skip_docker_compose()
return()
endif()
if (NOT DEFINED QT_DOCKER_TEST_SERVER)
@ -145,7 +139,6 @@ function(qt_internal_setup_docker_test_fixture name)
"Docker image qt-test-server-* not found.\n"
"Run the provisioning script (coin/provisioning/.../testserver/docker_testserver.sh) in advance\n"
"Docker network tests will not be run.")
qt_internal_skip_docker_compose()
return()
endif()
set(QT_DOCKER_TEST_SERVER "ON" CACHE BOOL "docker qt-test-server-* present")
@ -239,7 +232,6 @@ function(qt_internal_get_test_arg_definitions optional_args single_value_args mu
QML_IMPORTPATH
TESTDATA
QT_TEST_SERVER_LIST
ANDROID_TESTRUNNER_PRE_TEST_ADB_COMMANDS
${__default_private_args}
${__default_public_args}
PARENT_SCOPE
@ -464,8 +456,6 @@ endfunction()
# The option forces adding the provided TESTDATA to resources.
# MANUAL
# The option indicates that the test is a manual test.
# ANDROID_TESTRUNNER_PRE_TEST_ADB_COMMANDS
# Passes --pre-test-adb-command <command> to androidTestRunner. Android specific argument.
function(qt_internal_add_test name)
qt_internal_get_test_arg_definitions(optional_args single_value_args multi_value_args)
@ -576,17 +566,13 @@ function(qt_internal_add_test name)
# Manual tests can be bundle apps
if(NOT arg_MANUAL)
if(NOT DEFINED CMAKE_MACOSX_BUNDLE)
# Tests should not be bundles on macOS even if arg_GUI is true, because some tests make
# assumptions about the location of helper processes, and those paths would be different
# if a test is built as a bundle.
set_property(TARGET "${name}" PROPERTY MACOSX_BUNDLE FALSE)
endif()
if(NOT DEFINED CMAKE_WIN32_EXECUTABLE)
# The same goes for WIN32_EXECUTABLE, but because it will detach from the console window
# and not print anything.
set_property(TARGET "${name}" PROPERTY WIN32_EXECUTABLE FALSE)
endif()
# Tests should not be bundles on macOS even if arg_GUI is true, because some tests make
# assumptions about the location of helper processes, and those paths would be different
# if a test is built as a bundle.
set_property(TARGET "${name}" PROPERTY MACOSX_BUNDLE FALSE)
# The same goes for WIN32_EXECUTABLE, but because it will detach from the console window
# and not print anything.
set_property(TARGET "${name}" PROPERTY WIN32_EXECUTABLE FALSE)
endif()
# Tests on iOS must be app bundles.
@ -698,13 +684,6 @@ function(qt_internal_add_test name)
if(QT_ENABLE_VERBOSE_DEPLOYMENT OR build_environment STREQUAL "ci")
list(APPEND extra_test_args "--verbose")
endif()
if(arg_ANDROID_TESTRUNNER_PRE_TEST_ADB_COMMANDS)
foreach(command IN LISTS arg_ANDROID_TESTRUNNER_PRE_TEST_ADB_COMMANDS)
list(APPEND extra_test_args "--pre-test-adb-command" "${command}")
endforeach()
endif()
set(test_working_dir "${CMAKE_CURRENT_BINARY_DIR}")
elseif(QNX)
set(test_working_dir "")
@ -729,11 +708,7 @@ function(qt_internal_add_test name)
set(browser "chrome")
endif()
list(APPEND extra_test_args "--browser=${browser}")
if(DEFINED ENV{HEADLESS_CHROME_FOR_TESTING})
list(APPEND extra_test_args "--browser_args=\"--password-store=basic --headless\"")
else()
list(APPEND extra_test_args "--browser_args=\"--password-store=basic\"")
endif()
list(APPEND extra_test_args "--browser_args=\"--password-store=basic\"")
list(APPEND extra_test_args "--kill_exit")
# Tests may require asyncify if they use exec(). Enable asyncify for
@ -753,40 +728,8 @@ function(qt_internal_add_test name)
endif()
else()
if(arg_QMLTEST AND NOT arg_SOURCES)
set(qt_additional_libexec_paths "")
if(DEFINED QT_ADDITIONAL_PACKAGES_PREFIX_PATH)
foreach(additional_prefix IN LISTS QT_ADDITIONAL_PACKAGES_PREFIX_PATH)
set(additional_libexec "${additional_prefix}/${QT6_INSTALL_LIBEXECS}")
list(PREPEND qt_additional_libexec_paths "${additional_libexec}")
endforeach()
endif()
# First look for the scanner in the target qt libexec dir. We prefer this one
# over the tool target which might be for the host platform.
find_program(qmltestrunner_executable
NAMES qmltestrunner qmltestrunner.exe
PATHS "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_LIBEXECS}"
${qt_additional_libexec_paths}
NO_DEFAULT_PATH
)
# If we don't find it in the paths, fallback to using target names.
if(NOT qmltestrunner_executable
AND TARGET "${QT_CMAKE_EXPORT_NAMESPACE}::qmltestrunner")
set(qmltestrunner_executable ${QT_CMAKE_EXPORT_NAMESPACE}::qmltestrunner)
endif()
if(NOT qmltestrunner_executable AND TARGET qmltestrunner)
set(qmltestrunner_executable qmltestrunner)
endif()
if(NOT qmltestrunner_executable)
message(FATAL_ERROR "qmltestrunner not found.")
endif()
set(test_working_dir "${CMAKE_CURRENT_SOURCE_DIR}")
set(test_executable "${qmltestrunner_executable}")
set(test_executable ${QT_CMAKE_EXPORT_NAMESPACE}::qmltestrunner)
else()
if (arg_WORKING_DIRECTORY)
set(test_working_dir "${arg_WORKING_DIRECTORY}")
@ -851,10 +794,18 @@ function(qt_internal_add_test name)
)
endif()
# Add a ${target}_check makefile target, to more easily test one test.
# TODO: Note in batch mode testname tests would execute all batched tests defined in name
_qt_internal_make_check_target(${testname} CTEST_TEST_NAME ${name})
# Add appropriate dependencies to the targets as needed
# Add a ${target}/check makefile target, to more easily test one test.
set(test_config_options "")
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
if(is_multi_config)
set(test_config_options -C $<CONFIG>)
endif()
add_custom_target("${testname}_check"
VERBATIM
COMMENT "Running ${CMAKE_CTEST_COMMAND} -V -R \"^${name}$\" ${test_config_options}"
COMMAND "${CMAKE_CTEST_COMMAND}" -V -R "^${name}$" ${test_config_options}
)
if(TARGET "${name}")
add_dependencies("${testname}_check" "${name}")
if(ANDROID)

View File

@ -168,10 +168,7 @@ function(qt_internal_add_tool target_name)
APPEND PROPERTY
EXPORT_PROPERTIES "_qt_package_version")
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.19.0"
AND QT_FEATURE_debug_and_release
AND is_multi_config)
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.19.0" AND QT_FEATURE_debug_and_release)
set_property(TARGET "${target_name}"
PROPERTY EXCLUDE_FROM_ALL "$<NOT:$<CONFIG:${QT_MULTI_CONFIG_FIRST_CONFIG}>>")
endif()
@ -306,7 +303,7 @@ function(qt_internal_add_tool target_name)
${__qt_internal_sbom_multi_args}
)
qt_internal_extend_qt_entity_sbom(${target_name} ${sbom_args})
_qt_internal_extend_sbom(${target_name} ${sbom_args})
endif()
qt_add_list_file_finalizer(qt_internal_finalize_tool ${target_name})
@ -712,14 +709,14 @@ function(qt_internal_find_tool out_var target_name tools_target)
set(${tools_package_name}_BACKUP_CMAKE_FIND_ROOT_PATH "${CMAKE_FIND_ROOT_PATH}")
if(QT_HOST_PATH_CMAKE_DIR)
set(qt_host_path_cmake_dir_absolute "${QT_HOST_PATH_CMAKE_DIR}")
elseif(${INSTALL_CMAKE_NAMESPACE}HostInfo_DIR)
elseif(Qt${PROJECT_VERSION_MAJOR}HostInfo_DIR)
get_filename_component(qt_host_path_cmake_dir_absolute
"${${INSTALL_CMAKE_NAMESPACE}HostInfo_DIR}/.." ABSOLUTE)
"${Qt${PROJECT_VERSION_MAJOR}HostInfo_DIR}/.." ABSOLUTE)
else()
# This should never happen, serves as an assert.
message(FATAL_ERROR
"Neither QT_HOST_PATH_CMAKE_DIR nor "
"${INSTALL_CMAKE_NAMESPACE}HostInfo_DIR available.")
"Qt${PROJECT_VERSION_MAJOR}HostInfo_DIR available.")
endif()
set(CMAKE_PREFIX_PATH "${qt_host_path_cmake_dir_absolute}")

Some files were not shown because too many files have changed in this diff Show More