mirror of
git://code.qt.io/qt/qt5.git
synced 2026-10-09 00:27:21 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20d43de824 | ||
|
|
5a30e209bf | ||
|
|
38543c7d08 | ||
|
|
5ad8a50502 | ||
|
|
924e26cc1a | ||
|
|
569a071969 | ||
|
|
5e77a0af5c | ||
|
|
da1126957f | ||
|
|
c63b5fb4e5 | ||
|
|
7776c20e0d | ||
|
|
07ed4b4d3c | ||
|
|
d44d627511 | ||
|
|
eb4c6930cc | ||
|
|
bfd13f4e40 | ||
|
|
7dfe909998 | ||
|
|
869a284623 | ||
|
|
58f92aa5fc | ||
|
|
0f51285e8f | ||
|
|
9052403463 | ||
|
|
0f1efe98c7 | ||
|
|
53c0ff7b21 | ||
|
|
d1e924d592 | ||
|
|
06aca27abd | ||
|
|
7b6457f76e | ||
|
|
75400695b5 | ||
|
|
eb5b9a0dbc | ||
|
|
397258285c | ||
|
|
e7fafe9211 | ||
|
|
4d792f7bb9 | ||
|
|
cbbd7e2d22 | ||
|
|
5671be2454 | ||
|
|
bb6a722532 | ||
|
|
3208f5c95a | ||
|
|
5b4b15e12b | ||
|
|
60525c8de8 | ||
|
|
1880c78815 | ||
|
|
1eb5f09e3d | ||
|
|
1e99891027 | ||
|
|
d388103e82 | ||
|
|
2eb362d1c8 | ||
|
|
61d6a83316 | ||
|
|
574f06fdcc | ||
|
|
6e7735f5db | ||
|
|
85f201f07f | ||
|
|
14fd3ac200 | ||
|
|
a8cd722ee2 | ||
|
|
61b2b03b78 | ||
|
|
8c31c16298 | ||
|
|
75ce1846a3 | ||
|
|
9fc2fe4bb5 | ||
|
|
7e2b6df4a8 | ||
|
|
897d609dad | ||
|
|
26a7125a2c | ||
|
|
653c7cec5b | ||
|
|
ee8728d202 | ||
|
|
f1632a6b40 | ||
|
|
e94bda4040 | ||
|
|
dc29c6d134 | ||
|
|
6a9e9eb192 | ||
|
|
31071aed4a | ||
|
|
6bda9bdef9 | ||
|
|
779613db43 | ||
|
|
056ef7a139 | ||
|
|
58b1334bac | ||
|
|
e0f1c974c3 | ||
|
|
5ad4448629 | ||
|
|
81c7c49f23 | ||
|
|
6683a395e8 | ||
|
|
6920b96315 | ||
|
|
e96543ec42 | ||
|
|
eaa6423f36 | ||
|
|
33df950977 | ||
|
|
cb8860d23a | ||
|
|
6b51154f65 | ||
|
|
b03667a922 | ||
|
|
7fdc3c2e63 | ||
|
|
790d69eff5 | ||
|
|
df694084d7 | ||
|
|
51aab48f53 | ||
|
|
0e12d8a718 | ||
|
|
204528c5bd | ||
|
|
2b92278152 | ||
|
|
333b23bd43 | ||
|
|
9ed1386484 | ||
|
|
1a8bf86bf7 | ||
|
|
49c5952b0c | ||
|
|
092792a1f4 | ||
|
|
295083dd9b | ||
|
|
8732522eea | ||
|
|
aea8ccd137 | ||
|
|
d4992d4da4 | ||
|
|
e9ce684743 | ||
|
|
c899623a25 | ||
|
|
3ed07a35b3 | ||
|
|
dd170ab8a4 | ||
|
|
f86d819c55 | ||
|
|
906b43060f | ||
|
|
78e1c81b1e | ||
|
|
ab868d79a0 | ||
|
|
6326e57a40 | ||
|
|
a60717f3fa | ||
|
|
065d6d06d9 | ||
|
|
fec1887c6e | ||
|
|
cdadd80b87 | ||
|
|
8804b39aa5 | ||
|
|
3ea33c05bf | ||
|
|
f0a6bdb87e | ||
|
|
a20ee395b0 | ||
|
|
f408aa690a | ||
|
|
0979c63ba8 | ||
|
|
80f542aa53 | ||
|
|
4d6a473bed | ||
|
|
4bb35ed3bb | ||
|
|
65104d023e | ||
|
|
20c9b61cf6 | ||
|
|
b49f3297b8 | ||
|
|
81f3a57d3b | ||
|
|
6f4085c84d | ||
|
|
14aeaae7de | ||
|
|
b679f634ea | ||
|
|
9136724f2e | ||
|
|
44aa931e29 | ||
|
|
dd13fa7b41 | ||
|
|
d4fc6f01a9 | ||
|
|
c425276693 | ||
|
|
654c9c2b03 | ||
|
|
8e218fec47 | ||
|
|
444670374a | ||
|
|
02df2a107d | ||
|
|
42370c3e0b | ||
|
|
34e6afee88 | ||
|
|
eb6aff6f96 | ||
|
|
5a7814e918 | ||
|
|
41b759dba7 | ||
|
|
9969af72b5 | ||
|
|
4549003489 | ||
|
|
d059dc0446 | ||
|
|
cb7d1367be | ||
|
|
862c3df5bf | ||
|
|
e37b588b62 | ||
|
|
28c27e1256 | ||
|
|
129c6abe37 | ||
|
|
b5af653382 | ||
|
|
ed632de606 | ||
|
|
8f3e7cd7eb | ||
|
|
e84b449ab5 | ||
|
|
fc6d6d66cc | ||
|
|
341fe4e602 | ||
|
|
42039d0819 | ||
|
|
b7a2e3ba1c | ||
|
|
9b7e7d5852 | ||
|
|
99c69904b8 | ||
|
|
adcff73e24 | ||
|
|
609c6903c7 | ||
|
|
156feaa139 | ||
|
|
f898c700d3 | ||
|
|
7c5594ea08 | ||
|
|
bb7ae5f3dc | ||
|
|
75db654544 | ||
|
|
2882b5615b | ||
|
|
87c2d0b629 | ||
|
|
adc52dde71 | ||
|
|
3f495a95ee | ||
|
|
6282a3fd8a | ||
|
|
01ed52ad4c | ||
|
|
5e9c31fe74 | ||
|
|
6cecda38fa | ||
|
|
75a537b6d5 | ||
|
|
c0e391423d | ||
|
|
4f97b4bea8 | ||
|
|
a377574e66 | ||
|
|
74d1e3a4c8 | ||
|
|
526a09e46a | ||
|
|
b002b0fde9 | ||
|
|
640b9c2ea2 | ||
|
|
3275891741 | ||
|
|
6a6f4fa55e | ||
|
|
d6315c6f58 | ||
|
|
b684ef99a6 | ||
|
|
ce75c3c977 | ||
|
|
5d41389310 | ||
|
|
b3e3927f22 | ||
|
|
50086ff8f3 | ||
|
|
c22a682b4f | ||
|
|
6ead7af28d | ||
|
|
2b6e156008 | ||
|
|
00177db989 | ||
|
|
23c201ac4e | ||
|
|
41986ce213 | ||
|
|
596f204006 | ||
|
|
a10af2c0e8 | ||
|
|
cc750dc924 | ||
|
|
4826d56e8d | ||
|
|
d6ac43b433 | ||
|
|
8d4971fd6e | ||
|
|
d43a68e9b4 | ||
|
|
393b7adc1f | ||
|
|
38e3864f3e | ||
|
|
4df5cb5b02 | ||
|
|
f505ed1baf | ||
|
|
ec2e17e25d | ||
|
|
36efc0bfb0 | ||
|
|
f0ab3c330f | ||
|
|
9448447668 |
+46
-46
@@ -1,46 +1,46 @@
|
||||
[submodule "qtbase"]
|
||||
path = qtbase
|
||||
url = ../qtbase.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = essential
|
||||
[submodule "qtsvg"]
|
||||
depends = qtbase
|
||||
path = qtsvg
|
||||
url = ../qtsvg.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtdeclarative"]
|
||||
depends = qtbase
|
||||
recommends = qtimageformats qtshadertools qtsvg qtlanguageserver
|
||||
path = qtdeclarative
|
||||
url = ../qtdeclarative.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = essential
|
||||
[submodule "qtactiveqt"]
|
||||
depends = qtbase
|
||||
path = qtactiveqt
|
||||
url = ../qtactiveqt.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtmultimedia"]
|
||||
depends = qtbase qtshadertools
|
||||
recommends = qtdeclarative qtquick3d
|
||||
path = qtmultimedia
|
||||
url = ../qtmultimedia.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qttools"]
|
||||
depends = qtbase
|
||||
recommends = qtdeclarative qtactiveqt
|
||||
path = qttools
|
||||
url = ../qttools.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = essential
|
||||
[submodule "qttranslations"]
|
||||
depends = qttools
|
||||
path = qttranslations
|
||||
url = ../qttranslations.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = essential
|
||||
priority = 30
|
||||
[submodule "qtdoc"]
|
||||
@@ -48,7 +48,7 @@
|
||||
recommends = qtmultimedia qtshadertools qttasktree
|
||||
path = qtdoc
|
||||
url = ../qtdoc.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = essential
|
||||
priority = 40
|
||||
[submodule "qtrepotools"]
|
||||
@@ -61,7 +61,7 @@
|
||||
depends = qtbase
|
||||
path = qtqa
|
||||
url = ../qtqa.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = essential
|
||||
priority = 50
|
||||
[submodule "qtlocation"]
|
||||
@@ -69,234 +69,234 @@
|
||||
recommends = qtdeclarative
|
||||
path = qtlocation
|
||||
url = ../qtlocation.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = preview
|
||||
[submodule "qtpositioning"]
|
||||
depends = qtbase
|
||||
recommends = qtdeclarative qtserialport
|
||||
path = qtpositioning
|
||||
url = ../qtpositioning.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtsensors"]
|
||||
depends = qtbase
|
||||
recommends = qtdeclarative
|
||||
path = qtsensors
|
||||
url = ../qtsensors.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtconnectivity"]
|
||||
depends = qtbase
|
||||
recommends = qtdeclarative
|
||||
path = qtconnectivity
|
||||
url = ../qtconnectivity.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtwayland"]
|
||||
depends = qtbase
|
||||
recommends = qtdeclarative
|
||||
path = qtwayland
|
||||
url = ../qtwayland.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qt3d"]
|
||||
depends = qtbase
|
||||
recommends = qtdeclarative qtshadertools qtmultimedia
|
||||
path = qt3d
|
||||
url = ../qt3d.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = deprecated
|
||||
[submodule "qtimageformats"]
|
||||
depends = qtbase
|
||||
path = qtimageformats
|
||||
url = ../qtimageformats.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtserialbus"]
|
||||
depends = qtbase
|
||||
recommends = qtserialport
|
||||
path = qtserialbus
|
||||
url = ../qtserialbus.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtserialport"]
|
||||
depends = qtbase
|
||||
path = qtserialport
|
||||
url = ../qtserialport.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtwebsockets"]
|
||||
depends = qtbase
|
||||
recommends = qtdeclarative
|
||||
path = qtwebsockets
|
||||
url = ../qtwebsockets.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtwebchannel"]
|
||||
depends = qtbase
|
||||
recommends = qtdeclarative qtwebsockets
|
||||
path = qtwebchannel
|
||||
url = ../qtwebchannel.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtwebview"]
|
||||
depends = qtdeclarative
|
||||
path = qtwebview
|
||||
url = ../qtwebview.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtcharts"]
|
||||
depends = qtbase
|
||||
recommends = qtdeclarative qtmultimedia
|
||||
path = qtcharts
|
||||
url = ../qtcharts.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = deprecated
|
||||
[submodule "qtdatavis3d"]
|
||||
depends = qtbase
|
||||
recommends = qtdeclarative qtmultimedia
|
||||
path = qtdatavis3d
|
||||
url = ../qtdatavis3d.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = deprecated
|
||||
[submodule "qtvirtualkeyboard"]
|
||||
depends = qtbase qtdeclarative qtsvg
|
||||
recommends = qtmultimedia
|
||||
path = qtvirtualkeyboard
|
||||
url = ../qtvirtualkeyboard.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtscxml"]
|
||||
depends = qtbase qtdeclarative
|
||||
path = qtscxml
|
||||
url = ../qtscxml.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtspeech"]
|
||||
depends = qtbase qtmultimedia
|
||||
recommends = qtdeclarative
|
||||
path = qtspeech
|
||||
url = ../qtspeech.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtnetworkauth"]
|
||||
depends = qtbase
|
||||
path = qtnetworkauth
|
||||
url = ../qtnetworkauth.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtremoteobjects"]
|
||||
depends = qtbase
|
||||
recommends = qtdeclarative
|
||||
path = qtremoteobjects
|
||||
url = ../qtremoteobjects.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtlottie"]
|
||||
depends = qtbase qtdeclarative qtquicktimeline
|
||||
path = qtlottie
|
||||
url = ../qtlottie.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtquicktimeline"]
|
||||
depends = qtbase qtdeclarative
|
||||
path = qtquicktimeline
|
||||
url = ../qtquicktimeline
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtquick3d"]
|
||||
depends = qtbase qtdeclarative qtshadertools
|
||||
recommends = qtquicktimeline
|
||||
path = qtquick3d
|
||||
url = ../qtquick3d.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtshadertools"]
|
||||
depends = qtbase
|
||||
path = qtshadertools
|
||||
url = ../qtshadertools.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qt5compat"]
|
||||
depends = qtbase qtdeclarative
|
||||
path = qt5compat
|
||||
url = ../qt5compat.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = deprecated
|
||||
[submodule "qtcoap"]
|
||||
depends = qtbase
|
||||
path = qtcoap
|
||||
url = ../qtcoap.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtmqtt"]
|
||||
depends = qtbase qtdeclarative
|
||||
recommends = qtwebsockets
|
||||
path = qtmqtt
|
||||
url = ../qtmqtt.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtopcua"]
|
||||
depends = qtbase qtdeclarative
|
||||
path = qtopcua
|
||||
url = ../qtopcua.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtlanguageserver"]
|
||||
depends = qtbase
|
||||
path = qtlanguageserver
|
||||
url = ../qtlanguageserver.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = preview
|
||||
[submodule "qthttpserver"]
|
||||
depends = qtbase
|
||||
recommends = qtwebsockets
|
||||
path = qthttpserver
|
||||
url = ../qthttpserver.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtquick3dphysics"]
|
||||
depends = qtbase qtdeclarative qtquick3d qtshadertools
|
||||
path = qtquick3dphysics
|
||||
url = ../qtquick3dphysics.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtgrpc"]
|
||||
depends = qtbase
|
||||
recommends = qtdeclarative
|
||||
path = qtgrpc
|
||||
url = ../qtgrpc.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtquickeffectmaker"]
|
||||
depends = qtbase qtdeclarative qtshadertools
|
||||
recommends = qtquick3d
|
||||
path = qtquickeffectmaker
|
||||
url = ../qtquickeffectmaker.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qtgraphs"]
|
||||
depends = qtbase qtdeclarative qtquick3d
|
||||
path = qtgraphs
|
||||
url = ../qtgraphs.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = addon
|
||||
[submodule "qttasktree"]
|
||||
depends = qtbase
|
||||
path = qttasktree
|
||||
url = ../qttasktree.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = preview
|
||||
[submodule "qtopenapi"]
|
||||
depends = qtbase
|
||||
recommends = qtdeclarative
|
||||
path = qtopenapi
|
||||
url = ../qtopenapi.git
|
||||
branch = 6.12.0
|
||||
branch = dev
|
||||
status = preview
|
||||
[submodule "qtcanvaspainter"]
|
||||
depends = qtbase qtdeclarative qtshadertools
|
||||
path = qtcanvaspainter
|
||||
url = ../qtcanvaspainter.git
|
||||
branch = 6.12.0
|
||||
status = addon
|
||||
branch = dev
|
||||
status = preview
|
||||
|
||||
+2
-2
@@ -38,5 +38,5 @@ EWL subscription requires an active
|
||||
header that marks how security-relevant a source file is.
|
||||
* [QUIP 16](https://contribute.qt-project.org/quips/16) — the branch policy,
|
||||
which governs which branches accept which changes.
|
||||
* [Responsible Vulnerability Disclosure Agreement](https://www.qt.io/terms-conditions/responsible-vulnerability-disclosure-process) -
|
||||
Terms and Conditions of Responsible Vulnerability Disclosure Process at Qt Group.
|
||||
* [Coordinated Vulnerability Disclosure Policy](https://www.qt.io/terms-conditions/coordinated-vulnerability-disclosure-policy) -
|
||||
Terms and Conditions of Coordinated Vulnerability Disclosure Policy at Qt Group.
|
||||
|
||||
@@ -21,7 +21,9 @@ ColumnLimit: 100
|
||||
# Disable reflow of some specific comments
|
||||
# qdoc comments: indentation rules are different.
|
||||
# Translation comments and SPDX license identifiers are also excluded.
|
||||
# REUSE-IgnoreStart
|
||||
CommentPragmas: "^!|^:|^ SPDX-License-Identifier:"
|
||||
# REUSE-IgnoreEnd
|
||||
|
||||
# We want a space between the type and the star for pointer types.
|
||||
PointerBindsToType: false
|
||||
|
||||
@@ -181,6 +181,7 @@ function(qt_ir_clone_one_submodule submodule_name)
|
||||
set(oneValueArgs
|
||||
ALTERNATES
|
||||
BASE_URL
|
||||
DEPTH
|
||||
WORKING_DIRECTORY
|
||||
)
|
||||
set(multiValueArgs "")
|
||||
@@ -263,6 +264,9 @@ function(qt_ir_clone_one_submodule submodule_name)
|
||||
else()
|
||||
list(APPEND clone_args --no-checkout)
|
||||
endif()
|
||||
if(arg_DEPTH)
|
||||
list(APPEND clone_args --depth "${arg_DEPTH}")
|
||||
endif()
|
||||
list(APPEND clone_args ${progress_args})
|
||||
qt_ir_execute_process_and_log_and_handle_error(
|
||||
COMMAND_ARGS git clone ${clone_args} "${mirror_or_original_url}" "${submodule_path}"
|
||||
@@ -1063,6 +1067,7 @@ function(qt_ir_handle_init_submodules prefix)
|
||||
set(oneValueArgs
|
||||
ALTERNATES
|
||||
BASE_URL
|
||||
DEPTH
|
||||
PARENT_REPO_BASE_GIT_PATH
|
||||
WORKING_DIRECTORY
|
||||
)
|
||||
@@ -1123,6 +1128,7 @@ function(qt_ir_handle_init_submodules prefix)
|
||||
qt_ir_clone_one_submodule(${submodule_name}
|
||||
ALTERNATES ${arg_ALTERNATES}
|
||||
BASE_URL ${arg_BASE_URL}
|
||||
DEPTH "${arg_DEPTH}"
|
||||
WORKING_DIRECTORY "${working_directory}"
|
||||
${branch_flag}
|
||||
${fetch_flag}
|
||||
@@ -1163,6 +1169,7 @@ function(qt_ir_handle_init_submodules prefix)
|
||||
SUBMODULES "all"
|
||||
|
||||
BASE_URL "${base_url}"
|
||||
DEPTH "${arg_DEPTH}"
|
||||
PARENT_REPO_BASE_GIT_PATH "${submodule_base_git_path}"
|
||||
WORKING_DIRECTORY "${working_directory}/${submodule_name}"
|
||||
|
||||
|
||||
@@ -122,6 +122,16 @@ Options:
|
||||
|
||||
Note that this negates the disk usage benefits gained from the use
|
||||
of `--alternates'.
|
||||
|
||||
--depth <n>
|
||||
Creates a shallow clone with a history truncated to <n> commits for
|
||||
each submodule that is cloned, by passing `--depth <n>' to `git
|
||||
clone'. This also applies recursively to submodules of submodules
|
||||
(e.g. qtwebengine's third-party dependencies).
|
||||
|
||||
This option only affects submodules that are freshly cloned; it has
|
||||
no effect on already-cloned submodules that are merely updated or
|
||||
fetched.
|
||||
--mirror <url-base>
|
||||
Uses <url-base> as the base URL for submodule git mirrors.
|
||||
|
||||
|
||||
+13
-35
@@ -128,7 +128,6 @@ function(qt_ir_get_args_from_optfile_configure_filtered optfile_path out_var)
|
||||
|
||||
set(filtered_args ${unknown_args})
|
||||
set(extra_configure_args "")
|
||||
set(extra_cmake_args "")
|
||||
|
||||
# Collect modules to skip. These may come from:
|
||||
# 1. The -skip option (consumed by init-repository's option parser)
|
||||
@@ -149,14 +148,10 @@ function(qt_ir_get_args_from_optfile_configure_filtered optfile_path out_var)
|
||||
# have a CMakeLists.txt, so remove it.
|
||||
list(REMOVE_ITEM include_submodules "qtrepotools")
|
||||
|
||||
# Make sure to explicitly pass -DBUILD_<module>=ON, in case they were
|
||||
# skipped before, otherwise configure might fail.
|
||||
if(include_submodules)
|
||||
set(explicit_build_submodules "${include_submodules}")
|
||||
list(TRANSFORM explicit_build_submodules PREPEND "-DBUILD_")
|
||||
list(TRANSFORM explicit_build_submodules APPEND "=ON")
|
||||
list(APPEND extra_cmake_args ${explicit_build_submodules})
|
||||
endif()
|
||||
# Note: the submodules are turned on explicitly with -DBUILD_<module>=ON by configure's
|
||||
# own handling of -submodules. Adding those arguments here as well would record them in
|
||||
# config.opt, which is supposed to reflect the command line as it was given.
|
||||
# See QTBUG-134948.
|
||||
|
||||
list(JOIN include_submodules "," include_submodules)
|
||||
|
||||
@@ -179,33 +174,14 @@ function(qt_ir_get_args_from_optfile_configure_filtered optfile_path out_var)
|
||||
list(APPEND extra_configure_args "-skip" "${skip_csv}")
|
||||
endif()
|
||||
|
||||
# Insert the extra arguments into the proper positions before and after '--'.
|
||||
list(FIND filtered_args "--" cmake_args_index)
|
||||
|
||||
# -- is not found
|
||||
if(cmake_args_index EQUAL -1)
|
||||
# Append extra configure args if present
|
||||
if(extra_configure_args)
|
||||
list(APPEND filtered_args ${extra_configure_args})
|
||||
endif()
|
||||
# Append extra cmake args if present, but make sure to add -- first at the end
|
||||
if(extra_cmake_args)
|
||||
list(APPEND filtered_args "--")
|
||||
list(APPEND filtered_args ${extra_cmake_args})
|
||||
endif()
|
||||
else()
|
||||
# -- is found, that means we probably have cmake args
|
||||
# Insert extra configure args if present, before the -- index.
|
||||
if(extra_configure_args)
|
||||
list(INSERT filtered_args "${cmake_args_index}" ${extra_configure_args})
|
||||
endif()
|
||||
# Find the -- index again, because it might have moved
|
||||
# Insert the extra arguments, which are all configure arguments, so they have to go before
|
||||
# a '--' if there is one.
|
||||
if(extra_configure_args)
|
||||
list(FIND filtered_args "--" cmake_args_index)
|
||||
# Compute the index of the argument after the --.
|
||||
math(EXPR cmake_args_index "${cmake_args_index} + 1")
|
||||
# Insert extra cmake args if present, after the -- index.
|
||||
if(extra_cmake_args)
|
||||
list(INSERT filtered_args "${cmake_args_index}" ${extra_cmake_args})
|
||||
if(cmake_args_index EQUAL -1)
|
||||
list(APPEND filtered_args ${extra_configure_args})
|
||||
else()
|
||||
list(INSERT filtered_args "${cmake_args_index}" ${extra_configure_args})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -312,6 +288,7 @@ function(qt_ir_run_after_args_parsed top_level_src_path out_var_exit_reason)
|
||||
# Get some additional options to pass down.
|
||||
qt_ir_get_option_as_existing_absolute_path(alternates alternates)
|
||||
qt_ir_get_option_as_cmake_flag_option(branch "CHECKOUT_BRANCH" checkout_branch_option)
|
||||
qt_ir_get_option_value(depth depth)
|
||||
|
||||
# The prefix for the cmake-style 'dictionary' that will be used by various functions.
|
||||
set(prefix "ir_top")
|
||||
@@ -321,6 +298,7 @@ function(qt_ir_run_after_args_parsed top_level_src_path out_var_exit_reason)
|
||||
ALTERNATES "${alternates}"
|
||||
ALREADY_INITIALIZED_SUBMODULES "${already_initialized_submodules}"
|
||||
BASE_URL "${base_url}"
|
||||
DEPTH "${depth}"
|
||||
PARENT_REPO_BASE_GIT_PATH "${qt5_repo_name}"
|
||||
PROCESS_SUBMODULES_FROM_COMMAND_LINE
|
||||
WORKING_DIRECTORY "${working_directory}"
|
||||
|
||||
@@ -16,6 +16,7 @@ macro(qt_ir_set_known_command_line_options)
|
||||
qt_ir_commandline_option(codereview-username TYPE string)
|
||||
qt_ir_commandline_option(codereview-https TYPE boolean)
|
||||
qt_ir_commandline_option(copy-objects TYPE boolean)
|
||||
qt_ir_commandline_option(depth TYPE string)
|
||||
qt_ir_commandline_option(fetch TYPE boolean DEFAULT_VALUE yes)
|
||||
qt_ir_commandline_option(force SHORT_NAME f TYPE boolean)
|
||||
qt_ir_commandline_option(force-hooks TYPE boolean)
|
||||
|
||||
@@ -30,3 +30,6 @@ enable_if:
|
||||
- condition: property
|
||||
property: target.os
|
||||
equals_value: Linux
|
||||
- condition: property
|
||||
property: target.osVersion
|
||||
not_equals_value: HarmonyOS_ANY
|
||||
|
||||
@@ -92,6 +92,59 @@ Configurations:
|
||||
'QT_QPA_PLATFORM=offscreen'
|
||||
]
|
||||
Platform dependency: 'ubuntu-24.04-arm64'
|
||||
|
||||
# Build on Ubuntu 26.04 ARM64 Wayland and test on offscreen and Wayland later
|
||||
-
|
||||
Id: 'ubuntu-26.04-arm64-developer-build'
|
||||
Template: 'qtci-linux-Ubuntu-26.04-aarch64-51'
|
||||
Compiler: 'GCC'
|
||||
Features: ['Sccache', 'UseConfigure', 'DoNotRunTests', 'StandaloneExamples']
|
||||
Configure arguments: '-make examples -developer-build -c++std c++20 -linker lld -qtlibinfix TestInfix -qtnamespace TestNamespace -qpa offscreen\;xcb'
|
||||
Environment variables: [
|
||||
'COMMON_TEST_CMAKE_ARGS=-DQT_SKIP_DOCKER_COMPOSE=ON',
|
||||
'NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR}} -DQT_DEPLOY_FFMPEG=TRUE',
|
||||
'VCPKG_HOST_TRIPLET=arm64-linux-qt',
|
||||
'VCPKG_TARGET_TRIPLET=arm64-linux-qt',
|
||||
]
|
||||
-
|
||||
Id: 'ubuntu-26.04-arm64'
|
||||
Template: 'qtci-linux-Ubuntu-26.04-aarch64-51'
|
||||
Compiler: 'GCC'
|
||||
Features: ['Sccache', 'UseConfigure', 'DoNotRunTests', 'GenerateSBOM', 'VerifySBOM']
|
||||
Configure arguments: '-nomake examples -release -force-debug-info -separate-debug-info -headersclean -qt-libjpeg -qt-libpng -qt-pcre -qt-harfbuzz -qt-doubleconversion -no-libudev -no-feature-liburing -bundled-xcb-xinput -qpa offscreen\;xcb'
|
||||
Environment variables: [
|
||||
'CMAKE_ARGS=-DOpenGL_GL_PREFERENCE=LEGACY',
|
||||
'COMMON_TEST_CMAKE_ARGS=-DQT_SKIP_DOCKER_COMPOSE=ON',
|
||||
'NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR}} -DQT_DEPLOY_FFMPEG=TRUE -DINPUT_headersclean=ON -DINPUT_tiff=qt -DINPUT_webp=qt',
|
||||
'VCPKG_HOST_TRIPLET=arm64-linux-qt',
|
||||
'VCPKG_TARGET_TRIPLET=arm64-linux-qt',
|
||||
]
|
||||
# Test on Ubuntu 26.04 ARM64 Wayland
|
||||
-
|
||||
Id: 'ubuntu-26.04-arm64-developer-build-wayland-tests'
|
||||
Template: 'qtci-linux-Ubuntu-26.04-aarch64-51'
|
||||
Compiler: 'GCC'
|
||||
Features: ['TestOnly', 'InsignificantTests', 'VerboseCTestOutput']
|
||||
Platform dependency: 'ubuntu-26.04-arm64-developer-build'
|
||||
-
|
||||
Id: 'ubuntu-26.04-arm64-wayland-tests'
|
||||
Template: 'qtci-linux-Ubuntu-26.04-aarch64-51'
|
||||
Compiler: 'GCC'
|
||||
Features: ['TestOnly', 'InsignificantTests', 'VerboseCTestOutput']
|
||||
Platform dependency: 'ubuntu-26.04-arm64'
|
||||
# Test on Ubuntu 26.04 ARM64 offscreen
|
||||
-
|
||||
Id: 'ubuntu-26.04-arm64-offscreen-tests'
|
||||
Template: 'qtci-linux-Ubuntu-26.04-aarch64-51'
|
||||
Compiler: 'GCC'
|
||||
Features: ['TestOnly', 'InsignificantTests']
|
||||
Environment variables: [
|
||||
'CMAKE_ARGS=-DOpenGL_GL_PREFERENCE=LEGACY',
|
||||
'QT_QPA_OFFSCREEN_NO_GLX=1',
|
||||
'QT_QPA_PLATFORM=offscreen'
|
||||
]
|
||||
Platform dependency: 'ubuntu-26.04-arm64'
|
||||
|
||||
# Build on Ubuntu 24.04 x64 Wayland and test on both X11 and Wayland (Wayland=default)
|
||||
-
|
||||
Id: 'ubuntu-24.04-x64-developer-build'
|
||||
@@ -105,6 +158,20 @@ Configurations:
|
||||
'VCPKG_HOST_TRIPLET=x64-linux-qt',
|
||||
'VCPKG_TARGET_TRIPLET=x64-linux-qt',
|
||||
]
|
||||
# Ubuntu 26.04 x64 Wayland
|
||||
-
|
||||
Id: 'ubuntu-26.04-x64-developer-build'
|
||||
Template: 'qtci-linux-Ubuntu-26.04-x86_64-51'
|
||||
Compiler: 'GCC'
|
||||
Features: ['Sccache', 'UseConfigure', 'InsignificantTests', 'VerboseCTestOutput', 'StandaloneExamples']
|
||||
Configure arguments: '-make examples -developer-build -c++std c++20 -linker gold -qtlibinfix TestInfix -qtnamespace TestNamespace'
|
||||
Environment variables: [
|
||||
'COMMON_TEST_CMAKE_ARGS=-DQT_SKIP_DOCKER_COMPOSE=ON',
|
||||
'NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR}} -DQT_DEPLOY_FFMPEG=TRUE',
|
||||
'VCPKG_HOST_TRIPLET=x64-linux-qt',
|
||||
'VCPKG_TARGET_TRIPLET=x64-linux-qt',
|
||||
]
|
||||
# Ubuntu 24.04 x64 Wayland
|
||||
-
|
||||
Id: 'ubuntu-24.04-x64'
|
||||
Template: 'qtci-linux-Ubuntu-24.04-x86_64-50'
|
||||
@@ -118,6 +185,20 @@ Configurations:
|
||||
'VCPKG_HOST_TRIPLET=x64-linux-qt',
|
||||
'VCPKG_TARGET_TRIPLET=x64-linux-qt',
|
||||
]
|
||||
# Ubuntu 26.04 x64 Wayland
|
||||
-
|
||||
Id: 'ubuntu-26.04-x64'
|
||||
Template: 'qtci-linux-Ubuntu-26.04-x86_64-51'
|
||||
Compiler: 'GCC'
|
||||
Features: ['Sccache', 'UseConfigure', 'InsignificantTests', 'VerboseCTestOutput', 'GenerateSBOM', 'VerifySBOM', 'DocsGenerationV2']
|
||||
Configure arguments: '-nomake examples -release -force-debug-info -separate-debug-info -headersclean -qt-libjpeg -qt-libpng -qt-pcre -qt-harfbuzz -qt-doubleconversion -no-libudev -bundled-xcb-xinput'
|
||||
Environment variables: [
|
||||
'CMAKE_ARGS=-DOpenGL_GL_PREFERENCE=LEGACY',
|
||||
'COMMON_TEST_CMAKE_ARGS=-DQT_SKIP_DOCKER_COMPOSE=ON',
|
||||
'NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR}} -DQT_DEPLOY_FFMPEG=TRUE -DINPUT_headersclean=ON',
|
||||
'VCPKG_HOST_TRIPLET=x64-linux-qt',
|
||||
'VCPKG_TARGET_TRIPLET=x64-linux-qt',
|
||||
]
|
||||
# Test on Ubuntu 24.04 x64 X11
|
||||
-
|
||||
Id: 'ubuntu-24.04-x64-developer-build-x11-tests'
|
||||
@@ -358,7 +439,7 @@ Configurations:
|
||||
Id: 'rhel-10.0'
|
||||
Template: 'qtci-linux-RHEL-10.0-x86_64-51'
|
||||
Compiler: 'GCC'
|
||||
Features: ['Sccache', 'UseConfigure', 'InstallQt5Dependencies', 'GenerateSBOM', 'VerifySBOM', 'InsignificantTests', 'DoNotAbortTestingOnFirstFailure']
|
||||
Features: ['Sccache', 'UseConfigure', 'InstallQt5Dependencies', 'GenerateSBOM', 'VerifySBOM', 'DoNotAbortTestingOnFirstFailure']
|
||||
Configure arguments: '-nomake examples -release -force-debug-info -headersclean -separate-debug-info -qt-libjpeg -qt-libpng -qt-pcre -qt-harfbuzz -qt-doubleconversion -no-libudev -bundled-xcb-xinput'
|
||||
Environment variables: [
|
||||
'CMAKE_ARGS=-DOpenGL_GL_PREFERENCE=LEGACY',
|
||||
|
||||
@@ -16,8 +16,6 @@ Configurations:
|
||||
'QT_SYSROOT_FOR_RUNNING_TESTS={{.Env.QEMUARMV7_TOOLCHAIN_SYSROOT}}',
|
||||
'GST_PLUGIN_SCANNER={{.Env.QEMUARMV7_TOOLCHAIN_SYSROOT}}/usr/libexec/gstreamer-1.0/gst-plugin-scanner',
|
||||
'QT_QUICK_BACKEND=software',
|
||||
'VCPKG_HOST_TRIPLET=x64-linux-qt',
|
||||
'VCPKG_TARGET_TRIPLET=armv7-linux-qt',
|
||||
]
|
||||
-
|
||||
Id: 'qemu-arm64-developer-build'
|
||||
@@ -35,8 +33,6 @@ Configurations:
|
||||
'QT_SYSROOT_FOR_RUNNING_TESTS={{.Env.QEMUARM64_TOOLCHAIN_SYSROOT}}',
|
||||
'GST_PLUGIN_SCANNER={{.Env.QEMUARM64_TOOLCHAIN_SYSROOT}}/usr/libexec/gstreamer-1.0/gst-plugin-scanner',
|
||||
'QT_QUICK_BACKEND=software',
|
||||
'VCPKG_HOST_TRIPLET=x64-linux-qt',
|
||||
'VCPKG_TARGET_TRIPLET=arm64-linux-qt',
|
||||
]
|
||||
-
|
||||
Id: 'qemu-mips64-developer-build'
|
||||
@@ -54,6 +50,4 @@ Configurations:
|
||||
'QT_SYSROOT_FOR_RUNNING_TESTS={{.Env.QEMUMIPS64_TOOLCHAIN_SYSROOT}}',
|
||||
'GST_PLUGIN_SCANNER={{.Env.QEMUMIPS64_TOOLCHAIN_SYSROOT}}/usr/libexec/gstreamer-1.0/gst-plugin-scanner',
|
||||
'QT_QUICK_BACKEND=software',
|
||||
'VCPKG_HOST_TRIPLET=x64-linux-qt',
|
||||
'VCPKG_TARGET_TRIPLET=mips64-linux-qt',
|
||||
]
|
||||
|
||||
@@ -55,7 +55,7 @@ Configurations:
|
||||
|
||||
-
|
||||
Id: 'macos-universal-on-x86_64-minimal-static-test'
|
||||
Template: 'qtci-macos-15-x86_64-103'
|
||||
Template: 'qtci-macos-15-x86_64-104'
|
||||
Compiler: 'Clang'
|
||||
Target arch: 'x86_64-arm64'
|
||||
Features: ['Packaging', 'Sccache', 'DoNotRunTests', 'WarningsAreErrors', 'UseConfigure', 'MinimalStaticTests']
|
||||
|
||||
@@ -51,7 +51,7 @@ Configurations:
|
||||
'ANDROID_EMULATOR=emulator_x86_api_28'
|
||||
]
|
||||
-
|
||||
Id: 'android-16-x86_64-on-linux'
|
||||
Id: 'android-17-x86_64-on-linux'
|
||||
Template: 'qtci-linux-RHEL-9.6-x86_64-51'
|
||||
Target os: 'Android_ANY'
|
||||
Target arch: 'x86_64'
|
||||
@@ -59,25 +59,6 @@ Configurations:
|
||||
Target compiler: 'Clang'
|
||||
Platform dependency: 'rhel-9.6'
|
||||
Features: ['Packaging', 'Sccache', 'WarningsAreErrors', 'AndroidTestRun', 'VMSize8', 'UseConfigure', 'GenerateSBOM', 'VerifySBOM', 'JavaDocs']
|
||||
Environment variables: [
|
||||
'TARGET_CONFIGURE_ARGS=-nomake examples -release -force-debug-info -qpa android;offscreen -android-ndk {{.Env.ANDROID_NDK_ROOT_LATEST}} -android-sdk {{.Env.ANDROID_SDK_ROOT}} -android-abis x86_64',
|
||||
'TARGET_CMAKE_ARGS=-DCMAKE_C_COMPILER_FRONTEND_VARIANT=GNU -DCMAKE_CXX_COMPILER_FRONTEND_VARIANT=GNU -DOPENSSL_ROOT_DIR={{.Env.OPENSSL_ANDROID_HOME_LATEST}} -DQT_GENERATE_WRAPPER_SCRIPTS_FOR_ALL_HOSTS=ON',
|
||||
'NON_QTBASE_TARGET_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR_ANDROID_X86_64_NDK_LATEST}} -DQT_DEPLOY_FFMPEG=TRUE -DQT_PROTOBUF_WELL_KNOWN_TYPES_PROTO_DIR=/usr/local/include',
|
||||
# We check QT_USE_TARGET_ANDROID_BUILD_DIR and QT_ANDROID_GRADLE_MULTI_MODULE only in one
|
||||
# configuration, to ensure builds without this option work too.
|
||||
'COMMON_TARGET_TEST_CMAKE_ARGS=-DQT_USE_TARGET_ANDROID_BUILD_DIR=ON -DQT_ANDROID_GRADLE_MULTI_MODULE=ON',
|
||||
'ANDROID_NDK_ROOT={{.Env.ANDROID_NDK_ROOT_LATEST}}',
|
||||
'ANDROID_EMULATOR=emulator_x86_64_api_36'
|
||||
]
|
||||
-
|
||||
Id: 'android-17-x86_64-on-linux'
|
||||
Template: 'qtci-linux-RHEL-9.6-x86_64-51'
|
||||
Target os: 'Android_ANY'
|
||||
Target arch: 'x86_64'
|
||||
Compiler: 'GCC'
|
||||
Target compiler: 'Clang'
|
||||
Platform dependency: 'rhel-9.6'
|
||||
Features: ['Sccache', 'WarningsAreErrors', 'AndroidTestRun', 'VMSize8', 'UseConfigure', 'GenerateSBOM', 'VerifySBOM', 'JavaDocs', 'InsignificantTests', 'DoNotAbortTestingOnFirstFailure']
|
||||
Environment variables: [
|
||||
'TARGET_CONFIGURE_ARGS=-nomake examples -release -force-debug-info -qpa android;offscreen -android-ndk {{.Env.ANDROID_NDK_ROOT_LATEST}} -android-sdk {{.Env.ANDROID_SDK_ROOT}} -android-abis x86_64',
|
||||
'TARGET_CMAKE_ARGS=-DCMAKE_C_COMPILER_FRONTEND_VARIANT=GNU -DCMAKE_CXX_COMPILER_FRONTEND_VARIANT=GNU -DOPENSSL_ROOT_DIR={{.Env.OPENSSL_ANDROID_HOME_LATEST}} -DQT_GENERATE_WRAPPER_SCRIPTS_FOR_ALL_HOSTS=ON',
|
||||
|
||||
@@ -11,10 +11,10 @@ Configurations:
|
||||
Features: ['Sccache', 'UseConfigure', 'DoNotRunTests', 'Packaging', 'GenerateSBOM', 'VerifySBOM']
|
||||
Environment variables: [
|
||||
'TARGET_CONFIGURE_ARGS=-release -nomake examples -no-dbus -no-use-gold-linker -no-pch -openssl-runtime',
|
||||
'TARGET_CMAKE_ARGS=-DOHOS_SDK_ROOT={{.Env.HARMONYOS_SDK_ROOT}} -DOHOS_ARCH=arm64-v8a -DWARNINGS_ARE_ERRORS=OFF -DQT_QMAKE_TARGET_MKSPEC=ohos-clang -DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}} -DQT_GENERATE_WRAPPER_SCRIPTS_FOR_ALL_HOSTS=ON',
|
||||
'TARGET_CMAKE_ARGS=-DOHOS_SDK_ROOT={{.Env.HARMONYOS_SDK_ROOT_CURRENT}}/sdk/default/openharmony -DOHOS_ARCH=arm64-v8a -DWARNINGS_ARE_ERRORS=OFF -DQT_QMAKE_TARGET_MKSPEC=ohos-clang -DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}} -DQT_GENERATE_WRAPPER_SCRIPTS_FOR_ALL_HOSTS=ON',
|
||||
'NON_QTBASE_TARGET_CMAKE_ARGS=-DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'COMMON_TARGET_TEST_CMAKE_ARGS=-DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'QT_HARMONYOS_HVIGOR=/opt/harmonyos/command-line-tools/bin/hvigorw'
|
||||
'QT_HARMONYOS_HVIGOR={{.Env.HARMONYOS_SDK_ROOT_CURRENT}}/bin/hvigorw'
|
||||
]
|
||||
-
|
||||
Id: 'harmonyos-23-arm64-on-linux-developer-build'
|
||||
@@ -27,13 +27,45 @@ Configurations:
|
||||
Features: ['Sccache', 'UseConfigure', 'DoNotRunTests', 'StandaloneExamples']
|
||||
Environment variables: [
|
||||
'TARGET_CONFIGURE_ARGS=-developer-build -debug -make examples -no-dbus -no-use-gold-linker -no-pch -openssl-runtime',
|
||||
'TARGET_CMAKE_ARGS=-DOHOS_SDK_ROOT={{.Env.HARMONYOS_SDK_ROOT}} -DOHOS_ARCH=arm64-v8a -DWARNINGS_ARE_ERRORS=OFF -DQT_QMAKE_TARGET_MKSPEC=ohos-clang -DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'TARGET_CMAKE_ARGS=-DOHOS_SDK_ROOT={{.Env.HARMONYOS_SDK_ROOT_CURRENT}}/sdk/default/openharmony -DOHOS_ARCH=arm64-v8a -DWARNINGS_ARE_ERRORS=OFF -DQT_QMAKE_TARGET_MKSPEC=ohos-clang -DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'NON_QTBASE_TARGET_CMAKE_ARGS=-DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'COMMON_TARGET_TEST_CMAKE_ARGS=-DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'QT_HARMONYOS_HVIGOR=/opt/harmonyos/command-line-tools/bin/hvigorw'
|
||||
'QT_HARMONYOS_HVIGOR={{.Env.HARMONYOS_SDK_ROOT_CURRENT}}/bin/hvigorw'
|
||||
]
|
||||
-
|
||||
Id: 'harmonyos-23-arm64-on-macos'
|
||||
Id: 'harmonyos-26-arm64-on-linux'
|
||||
Template: 'qtci-linux-Ubuntu-24.04-x86_64-50'
|
||||
Target os: 'HarmonyOS_ANY'
|
||||
Target arch: 'arm64'
|
||||
Compiler: 'Clang'
|
||||
Target compiler: 'Clang'
|
||||
Platform dependency: 'ubuntu-24.04-x64'
|
||||
Features: ['Sccache', 'UseConfigure', 'DoNotRunTests', 'Packaging', 'GenerateSBOM', 'VerifySBOM']
|
||||
Environment variables: [
|
||||
'TARGET_CONFIGURE_ARGS=-release -nomake examples -no-dbus -no-use-gold-linker -no-pch -openssl-runtime',
|
||||
'TARGET_CMAKE_ARGS=-DOHOS_SDK_ROOT={{.Env.HARMONYOS_SDK_ROOT_NEXT}}/sdk/default/openharmony -DOHOS_ARCH=arm64-v8a -DWARNINGS_ARE_ERRORS=OFF -DQT_QMAKE_TARGET_MKSPEC=ohos-clang -DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}} -DQT_GENERATE_WRAPPER_SCRIPTS_FOR_ALL_HOSTS=ON',
|
||||
'NON_QTBASE_TARGET_CMAKE_ARGS=-DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'COMMON_TARGET_TEST_CMAKE_ARGS=-DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'QT_HARMONYOS_HVIGOR={{.Env.HARMONYOS_SDK_ROOT_NEXT}}/bin/hvigorw'
|
||||
]
|
||||
-
|
||||
Id: 'harmonyos-26-arm64-on-linux-developer-build'
|
||||
Template: 'qtci-linux-Ubuntu-24.04-x86_64-50'
|
||||
Target os: 'HarmonyOS_ANY'
|
||||
Target arch: 'arm64'
|
||||
Compiler: 'Clang'
|
||||
Target compiler: 'Clang'
|
||||
Platform dependency: 'ubuntu-24.04-x64-developer-build'
|
||||
Features: ['Sccache', 'UseConfigure', 'DoNotRunTests', 'StandaloneExamples']
|
||||
Environment variables: [
|
||||
'TARGET_CONFIGURE_ARGS=-developer-build -debug -make examples -no-dbus -no-use-gold-linker -no-pch -openssl-runtime',
|
||||
'TARGET_CMAKE_ARGS=-DOHOS_SDK_ROOT={{.Env.HARMONYOS_SDK_ROOT_NEXT}}/sdk/default/openharmony -DOHOS_ARCH=arm64-v8a -DWARNINGS_ARE_ERRORS=OFF -DQT_QMAKE_TARGET_MKSPEC=ohos-clang -DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'NON_QTBASE_TARGET_CMAKE_ARGS=-DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'COMMON_TARGET_TEST_CMAKE_ARGS=-DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'QT_HARMONYOS_HVIGOR={{.Env.HARMONYOS_SDK_ROOT_NEXT}}/bin/hvigorw'
|
||||
]
|
||||
-
|
||||
Id: 'harmonyos-23-arm64-on-macos-developer-build'
|
||||
Template: 'qtci-macos-26-arm-105'
|
||||
Target os: 'HarmonyOS_ANY'
|
||||
Target arch: 'arm64'
|
||||
@@ -43,8 +75,8 @@ Configurations:
|
||||
Features: ['Sccache', 'UseConfigure', 'DoNotRunTests', 'StandaloneExamples']
|
||||
Environment variables: [
|
||||
'TARGET_CONFIGURE_ARGS=-developer-build -debug -make examples -no-dbus -no-use-gold-linker -no-pch -openssl-runtime',
|
||||
'TARGET_CMAKE_ARGS=-DOHOS_SDK_ROOT={{.Env.HARMONYOS_SDK_ROOT}} -DOHOS_ARCH=arm64-v8a -DWARNINGS_ARE_ERRORS=OFF -DQT_QMAKE_TARGET_MKSPEC=ohos-clang -DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'TARGET_CMAKE_ARGS=-DOHOS_SDK_ROOT={{.Env.HARMONYOS_SDK_ROOT_CURRENT}}/sdk/default/openharmony -DOHOS_ARCH=arm64-v8a -DWARNINGS_ARE_ERRORS=OFF -DQT_QMAKE_TARGET_MKSPEC=ohos-clang -DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'NON_QTBASE_TARGET_CMAKE_ARGS=-DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'COMMON_TARGET_TEST_CMAKE_ARGS=-DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'QT_HARMONYOS_HVIGOR=/opt/harmonyos/command-line-tools/bin/hvigorw'
|
||||
'QT_HARMONYOS_HVIGOR={{.Env.HARMONYOS_SDK_ROOT_CURRENT}}/bin/hvigorw'
|
||||
]
|
||||
|
||||
@@ -10,7 +10,7 @@ Configurations:
|
||||
Platform dependency: [
|
||||
'rhel-9.6',
|
||||
'android-9-x86-on-linux',
|
||||
'android-16-x86_64-on-linux'
|
||||
'android-17-x86_64-on-linux'
|
||||
]
|
||||
Features: [
|
||||
'Sccache',
|
||||
@@ -24,7 +24,7 @@ Configurations:
|
||||
Environment variables: [
|
||||
'QT_CI_ARTIFACT_ID_PATH_Android-host=QT_CI_ARTIFACT_ID_PATH_rhel-9.6',
|
||||
'QT_CI_ARTIFACT_ID_PATH_Android-x86=QT_CI_ARTIFACT_ID_PATH_android-9-x86-on-linux',
|
||||
'QT_CI_ARTIFACT_ID_PATH_Android-x86_64=QT_CI_ARTIFACT_ID_PATH_android-16-x86_64-on-linux',
|
||||
'QT_CI_ARTIFACT_ID_PATH_Android-x86_64=QT_CI_ARTIFACT_ID_PATH_android-17-x86_64-on-linux',
|
||||
'COMMON_TARGET_TEST_CMAKE_ARGS=-DQT_ANDROID_ABIS="x86;x86_64"',
|
||||
'ANDROID_EMULATOR=emulator_x86_api_28'
|
||||
]
|
||||
|
||||
@@ -33,7 +33,7 @@ Configurations:
|
||||
Platform dependency: 'macos-universal-on-arm64'
|
||||
-
|
||||
Id: 'macos-15-x86_64-tests'
|
||||
Template: 'qtci-macos-15-x86_64-103'
|
||||
Template: 'qtci-macos-15-x86_64-104'
|
||||
Compiler: 'Clang'
|
||||
Features: ['Sccache', 'TestOnly', 'Packaging']
|
||||
Platform dependency: 'macos-universal-on-arm64'
|
||||
@@ -64,6 +64,13 @@ Configurations:
|
||||
Compiler: 'Clang'
|
||||
Features: ['Sccache', 'TestOnly', 'Packaging']
|
||||
Platform dependency: 'macos-universal-on-arm64'
|
||||
-
|
||||
Id: 'macos-27-arm64-tests'
|
||||
Template: 'qtci-macos-27-arm-101'
|
||||
Compiler: 'Clang'
|
||||
Features: ['Sccache', 'TestOnly', 'Packaging', 'DoNotAbortTestingOnFirstFailure']
|
||||
Platform dependency: 'macos-universal-on-arm64'
|
||||
Environment variables: [ 'COIN_CTEST_IGNORE_EXIT_CODE=1' ]
|
||||
|
||||
# =========================================================================
|
||||
# Developer build. Single architecture builds.
|
||||
@@ -126,3 +133,10 @@ Configurations:
|
||||
Compiler: 'Clang'
|
||||
Features: ['TestOnly']
|
||||
Platform dependency: 'macos-26-arm64-developer-build'
|
||||
-
|
||||
Id: 'macos-27-arm64-developer-build-tests'
|
||||
Template: 'qtci-macos-27-arm-101'
|
||||
Compiler: 'Clang'
|
||||
Features: ['TestOnly', 'DoNotAbortTestingOnFirstFailure']
|
||||
Platform dependency: 'macos-26-arm64-developer-build'
|
||||
Environment variables: [ 'COIN_CTEST_IGNORE_EXIT_CODE=1' ]
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
Version: 2
|
||||
Module only: True
|
||||
Include: [yocto.yaml]
|
||||
Configurations: []
|
||||
@@ -0,0 +1,4 @@
|
||||
Version: 2
|
||||
Module only: True
|
||||
Include: [yocto.yaml]
|
||||
Configurations: []
|
||||
@@ -4,7 +4,7 @@ Include: [
|
||||
'rhel-9.6'
|
||||
],
|
||||
cmake_platforms_target_android.yaml: [
|
||||
'android-15-x86_64-on-linux',
|
||||
'android-17-x86_64-on-linux',
|
||||
'android-9-x86-on-linux'
|
||||
]
|
||||
]
|
||||
@@ -12,14 +12,14 @@ Configurations: []
|
||||
# Android nightly to check for -qtnamespace errors/issues
|
||||
Overrides:
|
||||
-
|
||||
Id: 'android-15-x86_64-on-linux'
|
||||
Id: 'android-17-x86_64-on-linux'
|
||||
Features: ['Sccache', 'AndroidTestRun', 'VMSize8', 'UseConfigure']
|
||||
Environment variables: [
|
||||
'TARGET_CONFIGURE_ARGS=-qtnamespace TestNamespace -nomake examples -release -force-debug-info -android-ndk {{.Env.ANDROID_NDK_ROOT_LATEST}} -android-sdk {{.Env.ANDROID_SDK_ROOT}} -android-abis x86_64',
|
||||
'TARGET_CMAKE_ARGS=-DCMAKE_C_COMPILER_FRONTEND_VARIANT=GNU -DCMAKE_CXX_COMPILER_FRONTEND_VARIANT=GNU -DOPENSSL_ROOT_DIR={{.Env.OPENSSL_ANDROID_HOME_LATEST}} -DQT_GENERATE_WRAPPER_SCRIPTS_FOR_ALL_HOSTS=ON',
|
||||
'NON_QTBASE_TARGET_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR_ANDROID_X86_64_NDK_LATEST}} -DQT_DEPLOY_FFMPEG=TRUE -DQT_PROTOBUF_WELL_KNOWN_TYPES_PROTO_DIR=/usr/local/include',
|
||||
'ANDROID_NDK_ROOT={{.Env.ANDROID_NDK_ROOT_LATEST}}',
|
||||
'ANDROID_EMULATOR=emulator_x86_64_api_35'
|
||||
'ANDROID_EMULATOR=emulator_x86_64_api_37'
|
||||
]
|
||||
-
|
||||
Id: 'android-9-x86-on-linux'
|
||||
|
||||
@@ -5,7 +5,7 @@ Include: [
|
||||
'windows-11_24h2-mingw15'
|
||||
],
|
||||
cmake_platforms_target_android.yaml: [
|
||||
'android-15-x86_64-on-linux',
|
||||
'android-17-x86_64-on-linux',
|
||||
'android-9-x86-on-linux',
|
||||
'android-armv7-on-windows',
|
||||
'android-arm64-on-macos'
|
||||
@@ -18,14 +18,14 @@ Configurations: []
|
||||
# Android nightly to check for older (but still supported for the branch) NDKs
|
||||
Overrides:
|
||||
-
|
||||
Id: 'android-15-x86_64-on-linux'
|
||||
Id: 'android-17-x86_64-on-linux'
|
||||
Features: ['Sccache', 'AndroidTestRun', 'VMSize8', 'UseConfigure', 'WarningsAreErrors']
|
||||
Environment variables: [
|
||||
'TARGET_CONFIGURE_ARGS=-nomake examples -release -force-debug-info -android-ndk {{.Env.ANDROID_NDK_ROOT_NIGHTLY1}} -android-sdk {{.Env.ANDROID_SDK_ROOT}} -android-abis x86_64',
|
||||
'TARGET_CMAKE_ARGS=-DCMAKE_C_COMPILER_FRONTEND_VARIANT=GNU -DCMAKE_CXX_COMPILER_FRONTEND_VARIANT=GNU -DOPENSSL_ROOT_DIR={{.Env.OPENSSL_ANDROID_HOME_NIGHTLY1}} -DQT_GENERATE_WRAPPER_SCRIPTS_FOR_ALL_HOSTS=ON',
|
||||
'NON_QTBASE_TARGET_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR_ANDROID_X86_64_NDK_NIGHTLY1}} -DQT_DEPLOY_FFMPEG=TRUE -DQT_PROTOBUF_WELL_KNOWN_TYPES_PROTO_DIR=/usr/local/include',
|
||||
'ANDROID_NDK_ROOT={{.Env.ANDROID_NDK_ROOT_NIGHTLY1}}',
|
||||
'ANDROID_EMULATOR=emulator_x86_64_api_35'
|
||||
'ANDROID_EMULATOR=emulator_x86_64_api_37'
|
||||
]
|
||||
-
|
||||
Id: 'android-9-x86-on-linux'
|
||||
|
||||
@@ -5,7 +5,7 @@ Include: [
|
||||
'windows-11_24h2-mingw15'
|
||||
],
|
||||
cmake_platforms_target_android.yaml: [
|
||||
'android-15-x86_64-on-linux',
|
||||
'android-17-x86_64-on-linux',
|
||||
'android-9-x86-on-linux',
|
||||
'android-armv7-on-windows',
|
||||
'android-arm64-on-macos'
|
||||
@@ -18,14 +18,14 @@ Configurations: []
|
||||
# Android nightly to check for older (but still supported for the branch) NDKs
|
||||
Overrides:
|
||||
-
|
||||
Id: 'android-15-x86_64-on-linux'
|
||||
Id: 'android-17-x86_64-on-linux'
|
||||
Features: ['Sccache', 'AndroidTestRun', 'VMSize8', 'UseConfigure', 'WarningsAreErrors']
|
||||
Environment variables: [
|
||||
'TARGET_CONFIGURE_ARGS=-nomake examples -release -force-debug-info -android-ndk {{.Env.ANDROID_NDK_ROOT_NIGHTLY2}} -android-sdk {{.Env.ANDROID_SDK_ROOT}} -android-abis x86_64',
|
||||
'TARGET_CMAKE_ARGS=-DCMAKE_C_COMPILER_FRONTEND_VARIANT=GNU -DCMAKE_CXX_COMPILER_FRONTEND_VARIANT=GNU -DOPENSSL_ROOT_DIR={{.Env.OPENSSL_ANDROID_HOME_NIGHTLY2}} -DQT_GENERATE_WRAPPER_SCRIPTS_FOR_ALL_HOSTS=ON',
|
||||
'NON_QTBASE_TARGET_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR_ANDROID_X86_64_NDK_NIGHTLY2}} -DQT_DEPLOY_FFMPEG=TRUE -DQT_PROTOBUF_WELL_KNOWN_TYPES_PROTO_DIR=/usr/local/include',
|
||||
'ANDROID_NDK_ROOT={{.Env.ANDROID_NDK_ROOT_NIGHTLY2}}',
|
||||
'ANDROID_EMULATOR=emulator_x86_64_api_35'
|
||||
'ANDROID_EMULATOR=emulator_x86_64_api_37'
|
||||
]
|
||||
-
|
||||
Id: 'android-9-x86-on-linux'
|
||||
|
||||
@@ -4,7 +4,7 @@ Include: [
|
||||
'rhel-9.6'
|
||||
],
|
||||
cmake_platforms_target_android.yaml: [
|
||||
'android-16-x86_64-on-linux',
|
||||
'android-17-x86_64-on-linux',
|
||||
'android-9-x86-on-linux'
|
||||
]
|
||||
]
|
||||
@@ -12,14 +12,14 @@ Configurations: []
|
||||
# Android nightly to check for preview NDKs (beta/RC or a newer NDK than the _LATEST used in CI)
|
||||
Overrides:
|
||||
-
|
||||
Id: 'android-16-x86_64-on-linux'
|
||||
Id: 'android-17-x86_64-on-linux'
|
||||
Features: ['Sccache', 'AndroidTestRun', 'VMSize8', 'UseConfigure', 'WarningsAreErrors']
|
||||
Environment variables: [
|
||||
'TARGET_CONFIGURE_ARGS=-nomake examples -release -force-debug-info -android-ndk {{.Env.ANDROID_NDK_ROOT_PREVIEW}} -android-sdk {{.Env.ANDROID_SDK_ROOT}} -android-abis x86_64',
|
||||
'TARGET_CMAKE_ARGS=-DCMAKE_C_COMPILER_FRONTEND_VARIANT=GNU -DCMAKE_CXX_COMPILER_FRONTEND_VARIANT=GNU -DOPENSSL_ROOT_DIR={{.Env.OPENSSL_ANDROID_HOME_PREVIEW}} -DQT_GENERATE_WRAPPER_SCRIPTS_FOR_ALL_HOSTS=ON',
|
||||
'NON_QTBASE_TARGET_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR_ANDROID_X86_64_NDK_PREVIEW}} -DQT_DEPLOY_FFMPEG=TRUE -DQT_PROTOBUF_WELL_KNOWN_TYPES_PROTO_DIR=/usr/local/include',
|
||||
'ANDROID_NDK_ROOT={{.Env.ANDROID_NDK_ROOT_PREVIEW}}',
|
||||
'ANDROID_EMULATOR=emulator_x86_64_api_35'
|
||||
'ANDROID_EMULATOR=emulator_x86_64_api_37'
|
||||
]
|
||||
-
|
||||
Id: 'android-9-x86-on-linux'
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
Version: 2
|
||||
Module only: True
|
||||
Include: [
|
||||
macos.yaml: [
|
||||
"macos-universal-on-arm64"
|
||||
],
|
||||
cmake_platforms_target_harmonyos.yaml: [
|
||||
"harmonyos-23-arm64-on-macos-developer-build"
|
||||
]
|
||||
]
|
||||
Configurations: []
|
||||
Overrides:
|
||||
-
|
||||
Id: 'harmonyos-23-arm64-on-macos-developer-build'
|
||||
-Features: ['DoNotRunTests']
|
||||
@@ -0,0 +1,25 @@
|
||||
Version: 2
|
||||
Module only: True
|
||||
Include: [
|
||||
macos.yaml: [
|
||||
"macos-universal-on-arm64"
|
||||
]
|
||||
]
|
||||
|
||||
Configurations:
|
||||
-
|
||||
Id: 'harmonyos-23-arm64-on-macos'
|
||||
Template: 'qtci-macos-26-arm-105'
|
||||
Target os: 'HarmonyOS_ANY'
|
||||
Target arch: 'arm64'
|
||||
Compiler: 'Clang'
|
||||
Target compiler: 'Clang'
|
||||
Platform dependency: 'macos-universal-on-arm64'
|
||||
Features: ['Sccache', 'UseConfigure', 'StandaloneExamples']
|
||||
Environment variables: [
|
||||
'TARGET_CONFIGURE_ARGS=-release -make examples -no-dbus -no-use-gold-linker -no-pch -openssl-runtime',
|
||||
'TARGET_CMAKE_ARGS=-DOHOS_SDK_ROOT={{.Env.HARMONYOS_SDK_ROOT_CURRENT}}/sdk/default/openharmony -DOHOS_ARCH=arm64-v8a -DWARNINGS_ARE_ERRORS=OFF -DQT_QMAKE_TARGET_MKSPEC=ohos-clang -DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'NON_QTBASE_TARGET_CMAKE_ARGS=-DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'COMMON_TARGET_TEST_CMAKE_ARGS=-DCMAKE_FIND_ROOT_PATH={{.Env.VCPKG_OHOS_INSTALLED}}',
|
||||
'QT_HARMONYOS_HVIGOR={{.Env.HARMONYOS_SDK_ROOT_CURRENT}}/bin/hvigorw'
|
||||
]
|
||||
@@ -0,0 +1,24 @@
|
||||
Version: 2
|
||||
Module only: True
|
||||
Include: [
|
||||
cmake_platforms.yaml: [
|
||||
"ios-arm64-simulator"
|
||||
]
|
||||
]
|
||||
Configurations:
|
||||
-
|
||||
Id: 'ios-26-simulator-tests'
|
||||
Template: 'qtci-macos-26-arm-105'
|
||||
Compiler: 'Clang'
|
||||
Target os: 'IOS_ANY'
|
||||
Target arch: 'arm64'
|
||||
Platform dependency: 'ios-arm64-simulator'
|
||||
Features: ['TestOnly', 'Insignificant', 'DoNotAbortTestingOnFirstFailure']
|
||||
Environment variables: [
|
||||
'APPLE_SIMULATOR_DEVICE_TYPE=com.apple.CoreSimulator.SimDeviceType.iPad-Pro-13-inch-M4-8GB',
|
||||
]
|
||||
Overrides:
|
||||
-
|
||||
Id: 'ios-arm64-simulator'
|
||||
-Features: ['DisableTests']
|
||||
+Features: ['DoNotRunTests']
|
||||
@@ -22,7 +22,5 @@ Configurations:
|
||||
'QT_SYSROOT_FOR_RUNNING_TESTS=/opt/b2qt/imx8qm/sysroots/cortexa72-cortexa53-crypto-poky-linux',
|
||||
'GST_PLUGIN_SCANNER=/opt/b2qt/imx8qm/sysroots/cortexa72-cortexa53-crypto-poky-linux/usr/libexec/gstreamer-1.0/gst-plugin-scanner',
|
||||
'QT_QUICK_BACKEND=software',
|
||||
'VCPKG_HOST_TRIPLET=x64-linux-qt',
|
||||
'VCPKG_TARGET_TRIPLET=arm64-linux-qt'
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
Version: 2
|
||||
Module only: True
|
||||
Configurations:
|
||||
-
|
||||
Id: 'ubuntu-24.04-lcov'
|
||||
Template: 'qtci-linux-Ubuntu-24.04-x86_64-51'
|
||||
Compiler: 'GCC'
|
||||
Features: ['Sccache', 'UseConfigure', 'lcov', 'VMSize8', 'DisableTests']
|
||||
Configure arguments: '-developer-build -nomake examples -release -force-debug-info -separate-debug-info -headersclean -qt-libjpeg -qt-libpng -qt-pcre -qt-harfbuzz -qt-doubleconversion -no-libudev -bundled-xcb-xinput'
|
||||
Environment variables: [
|
||||
'CMAKE_ARGS=-DOpenGL_GL_PREFERENCE=LEGACY',
|
||||
'NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR}} -DINPUT_headersclean=ON'
|
||||
]
|
||||
|
||||
@@ -21,7 +21,7 @@ Configurations:
|
||||
Configure arguments: ''
|
||||
Environment variables: []
|
||||
-
|
||||
Template: 'qtci-macos-15-arm-105'
|
||||
Template: 'qtci-macos-26-arm-105'
|
||||
Compiler: 'Clang'
|
||||
Features: ['Sccache', 'DebugAndRelease']
|
||||
Configure arguments: ''
|
||||
@@ -55,7 +55,7 @@ Configurations:
|
||||
Configure arguments: ''
|
||||
Environment variables: []
|
||||
-
|
||||
Template: 'qtci-macos-15-arm-105'
|
||||
Template: 'qtci-macos-26-arm-105'
|
||||
Compiler: 'Clang'
|
||||
Features: ['Sccache', 'DebugAndRelease', 'OldestQt']
|
||||
Configure arguments: ''
|
||||
|
||||
@@ -5,7 +5,7 @@ Include: [
|
||||
'rhel-9.6'
|
||||
],
|
||||
cmake_platforms_target_android.yaml: [
|
||||
'android-15-x86_64-on-linux'
|
||||
'android-17-x86_64-on-linux'
|
||||
]
|
||||
]
|
||||
Configurations: []
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
Version: 2
|
||||
Include: [
|
||||
cmake_platforms.yaml,
|
||||
address_sanitizer_platforms.yaml
|
||||
]
|
||||
Configurations: []
|
||||
@@ -7,6 +7,7 @@ Include: [
|
||||
"ubuntu-22.04",
|
||||
"ubuntu-22.04-developer-build",
|
||||
"ubuntu-24.04-arm64",
|
||||
"ubuntu-24.04-x64",
|
||||
"opensuse-16.0-developer-build",
|
||||
"sles-15_sp6-static",
|
||||
"windows-10_22h2-msvc2022",
|
||||
|
||||
@@ -12,7 +12,7 @@ Include: [
|
||||
'android-arm64-on-macos',
|
||||
'android-armv7-on-windows',
|
||||
'android-9-x86-on-linux',
|
||||
'android-16-x86_64-on-linux'
|
||||
'android-17-x86_64-on-linux'
|
||||
],
|
||||
offline_documentation.yaml
|
||||
]
|
||||
|
||||
@@ -1,25 +1,17 @@
|
||||
Version: 2
|
||||
Include: [
|
||||
cmake_platforms.yaml: [
|
||||
'ubuntu-22.04',
|
||||
'ubuntu-22.04-x11-tests',
|
||||
'ubuntu-24.04-x64',
|
||||
'ubuntu-24.04-x64-x11-tests',
|
||||
'rhel-9.6',
|
||||
'rhel-10.0',
|
||||
'windows-11_24H2-msvc2022',
|
||||
'windows-11_24H2-msvc2026',
|
||||
'windows-11_24h2-mingw15',
|
||||
'windows-11_24H2-llvm'
|
||||
],
|
||||
macos.yaml: [
|
||||
'macos-universal-on-arm64',
|
||||
'macos-14-x86_64-tests',
|
||||
'macos-15-x86_64-tests',
|
||||
'macos-26-x86_64-tests',
|
||||
'macos-14-arm64-tests',
|
||||
'macos-15-arm64-tests',
|
||||
'macos-26-arm64-tests'
|
||||
tqtc-qtmcp.yaml: [
|
||||
'rhel-9.6-nohttp',
|
||||
'windows-11_24H2-msvc2022-nohttp',
|
||||
'windows-11_24h2-mingw15-nohttp',
|
||||
'windows-11_24H2-llvm-nohttp',
|
||||
'macos-universal-on-arm64-nohttp',
|
||||
'macos-14-x86_64-tests-nohttp',
|
||||
'macos-15-x86_64-tests-nohttp',
|
||||
'macos-26-x86_64-tests-nohttp',
|
||||
'macos-14-arm64-tests-nohttp',
|
||||
'macos-15-arm64-tests-nohttp',
|
||||
'macos-26-arm64-tests-nohttp'
|
||||
]
|
||||
]
|
||||
Configurations: []
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
Version: 2
|
||||
Include: [
|
||||
cmake_platforms.yaml: [
|
||||
'ubuntu-22.04',
|
||||
'ubuntu-24.04-x64',
|
||||
'ubuntu-24.04-arm64',
|
||||
'jammy-arm64-debian-pkg-packaging',
|
||||
'jammy-amd64-debian-pkg-packaging'
|
||||
],
|
||||
cmake_platforms_qemu.yaml: [
|
||||
'qemu-arm64-developer-build'
|
||||
]
|
||||
]
|
||||
Configurations: []
|
||||
Overrides:
|
||||
# Set pch off due to stale pch file causing false positive sccache hit
|
||||
-
|
||||
Id: 'ubuntu-22.04'
|
||||
-Features: ['DoNotRunTests']
|
||||
-Environment variables: ['NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR}} -DINPUT_headersclean=ON -DQT_DEPLOY_FFMPEG=TRUE']
|
||||
+Environment variables: ['NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR}} -DINPUT_headersclean=ON -DQT_DEPLOY_FFMPEG=TRUE -DQT_FEATURE_gstreamer_qt_api=ON -DBUILD_WITH_PCH=OFF']
|
||||
-
|
||||
Id: 'ubuntu-24.04-x64'
|
||||
-Features: ['DoNotRunTests']
|
||||
-Environment variables: ['NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR}} -DQT_DEPLOY_FFMPEG=TRUE -DINPUT_headersclean=ON']
|
||||
+Environment variables: ['NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR}} -DQT_DEPLOY_FFMPEG=TRUE -DINPUT_headersclean=ON -DQT_FEATURE_gstreamer_qt_api=ON -DBUILD_WITH_PCH=OFF']
|
||||
-
|
||||
Id: 'ubuntu-24.04-arm64'
|
||||
-Features: ['DoNotRunTests']
|
||||
-Environment variables: ['NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR}} -DQT_DEPLOY_FFMPEG=TRUE -DINPUT_headersclean=ON -DINPUT_tiff=qt -DINPUT_webp=qt']
|
||||
+Environment variables: ['NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR}} -DQT_DEPLOY_FFMPEG=TRUE -DINPUT_headersclean=ON -DINPUT_tiff=qt -DINPUT_webp=qt -DQT_FEATURE_gstreamer_qt_api=ON -DBUILD_WITH_PCH=OFF']
|
||||
-
|
||||
Id: 'jammy-arm64-debian-pkg-packaging'
|
||||
-Features: ['DisableTests']
|
||||
+Environment variables: ['NON_QTBASE_CMAKE_ARGS=-DQT_FEATURE_gstreamer_qt_api=ON -DBUILD_WITH_PCH=OFF']
|
||||
-
|
||||
Id: 'jammy-amd64-debian-pkg-packaging'
|
||||
-Features: ['DisableTests']
|
||||
+Environment variables: ['NON_QTBASE_CMAKE_ARGS=-DQT_FEATURE_gstreamer_qt_api=ON -DBUILD_WITH_PCH=OFF']
|
||||
-
|
||||
Id: 'qemu-arm64-developer-build'
|
||||
-Features: ['InsignificantTests']
|
||||
+Environment variables: ['NON_QTBASE_CMAKE_ARGS=-DQT_FEATURE_gstreamer_qt_api=ON -DBUILD_WITH_PCH=OFF']
|
||||
@@ -20,6 +20,122 @@ Include: [
|
||||
'macos-14-arm64-tests',
|
||||
'macos-15-arm64-tests',
|
||||
'macos-26-arm64-tests'
|
||||
]
|
||||
]
|
||||
]
|
||||
Configurations: []
|
||||
Overrides:
|
||||
-
|
||||
Id: 'rhel-(9\.6|10\.0)|windows-11_24H2-(msvc2022|llvm)|windows-11_24h2-mingw15|macos-universal-on-arm64|macos-(14|15|26)-(x86_64|arm64)-tests'
|
||||
-Features: ['Packaging']
|
||||
|
||||
Configurations:
|
||||
# RHEL 9.6
|
||||
-
|
||||
Id: 'rhel-9.6-nohttp'
|
||||
Template: 'qtci-linux-RHEL-9.6-x86_64-51'
|
||||
Compiler: 'GCC'
|
||||
Features: ['Packaging', 'Sccache', 'UseConfigure', 'InstallQt5Dependencies', 'GenerateSBOM', 'VerifySBOM']
|
||||
Configure arguments: '-nomake examples -release -force-debug-info -headersclean -separate-debug-info -qt-libjpeg -qt-libpng -qt-pcre -qt-harfbuzz -qt-doubleconversion -no-libudev -no-feature-liburing -bundled-xcb-xinput'
|
||||
Environment variables: [
|
||||
'CMAKE_ARGS=-DOpenGL_GL_PREFERENCE=LEGACY',
|
||||
'NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR}} -DQT_DEPLOY_FFMPEG=TRUE -DINPUT_headersclean=ON -DINPUT_tiff=qt -DINPUT_webp=qt -DQT_FEATURE_httpmcp=OFF',
|
||||
'VCPKG_HOST_TRIPLET=x64-linux-qt',
|
||||
'VCPKG_TARGET_TRIPLET=x64-linux-qt',
|
||||
]
|
||||
|
||||
# Windows 11 MSVC 2022
|
||||
-
|
||||
Id: 'windows-11_24H2-msvc2022-nohttp'
|
||||
Template: 'qtci-windows-11_24H2-x86_64-73'
|
||||
Compiler: 'MSVC2022'
|
||||
Features: ['Sccache', 'Packaging', "DebugAndRelease", 'UseConfigure', 'GenerateSBOM', 'VerifySBOM']
|
||||
Configure arguments: '-debug-and-release -force-debug-info -headersclean -nomake examples -qt-zlib'
|
||||
Environment variables: [
|
||||
'CMAKE_ARGS=-DFEATURE_msvc_obj_debug_info=ON -DOPENSSL_ROOT_DIR={{.Env.OPENSSL_ROOT_DIR_x64}}\.. -DPostgreSQL_ROOT={{.Env.POSTGRESQL_LIB_x64}}\..',
|
||||
'NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR_MSVC}} -DQT_DEPLOY_FFMPEG=TRUE -DFEATURE_clangcpp=OFF -DINPUT_headersclean=ON -DQT_FEATURE_httpmcp=OFF',
|
||||
'LLVM_INSTALL_DIR={{.Env.LLVM_INSTALL_DIR_msvc}}',
|
||||
'VCPKG_HOST_TRIPLET=x64-windows-qt',
|
||||
'VCPKG_TARGET_TRIPLET=x64-windows-qt',
|
||||
'Protobuf_ROOT={{.Env.Protobuf_ROOT_msvc}}',
|
||||
'WEBVIEW2_SDK_ROOT={{.Env.WEBVIEW2_SDK_ROOT_PATH}}',
|
||||
]
|
||||
|
||||
# Windows 11 MinGW 15
|
||||
-
|
||||
Id: 'windows-11_24h2-mingw15-nohttp'
|
||||
Template: 'qtci-windows-11_24H2-x86_64-73'
|
||||
Compiler: 'Mingw'
|
||||
Features: ['Packaging', 'Sccache', 'UseConfigure', 'GenerateSBOM', 'VerifySBOM']
|
||||
Configure arguments: '-release -force-debug-info -separate-debug-info -nomake examples'
|
||||
Environment variables: [
|
||||
'Path={{.Env.MINGW_PATH}}\bin;{{.Env.Path}}',
|
||||
'CMAKE_ARGS=-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DOPENSSL_ROOT_DIR={{.Env.OPENSSL_INCLUDE_x64}}\.. -DPostgreSQL_ROOT={{.Env.POSTGRESQL_LIB_x64}}\.. -DCMAKE_IGNORE_PREFIX_PATH=C:/strawberry/c',
|
||||
'NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR_MINGW}} -DQT_DEPLOY_FFMPEG=TRUE -DCMAKE_IGNORE_PREFIX_PATH=C:/strawberry/c -DQT_FEATURE_httpmcp=OFF',
|
||||
'LLVM_INSTALL_DIR={{.Env.LLVM_INSTALL_DIR_mingw}}',
|
||||
'Protobuf_ROOT={{.Env.Protobuf_ROOT_mingw}}',
|
||||
]
|
||||
|
||||
# Windows 11 LLVM-MinGW
|
||||
-
|
||||
Id: 'windows-11_24H2-llvm-nohttp'
|
||||
Template: 'qtci-windows-11_24H2-x86_64-73'
|
||||
Compiler: 'Clang'
|
||||
Features: ['Sccache', 'Packaging', 'UseConfigure', 'GenerateSBOM', 'VerifySBOM']
|
||||
Configure arguments: '-release -force-debug-info -separate-debug-info -nomake examples'
|
||||
Environment variables: [
|
||||
'Path=C:\llvm-mingw\bin;{{.Env.Path}}',
|
||||
'CMAKE_ARGS=-DOPENSSL_ROOT_DIR={{.Env.OPENSSL_INCLUDE_x64}}\.. -DPostgreSQL_ROOT={{.Env.POSTGRESQL_LIB_x64}}\.. -DCMAKE_IGNORE_PREFIX_PATH=C:/strawberry/c',
|
||||
'NON_QTBASE_CMAKE_ARGS=-DFFMPEG_DIR={{.Env.FFMPEG_DIR_LLVM_MINGW}} -DQT_DEPLOY_FFMPEG=TRUE -DCMAKE_IGNORE_PREFIX_PATH=C:/strawberry/c -DQT_FEATURE_httpmcp=OFF',
|
||||
'LLVM_INSTALL_DIR={{.Env.LLVM_INSTALL_DIR_llvm_mingw}}',
|
||||
'Protobuf_ROOT={{.Env.Protobuf_ROOT_llvm_mingw}}',
|
||||
]
|
||||
|
||||
# macOS universal build, tested on all supported macOS versions
|
||||
-
|
||||
Id: 'macos-universal-on-arm64-nohttp'
|
||||
Template: 'qtci-macos-26-arm-105'
|
||||
Compiler: 'Clang'
|
||||
Target arch: 'x86_64-arm64'
|
||||
Features: ['Sccache', 'Packaging', 'DoNotRunTests', 'WarningsAreErrors', 'UseConfigure', 'GenerateSBOM', 'VerifySBOM']
|
||||
Configure arguments: '-nomake examples -release -force-debug-info -separate-debug-info -headersclean -framework'
|
||||
Environment variables: [
|
||||
'CMAKE_ARGS=-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -DOPENSSL_ROOT_DIR={{.Env.OPENSSL_DIR}}',
|
||||
'NON_QTBASE_CMAKE_ARGS=-DFEATURE_gds=OFF -DFFMPEG_DIR={{.Env.FFMPEG_DIR}} -DQT_DEPLOY_FFMPEG=TRUE -DINPUT_headersclean=ON -DQT_FEATURE_open62541_security=OFF -DQT_FEATURE_httpmcp=OFF',
|
||||
'VCPKG_HOST_TRIPLET=universal-osx-qt',
|
||||
'VCPKG_TARGET_TRIPLET=universal-osx-qt',
|
||||
]
|
||||
-
|
||||
Id: 'macos-14-x86_64-tests-nohttp'
|
||||
Template: 'qtci-macos-14-x86_64-106'
|
||||
Compiler: 'Clang'
|
||||
Features: ['Sccache', 'TestOnly', 'Packaging']
|
||||
Platform dependency: 'macos-universal-on-arm64-nohttp'
|
||||
-
|
||||
Id: 'macos-15-x86_64-tests-nohttp'
|
||||
Template: 'qtci-macos-15-x86_64-104'
|
||||
Compiler: 'Clang'
|
||||
Features: ['Sccache', 'TestOnly', 'Packaging']
|
||||
Platform dependency: 'macos-universal-on-arm64-nohttp'
|
||||
-
|
||||
Id: 'macos-26-x86_64-tests-nohttp'
|
||||
Template: 'qtci-macos-26-x86_64-103'
|
||||
Compiler: 'Clang'
|
||||
Features: ['Sccache', 'TestOnly', 'Packaging']
|
||||
Platform dependency: 'macos-universal-on-arm64-nohttp'
|
||||
-
|
||||
Id: 'macos-14-arm64-tests-nohttp'
|
||||
Template: 'qtci-macos-14-arm-108'
|
||||
Compiler: 'Clang'
|
||||
Features: ['Sccache', 'TestOnly', 'Packaging']
|
||||
Platform dependency: 'macos-universal-on-arm64-nohttp'
|
||||
-
|
||||
Id: 'macos-15-arm64-tests-nohttp'
|
||||
Template: 'qtci-macos-15-arm-105'
|
||||
Compiler: 'Clang'
|
||||
Features: ['Sccache', 'TestOnly', 'Packaging']
|
||||
Platform dependency: 'macos-universal-on-arm64-nohttp'
|
||||
-
|
||||
Id: 'macos-26-arm64-tests-nohttp'
|
||||
Template: 'qtci-macos-26-arm-105'
|
||||
Compiler: 'Clang'
|
||||
Features: ['Sccache', 'TestOnly', 'Packaging']
|
||||
Platform dependency: 'macos-universal-on-arm64-nohttp'
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
# Distribution-specific build settings.
|
||||
# For another distro/version, copy the bundle and change these values first.
|
||||
|
||||
DISTRO_NAME="ubuntu"
|
||||
DISTRO_VERSION="26.04"
|
||||
ISO_PATH="/tmp/ubuntu-26.04.1-desktop-arm64.iso"
|
||||
# ISO_CHECKSUM_FILE="/tmp/SHA256SUMS"
|
||||
|
||||
# Usually reusable without changes.
|
||||
IMAGE_PREFIX="qtci-linux"
|
||||
ARCH="aarch64"
|
||||
MINIMAL_INDEX="50"
|
||||
CUSTOM_INDEX="51"
|
||||
DISK_SIZE="500G"
|
||||
CPUS="8"
|
||||
MEMORY_MB="16184"
|
||||
SSH_USERNAME="qt"
|
||||
SSH_PASSWORD="$(cat /tmp/PASS)"
|
||||
|
||||
PROJECT_DIR="/tmp/packer-linux"
|
||||
ARTIFACT_DIR="/tmp/output-linux-images"
|
||||
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=build-config.sh
|
||||
source "${script_dir}/build-config.sh"
|
||||
|
||||
image_base_name="${IMAGE_PREFIX}-${DISTRO_NAME}-${DISTRO_VERSION}-${ARCH}"
|
||||
image_50_name="${image_base_name}-${MINIMAL_INDEX}"
|
||||
image_51_name="${image_base_name}-${CUSTOM_INDEX}"
|
||||
image_50="${ARTIFACT_DIR}/${image_50_name}"
|
||||
image_51="${ARTIFACT_DIR}/${image_51_name}"
|
||||
image_50_vars="${ARTIFACT_DIR}/${image_50_name}_VARS.fd"
|
||||
image_51_vars="${ARTIFACT_DIR}/${image_51_name}_VARS.fd"
|
||||
image_51_seed="/tmp/${image_51_name}-seed.qcow2"
|
||||
stage_50_output="/tmp/packer-output-${MINIMAL_INDEX}"
|
||||
stage_51_output="/tmp/packer-output-${CUSTOM_INDEX}"
|
||||
template="linux-image.pkr.hcl"
|
||||
|
||||
# Pass one source of configuration into Packer without duplicating distro and
|
||||
# version literals in HCL or a second variable file.
|
||||
export PKR_VAR_distro_name="$DISTRO_NAME"
|
||||
export PKR_VAR_distro_version="$DISTRO_VERSION"
|
||||
export PKR_VAR_image_prefix="$IMAGE_PREFIX"
|
||||
export PKR_VAR_arch="$ARCH"
|
||||
export PKR_VAR_minimal_index="$MINIMAL_INDEX"
|
||||
export PKR_VAR_custom_index="$CUSTOM_INDEX"
|
||||
export PKR_VAR_iso_path="$ISO_PATH"
|
||||
# export PKR_VAR_iso_checksum_file="$ISO_CHECKSUM_FILE"
|
||||
export PKR_VAR_project_dir="$PROJECT_DIR"
|
||||
export PKR_VAR_artifact_dir="$ARTIFACT_DIR"
|
||||
export PKR_VAR_disk_size="$DISK_SIZE"
|
||||
export PKR_VAR_cpus="$CPUS"
|
||||
export PKR_VAR_memory_mb="$MEMORY_MB"
|
||||
export PKR_VAR_ssh_username="$SSH_USERNAME"
|
||||
export PKR_VAR_ssh_password="$SSH_PASSWORD"
|
||||
|
||||
if [[ "$script_dir" != "$PROJECT_DIR" ]]; then
|
||||
echo "ERROR: Bundle is at '$script_dir', but PROJECT_DIR is '$PROJECT_DIR'." >&2
|
||||
echo "Move/extract it there or update PROJECT_DIR in build-config.sh." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for required_file in $ISO_PATH; do
|
||||
if [[ ! -f "$required_file" ]]; then
|
||||
echo "ERROR: Required file is missing: $required_file" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Stage 51 is always regenerated. Stage 50 is retained
|
||||
rm -rf "$stage_50_output" "$stage_51_output"
|
||||
rm -f "$image_51" "$image_51_seed"
|
||||
rm -f "${image_51}.sha256"
|
||||
|
||||
packer init "$template"
|
||||
packer validate "$template"
|
||||
|
||||
if [[ -f "$image_50" ]]; then
|
||||
echo "Stage ${MINIMAL_INDEX}: existing image found:"
|
||||
echo " $image_50"
|
||||
echo "Validating existing image before skipping the build..."
|
||||
|
||||
if ! qemu-img check "$image_50"; then
|
||||
echo "ERROR: Existing stage-${MINIMAL_INDEX} image failed validation:" >&2
|
||||
echo " $image_50" >&2
|
||||
echo "The image was not deleted or overwritten." >&2
|
||||
echo "Remove it manually" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Stage ${MINIMAL_INDEX}: image is valid, skipping Packer build."
|
||||
sha256sum "$image_50" > "${image_50}.sha256"
|
||||
|
||||
else
|
||||
echo "Stage ${MINIMAL_INDEX}: no existing image found, starting Packer."
|
||||
|
||||
PACKER_LOG=1 \
|
||||
PACKER_LOG_PATH="/tmp/packer-stage-${MINIMAL_INDEX}.log" \
|
||||
packer build -only=stage-50.qemu.stage_50 "$template"
|
||||
|
||||
qemu-img check "$image_50"
|
||||
sha256sum "$image_50" > "${image_50}.sha256"
|
||||
fi
|
||||
|
||||
echo "Creating independent stage-${CUSTOM_INDEX} seed..."
|
||||
qemu-img convert -p -f qcow2 -O qcow2 "$image_50" "$image_51_seed"
|
||||
qemu-img check "$image_51_seed"
|
||||
|
||||
PACKER_LOG=1 \
|
||||
PACKER_LOG_PATH="/tmp/packer-stage-${CUSTOM_INDEX}.log" \
|
||||
packer build -only=stage-51.qemu.stage_51 "$template"
|
||||
|
||||
qemu-img check "$image_51"
|
||||
sha256sum "$image_51" > "${image_51}.sha256"
|
||||
|
||||
(
|
||||
cd "$ARTIFACT_DIR"
|
||||
sha256sum --check "$(basename "${image_50}.sha256")"
|
||||
)
|
||||
|
||||
# Stage 50 may have been skipped because its image already existed. In that
|
||||
# case its temporary efivars.fd was removed at startup, so use a separate copy
|
||||
# of the Stage 51 variable store for the cloned image.
|
||||
stage_51_vars="${stage_51_output}/efivars.fd"
|
||||
if [[ ! -f "$stage_51_vars" ]]; then
|
||||
echo "ERROR: Stage ${CUSTOM_INDEX} UEFI variable store is missing:" >&2
|
||||
echo " $stage_51_vars" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -f "${stage_50_output}/efivars.fd" ]]; then
|
||||
stage_50_vars="${stage_50_output}/efivars.fd"
|
||||
else
|
||||
stage_50_vars="$stage_51_vars"
|
||||
echo "Stage ${MINIMAL_INDEX} UEFI variable store was not retained; using a separate copy of:"
|
||||
echo " $stage_51_vars"
|
||||
fi
|
||||
|
||||
cp "$stage_50_vars" "$image_50_vars"
|
||||
cp "$stage_51_vars" "$image_51_vars"
|
||||
|
||||
rm -f "$image_51_seed"
|
||||
|
||||
echo
|
||||
echo "Created independent images:"
|
||||
echo " $image_50"
|
||||
echo " $image_51"
|
||||
echo "UEFI variable stores:"
|
||||
echo " $image_50_vars"
|
||||
echo " $image_51_vars"
|
||||
echo "Checksums:"
|
||||
echo " ${image_50}.sha256"
|
||||
echo " ${image_51}.sha256"
|
||||
@@ -0,0 +1,2 @@
|
||||
instance-id: qtci-ubuntu26-packer
|
||||
local-hostname: qtci-ubuntu26-arm64
|
||||
@@ -0,0 +1,22 @@
|
||||
#cloud-config
|
||||
# This file is installer/distribution-specific. The generic HCL and wrapper can
|
||||
# be reused, but replace this file for a distro that does not use autoinstall.
|
||||
autoinstall:
|
||||
version: 1
|
||||
source:
|
||||
id: ubuntu-desktop-minimal
|
||||
locale: en_US.UTF-8
|
||||
keyboard:
|
||||
layout: us
|
||||
timezone: UTC
|
||||
identity:
|
||||
hostname: qtci-ubuntu26-arm64
|
||||
username: qt
|
||||
password: "$6$qtciubuntu2604$FAeHIUtg1iOarKFnnDZim5fWEJ6ZaaYXSc360m68XFTqurIBWNBxsmUDKj.8mGJkVDKlWjFdKZLfrqHYhuBH8/"
|
||||
ssh:
|
||||
install-server: true
|
||||
allow-pw: true
|
||||
storage:
|
||||
layout:
|
||||
name: direct
|
||||
shutdown: reboot
|
||||
@@ -0,0 +1,214 @@
|
||||
packer {
|
||||
required_version = ">= 1.14.0"
|
||||
|
||||
required_plugins {
|
||||
qemu = {
|
||||
version = "~> 1"
|
||||
source = "github.com/hashicorp/qemu"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "distro_name" {
|
||||
type = string
|
||||
}
|
||||
variable "distro_version" {
|
||||
type = string
|
||||
}
|
||||
variable "image_prefix" {
|
||||
type = string
|
||||
}
|
||||
variable "arch" {
|
||||
type = string
|
||||
}
|
||||
variable "minimal_index" {
|
||||
type = string
|
||||
}
|
||||
variable "custom_index" {
|
||||
type = string
|
||||
}
|
||||
variable "iso_path" {
|
||||
type = string
|
||||
}
|
||||
variable "project_dir" {
|
||||
type = string
|
||||
}
|
||||
variable "artifact_dir" {
|
||||
type = string
|
||||
}
|
||||
variable "disk_size" {
|
||||
type = string
|
||||
}
|
||||
variable "cpus" {
|
||||
type = number
|
||||
}
|
||||
variable "memory_mb" {
|
||||
type = number
|
||||
}
|
||||
variable "ssh_username" {
|
||||
type = string
|
||||
}
|
||||
variable "ssh_password" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
locals {
|
||||
image_base_name = "${var.image_prefix}-${var.distro_name}-${var.distro_version}-${var.arch}"
|
||||
image_50_name = "${local.image_base_name}-${var.minimal_index}"
|
||||
image_51_name = "${local.image_base_name}-${var.custom_index}"
|
||||
|
||||
image_50_path = "${var.artifact_dir}/${local.image_50_name}"
|
||||
image_51_path = "${var.artifact_dir}/${local.image_51_name}"
|
||||
image_51_seed = "/tmp/${local.image_51_name}-seed.qcow2"
|
||||
|
||||
stage_50_output = "/tmp/packer-output-${var.minimal_index}"
|
||||
stage_51_output = "/tmp/packer-output-${var.custom_index}"
|
||||
}
|
||||
|
||||
source "qemu" "stage_50" {
|
||||
vm_name = local.image_50_name
|
||||
output_directory = local.stage_50_output
|
||||
|
||||
iso_url = var.iso_path
|
||||
iso_checksum = "none"
|
||||
|
||||
accelerator = "kvm"
|
||||
qemu_binary = "qemu-system-aarch64"
|
||||
machine_type = "virt,gic-version=max"
|
||||
efi_boot = true
|
||||
efi_firmware_code = "/usr/share/AAVMF/AAVMF_CODE.fd"
|
||||
efi_firmware_vars = "/usr/share/AAVMF/AAVMF_VARS.fd"
|
||||
qemuargs = [
|
||||
["-device", "ramfb"],
|
||||
["-device", "nec-usb-xhci,id=usb"],
|
||||
["-device", "usb-kbd,bus=usb.0"],
|
||||
["-monitor", "none"],
|
||||
["-serial", "file:/tmp/packer-stage-50-serial.log"]
|
||||
]
|
||||
format = "qcow2"
|
||||
disk_size = var.disk_size
|
||||
disk_interface = "virtio"
|
||||
net_device = "virtio-net"
|
||||
|
||||
cpus = var.cpus
|
||||
memory = var.memory_mb
|
||||
|
||||
communicator = "ssh"
|
||||
ssh_username = var.ssh_username
|
||||
ssh_password = var.ssh_password
|
||||
ssh_timeout = "60m"
|
||||
ssh_handshake_attempts = 100
|
||||
|
||||
http_directory = "${var.project_dir}/http"
|
||||
boot_wait = "20s"
|
||||
|
||||
# This boot sequence is installer-family-specific. Replace it when adapting
|
||||
# the bundle to a distro that does not use Ubuntu/Subiquity autoinstall.
|
||||
boot_command = [
|
||||
"<esc><wait>c<wait>",
|
||||
"linux /casper/vmlinuz autoinstall ds=nocloud-net\\;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ console=ttyAMA0,115200n8 ---<enter><wait>",
|
||||
"initrd /casper/initrd<enter><wait>",
|
||||
"boot<enter>"
|
||||
]
|
||||
|
||||
headless = true
|
||||
vnc_bind_address = "0.0.0.0"
|
||||
shutdown_command = "echo '${var.ssh_password}' | sudo -S shutdown -P now"
|
||||
}
|
||||
|
||||
source "qemu" "stage_51" {
|
||||
vm_name = local.image_51_name
|
||||
output_directory = local.stage_51_output
|
||||
|
||||
# build-images.sh creates this independent seed from immutable image -50.
|
||||
iso_url = local.image_51_seed
|
||||
iso_checksum = "none"
|
||||
disk_image = true
|
||||
|
||||
accelerator = "kvm"
|
||||
qemu_binary = "qemu-system-aarch64"
|
||||
machine_type = "virt,gic-version=max"
|
||||
efi_boot = true
|
||||
efi_firmware_code = "/usr/share/AAVMF/AAVMF_CODE.fd"
|
||||
efi_firmware_vars = "/usr/share/AAVMF/AAVMF_VARS.fd"
|
||||
qemuargs = [
|
||||
["-device", "ramfb"],
|
||||
["-device", "nec-usb-xhci,id=usb"],
|
||||
["-device", "usb-kbd,bus=usb.0"],
|
||||
["-monitor", "none"], # prevents Packer boot keystrokes from being interpreted as QEMU monitor commands.
|
||||
["-serial", "file:/tmp/packer-stage-51-serial.log"]
|
||||
]
|
||||
format = "qcow2"
|
||||
disk_size = var.disk_size
|
||||
disk_interface = "virtio"
|
||||
net_device = "virtio-net"
|
||||
|
||||
cpus = var.cpus
|
||||
memory = var.memory_mb
|
||||
|
||||
communicator = "ssh"
|
||||
ssh_username = var.ssh_username
|
||||
ssh_password = var.ssh_password
|
||||
ssh_timeout = "30m"
|
||||
ssh_handshake_attempts = 100
|
||||
|
||||
headless = true
|
||||
vnc_bind_address = "0.0.0.0"
|
||||
shutdown_command = "echo '${var.ssh_password}' | sudo -S shutdown -P now"
|
||||
}
|
||||
|
||||
build {
|
||||
name = "stage-50"
|
||||
sources = ["source.qemu.stage_50"]
|
||||
|
||||
provisioner "shell" {
|
||||
execute_command = "echo '${var.ssh_password}' | {{ .Vars }} sudo -S -E bash '{{ .Path }}'"
|
||||
script = "${var.project_dir}/scripts/01-minimal-50.sh"
|
||||
}
|
||||
|
||||
post-processor "shell-local" {
|
||||
inline = [
|
||||
"mkdir -p '${var.artifact_dir}'",
|
||||
"rm -f '${local.image_50_path}'",
|
||||
"mv '${local.stage_50_output}/${local.image_50_name}' '${local.image_50_path}'",
|
||||
"qemu-img check '${local.image_50_path}'",
|
||||
"qemu-img info '${local.image_50_path}'"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
build {
|
||||
name = "stage-51"
|
||||
sources = ["source.qemu.stage_51"]
|
||||
|
||||
provisioner "shell" {
|
||||
execute_command = "echo '${var.ssh_password}' | {{ .Vars }} sudo -S -E bash '{{ .Path }}'"
|
||||
script = "${var.project_dir}/scripts/02-coin-configuration-51.sh"
|
||||
}
|
||||
|
||||
provisioner "shell" {
|
||||
execute_command = "echo '${var.ssh_password}' | {{ .Vars }} sudo -S -E bash '{{ .Path }}'"
|
||||
script = "${var.project_dir}/scripts/03-gnome-configuration-51.sh"
|
||||
}
|
||||
|
||||
provisioner "shell" {
|
||||
execute_command = "echo '${var.ssh_password}' | {{ .Vars }} sudo -S -E bash '{{ .Path }}'"
|
||||
script = "${var.project_dir}/scripts/04-no-overview-extension-51.sh"
|
||||
}
|
||||
|
||||
provisioner "shell" {
|
||||
execute_command = "echo '${var.ssh_password}' | {{ .Vars }} sudo -S -E bash '{{ .Path }}'"
|
||||
script = "${var.project_dir}/scripts/05-check-configurations-51.sh"
|
||||
}
|
||||
|
||||
post-processor "shell-local" {
|
||||
inline = [
|
||||
"mkdir -p '${var.artifact_dir}'",
|
||||
"rm -f '${local.image_51_path}'",
|
||||
"mv '${local.stage_51_output}/${local.image_51_name}' '${local.image_51_path}'",
|
||||
"qemu-img check '${local.image_51_path}'",
|
||||
"qemu-img info '${local.image_51_path}'"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# This script is run on the minimal -50 image
|
||||
# Other scripts will be run on the -50 -> -51 cloned image
|
||||
|
||||
readonly CI_USER="${CI_USER:-qt}"
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Debian/Ubuntu implementation. Replace this script with the distro's package
|
||||
# manager commands when reusing the generic wrapper and HCL elsewhere.
|
||||
apt-get update
|
||||
apt-get -y full-upgrade
|
||||
apt-get install -y qemu-guest-agent
|
||||
systemctl enable qemu-guest-agent
|
||||
|
||||
dpkg-query -W -f='${binary:Package}\t${Version}\n' \
|
||||
> /var/tmp/qtci-minimal-image-packages.txt
|
||||
|
||||
apt-get -y autoremove
|
||||
apt-get clean
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
qemu-ga --version
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Initial Coin configuration for the customized image (-51).
|
||||
|
||||
readonly CI_USER="${CI_USER:-qt}"
|
||||
readonly GRUB_GFXMODE_VALUE="${GRUB_GFXMODE_VALUE:-1280x800}"
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
log() {
|
||||
printf '\n[51-coin-configuration] %s\n' "$*"
|
||||
}
|
||||
|
||||
require_root() {
|
||||
if [[ "${EUID}" -ne 0 ]]; then
|
||||
echo "ERROR: This script must run as root." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
require_user() {
|
||||
if ! id "$CI_USER" >/dev/null 2>&1; then
|
||||
echo "ERROR: Required CI user does not exist: $CI_USER" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
require_root
|
||||
require_user
|
||||
|
||||
log "Installing required base packages"
|
||||
apt-get update
|
||||
apt-get install -y \
|
||||
openssh-server \
|
||||
ufw
|
||||
|
||||
# Remove GNOME welcome window at boot
|
||||
log "Removing gnome-initial-setup"
|
||||
apt-get purge -y gnome-initial-setup
|
||||
|
||||
# No sudo PW
|
||||
log "Configuring passwordless sudo for ${CI_USER}"
|
||||
cat > "/etc/sudoers.d/${CI_USER}" <<EOF
|
||||
${CI_USER} ALL=(ALL) NOPASSWD: ALL
|
||||
EOF
|
||||
chmod 0440 "/etc/sudoers.d/${CI_USER}"
|
||||
visudo --check
|
||||
|
||||
# UTC
|
||||
log "Setting the system timezone to UTC"
|
||||
timedatectl set-timezone UTC
|
||||
|
||||
# Enable SSH
|
||||
log "Enabling SSH"
|
||||
# Current Ubuntu releases may use socket activation. Enabling both units is
|
||||
# harmless and keeps the image compatible with service- and socket-based SSH.
|
||||
systemctl enable ssh.service
|
||||
systemctl enable ssh.socket 2>/dev/null || true
|
||||
|
||||
# Enable QEMU GA
|
||||
log "Enabling QEMU guest agent"
|
||||
systemctl enable qemu-guest-agent
|
||||
|
||||
# Disable firewall
|
||||
log "Disabling UFW"
|
||||
ufw --force disable
|
||||
systemctl disable ufw.service 2>/dev/null || true
|
||||
|
||||
# Set resolution
|
||||
log "Configuring GRUB graphics mode: ${GRUB_GFXMODE_VALUE}"
|
||||
if grep -qE '^GRUB_GFXMODE=' /etc/default/grub; then
|
||||
sed -i "s/^GRUB_GFXMODE=.*/GRUB_GFXMODE=${GRUB_GFXMODE_VALUE}/" /etc/default/grub
|
||||
else
|
||||
printf '\nGRUB_GFXMODE=%s\n' "$GRUB_GFXMODE_VALUE" >> /etc/default/grub
|
||||
fi
|
||||
update-grub
|
||||
|
||||
# Disable auto upgrade/update
|
||||
log "Disabling periodic APT update checks"
|
||||
cat > /etc/apt/apt.conf.d/99-qtci-no-periodic-updates << EOF
|
||||
APT::Periodic "0";
|
||||
APT::Periodic::Update-Package-Lists "0";
|
||||
APT::Periodic::Download-Upgradeable-Packages "0";
|
||||
APT::Periodic::AutocleanInterval "0";
|
||||
APT::Periodic::Unattended-Upgrade "0";
|
||||
EOF
|
||||
|
||||
sudo systemctl disable --now \
|
||||
apt-daily.timer \
|
||||
apt-daily-upgrade.timer
|
||||
|
||||
sudo systemctl mask \
|
||||
apt-daily.service \
|
||||
apt-daily-upgrade.service \
|
||||
apt-daily.timer \
|
||||
apt-daily-upgrade.timer
|
||||
|
||||
log "Disabling release-upgrade notifications"
|
||||
if [[ -f /etc/update-manager/release-upgrades ]]; then
|
||||
if grep -qE '^Prompt=' /etc/update-manager/release-upgrades; then
|
||||
sed -i 's/^Prompt=.*/Prompt=never/' \
|
||||
/etc/update-manager/release-upgrades
|
||||
else
|
||||
printf '\nPrompt=never\n' >> /etc/update-manager/release-upgrades
|
||||
fi
|
||||
fi
|
||||
|
||||
# GDM Auto login
|
||||
log "Configuring GDM for ${CI_USER}"
|
||||
if [[ -d /etc/gdm3 ]]; then
|
||||
gdm_config="/etc/gdm3/custom.conf"
|
||||
touch "$gdm_config"
|
||||
|
||||
if ! grep -qE '^\[daemon\]' "$gdm_config"; then
|
||||
printf '\n[daemon]\n' >> "$gdm_config"
|
||||
fi
|
||||
sed -i \
|
||||
'/^AutomaticLoginEnable=/d; /^AutomaticLogin=/d; /^InitialSetupEnable=/d' \
|
||||
"$gdm_config"
|
||||
sed -i \
|
||||
"/^\[daemon\]/a InitialSetupEnable=False\nAutomaticLogin=${CI_USER}\nAutomaticLoginEnable=True" \
|
||||
"$gdm_config"
|
||||
else
|
||||
log "GDM is not installed; skipping GDM configuration"
|
||||
fi
|
||||
|
||||
# Run Coin-setup
|
||||
log "Downloading and running coin-setup"
|
||||
|
||||
coin_setup_url="https://ci-files01-hki.ci.qt.io/input/linux/coin-setup-linux-arm64.zip"
|
||||
coin_setup_zip="/tmp/coin-setup-linux-arm64.zip"
|
||||
coin_setup_dir="/tmp/coin-setup-linux-arm64"
|
||||
coin_setup_binary="${coin_setup_dir}/coin-setup"
|
||||
|
||||
rm -rf "$coin_setup_dir"
|
||||
rm -f "$coin_setup_zip"
|
||||
mkdir -p "$coin_setup_dir"
|
||||
|
||||
wget --quiet --output-document="$coin_setup_zip" "$coin_setup_url"
|
||||
|
||||
unzip -q "$coin_setup_zip" -d "$coin_setup_dir"
|
||||
|
||||
if [[ ! -f "$coin_setup_binary" ]]; then
|
||||
echo "ERROR: coin-setup binary was not found at ${coin_setup_binary}" >&2
|
||||
echo "Archive contents:" >&2
|
||||
unzip -l "$coin_setup_zip" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
chmod 0755 "$coin_setup_binary"
|
||||
|
||||
sudo -H -u "$CI_USER" "$coin_setup_binary"
|
||||
|
||||
rm -rf "$coin_setup_dir"
|
||||
rm -f "$coin_setup_zip"
|
||||
|
||||
log "coin-setup completed successfully"
|
||||
|
||||
# Clean apt
|
||||
log "Cleaning APT metadata"
|
||||
apt-get clean
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
log "Configuration completed successfully"
|
||||
echo "A reboot is required for all GRUB and login-manager changes to take effect."
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
readonly CI_USER="${CI_USER:-qt}"
|
||||
|
||||
log() {
|
||||
printf '\n[gnome-configuration] %s\n' "$*"
|
||||
}
|
||||
|
||||
if [[ "$EUID" -ne 0 ]]; then
|
||||
echo "ERROR: This script must run as root." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! id "$CI_USER" >/dev/null 2>&1; then
|
||||
echo "ERROR: User does not exist: $CI_USER" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ci_home="$(getent passwd "$CI_USER" | cut -d: -f6)"
|
||||
|
||||
if [[ -z "$ci_home" || ! -d "$ci_home" ]]; then
|
||||
echo "ERROR: Cannot determine home directory for $CI_USER" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Applying GNOME preferences for ${CI_USER}"
|
||||
|
||||
# GNOME preferences are stored per user in the dconf database. Packer runs this
|
||||
# provisioner as root over SSH, without a graphical login or user D-Bus session.
|
||||
# Run gsettings as the CI user inside a temporary D-Bus session so the values
|
||||
# are written to the CI user's dconf database rather than root's configuration.
|
||||
|
||||
sudo -H -u "$CI_USER" HOME="$ci_home" dbus-run-session -- bash <<'GNOME_SETTINGS'
|
||||
set -euo pipefail
|
||||
|
||||
schema_exists() {
|
||||
local schema="$1"
|
||||
|
||||
gsettings list-schemas |
|
||||
grep -Fx "$schema" >/dev/null
|
||||
}
|
||||
|
||||
key_exists() {
|
||||
local schema="$1"
|
||||
local key="$2"
|
||||
|
||||
gsettings list-keys "$schema" |
|
||||
grep -Fx "$key" >/dev/null
|
||||
}
|
||||
|
||||
set_setting() {
|
||||
local schema="$1"
|
||||
local key="$2"
|
||||
local value="$3"
|
||||
|
||||
if ! schema_exists "$schema"; then
|
||||
echo "ERROR: Missing GSettings schema: $schema" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! key_exists "$schema" "$key"; then
|
||||
echo "ERROR: Missing GSettings key: $schema $key" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Setting: $schema $key = $value"
|
||||
gsettings set "$schema" "$key" "$value"
|
||||
|
||||
actual="$(gsettings get "$schema" "$key")"
|
||||
echo "Result: $schema $key = $actual"
|
||||
}
|
||||
|
||||
set_setting \
|
||||
org.gnome.desktop.notifications \
|
||||
show-banners \
|
||||
false
|
||||
|
||||
set_setting \
|
||||
org.gnome.desktop.notifications \
|
||||
show-in-lock-screen \
|
||||
false
|
||||
|
||||
set_setting \
|
||||
org.gnome.desktop.screensaver \
|
||||
lock-enabled \
|
||||
false
|
||||
|
||||
if key_exists \
|
||||
org.gnome.desktop.screensaver \
|
||||
ubuntu-lock-on-suspend; then
|
||||
|
||||
set_setting \
|
||||
org.gnome.desktop.screensaver \
|
||||
ubuntu-lock-on-suspend \
|
||||
false
|
||||
fi
|
||||
|
||||
set_setting \
|
||||
org.gnome.desktop.privacy \
|
||||
remember-recent-files \
|
||||
false
|
||||
|
||||
rm -f "${XDG_DATA_HOME:-$HOME/.local/share}/recently-used.xbel"
|
||||
|
||||
set_setting \
|
||||
org.gnome.desktop.session \
|
||||
idle-delay \
|
||||
'uint32 0'
|
||||
|
||||
set_setting \
|
||||
org.gnome.settings-daemon.plugins.power \
|
||||
sleep-inactive-ac-type \
|
||||
"'nothing'"
|
||||
|
||||
set_setting \
|
||||
org.gnome.settings-daemon.plugins.power \
|
||||
sleep-inactive-battery-type \
|
||||
"'nothing'"
|
||||
|
||||
set_setting \
|
||||
org.gnome.settings-daemon.plugins.power \
|
||||
sleep-inactive-ac-timeout \
|
||||
0
|
||||
|
||||
set_setting \
|
||||
org.gnome.settings-daemon.plugins.power \
|
||||
sleep-inactive-battery-timeout \
|
||||
0
|
||||
|
||||
set_setting \
|
||||
org.gnome.shell.extensions.dash-to-dock \
|
||||
dock-fixed \
|
||||
true
|
||||
|
||||
set_setting \
|
||||
org.gnome.shell.extensions.dash-to-dock \
|
||||
autohide \
|
||||
false
|
||||
|
||||
set_setting \
|
||||
org.gnome.shell.extensions.dash-to-dock \
|
||||
intellihide \
|
||||
false
|
||||
GNOME_SETTINGS
|
||||
|
||||
log "GNOME preferences applied successfully"
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Install no-overview gnome extension to prevent desktop overview at boot (QTBUG-132070)
|
||||
|
||||
readonly CI_USER="${CI_USER:-qt}"
|
||||
readonly EXTENSION_UUID="no-overview@fthx"
|
||||
readonly EXTENSION_URL="https://ci-files01-hki.ci.qt.io/input/linux/no-overviewfthx.v23.shell-extension.zip" # GNOME <50
|
||||
readonly EXTENSION_ZIP="/tmp/${EXTENSION_UUID}.zip"
|
||||
readonly EXTENSION_DIR="/usr/share/gnome-shell/extensions/${EXTENSION_UUID}"
|
||||
|
||||
if [[ "$EUID" -ne 0 ]]; then
|
||||
echo "ERROR: This script must run as root." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! id "$CI_USER" >/dev/null 2>&1; then
|
||||
echo "ERROR: User does not exist: $CI_USER" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ci_home="$(getent passwd "$CI_USER" | cut -d: -f6)"
|
||||
|
||||
echo "Installing No Overview GNOME extension"
|
||||
|
||||
wget --quiet --output-document="$EXTENSION_ZIP" "$EXTENSION_URL"
|
||||
|
||||
install -d -o root -g root -m 0755 "$EXTENSION_DIR"
|
||||
|
||||
unzip -q "$EXTENSION_ZIP" -d "$EXTENSION_DIR"
|
||||
|
||||
chown -R root:root "$EXTENSION_DIR"
|
||||
find "$EXTENSION_DIR" -type d -exec chmod 0755 {} +
|
||||
find "$EXTENSION_DIR" -type f -exec chmod 0644 {} +
|
||||
|
||||
# gnome-extensions writes the enabled state to the CI user's dconf database.
|
||||
# Packer runs over SSH without a user session, so provide a temporary D-Bus.
|
||||
sudo -H -u "$CI_USER" HOME="$ci_home" dbus-run-session -- gnome-extensions enable "$EXTENSION_UUID"
|
||||
|
||||
rm -f "$EXTENSION_ZIP"
|
||||
|
||||
echo "Installed and enabled: $EXTENSION_UUID"
|
||||
echo "After a reboot, check with: gnome-extensions list --enabled"
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
failures=0
|
||||
|
||||
pass() {
|
||||
printf 'PASS: %s\n' "$1"
|
||||
}
|
||||
|
||||
fail() {
|
||||
printf 'FAIL: %s\n' "$1"
|
||||
failures=$((failures + 1))
|
||||
}
|
||||
|
||||
echo "=== Image -51 verification ==="
|
||||
|
||||
# No PW prompt
|
||||
if sudo -n true 2>/dev/null; then
|
||||
pass "passwordless sudo"
|
||||
else
|
||||
fail "passwordless sudo"
|
||||
fi
|
||||
|
||||
if sudo visudo --check >/dev/null 2>&1; then
|
||||
pass "sudoers syntax"
|
||||
else
|
||||
fail "sudoers syntax"
|
||||
fi
|
||||
|
||||
# Timezone
|
||||
timezone="$(timedatectl show --property=Timezone --value)"
|
||||
|
||||
if [[ "$timezone" == "UTC" || "$timezone" == "Etc/UTC" ]]; then
|
||||
pass "timezone is UTC"
|
||||
else
|
||||
fail "timezone is '$timezone', expected UTC"
|
||||
fi
|
||||
|
||||
# SSH
|
||||
if dpkg-query -W -f='${db:Status-Abbrev}' openssh-server 2>/dev/null | grep -q '^ii'; then
|
||||
pass "openssh-server installed"
|
||||
else
|
||||
fail "openssh-server installed"
|
||||
fi
|
||||
|
||||
if systemctl is-active --quiet ssh.socket || systemctl is-active --quiet ssh.service; then
|
||||
pass "SSH listener active"
|
||||
else
|
||||
fail "SSH listener active"
|
||||
fi
|
||||
|
||||
if sudo ss -ltn |
|
||||
grep -qE 'LISTEN.+:22[[:space:]]'; then
|
||||
pass "TCP port 22 listening"
|
||||
else
|
||||
fail "TCP port 22 listening"
|
||||
fi
|
||||
|
||||
# QEMU GA
|
||||
if dpkg-query -W -f='${db:Status-Abbrev}' qemu-guest-agent 2>/dev/null | grep -q '^ii'; then
|
||||
pass "qemu-guest-agent installed"
|
||||
else
|
||||
fail "qemu-guest-agent installed"
|
||||
fi
|
||||
|
||||
if systemctl is-enabled --quiet qemu-guest-agent; then
|
||||
pass "qemu-guest-agent enabled"
|
||||
else
|
||||
fail "qemu-guest-agent enabled"
|
||||
fi
|
||||
|
||||
# UFW
|
||||
if sudo ufw status | grep -Fxq 'Status: inactive'; then
|
||||
pass "UFW inactive"
|
||||
else
|
||||
fail "UFW inactive"
|
||||
fi
|
||||
|
||||
# Resolution
|
||||
if grep -Fxq 'GRUB_GFXMODE=1280x800' /etc/default/grub; then
|
||||
pass "GRUB graphics mode"
|
||||
else
|
||||
fail "GRUB graphics mode"
|
||||
fi
|
||||
|
||||
# Auto update/upgrade disabled
|
||||
if apt-config dump | grep -i 'APT::Periodic \"0\";'; then
|
||||
pass "APT periodic processing disabled"
|
||||
else
|
||||
apt-config dump | grep -i APT::Periodic
|
||||
fail "APT periodic processing enabled"
|
||||
fi
|
||||
|
||||
if apt-config dump | grep -i 'APT::Periodic::Unattended-Upgrade \"0\";'; then
|
||||
pass "APT unattended upgrades disabled"
|
||||
else
|
||||
apt-config dump | grep -i APT::Periodic
|
||||
fail "APT unattended upgrades enabled"
|
||||
fi
|
||||
|
||||
if grep -Fxq 'Prompt=never' /etc/update-manager/release-upgrades; then
|
||||
pass "release-upgrade notifications disabled"
|
||||
else
|
||||
fail "release-upgrade notifications enabled"
|
||||
fi
|
||||
|
||||
# Auto login
|
||||
if sudo grep -Fxq 'AutomaticLoginEnable=True' /etc/gdm3/custom.conf && sudo grep -Fxq 'AutomaticLogin=qt' /etc/gdm3/custom.conf; then
|
||||
pass "GDM automatic login configured"
|
||||
else
|
||||
fail "GDM automatic login configured"
|
||||
fi
|
||||
|
||||
# Broken packages
|
||||
if [[ -z "$(sudo dpkg --audit)" ]]; then
|
||||
pass "dpkg audit"
|
||||
else
|
||||
fail "dpkg audit"
|
||||
fi
|
||||
|
||||
# GNOME initial setup executable removed
|
||||
if [[ ! -x /usr/libexec/gnome-initial-setup ]]; then
|
||||
pass "GNOME initial setup executable is absent"
|
||||
else
|
||||
fail "/usr/libexec/gnome-initial-setup exists. There might be a welcome window popup"
|
||||
fi
|
||||
|
||||
# Summary
|
||||
echo
|
||||
if (( failures == 0 )); then
|
||||
echo "All conf checks passed."
|
||||
else
|
||||
echo "${failures} check(s) failed."
|
||||
# exit 1
|
||||
fi
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
# Distribution-specific build settings.
|
||||
# For another distro/version, copy the bundle and change these values first.
|
||||
|
||||
DISTRO_NAME="ubuntu"
|
||||
DISTRO_VERSION="26.04"
|
||||
ISO_PATH="/tmp/ubuntu-26.04-desktop-amd64.iso"
|
||||
# ISO_CHECKSUM_FILE="/tmp/SHA256SUMS"
|
||||
|
||||
# Usually reusable without changes.
|
||||
IMAGE_PREFIX="qtci-linux"
|
||||
ARCH="x86_64"
|
||||
MINIMAL_INDEX="50"
|
||||
CUSTOM_INDEX="51"
|
||||
DISK_SIZE="500G"
|
||||
CPUS="8"
|
||||
MEMORY_MB="16184"
|
||||
SSH_USERNAME="qt"
|
||||
SSH_PASSWORD="$(cat /tmp/PASS)"
|
||||
|
||||
PROJECT_DIR="/tmp/packer-linux"
|
||||
ARTIFACT_DIR="/tmp/output-linux-images"
|
||||
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=build-config.sh
|
||||
source "${script_dir}/build-config.sh"
|
||||
|
||||
image_base_name="${IMAGE_PREFIX}-${DISTRO_NAME}-${DISTRO_VERSION}-${ARCH}"
|
||||
image_50_name="${image_base_name}-${MINIMAL_INDEX}"
|
||||
image_51_name="${image_base_name}-${CUSTOM_INDEX}"
|
||||
image_50="${ARTIFACT_DIR}/${image_50_name}"
|
||||
image_51="${ARTIFACT_DIR}/${image_51_name}"
|
||||
image_51_seed="/tmp/${image_51_name}-seed.qcow2"
|
||||
stage_50_output="/tmp/packer-output-${MINIMAL_INDEX}"
|
||||
stage_51_output="/tmp/packer-output-${CUSTOM_INDEX}"
|
||||
template="linux-image.pkr.hcl"
|
||||
|
||||
# Pass one source of configuration into Packer without duplicating distro and
|
||||
# version literals in HCL or a second variable file.
|
||||
export PKR_VAR_distro_name="$DISTRO_NAME"
|
||||
export PKR_VAR_distro_version="$DISTRO_VERSION"
|
||||
export PKR_VAR_image_prefix="$IMAGE_PREFIX"
|
||||
export PKR_VAR_arch="$ARCH"
|
||||
export PKR_VAR_minimal_index="$MINIMAL_INDEX"
|
||||
export PKR_VAR_custom_index="$CUSTOM_INDEX"
|
||||
export PKR_VAR_iso_path="$ISO_PATH"
|
||||
# export PKR_VAR_iso_checksum_file="$ISO_CHECKSUM_FILE"
|
||||
export PKR_VAR_project_dir="$PROJECT_DIR"
|
||||
export PKR_VAR_artifact_dir="$ARTIFACT_DIR"
|
||||
export PKR_VAR_disk_size="$DISK_SIZE"
|
||||
export PKR_VAR_cpus="$CPUS"
|
||||
export PKR_VAR_memory_mb="$MEMORY_MB"
|
||||
export PKR_VAR_ssh_username="$SSH_USERNAME"
|
||||
export PKR_VAR_ssh_password="$SSH_PASSWORD"
|
||||
|
||||
if [[ "$script_dir" != "$PROJECT_DIR" ]]; then
|
||||
echo "ERROR: Bundle is at '$script_dir', but PROJECT_DIR is '$PROJECT_DIR'." >&2
|
||||
echo "Move/extract it there or update PROJECT_DIR in build-config.sh." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for required_file in $ISO_PATH; do
|
||||
if [[ ! -f "$required_file" ]]; then
|
||||
echo "ERROR: Required file is missing: $required_file" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Stage 51 is always regenerated. Stage 50 is retained
|
||||
rm -rf "$stage_50_output" "$stage_51_output"
|
||||
rm -f "$image_51" "$image_51_seed"
|
||||
rm -f "${image_51}.sha256"
|
||||
|
||||
packer init "$template"
|
||||
packer validate "$template"
|
||||
|
||||
if [[ -f "$image_50" ]]; then
|
||||
echo "Stage ${MINIMAL_INDEX}: existing image found:"
|
||||
echo " $image_50"
|
||||
echo "Validating existing image before skipping the build..."
|
||||
|
||||
if ! qemu-img check "$image_50"; then
|
||||
echo "ERROR: Existing stage-${MINIMAL_INDEX} image failed validation:" >&2
|
||||
echo " $image_50" >&2
|
||||
echo "The image was not deleted or overwritten." >&2
|
||||
echo "Remove it manually" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Stage ${MINIMAL_INDEX}: image is valid, skipping Packer build."
|
||||
sha256sum "$image_50" > "${image_50}.sha256"
|
||||
|
||||
else
|
||||
echo "Stage ${MINIMAL_INDEX}: no existing image found, starting Packer."
|
||||
|
||||
PACKER_LOG=1 \
|
||||
PACKER_LOG_PATH="/tmp/packer-stage-${MINIMAL_INDEX}.log" \
|
||||
packer build -only=stage-50.qemu.stage_50 "$template"
|
||||
|
||||
qemu-img check "$image_50"
|
||||
sha256sum "$image_50" > "${image_50}.sha256"
|
||||
fi
|
||||
|
||||
echo "Creating independent stage-${CUSTOM_INDEX} seed..."
|
||||
qemu-img convert -p -f qcow2 -O qcow2 "$image_50" "$image_51_seed"
|
||||
qemu-img check "$image_51_seed"
|
||||
|
||||
PACKER_LOG=1 \
|
||||
PACKER_LOG_PATH="/tmp/packer-stage-${CUSTOM_INDEX}.log" \
|
||||
packer build -only=stage-51.qemu.stage_51 "$template"
|
||||
|
||||
qemu-img check "$image_51"
|
||||
sha256sum "$image_51" > "${image_51}.sha256"
|
||||
|
||||
(
|
||||
cd "$ARTIFACT_DIR"
|
||||
sha256sum --check "$(basename "${image_50}.sha256")"
|
||||
)
|
||||
|
||||
rm -f "$image_51_seed"
|
||||
|
||||
echo
|
||||
echo "Created independent images:"
|
||||
echo " $image_50"
|
||||
echo " $image_51"
|
||||
echo "Checksums:"
|
||||
echo " ${image_50}.sha256"
|
||||
echo " ${image_51}.sha256"
|
||||
@@ -0,0 +1,2 @@
|
||||
instance-id: qtci-ubuntu26-packer
|
||||
local-hostname: qtci-ubuntu26-x64
|
||||
@@ -0,0 +1,22 @@
|
||||
#cloud-config
|
||||
# This file is installer/distribution-specific. The generic HCL and wrapper can
|
||||
# be reused, but replace this file for a distro that does not use autoinstall.
|
||||
autoinstall:
|
||||
version: 1
|
||||
source:
|
||||
id: ubuntu-desktop-minimal
|
||||
locale: en_US.UTF-8
|
||||
keyboard:
|
||||
layout: us
|
||||
timezone: UTC
|
||||
identity:
|
||||
hostname: qtci-ubuntu26-x64
|
||||
username: qt
|
||||
password: "$6$qtciubuntu2604$FAeHIUtg1iOarKFnnDZim5fWEJ6ZaaYXSc360m68XFTqurIBWNBxsmUDKj.8mGJkVDKlWjFdKZLfrqHYhuBH8/"
|
||||
ssh:
|
||||
install-server: true
|
||||
allow-pw: true
|
||||
storage:
|
||||
layout:
|
||||
name: direct
|
||||
shutdown: reboot
|
||||
@@ -0,0 +1,192 @@
|
||||
packer {
|
||||
required_version = ">= 1.14.0"
|
||||
|
||||
required_plugins {
|
||||
qemu = {
|
||||
version = "~> 1"
|
||||
source = "github.com/hashicorp/qemu"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "distro_name" {
|
||||
type = string
|
||||
}
|
||||
variable "distro_version" {
|
||||
type = string
|
||||
}
|
||||
variable "image_prefix" {
|
||||
type = string
|
||||
}
|
||||
variable "arch" {
|
||||
type = string
|
||||
}
|
||||
variable "minimal_index" {
|
||||
type = string
|
||||
}
|
||||
variable "custom_index" {
|
||||
type = string
|
||||
}
|
||||
variable "iso_path" {
|
||||
type = string
|
||||
}
|
||||
variable "project_dir" {
|
||||
type = string
|
||||
}
|
||||
variable "artifact_dir" {
|
||||
type = string
|
||||
}
|
||||
variable "disk_size" {
|
||||
type = string
|
||||
}
|
||||
variable "cpus" {
|
||||
type = number
|
||||
}
|
||||
variable "memory_mb" {
|
||||
type = number
|
||||
}
|
||||
variable "ssh_username" {
|
||||
type = string
|
||||
}
|
||||
variable "ssh_password" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
locals {
|
||||
image_base_name = "${var.image_prefix}-${var.distro_name}-${var.distro_version}-${var.arch}"
|
||||
image_50_name = "${local.image_base_name}-${var.minimal_index}"
|
||||
image_51_name = "${local.image_base_name}-${var.custom_index}"
|
||||
|
||||
image_50_path = "${var.artifact_dir}/${local.image_50_name}"
|
||||
image_51_path = "${var.artifact_dir}/${local.image_51_name}"
|
||||
image_51_seed = "/tmp/${local.image_51_name}-seed.qcow2"
|
||||
|
||||
stage_50_output = "/tmp/packer-output-${var.minimal_index}"
|
||||
stage_51_output = "/tmp/packer-output-${var.custom_index}"
|
||||
}
|
||||
|
||||
source "qemu" "stage_50" {
|
||||
vm_name = local.image_50_name
|
||||
output_directory = local.stage_50_output
|
||||
|
||||
iso_url = var.iso_path
|
||||
iso_checksum = "none"
|
||||
|
||||
accelerator = "kvm"
|
||||
qemu_binary = "qemu-system-x86_64"
|
||||
format = "qcow2"
|
||||
disk_size = var.disk_size
|
||||
disk_interface = "virtio"
|
||||
net_device = "virtio-net"
|
||||
|
||||
cpus = var.cpus
|
||||
memory = var.memory_mb
|
||||
|
||||
communicator = "ssh"
|
||||
ssh_username = var.ssh_username
|
||||
ssh_password = var.ssh_password
|
||||
ssh_timeout = "60m"
|
||||
ssh_handshake_attempts = 100
|
||||
|
||||
http_directory = "${var.project_dir}/http"
|
||||
boot_wait = "10s"
|
||||
|
||||
# This boot sequence is installer-family-specific. Replace it when adapting
|
||||
# the bundle to a distro that does not use Ubuntu/Subiquity autoinstall.
|
||||
boot_command = [
|
||||
"c<wait>",
|
||||
"linux /casper/vmlinuz autoinstall ds=nocloud-net\\;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ ---<enter><wait>",
|
||||
"initrd /casper/initrd<enter><wait>",
|
||||
"boot<enter>"
|
||||
]
|
||||
|
||||
headless = true
|
||||
vnc_bind_address = "127.0.0.1"
|
||||
shutdown_command = "echo '${var.ssh_password}' | sudo -S shutdown -P now"
|
||||
}
|
||||
|
||||
source "qemu" "stage_51" {
|
||||
vm_name = local.image_51_name
|
||||
output_directory = local.stage_51_output
|
||||
|
||||
# build-images.sh creates this independent seed from immutable image -50.
|
||||
iso_url = local.image_51_seed
|
||||
iso_checksum = "none"
|
||||
disk_image = true
|
||||
|
||||
accelerator = "kvm"
|
||||
qemu_binary = "qemu-system-x86_64"
|
||||
format = "qcow2"
|
||||
disk_size = var.disk_size
|
||||
disk_interface = "virtio"
|
||||
net_device = "virtio-net"
|
||||
|
||||
cpus = var.cpus
|
||||
memory = var.memory_mb
|
||||
|
||||
communicator = "ssh"
|
||||
ssh_username = var.ssh_username
|
||||
ssh_password = var.ssh_password
|
||||
ssh_timeout = "30m"
|
||||
ssh_handshake_attempts = 100
|
||||
|
||||
headless = true
|
||||
vnc_bind_address = "127.0.0.1"
|
||||
shutdown_command = "echo '${var.ssh_password}' | sudo -S shutdown -P now"
|
||||
}
|
||||
|
||||
build {
|
||||
name = "stage-50"
|
||||
sources = ["source.qemu.stage_50"]
|
||||
|
||||
provisioner "shell" {
|
||||
execute_command = "echo '${var.ssh_password}' | {{ .Vars }} sudo -S -E bash '{{ .Path }}'"
|
||||
script = "${var.project_dir}/scripts/01-minimal-50.sh"
|
||||
}
|
||||
|
||||
post-processor "shell-local" {
|
||||
inline = [
|
||||
"mkdir -p '${var.artifact_dir}'",
|
||||
"rm -f '${local.image_50_path}'",
|
||||
"mv '${local.stage_50_output}/${local.image_50_name}' '${local.image_50_path}'",
|
||||
"qemu-img check '${local.image_50_path}'",
|
||||
"qemu-img info '${local.image_50_path}'"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
build {
|
||||
name = "stage-51"
|
||||
sources = ["source.qemu.stage_51"]
|
||||
|
||||
provisioner "shell" {
|
||||
execute_command = "echo '${var.ssh_password}' | {{ .Vars }} sudo -S -E bash '{{ .Path }}'"
|
||||
script = "${var.project_dir}/scripts/02-coin-configuration-51.sh"
|
||||
}
|
||||
|
||||
provisioner "shell" {
|
||||
execute_command = "echo '${var.ssh_password}' | {{ .Vars }} sudo -S -E bash '{{ .Path }}'"
|
||||
script = "${var.project_dir}/scripts/03-gnome-configuration-51.sh"
|
||||
}
|
||||
|
||||
provisioner "shell" {
|
||||
execute_command = "echo '${var.ssh_password}' | {{ .Vars }} sudo -S -E bash '{{ .Path }}'"
|
||||
script = "${var.project_dir}/scripts/04-no-overview-extension-51.sh"
|
||||
}
|
||||
|
||||
provisioner "shell" {
|
||||
execute_command = "echo '${var.ssh_password}' | {{ .Vars }} sudo -S -E bash '{{ .Path }}'"
|
||||
script = "${var.project_dir}/scripts/05-check-configurations-51.sh"
|
||||
}
|
||||
|
||||
post-processor "shell-local" {
|
||||
inline = [
|
||||
"mkdir -p '${var.artifact_dir}'",
|
||||
"rm -f '${local.image_51_path}'",
|
||||
"mv '${local.stage_51_output}/${local.image_51_name}' '${local.image_51_path}'",
|
||||
"qemu-img check '${local.image_51_path}'",
|
||||
"qemu-img info '${local.image_51_path}'"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# This script is run on the minimal -50 image
|
||||
# Other scripts will be run on the -50 -> -51 cloned image
|
||||
|
||||
readonly CI_USER="${CI_USER:-qt}"
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Debian/Ubuntu implementation. Replace this script with the distro's package
|
||||
# manager commands when reusing the generic wrapper and HCL elsewhere.
|
||||
apt-get update
|
||||
apt-get -y full-upgrade
|
||||
apt-get install -y qemu-guest-agent
|
||||
systemctl enable qemu-guest-agent
|
||||
|
||||
dpkg-query -W -f='${binary:Package}\t${Version}\n' \
|
||||
> /var/tmp/qtci-minimal-image-packages.txt
|
||||
|
||||
apt-get -y autoremove
|
||||
apt-get clean
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
qemu-ga --version
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Initial Coin configuration for the customized image (-51).
|
||||
|
||||
readonly CI_USER="${CI_USER:-qt}"
|
||||
readonly GRUB_GFXMODE_VALUE="${GRUB_GFXMODE_VALUE:-1280x800}"
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
log() {
|
||||
printf '\n[51-coin-configuration] %s\n' "$*"
|
||||
}
|
||||
|
||||
require_root() {
|
||||
if [[ "${EUID}" -ne 0 ]]; then
|
||||
echo "ERROR: This script must run as root." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
require_user() {
|
||||
if ! id "$CI_USER" >/dev/null 2>&1; then
|
||||
echo "ERROR: Required CI user does not exist: $CI_USER" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
require_root
|
||||
require_user
|
||||
|
||||
log "Installing required base packages"
|
||||
apt-get update
|
||||
apt-get install -y \
|
||||
openssh-server \
|
||||
ufw
|
||||
|
||||
# Remove GNOME welcome window at boot
|
||||
log "Removing gnome-initial-setup"
|
||||
apt-get purge -y gnome-initial-setup
|
||||
|
||||
# No sudo PW
|
||||
log "Configuring passwordless sudo for ${CI_USER}"
|
||||
cat > "/etc/sudoers.d/${CI_USER}" <<EOF
|
||||
${CI_USER} ALL=(ALL) NOPASSWD: ALL
|
||||
EOF
|
||||
chmod 0440 "/etc/sudoers.d/${CI_USER}"
|
||||
visudo --check
|
||||
|
||||
# UTC
|
||||
log "Setting the system timezone to UTC"
|
||||
timedatectl set-timezone UTC
|
||||
|
||||
# Enable SSH
|
||||
log "Enabling SSH"
|
||||
# Current Ubuntu releases may use socket activation. Enabling both units is
|
||||
# harmless and keeps the image compatible with service- and socket-based SSH.
|
||||
systemctl enable ssh.service
|
||||
systemctl enable ssh.socket 2>/dev/null || true
|
||||
|
||||
# Enable QEMU GA
|
||||
log "Enabling QEMU guest agent"
|
||||
systemctl enable qemu-guest-agent
|
||||
|
||||
# Disable firewall
|
||||
log "Disabling UFW"
|
||||
ufw --force disable
|
||||
systemctl disable ufw.service 2>/dev/null || true
|
||||
|
||||
# Set resolution
|
||||
log "Configuring GRUB graphics mode: ${GRUB_GFXMODE_VALUE}"
|
||||
if grep -qE '^GRUB_GFXMODE=' /etc/default/grub; then
|
||||
sed -i "s/^GRUB_GFXMODE=.*/GRUB_GFXMODE=${GRUB_GFXMODE_VALUE}/" /etc/default/grub
|
||||
else
|
||||
printf '\nGRUB_GFXMODE=%s\n' "$GRUB_GFXMODE_VALUE" >> /etc/default/grub
|
||||
fi
|
||||
update-grub
|
||||
|
||||
# Disable auto upgrade/update
|
||||
log "Disabling periodic APT update checks"
|
||||
cat > /etc/apt/apt.conf.d/99-qtci-no-periodic-updates << EOF
|
||||
APT::Periodic "0";
|
||||
APT::Periodic::Update-Package-Lists "0";
|
||||
APT::Periodic::Download-Upgradeable-Packages "0";
|
||||
APT::Periodic::AutocleanInterval "0";
|
||||
APT::Periodic::Unattended-Upgrade "0";
|
||||
EOF
|
||||
|
||||
sudo systemctl disable --now \
|
||||
apt-daily.timer \
|
||||
apt-daily-upgrade.timer
|
||||
|
||||
sudo systemctl mask \
|
||||
apt-daily.service \
|
||||
apt-daily-upgrade.service \
|
||||
apt-daily.timer \
|
||||
apt-daily-upgrade.timer
|
||||
|
||||
log "Disabling release-upgrade notifications"
|
||||
if [[ -f /etc/update-manager/release-upgrades ]]; then
|
||||
if grep -qE '^Prompt=' /etc/update-manager/release-upgrades; then
|
||||
sed -i 's/^Prompt=.*/Prompt=never/' \
|
||||
/etc/update-manager/release-upgrades
|
||||
else
|
||||
printf '\nPrompt=never\n' >> /etc/update-manager/release-upgrades
|
||||
fi
|
||||
fi
|
||||
|
||||
# GDM Auto login
|
||||
log "Configuring GDM for ${CI_USER}"
|
||||
if [[ -d /etc/gdm3 ]]; then
|
||||
gdm_config="/etc/gdm3/custom.conf"
|
||||
touch "$gdm_config"
|
||||
|
||||
if ! grep -qE '^\[daemon\]' "$gdm_config"; then
|
||||
printf '\n[daemon]\n' >> "$gdm_config"
|
||||
fi
|
||||
sed -i \
|
||||
'/^AutomaticLoginEnable=/d; /^AutomaticLogin=/d; /^InitialSetupEnable=/d' \
|
||||
"$gdm_config"
|
||||
sed -i \
|
||||
"/^\[daemon\]/a InitialSetupEnable=False\nAutomaticLogin=${CI_USER}\nAutomaticLoginEnable=True" \
|
||||
"$gdm_config"
|
||||
else
|
||||
log "GDM is not installed; skipping GDM configuration"
|
||||
fi
|
||||
|
||||
# Run Coin-setup
|
||||
log "Downloading and running coin-setup"
|
||||
|
||||
coin_setup_url="https://ci-files01-hki.ci.qt.io/input/linux/coin-setup-linux-amd64.zip"
|
||||
coin_setup_zip="/tmp/coin-setup-linux-amd64.zip"
|
||||
coin_setup_dir="/tmp/coin-setup-linux-amd64"
|
||||
coin_setup_binary="${coin_setup_dir}/coin-setup"
|
||||
|
||||
rm -rf "$coin_setup_dir"
|
||||
rm -f "$coin_setup_zip"
|
||||
mkdir -p "$coin_setup_dir"
|
||||
|
||||
wget --quiet --output-document="$coin_setup_zip" "$coin_setup_url"
|
||||
|
||||
unzip -q "$coin_setup_zip" -d "$coin_setup_dir"
|
||||
|
||||
if [[ ! -f "$coin_setup_binary" ]]; then
|
||||
echo "ERROR: coin-setup binary was not found at ${coin_setup_binary}" >&2
|
||||
echo "Archive contents:" >&2
|
||||
unzip -l "$coin_setup_zip" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
chmod 0755 "$coin_setup_binary"
|
||||
|
||||
sudo -H -u "$CI_USER" "$coin_setup_binary"
|
||||
|
||||
rm -rf "$coin_setup_dir"
|
||||
rm -f "$coin_setup_zip"
|
||||
|
||||
log "coin-setup completed successfully"
|
||||
|
||||
# Clean apt
|
||||
log "Cleaning APT metadata"
|
||||
apt-get clean
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
log "Configuration completed successfully"
|
||||
echo "A reboot is required for all GRUB and login-manager changes to take effect."
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
readonly CI_USER="${CI_USER:-qt}"
|
||||
|
||||
log() {
|
||||
printf '\n[gnome-configuration] %s\n' "$*"
|
||||
}
|
||||
|
||||
if [[ "$EUID" -ne 0 ]]; then
|
||||
echo "ERROR: This script must run as root." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! id "$CI_USER" >/dev/null 2>&1; then
|
||||
echo "ERROR: User does not exist: $CI_USER" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ci_home="$(getent passwd "$CI_USER" | cut -d: -f6)"
|
||||
|
||||
if [[ -z "$ci_home" || ! -d "$ci_home" ]]; then
|
||||
echo "ERROR: Cannot determine home directory for $CI_USER" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Applying GNOME preferences for ${CI_USER}"
|
||||
|
||||
# GNOME preferences are stored per user in the dconf database. Packer runs this
|
||||
# provisioner as root over SSH, without a graphical login or user D-Bus session.
|
||||
# Run gsettings as the CI user inside a temporary D-Bus session so the values
|
||||
# are written to the CI user's dconf database rather than root's configuration.
|
||||
|
||||
sudo -H -u "$CI_USER" HOME="$ci_home" dbus-run-session -- bash <<'GNOME_SETTINGS'
|
||||
set -euo pipefail
|
||||
|
||||
schema_exists() {
|
||||
local schema="$1"
|
||||
|
||||
gsettings list-schemas |
|
||||
grep -Fx "$schema" >/dev/null
|
||||
}
|
||||
|
||||
key_exists() {
|
||||
local schema="$1"
|
||||
local key="$2"
|
||||
|
||||
gsettings list-keys "$schema" |
|
||||
grep -Fx "$key" >/dev/null
|
||||
}
|
||||
|
||||
set_setting() {
|
||||
local schema="$1"
|
||||
local key="$2"
|
||||
local value="$3"
|
||||
|
||||
if ! schema_exists "$schema"; then
|
||||
echo "ERROR: Missing GSettings schema: $schema" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! key_exists "$schema" "$key"; then
|
||||
echo "ERROR: Missing GSettings key: $schema $key" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Setting: $schema $key = $value"
|
||||
gsettings set "$schema" "$key" "$value"
|
||||
|
||||
actual="$(gsettings get "$schema" "$key")"
|
||||
echo "Result: $schema $key = $actual"
|
||||
}
|
||||
|
||||
set_setting \
|
||||
org.gnome.desktop.notifications \
|
||||
show-banners \
|
||||
false
|
||||
|
||||
set_setting \
|
||||
org.gnome.desktop.notifications \
|
||||
show-in-lock-screen \
|
||||
false
|
||||
|
||||
set_setting \
|
||||
org.gnome.desktop.screensaver \
|
||||
lock-enabled \
|
||||
false
|
||||
|
||||
if key_exists \
|
||||
org.gnome.desktop.screensaver \
|
||||
ubuntu-lock-on-suspend; then
|
||||
|
||||
set_setting \
|
||||
org.gnome.desktop.screensaver \
|
||||
ubuntu-lock-on-suspend \
|
||||
false
|
||||
fi
|
||||
|
||||
set_setting \
|
||||
org.gnome.desktop.privacy \
|
||||
remember-recent-files \
|
||||
false
|
||||
|
||||
rm -f "${XDG_DATA_HOME:-$HOME/.local/share}/recently-used.xbel"
|
||||
|
||||
set_setting \
|
||||
org.gnome.desktop.session \
|
||||
idle-delay \
|
||||
'uint32 0'
|
||||
|
||||
set_setting \
|
||||
org.gnome.settings-daemon.plugins.power \
|
||||
sleep-inactive-ac-type \
|
||||
"'nothing'"
|
||||
|
||||
set_setting \
|
||||
org.gnome.settings-daemon.plugins.power \
|
||||
sleep-inactive-battery-type \
|
||||
"'nothing'"
|
||||
|
||||
set_setting \
|
||||
org.gnome.settings-daemon.plugins.power \
|
||||
sleep-inactive-ac-timeout \
|
||||
0
|
||||
|
||||
set_setting \
|
||||
org.gnome.settings-daemon.plugins.power \
|
||||
sleep-inactive-battery-timeout \
|
||||
0
|
||||
|
||||
set_setting \
|
||||
org.gnome.shell.extensions.dash-to-dock \
|
||||
dock-fixed \
|
||||
true
|
||||
|
||||
set_setting \
|
||||
org.gnome.shell.extensions.dash-to-dock \
|
||||
autohide \
|
||||
false
|
||||
|
||||
set_setting \
|
||||
org.gnome.shell.extensions.dash-to-dock \
|
||||
intellihide \
|
||||
false
|
||||
GNOME_SETTINGS
|
||||
|
||||
log "GNOME preferences applied successfully"
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Install no-overview gnome extension to prevent desktop overview at boot (QTBUG-132070)
|
||||
|
||||
readonly CI_USER="${CI_USER:-qt}"
|
||||
readonly EXTENSION_UUID="no-overview@fthx"
|
||||
readonly EXTENSION_URL="https://ci-files01-hki.ci.qt.io/input/linux/no-overviewfthx.v23.shell-extension.zip" # GNOME <50
|
||||
readonly EXTENSION_ZIP="/tmp/${EXTENSION_UUID}.zip"
|
||||
readonly EXTENSION_DIR="/usr/share/gnome-shell/extensions/${EXTENSION_UUID}"
|
||||
|
||||
if [[ "$EUID" -ne 0 ]]; then
|
||||
echo "ERROR: This script must run as root." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! id "$CI_USER" >/dev/null 2>&1; then
|
||||
echo "ERROR: User does not exist: $CI_USER" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ci_home="$(getent passwd "$CI_USER" | cut -d: -f6)"
|
||||
|
||||
echo "Installing No Overview GNOME extension"
|
||||
|
||||
wget --quiet --output-document="$EXTENSION_ZIP" "$EXTENSION_URL"
|
||||
|
||||
install -d -o root -g root -m 0755 "$EXTENSION_DIR"
|
||||
|
||||
unzip -q "$EXTENSION_ZIP" -d "$EXTENSION_DIR"
|
||||
|
||||
chown -R root:root "$EXTENSION_DIR"
|
||||
find "$EXTENSION_DIR" -type d -exec chmod 0755 {} +
|
||||
find "$EXTENSION_DIR" -type f -exec chmod 0644 {} +
|
||||
|
||||
# gnome-extensions writes the enabled state to the CI user's dconf database.
|
||||
# Packer runs over SSH without a user session, so provide a temporary D-Bus.
|
||||
sudo -H -u "$CI_USER" HOME="$ci_home" dbus-run-session -- gnome-extensions enable "$EXTENSION_UUID"
|
||||
|
||||
rm -f "$EXTENSION_ZIP"
|
||||
|
||||
echo "Installed and enabled: $EXTENSION_UUID"
|
||||
echo "After a reboot, check with: gnome-extensions list --enabled"
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
failures=0
|
||||
|
||||
pass() {
|
||||
printf 'PASS: %s\n' "$1"
|
||||
}
|
||||
|
||||
fail() {
|
||||
printf 'FAIL: %s\n' "$1"
|
||||
failures=$((failures + 1))
|
||||
}
|
||||
|
||||
echo "=== Image -51 verification ==="
|
||||
|
||||
# No PW prompt
|
||||
if sudo -n true 2>/dev/null; then
|
||||
pass "passwordless sudo"
|
||||
else
|
||||
fail "passwordless sudo"
|
||||
fi
|
||||
|
||||
if sudo visudo --check >/dev/null 2>&1; then
|
||||
pass "sudoers syntax"
|
||||
else
|
||||
fail "sudoers syntax"
|
||||
fi
|
||||
|
||||
# Timezone
|
||||
timezone="$(timedatectl show --property=Timezone --value)"
|
||||
|
||||
if [[ "$timezone" == "UTC" || "$timezone" == "Etc/UTC" ]]; then
|
||||
pass "timezone is UTC"
|
||||
else
|
||||
fail "timezone is '$timezone', expected UTC"
|
||||
fi
|
||||
|
||||
# SSH
|
||||
if dpkg-query -W -f='${db:Status-Abbrev}' openssh-server 2>/dev/null | grep -q '^ii'; then
|
||||
pass "openssh-server installed"
|
||||
else
|
||||
fail "openssh-server installed"
|
||||
fi
|
||||
|
||||
if systemctl is-active --quiet ssh.socket || systemctl is-active --quiet ssh.service; then
|
||||
pass "SSH listener active"
|
||||
else
|
||||
fail "SSH listener active"
|
||||
fi
|
||||
|
||||
if sudo ss -ltn |
|
||||
grep -qE 'LISTEN.+:22[[:space:]]'; then
|
||||
pass "TCP port 22 listening"
|
||||
else
|
||||
fail "TCP port 22 listening"
|
||||
fi
|
||||
|
||||
# QEMU GA
|
||||
if dpkg-query -W -f='${db:Status-Abbrev}' qemu-guest-agent 2>/dev/null | grep -q '^ii'; then
|
||||
pass "qemu-guest-agent installed"
|
||||
else
|
||||
fail "qemu-guest-agent installed"
|
||||
fi
|
||||
|
||||
if systemctl is-enabled --quiet qemu-guest-agent; then
|
||||
pass "qemu-guest-agent enabled"
|
||||
else
|
||||
fail "qemu-guest-agent enabled"
|
||||
fi
|
||||
|
||||
# UFW
|
||||
if sudo ufw status | grep -Fxq 'Status: inactive'; then
|
||||
pass "UFW inactive"
|
||||
else
|
||||
fail "UFW inactive"
|
||||
fi
|
||||
|
||||
# Resolution
|
||||
if grep -Fxq 'GRUB_GFXMODE=1280x800' /etc/default/grub; then
|
||||
pass "GRUB graphics mode"
|
||||
else
|
||||
fail "GRUB graphics mode"
|
||||
fi
|
||||
|
||||
# Auto update/upgrade disabled
|
||||
if apt-config dump | grep -i 'APT::Periodic \"0\";'; then
|
||||
pass "APT periodic processing disabled"
|
||||
else
|
||||
apt-config dump | grep -i APT::Periodic
|
||||
fail "APT periodic processing enabled"
|
||||
fi
|
||||
|
||||
if apt-config dump | grep -i 'APT::Periodic::Unattended-Upgrade \"0\";'; then
|
||||
pass "APT unattended upgrades disabled"
|
||||
else
|
||||
apt-config dump | grep -i APT::Periodic
|
||||
fail "APT unattended upgrades enabled"
|
||||
fi
|
||||
|
||||
if grep -Fxq 'Prompt=never' /etc/update-manager/release-upgrades; then
|
||||
pass "release-upgrade notifications disabled"
|
||||
else
|
||||
fail "release-upgrade notifications enabled"
|
||||
fi
|
||||
|
||||
# Auto login
|
||||
if sudo grep -Fxq 'AutomaticLoginEnable=True' /etc/gdm3/custom.conf && sudo grep -Fxq 'AutomaticLogin=qt' /etc/gdm3/custom.conf; then
|
||||
pass "GDM automatic login configured"
|
||||
else
|
||||
fail "GDM automatic login configured"
|
||||
fi
|
||||
|
||||
# Broken packages
|
||||
if [[ -z "$(sudo dpkg --audit)" ]]; then
|
||||
pass "dpkg audit"
|
||||
else
|
||||
fail "dpkg audit"
|
||||
fi
|
||||
|
||||
# GNOME initial setup executable removed
|
||||
if [[ ! -x /usr/libexec/gnome-initial-setup ]]; then
|
||||
pass "GNOME initial setup executable is absent"
|
||||
else
|
||||
fail "/usr/libexec/gnome-initial-setup exists. There might be a welcome window popup"
|
||||
fi
|
||||
|
||||
# Summary
|
||||
echo
|
||||
if (( failures == 0 )); then
|
||||
echo "All conf checks passed."
|
||||
else
|
||||
echo "${failures} check(s) failed."
|
||||
# exit 1
|
||||
fi
|
||||
@@ -161,12 +161,13 @@ cd "$sdkTargetFolder/cmdline-tools/tools/bin"
|
||||
./sdkmanager --install "emulator" --sdk_root="$sdkTargetFolder" \
|
||||
| eval "$sdkmanager_no_progress_bar_cmd"
|
||||
|
||||
echo "Download and unzip Android Emulator version 35.2.10"
|
||||
emulatorFileName="emulator-linux_x64-12414864.zip"
|
||||
echo "Download and unzip Android Emulator version 37.1.11"
|
||||
# See https://developer.android.com/studio/emulator_archive
|
||||
emulatorFileName="emulator-linux_x64-15917651.zip"
|
||||
emulatorCiUrl="https://ci-files01-hki.ci.qt.io/input/android/$emulatorFileName"
|
||||
emulatorUrl="http://dl.google.com/android/repository/$emulatorFileName"
|
||||
emulatorTargetFile="$sdkTargetFolder/$emulatorFileName"
|
||||
emulatorSha1="41dd213d120f727d8c3840347d234b135793ba10"
|
||||
emulatorSha1="1b1f78891abf8ec268264356e1365c25519e8379"
|
||||
DownloadURL "$emulatorCiUrl" "$emulatorUrl" "$emulatorSha1" "$emulatorTargetFile"
|
||||
echo "Unzipping the Android Emulator to '$sdkTargetFolder'"
|
||||
sudo unzip -o -q "$emulatorTargetFile" -d "$sdkTargetFolder"
|
||||
@@ -187,36 +188,21 @@ echo "Unzipping the Android 9 to $minVersionDestination"
|
||||
sudo unzip -o -q "$minVersionFilePath" -d "$minVersionDestination"
|
||||
rm "$minVersionFilePath"
|
||||
|
||||
echo "Download and unzip Android 16 System Image"
|
||||
maxVersionFileName="x86_64-36_r07.zip"
|
||||
maxVersionDestination="$sdkTargetFolder/system-images/android-36/google_apis/"
|
||||
maxVersionFilePath="$maxVersionDestination/$maxVersionFileName"
|
||||
maxVersionCiUrl="$basePath/system_images/google_apis/$maxVersionFileName"
|
||||
maxVersionUrl="https://dl.google.com/android/repository/sys-img/google_apis/$maxVersionFileName"
|
||||
maxVersionSha1="c6bf44bdcd885bb902b4ba752d111a073ad7a817"
|
||||
|
||||
mkdir -p "$maxVersionDestination"
|
||||
DownloadURL "$maxVersionCiUrl" "$maxVersionUrl" "$maxVersionSha1" "$maxVersionFilePath"
|
||||
|
||||
echo "Unzipping the Android 16 to $maxVersionDestination"
|
||||
sudo unzip -o -q "$maxVersionFilePath" -d "$maxVersionDestination"
|
||||
rm "$maxVersionFilePath"
|
||||
|
||||
echo "Download and unzip Android 17 Beta 3 16KB System Image"
|
||||
insignificantMaxVersionFileName="x86_64-ps16k-37.0_r03.zip"
|
||||
echo "Download and unzip Android 17 (16KB Page Size) System Image"
|
||||
insignificantMaxVersionFileName="x86_64-ps16k-37.1_r07.zip"
|
||||
insignificantMaxVersionDestination="$sdkTargetFolder/system-images/android-37/google_apis_ps16k/"
|
||||
insignificantMaxVersionFilePath="$insignificantMaxVersionDestination/$insignificantMaxVersionFileName"
|
||||
insignificantMaxVersionCiUrl="$basePath/system_images/google_apis/$insignificantMaxVersionFileName"
|
||||
insignificantMaxVersionUrl="https://dl.google.com/android/repository/sys-img/google_apis/$insignificantMaxVersionFileName"
|
||||
insignificantMaxVersionSha1="b89a6686f9a9e9942d596bed45d422cbccb70c98"
|
||||
insignificantMaxVersionSha1="88e208a83a5f0b18958275b7c1a047e931395f3f"
|
||||
|
||||
mkdir -p "$insignificantMaxVersionDestination"
|
||||
DownloadURL "$insignificantMaxVersionCiUrl" "$insignificantMaxVersionUrl" "$insignificantMaxVersionSha1" "$insignificantMaxVersionFilePath"
|
||||
|
||||
echo "Unzipping the Android 17 Beta3 16KB to $insignificantMaxVersionDestination"
|
||||
echo "Unzipping the Android 17 (16KB Page Size) to $insignificantMaxVersionDestination"
|
||||
sudo unzip -o -q "$insignificantMaxVersionFilePath" -d "$insignificantMaxVersionDestination"
|
||||
# Hack to avoid SDK version bug in source.properties file, the usage of ".0" messes things for avdmanager. TODO: undo when official comes
|
||||
sudo sed -i 's/AndroidVersion.ApiLevel=37.0/AndroidVersion.ApiLevel=37/g' "$insignificantMaxVersionDestination/x86_64/source.properties"
|
||||
sudo sed -i 's/AndroidVersion.ApiLevel=37.1/AndroidVersion.ApiLevel=37/g' "$insignificantMaxVersionDestination/x86_64/source.properties"
|
||||
rm "$insignificantMaxVersionFilePath"
|
||||
|
||||
echo "Checking the contents of Android SDK again..."
|
||||
@@ -225,11 +211,8 @@ ls -l "$sdkTargetFolder"
|
||||
echo "no" | ./avdmanager create avd -n emulator_x86_api_28 -c 2048M -f \
|
||||
-k "system-images;android-28;google_apis;x86"
|
||||
|
||||
echo "no" | ./avdmanager create avd -n emulator_x86_64_api_36 -c 2048M -f \
|
||||
-k "system-images;android-36;google_apis;x86_64"
|
||||
|
||||
echo "no" | ./avdmanager create avd -n emulator_x86_64_api_37 -c 2048M -f \
|
||||
-k "system-images;android-37;google_apis,page_size_16kb,ai_glasses_compatible;x86_64"
|
||||
-k "system-images;android-37;google_apis,page_size_16kb;x86_64"
|
||||
|
||||
echo "Install maximum supported SDK level image for Android Automotive $sdkApiLevelAutomotiveMax"
|
||||
DownloadURL "$androidAutomotiveMaxUrl" "$androidAutomotiveMaxUrl" "$androidAutomotiveMaxSha" \
|
||||
|
||||
@@ -11,8 +11,12 @@ PROVISIONING_DIR="$(dirname "$0")/../.."
|
||||
# shellcheck source=../unix/common.sourced.sh
|
||||
source "$PROVISIONING_DIR/common/unix/common.sourced.sh"
|
||||
|
||||
if [ -f /usr/lib/sysctl.d/55-ptrace.conf ]; then
|
||||
f="/usr/lib/sysctl.d/55-ptrace.conf" # New location in Ubuntu 26.04
|
||||
else
|
||||
f="/etc/sysctl.d/10-ptrace.conf"
|
||||
fi
|
||||
|
||||
f="/etc/sysctl.d/10-ptrace.conf"
|
||||
if [ -f $f ]
|
||||
then
|
||||
echo "Modifying $f ..."
|
||||
|
||||
@@ -16,52 +16,42 @@ source "${BASH_SOURCE%/*}/../unix/SetEnvVar.sh"
|
||||
targetFolder="/opt/harmonyos"
|
||||
sdkTargetFolder="$targetFolder/command-line-tools"
|
||||
|
||||
sudo mkdir -p "$sdkTargetFolder"
|
||||
|
||||
basePath="http://ci-files01-hki.ci.qt.io/input/harmonyos"
|
||||
|
||||
toolsVersion="6.1.0.850"
|
||||
toolsFile="commandline-tools-linux-x64-6.1.0.850.zip"
|
||||
toolsSha1="6fdf7dbe0faddeb6a36cc76752faaf03d2abd462"
|
||||
function InstallCommandLineTools() {
|
||||
|
||||
toolsTargetFile="/tmp/$toolsFile"
|
||||
toolsSourceFile="$basePath/$toolsFile"
|
||||
cltVersion=$1
|
||||
cltSha1=$2
|
||||
|
||||
echo "Download and unzip HarmonyOS SDK"
|
||||
DownloadURL "$toolsSourceFile" "$toolsSourceFile" "$toolsSha1" "$toolsTargetFile"
|
||||
echo "Unzipping HarmonyOS Tools to '$targetFolder'"
|
||||
sudo unzip -q "$toolsTargetFile" -d "$targetFolder"
|
||||
rm "$toolsTargetFile"
|
||||
cltFile="commandline-tools-linux-x64-$cltVersion.zip"
|
||||
cltTargetFile="/tmp/$cltFile"
|
||||
cltSourceFile="$basePath/$cltFile"
|
||||
|
||||
patchFile="harmonyos_sdk_patches.zip"
|
||||
patchSha1="7f912104a5600bc176891bc6e9d97732f4266ad6"
|
||||
cltTargetDir="$targetFolder/$cltVersion"
|
||||
sudo mkdir -p "$cltTargetDir"
|
||||
|
||||
patchTargetFile="/tmp/$patchFile"
|
||||
patchSourceFile="$basePath/$patchFile"
|
||||
patchTargetFolder="$targetFolder/harmonyos_sdk_patches"
|
||||
DownloadURL "$cltSourceFile" "$cltSourceFile" "$cltSha1" "$cltTargetFile"
|
||||
echo "Unzipping HarmonyOS Command Line Tools to '$cltTargetDir'"
|
||||
# Get the package base directory name as string
|
||||
zipBase=$(sudo zipinfo -1 "$cltTargetFile" 2>/dev/null | awk '!seen {sub("/.*",""); print; seen=1}')
|
||||
sudo unzip -q "$cltTargetFile" -d "$cltTargetDir"
|
||||
rm "$cltTargetFile"
|
||||
harmonycltRoot="${cltTargetDir}/${zipBase}"
|
||||
|
||||
echo "Download and unzip HarmonyOS SDK patches"
|
||||
DownloadURL "$patchSourceFile" "$patchSourceFile" "$patchSha1" "$patchTargetFile"
|
||||
echo "Unzipping HarmonyOS SDK patches to '$targetFolder'"
|
||||
sudo unzip -q "$patchTargetFile" -d "$targetFolder"
|
||||
rm "$patchTargetFile"
|
||||
echo "Changing ownership of HarmonyOS files."
|
||||
sudo chown -R qt:users "$harmonycltRoot"
|
||||
}
|
||||
|
||||
echo "Changing ownership of HarmonyOS files."
|
||||
if uname -a |grep -q "el7"; then
|
||||
sudo chown -R qt:wheel "$sdkTargetFolder"
|
||||
sudo chown -R qt:wheel "$patchTargetFolder"
|
||||
else
|
||||
sudo chown -R qt:users "$sdkTargetFolder"
|
||||
sudo chown -R qt:users "$patchTargetFolder"
|
||||
fi
|
||||
cltVersionCurrent="6.1.0.850"
|
||||
cltSha1Current="6fdf7dbe0faddeb6a36cc76752faaf03d2abd462"
|
||||
InstallCommandLineTools $cltVersionCurrent $cltSha1Current
|
||||
SetEnvVar "HARMONYOS_SDK_ROOT_CURRENT" "$harmonycltRoot"
|
||||
sudo ln -s "$harmonycltRoot" "$sdkTargetFolder"
|
||||
SetEnvVar "HARMONYOS_SDK_ROOT" "$sdkTargetFolder"
|
||||
|
||||
echo "Patching HarmonyOS SDK"
|
||||
|
||||
sdkRootFolder="$sdkTargetFolder/sdk/default/openharmony"
|
||||
echo "Checking the contents of HarmonyOS SDK..."
|
||||
ls -l "$sdkRootFolder"
|
||||
|
||||
SetEnvVar "HARMONYOS_SDK_ROOT" "$sdkRootFolder"
|
||||
export HARMONYOS_SDK_ROOT="$sdkRootFolder"
|
||||
cltVersionNext="26.0.0.821"
|
||||
cltSha1Next="d89fc1a09ceb5b25a350695068fe9918912785d2"
|
||||
InstallCommandLineTools $cltVersionNext $cltSha1Next
|
||||
SetEnvVar "HARMONYOS_SDK_ROOT_NEXT" "$harmonycltRoot"
|
||||
|
||||
echo "HarmonyOS SDK setup finished"
|
||||
|
||||
@@ -12,9 +12,15 @@ mkdir -p "$VCPKG_ROOT/installed"
|
||||
cp -R x86-android-qt-tmp/* "$VCPKG_ROOT/installed/"
|
||||
cp -R x86_64-android-qt-tmp/* "$VCPKG_ROOT/installed/"
|
||||
|
||||
for triplet in x86-android-qt x86_64-android-qt; do
|
||||
python3 "${BASH_SOURCE%/*}/../shared/vcpkg_generate_attributions.py" \
|
||||
--install-root "$VCPKG_ROOT/installed" \
|
||||
--triplet "$triplet"
|
||||
done
|
||||
|
||||
cmake "-DVCPKG_EXECUTABLE=$VCPKG_ROOT/vcpkg"\
|
||||
"-DVCPKG_INSTALL_ROOT=$PWD/x86-android-qt-tmp"\
|
||||
"-DOUTPUT=~/versions.txt"\
|
||||
"-DOUTPUT=$HOME/versions.txt"\
|
||||
-P\
|
||||
"${BASH_SOURCE%/*}/../shared/vcpkg_parse_packages.cmake"
|
||||
|
||||
|
||||
@@ -43,9 +43,9 @@ if [ ! -d "$targetFolder" ]; then
|
||||
fi
|
||||
|
||||
# QNX SDP
|
||||
sourceFile="http://ci-files01-hki.ci.qt.io/input/qnx/qnx710-windows-linux-20260422.tar.xz"
|
||||
sourceFile="http://ci-files01-hki.ci.qt.io/input/qnx/qnx710-windows-linux-20260828.tar.xz"
|
||||
targetFile="qnx710.tar.xz"
|
||||
sha1="98b24df7e8c53a104aee76e769011396fa4bdafd"
|
||||
sha1="c37e6f3a49a259d450b601843a9af2818b6feb96"
|
||||
DownloadAndExtract "$sourceFile" "$sha1" "$targetFile" "$targetFolder"
|
||||
|
||||
# IANA timezone database overlay. Packaged separately from the SDP so it can be
|
||||
|
||||
@@ -43,9 +43,9 @@ if [ ! -d "$targetFolder" ]; then
|
||||
fi
|
||||
|
||||
# QNX SDP
|
||||
sourceFile="http://ci-files01-hki.ci.qt.io/input/qnx/qnx800-windows-linux-20260410.tar.xz"
|
||||
sourceFile="http://ci-files01-hki.ci.qt.io/input/qnx/qnx800-windows-linux-20260828.tar.xz"
|
||||
targetFile="qnx800.tar.xz"
|
||||
sha1="a3fdcd98e12bc5054d00f18e4088af26288fd020"
|
||||
sha1="f44b66d91625ab33e367cfb62a2950a041607caa"
|
||||
DownloadAndExtract "$sourceFile" "$sha1" "$targetFile" "$targetFolder"
|
||||
|
||||
# IANA timezone database overlay. Packaged separately from the SDP so it can be
|
||||
@@ -60,14 +60,17 @@ sudo cp "$aarch64le_toolchain" "$targetPath"
|
||||
sudo cp "$armv7le_toolchain" "$targetPath"
|
||||
sudo cp "$x8664_toolchain" "$targetPath"
|
||||
cp -R "$QNX_qemu_bld_files_dir" "$qemuTargetPath"
|
||||
# fc-match tool is missing from QNX SDP and tst_qfont requires it to work corretly
|
||||
# Download code-only package from https://www.iana.org/time-zones and follow README
|
||||
# to build tools for QNX x86_64. If need to build new tool create new qnx_qemu_utils
|
||||
# package which contains it and update required info below
|
||||
sourceFile="http://ci-files01-hki.ci.qt.io/input/qnx/qnx_qemu_utils_20211208.tar.xz"
|
||||
# The SDP ships fc-cache but not fc-match, which tst_qfont needs. Build it from
|
||||
# fontconfig's fc-match/fc-match.c at the release matching the SDP's fontconfig
|
||||
# (FC_MINOR/FC_REVISION in fontconfig.h), once per arch:
|
||||
# qcc -Vgcc_ntox86_64 -O2 -o fc-match fc-match.c \
|
||||
# -DHAVE_GETOPT_LONG=1 -DHAVE_UNISTD_H=1 -lfontconfig
|
||||
# Pack as <arch>/fc-match into a new dated archive, then update below. 7.1 keeps
|
||||
# its own archive.
|
||||
sourceFile="http://ci-files01-hki.ci.qt.io/input/qnx/qnx_qemu_utils_800_20260825.tar.xz"
|
||||
targetFile="qnx_qemu_utils.tar.xz"
|
||||
targetFolder="$qemuTargetPath/local/misc_files"
|
||||
sha1="7653f5d50f61f1591d7785c3ec261228ecc9dd22"
|
||||
sha1="965b957c76d4bc59c010bb0908d1fea8975179c1"
|
||||
|
||||
mkdir -p "$targetFolder"
|
||||
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ var/etc/fontconfig/fonts.conf=etc/fonts/fonts.conf
|
||||
var/share/fonts=usr/share/fonts
|
||||
|
||||
var/etc/hosts=local/misc_files/etc/hosts
|
||||
var/etc/resolv.conf=local/misc_files/etc/resolv.conf
|
||||
var/dhcpcd/resolv.conf=local/misc_files/etc/resolv.conf
|
||||
var/etc/nsswitch.conf=etc/nsswitch.conf
|
||||
|
||||
[uid=0 gid=0 dperms=755 type=dir] var/etc/ssl/certs
|
||||
|
||||
+5
-1
@@ -17,7 +17,11 @@ echo "---> Remove large fonts"
|
||||
rm -rf /data/var/share/fonts/NotoSansCJK*
|
||||
rm -rf /data/var/share/fonts/NotoSansMonoCJK*
|
||||
echo "---> Create fontconfig cache"
|
||||
fc-cache &
|
||||
# fc-cache needs HOME to locate a writable cache directory, and the startup
|
||||
# environment has none. Keep these two in sync with QNX_TEST_ENV in
|
||||
# coin/platform_configs/cmake_platforms_qemu_qnx.yaml, so that the cache is
|
||||
# written where the tests will look for it.
|
||||
HOME=/data/home/root FONTCONFIG_FILE=/data/var/etc/fontconfig/fonts.conf fc-cache &
|
||||
|
||||
echo "---> Restart ssh daemon"
|
||||
slay sshd
|
||||
|
||||
+4
-3
@@ -28,6 +28,8 @@ lib/liblzma.so.5=usr/lib/liblzma.so.5
|
||||
lib/libdbus-1.so=usr/lib//libdbus-1.so
|
||||
lib/libdbus-1.so.22=usr/lib//libdbus-1.so.22
|
||||
lib/libbacktrace.so.1=lib/libbacktrace.so.1
|
||||
lib/libunwind-nto.so.0=usr/lib/libunwind-nto.so.0
|
||||
lib/libunwind-x86_64.so.8=usr/lib/libunwind-x86_64.so.8
|
||||
lib/libm.so.3=lib/libm.so.3
|
||||
|
||||
#############################################
|
||||
@@ -60,11 +62,10 @@ lib/libasound.so.5=lib/libasound.so.5
|
||||
|
||||
# for fontconfig
|
||||
lib/libfontconfig.so.17=usr/lib/libfontconfig.so.17
|
||||
xbin/fc-cache=bin/fc-cache
|
||||
xbin/fc-match=local/misc_files/fc-match
|
||||
bin/fc-cache=bin/fc-cache
|
||||
bin/fc-match=local/misc_files/x86_64/fc-match
|
||||
|
||||
# network
|
||||
lib/libssl.so=usr/lib/libssl.so
|
||||
xbin/nslookup=usr/bin/nslookup
|
||||
xbin/unbound=sbin/unbound
|
||||
xbin/curl=usr/bin/curl
|
||||
|
||||
@@ -22,12 +22,12 @@ SetEnvVar "VXWORKS_HOME" "/opt/vxworks"
|
||||
SetEnvVar "VXWORKS_SSH" "[email protected]"
|
||||
|
||||
# IMX 6
|
||||
VXWORKS_BUILD_VER="20-08-2026"
|
||||
VXWORKS_BUILD_VER="24-09-2026"
|
||||
######### VXworks toolchain #########
|
||||
# Installs to /opt/fsl_imx6_2_0_6_3_VSB
|
||||
PrimaryUrl="http://ci-files01-hki.ci.qt.io/input/vxworks/vxworks_arm_vsb_${VXWORKS_BUILD_VER}.tar.gz"
|
||||
AltUrl=""
|
||||
sha1="cb40acde7227aaefe8397e3472318fe09af2d9d0"
|
||||
sha1="aaa8d51a2e9d67573f808e92d71112926bfc2657"
|
||||
targetFolder="/opt/"
|
||||
InstallFromCompressedFileFromURL "$PrimaryUrl" "$AltUrl" "$sha1" "$targetFolder" ""
|
||||
SetEnvVar "WIND_CC_SYSROOT" "/opt/fsl_imx6_2_0_6_3_VSB"
|
||||
@@ -36,7 +36,7 @@ SetEnvVar "WIND_CC_SYSROOT" "/opt/fsl_imx6_2_0_6_3_VSB"
|
||||
# Installs to /opt/fsl_imx6_2_0_6_3_VIP_QEMU
|
||||
PrimaryUrl="http://ci-files01-hki.ci.qt.io/input/vxworks/vxworks_arm_vip_${VXWORKS_BUILD_VER}.tar.gz"
|
||||
AltUrl=""
|
||||
sha1="4209a8c2724fccfec9d30a22e53ca6598ef83b57"
|
||||
sha1="3b69676a8621776d162d3d14cb97681c5075a4e7"
|
||||
targetFolder="/opt/"
|
||||
InstallFromCompressedFileFromURL "$PrimaryUrl" "$AltUrl" "$sha1" "$targetFolder" ""
|
||||
|
||||
@@ -44,20 +44,20 @@ InstallFromCompressedFileFromURL "$PrimaryUrl" "$AltUrl" "$sha1" "$targetFolder"
|
||||
# Installs to /opt/nxp_imx8_1_0_7_1_VSB
|
||||
PrimaryUrl="http://ci-files01-hki.ci.qt.io/input/vxworks/vxworks_arm_imx8_vsb_${VXWORKS_BUILD_VER}.tar.gz"
|
||||
AltUrl=""
|
||||
sha1="20c1c31fc8ddc5356566a717a913e51bef42d41f"
|
||||
sha1="2b79925bf2f439ae23dbbd6d9f0eb7f12f5b5b30"
|
||||
targetFolder="/opt/"
|
||||
InstallFromCompressedFileFromURL "$PrimaryUrl" "$AltUrl" "$sha1" "$targetFolder" ""
|
||||
|
||||
# Installs to /opt/itl_generic_skylake_VSB
|
||||
PrimaryUrl="http://ci-files01-hki.ci.qt.io/input/vxworks/vxworks_intel_vsb_${VXWORKS_BUILD_VER}.tar.gz"
|
||||
AltUrl=""
|
||||
sha1="dae9280a45f0ece5a2adc3bc6182ff0b675f4389"
|
||||
sha1="59a4f78844d6d228fa9d74605a6a219a32f77ca8"
|
||||
targetFolder="/opt/"
|
||||
InstallFromCompressedFileFromURL "$PrimaryUrl" "$AltUrl" "$sha1" "$targetFolder" ""
|
||||
# Installs to /opt/itl_generic_skylake_VIP_QEMU
|
||||
PrimaryUrl="http://ci-files01-hki.ci.qt.io/input/vxworks/vxworks_intel_vip_${VXWORKS_BUILD_VER}.tar.gz"
|
||||
AltUrl=""
|
||||
sha1="264b3280e6fa89c8c8a2b1cdc8cb29bd3f1bb621"
|
||||
sha1="b56be2e8617004448dc918ff061347a44e653db7"
|
||||
targetFolder="/opt/"
|
||||
InstallFromCompressedFileFromURL "$PrimaryUrl" "$AltUrl" "$sha1" "$targetFolder" ""
|
||||
|
||||
@@ -77,7 +77,12 @@ targetFolder="/opt/itl_generic_skylake_VSB/"
|
||||
InstallFromCompressedFileFromURL "$PrimaryUrl" "$AltUrl" "$sha1" "$targetFolder" ""
|
||||
|
||||
# Enable ipv4 routing from vxWorks to Qt DNS
|
||||
sudo sed -i s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g /etc/sysctl.conf
|
||||
if [ -f /etc/sysctl.conf ]; then
|
||||
sudo sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g' /etc/sysctl.conf
|
||||
else
|
||||
# There's no /etc/sysctl.conf in Ubuntu 26.04, use sysctl.d instead
|
||||
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-vxworks.conf
|
||||
fi
|
||||
sudo iptables -I FORWARD 1 -j ACCEPT
|
||||
sudo iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ exec 9>&-
|
||||
if [ "$TYPE" = "arm" ] || [ "$TYPE" = "" ]; then
|
||||
$VXWORKS_QEMU/bin/qemu-system-arm \
|
||||
-machine sabrelite \
|
||||
-no-reboot \
|
||||
-smp 2 \
|
||||
-m 3G \
|
||||
-nographic \
|
||||
@@ -101,6 +102,7 @@ if [ "$TYPE" = "arm" ] || [ "$TYPE" = "" ]; then
|
||||
elif [ "$TYPE" = "intel" ]; then
|
||||
$VXWORKS_QEMU/bin/qemu-system-x86_64 \
|
||||
-M q35 \
|
||||
-no-reboot \
|
||||
-smp 4 \
|
||||
-m 15G \
|
||||
-cpu "Skylake-Client" \
|
||||
|
||||
@@ -61,4 +61,8 @@ ls -l "$sdkRootFolder"
|
||||
SetEnvVar "HARMONYOS_SDK_ROOT" "$sdkRootFolder"
|
||||
export HARMONYOS_SDK_ROOT="$sdkRootFolder"
|
||||
|
||||
# Same meaning as on Linux: the command-line-tools root, which holds hvigorw.
|
||||
SetEnvVar "HARMONYOS_SDK_ROOT_CURRENT" "$sdkTargetFolder"
|
||||
export HARMONYOS_SDK_ROOT_CURRENT="$sdkTargetFolder"
|
||||
|
||||
echo "HarmonyOS SDK setup finished"
|
||||
|
||||
@@ -6,8 +6,12 @@
|
||||
#
|
||||
# The script will package iOS and iOS-simulator binaries into one
|
||||
# single .xcframework. This .xcframework cannot contain .dylibs
|
||||
# directly. It must contain .framework files. Unlike macOS, binaries
|
||||
# should NOT be lipoed together.
|
||||
# directly. It must contain .framework files. Binaries for different
|
||||
# SDKs (iphoneos and iphonesimulator) should NOT be lipoed together,
|
||||
# they must be separate frameworks inside the .xcframework. However,
|
||||
# an .xcframework can hold only one framework per SDK, so binaries for
|
||||
# different architectures of the same SDK (arm64 and x86_64 simulator)
|
||||
# must be lipoed together into a single universal framework.
|
||||
#
|
||||
# From https://developer.apple.com/documentation/xcode/creating-a-multi-platform-binary-framework-bundle
|
||||
# "Avoid using dynamic library files (.dylib files) for dynamic
|
||||
@@ -41,6 +45,10 @@ prefix="${1:-$default_prefix}"
|
||||
# we care about
|
||||
ffmpeg_components="libavcodec libavformat libavutil libswresample libswscale"
|
||||
|
||||
# The target platforms to build for. Target platforms that share the
|
||||
# same SDK are lipoed together into one framework.
|
||||
target_platforms=("arm64-iphoneos" "arm64-simulator" "x86_64-simulator")
|
||||
|
||||
target_platform_to_sdk() {
|
||||
local target_platform="$1"
|
||||
if [[ "$target_platform" == "arm64-simulator" ]] \
|
||||
@@ -54,6 +62,16 @@ target_platform_to_sdk() {
|
||||
fi
|
||||
}
|
||||
|
||||
# The SDKs of all target platforms, without duplicates. Each SDK ends up as
|
||||
# a separate framework inside each .xcframework.
|
||||
target_sdks=()
|
||||
for target_platform in "${target_platforms[@]}"; do
|
||||
target_sdk="$(target_platform_to_sdk "$target_platform")"
|
||||
if [[ " ${target_sdks[*]:-} " != *" ${target_sdk} "* ]]; then
|
||||
target_sdks+=("$target_sdk")
|
||||
fi
|
||||
done
|
||||
|
||||
build_ffmpeg_ios() {
|
||||
local target_platform="$1"
|
||||
local target_cpu_arch=""
|
||||
@@ -113,6 +131,31 @@ build_ffmpeg_ios() {
|
||||
popd
|
||||
}
|
||||
|
||||
# Combine the FFmpeg dylibs of all target platforms that belong to the given
|
||||
# SDK into universal dylibs. The result is placed in a build directory named
|
||||
# after the SDK, which is then used to create the framework for that SDK.
|
||||
lipo_dylibs() {
|
||||
local target_sdk="$1"
|
||||
|
||||
local sdk_lib_dir="${ffmpeg_source_dir}/build_ios/${target_sdk}/installed/${prefix}/lib"
|
||||
sudo mkdir -p "$sdk_lib_dir"
|
||||
|
||||
local ffmpeg_component_name
|
||||
for ffmpeg_component_name in $ffmpeg_components; do
|
||||
local input_dylibs=()
|
||||
local target_platform
|
||||
for target_platform in "${target_platforms[@]}"; do
|
||||
if [ "$(target_platform_to_sdk "$target_platform")" == "$target_sdk" ]; then
|
||||
input_dylibs+=("${ffmpeg_source_dir}/build_ios/${target_platform}/installed/${prefix}/lib/${ffmpeg_component_name}.dylib")
|
||||
fi
|
||||
done
|
||||
|
||||
sudo lipo -create \
|
||||
"${input_dylibs[@]}" \
|
||||
-output "${sdk_lib_dir}/${ffmpeg_component_name}.dylib"
|
||||
done
|
||||
}
|
||||
|
||||
build_info_plist() {
|
||||
local file_path="$1"
|
||||
local framework_name="$2"
|
||||
@@ -183,9 +226,9 @@ build_info_plist() {
|
||||
# See https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Frameworks.html
|
||||
create_framework() {
|
||||
local ffmpeg_component_name="$1"
|
||||
local platform="$2"
|
||||
local target_sdk="$2"
|
||||
|
||||
local ffmpeg_build_path="${ffmpeg_source_dir}/build_ios/${platform}/installed/${prefix}"
|
||||
local ffmpeg_build_path="${ffmpeg_source_dir}/build_ios/${target_sdk}/installed/${prefix}"
|
||||
local ffmpeg_component_src_dylib="${ffmpeg_build_path}/lib/${ffmpeg_component_name}.dylib"
|
||||
local ffmpeg_component_framework="${ffmpeg_build_path}/framework/${ffmpeg_component_name}.framework"
|
||||
local ffmpeg_component_target_dylib="${ffmpeg_component_framework}/${ffmpeg_component_name}"
|
||||
@@ -213,10 +256,12 @@ create_framework() {
|
||||
-id "@rpath/${ffmpeg_component_name}.framework/${ffmpeg_component_name}" \
|
||||
"${ffmpeg_component_target_dylib}"
|
||||
|
||||
# Update the runpaths for each FFmpeg dependency entry
|
||||
# Update the runpaths for each FFmpeg dependency entry. The dylib may be
|
||||
# universal, in which case otool lists the dependencies once per
|
||||
# architecture, each list preceded by an unindented header line.
|
||||
otool -L "$ffmpeg_component_target_dylib" \
|
||||
| tail -n +2 \
|
||||
| awk '{print $1}' \
|
||||
| awk '/^[[:space:]]/ {print $1}' \
|
||||
| sort -u \
|
||||
| while read -r dep; do
|
||||
# Go through all dependency entries of this .dylib,
|
||||
# see if they point to a FFmpeg component. If it does,
|
||||
@@ -240,62 +285,65 @@ create_framework() {
|
||||
# At the end, we strip the dylib.
|
||||
create_dsym() {
|
||||
local ffmpeg_component_name="$1"
|
||||
local platform="$2"
|
||||
local target_sdk="$2"
|
||||
|
||||
local ffmpeg_build_path="${ffmpeg_source_dir}/build_ios/${platform}/installed/${prefix}"
|
||||
local ffmpeg_build_path="${ffmpeg_source_dir}/build_ios/${target_sdk}/installed/${prefix}"
|
||||
local target_dylib="${ffmpeg_build_path}/framework/${ffmpeg_component_name}.framework/${ffmpeg_component_name}"
|
||||
|
||||
sudo dsymutil "${target_dylib}" \
|
||||
-o "${ffmpeg_build_path}/framework/${ffmpeg_component_name}.framework.dSYM"
|
||||
|
||||
local target_sdk;
|
||||
target_sdk=$(target_platform_to_sdk "${platform}")
|
||||
|
||||
local strip;
|
||||
strip="$(xcrun -f --sdk ${target_sdk} strip)"
|
||||
sudo ${strip} -x "${target_dylib}"
|
||||
}
|
||||
|
||||
# Create an .xcframework from the given component's framework and dSYM
|
||||
# for each target SDK.
|
||||
create_xcframework() {
|
||||
# Create 'traditional' framework from the corresponding dylib,
|
||||
# also creating
|
||||
local framework_name="$1"
|
||||
local target_platform_a="$2"
|
||||
local target_platform_b="$3"
|
||||
shift
|
||||
|
||||
local platform_a_build="${ffmpeg_source_dir}/build_ios/${target_platform_a}/installed/${prefix}"
|
||||
local fw_a="${platform_a_build}/framework/${framework_name}.framework"
|
||||
local dsym_a="${fw_a}.dSYM"
|
||||
|
||||
local platform_b_build="${ffmpeg_source_dir}/build_ios/${target_platform_b}/installed/${prefix}"
|
||||
local fw_b="${platform_b_build}/framework/${framework_name}.framework"
|
||||
local dsym_b="${fw_b}.dSYM"
|
||||
local xcframework_args=()
|
||||
local target_sdk
|
||||
for target_sdk in "$@"; do
|
||||
local sdk_build="${ffmpeg_source_dir}/build_ios/${target_sdk}/installed/${prefix}"
|
||||
local fw="${sdk_build}/framework/${framework_name}.framework"
|
||||
xcframework_args+=(-framework "$fw" -debug-symbols "${fw}.dSYM")
|
||||
done
|
||||
|
||||
sudo mkdir -p "$prefix/lib/"
|
||||
sudo xcodebuild -create-xcframework \
|
||||
-framework "$fw_a" -debug-symbols "$dsym_a" \
|
||||
-framework $fw_b -debug-symbols "$dsym_b" \
|
||||
"${xcframework_args[@]}" \
|
||||
-output "${prefix}/lib/${framework_name}.xcframework"
|
||||
}
|
||||
|
||||
build_ffmpeg_ios "arm64-iphoneos"
|
||||
build_ffmpeg_ios "x86_64-simulator"
|
||||
|
||||
for name in $ffmpeg_components; do
|
||||
create_framework "$name" "arm64-iphoneos"
|
||||
create_framework "$name" "x86_64-simulator"
|
||||
|
||||
create_dsym "$name" "arm64-iphoneos"
|
||||
create_dsym "$name" "x86_64-simulator"
|
||||
# Build for each chosen ABI
|
||||
for target_platform in "${target_platforms[@]}"; do
|
||||
build_ffmpeg_ios "$target_platform"
|
||||
done
|
||||
|
||||
# Create corresponding xcframeworks containing both arm64 and x86_64-simulator frameworks:
|
||||
# Combine the ABIs of each SDK into universal dylibs
|
||||
for target_sdk in "${target_sdks[@]}"; do
|
||||
lipo_dylibs "$target_sdk"
|
||||
done
|
||||
|
||||
# Create .frameworks and dSYMs for each FFmpeg component, for each SDK
|
||||
for name in $ffmpeg_components; do
|
||||
create_xcframework "$name" "arm64-iphoneos" "x86_64-simulator"
|
||||
for target_sdk in "${target_sdks[@]}"; do
|
||||
create_framework "$name" "$target_sdk"
|
||||
create_dsym "$name" "$target_sdk"
|
||||
done
|
||||
done
|
||||
|
||||
# Create corresponding xcframeworks containing the frameworks of all target SDKs:
|
||||
for name in $ffmpeg_components; do
|
||||
create_xcframework "$name" "${target_sdks[@]}"
|
||||
done
|
||||
|
||||
# xcframeworks are already installed directly into the target output directory.
|
||||
# We need to install headers
|
||||
sudo cp -r "${ffmpeg_source_dir}/build_ios/arm64-iphoneos/installed/${prefix}/include" "$prefix"
|
||||
# We need to install headers. These are the same for all target platforms,
|
||||
# so we take them from the first one.
|
||||
sudo cp -r "${ffmpeg_source_dir}/build_ios/${target_platforms[0]}/installed/${prefix}/include" "$prefix"
|
||||
|
||||
set_ffmpeg_dir_env_var "FFMPEG_DIR_IOS" "$prefix"
|
||||
|
||||
@@ -58,7 +58,12 @@ function InstallXCode() {
|
||||
# Xcode 26 ships a more minimal base install
|
||||
if ((majorVersion >= 26)); then
|
||||
xcodebuild -downloadComponent MetalToolchain
|
||||
xcodebuild -downloadPlatform iOS
|
||||
if ((majorVersion >= 27)); then
|
||||
# No more universal iOS simulator in Xcode 27
|
||||
xcodebuild -downloadPlatform iOS
|
||||
else
|
||||
xcodebuild -downloadPlatform iOS -architectureVariant universal
|
||||
fi
|
||||
if [[ $(uname -m) == "arm64" ]]; then
|
||||
xcodebuild -downloadPlatform visionOS
|
||||
fi
|
||||
|
||||
@@ -31,29 +31,72 @@ TCC_CLIENTS+=("/usr/libexec/sshd-keygen-wrapper")
|
||||
SERVICES=()
|
||||
|
||||
# Qt Multimedia tests need microphone access
|
||||
SERVICES+=("kTCCServiceMicrophone|$HOME")
|
||||
SERVICES+=("kTCCServiceMicrophone|user")
|
||||
|
||||
# Qt Connectivity tests need Bluetooth access
|
||||
SERVICES+=("kTCCServiceBluetoothAlways|$HOME")
|
||||
SERVICES+=("kTCCServiceBluetoothAlways|user")
|
||||
|
||||
# Qt Multimedia might need screen capture, and it can
|
||||
# also be useful for capturing the state of the VM when
|
||||
# a test fails.
|
||||
SERVICES+=("kTCCServiceScreenCapture|/")
|
||||
SERVICES+=("kTCCServiceScreenCapture|system")
|
||||
|
||||
# Squish requires kTCCServiceAccessibility
|
||||
SERVICES+=("kTCCServiceAccessibility|/")
|
||||
SERVICES+=("kTCCServiceAccessibility|system")
|
||||
|
||||
# ------ Implementation ------
|
||||
|
||||
# Starting with macOS 27, tccd's per-user database moved out of
|
||||
# ~/Library/Application Support/com.apple.TCC into a randomly named
|
||||
# container under ProtectedSystem. The container UUID is assigned by
|
||||
# containermanagerd and isn't derived from anything we can compute, so
|
||||
# look it up by identifier instead. The system-wide database (owned by
|
||||
# "tccd system", running as root) is unaffected and stays where it was.
|
||||
function find_tccd_container() {
|
||||
local plist
|
||||
for plist in /private/var/containers/Data/ProtectedSystem/*/.com.apple.containermanagerd.metadata.plist; do
|
||||
if [[ "$(sudo defaults read "$plist" MCMMetadataIdentifier 2>/dev/null)" == "com.apple.tccd" ]]; then
|
||||
dirname "$plist"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
function is_macos_27_or_later() {
|
||||
local version
|
||||
version=$(sw_vers -productVersion)
|
||||
(( ${version%%.*} >= 27 ))
|
||||
}
|
||||
|
||||
# Resolve both database locations once, up front, instead of on every
|
||||
# add_permission_for_client call. The user one in particular requires
|
||||
# walking ProtectedSystem containers on macOS 27+, which is wasteful
|
||||
# to repeat for each client/service pair.
|
||||
SYSTEM_TCC_DB="/Library/Application Support/com.apple.TCC/TCC.db"
|
||||
if is_macos_27_or_later; then
|
||||
tccd_container=$(find_tccd_container) || {
|
||||
echo "Could not locate tccd's ProtectedSystem container" >&2
|
||||
exit 1
|
||||
}
|
||||
USER_TCC_DB="$tccd_container/Data/Library/Application Support/com.apple.TCC/TCC.db"
|
||||
else
|
||||
USER_TCC_DB="$HOME/Library/Application Support/com.apple.TCC/TCC.db"
|
||||
fi
|
||||
|
||||
function add_permission_for_client() {
|
||||
local client="$1"
|
||||
local service="$2"
|
||||
|
||||
local path="${service#*|}"
|
||||
local scope="${service#*|}"
|
||||
local service="${service%|*}"
|
||||
|
||||
tcc_database="${path%/}/Library/Application Support/com.apple.TCC/TCC.db"
|
||||
local tcc_database
|
||||
if [[ "$scope" == "system" ]]; then
|
||||
tcc_database="$SYSTEM_TCC_DB"
|
||||
else
|
||||
tcc_database="$USER_TCC_DB"
|
||||
fi
|
||||
if ! sudo touch "$tcc_database"; then
|
||||
echo "TCC database is not writable. Is SIP disabled?" >&2
|
||||
exit 1
|
||||
@@ -79,6 +122,7 @@ function add_permission_for_client() {
|
||||
local req_hex=$(echo "$req_str" | csreq -r- -b >(xxd -p | tr -d '\n'))
|
||||
|
||||
sudo sqlite3 -echo "$tcc_database" <<EOF
|
||||
PRAGMA busy_timeout = 5000;
|
||||
DELETE from access WHERE client = '$client' AND service = '$service';
|
||||
INSERT INTO access (service, client, client_type, auth_value, auth_reason, auth_version, csreq, flags) VALUES (
|
||||
'$service', -- service
|
||||
|
||||
@@ -3,6 +3,7 @@ spdx-tools>=0.8.0 ; python_version >= '3.9'
|
||||
ntia-conformance-checker ; python_version >= '3.9'
|
||||
sbomaudit ; python_version >= '3.9'
|
||||
sbom2doc ; python_version >= '3.9'
|
||||
reuse<=5.1.1 ; python_version >= '3.9'
|
||||
cyclonedx-python-lib==11.5.0 ; python_version >= '3.9'
|
||||
reuse<=5.1.1 ; python_version == '3.9'
|
||||
reuse==6.2.0 ; python_version >= '3.10'
|
||||
cyclonedx-python-lib==11.12.0 ; python_version >= '3.9'
|
||||
jsonschema>=4.20 ; python_version >= '3.12'
|
||||
|
||||
@@ -0,0 +1,410 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
"""Unit tests for vcpkg_generate_attributions.py.
|
||||
|
||||
Run from this directory with:
|
||||
python3 -m unittest test_vcpkg_generate_attributions -v
|
||||
"""
|
||||
|
||||
import json
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from vcpkg_generate_attributions import (
|
||||
CPE_FILE,
|
||||
build_attribution,
|
||||
compose_cpe,
|
||||
find_purl,
|
||||
generate,
|
||||
index_entries,
|
||||
load_cpe_map,
|
||||
normalize_license,
|
||||
port_installs_files,
|
||||
select_download_location,
|
||||
strip_port_version,
|
||||
)
|
||||
|
||||
TRIPLET = "arm64-ohos-qt"
|
||||
|
||||
FREETYPE_PORT = {
|
||||
"name": "freetype",
|
||||
"SPDXID": "SPDXRef-port",
|
||||
"versionInfo": "2.14.3",
|
||||
"homepage": "https://www.freetype.org/",
|
||||
"licenseConcluded": "(FTL OR GPL-2.0-or-later)",
|
||||
"description": "A library to render fonts.",
|
||||
"externalRefs": [
|
||||
{
|
||||
"referenceCategory": "PACKAGE-MANAGER",
|
||||
"referenceType": "purl",
|
||||
"referenceLocator": "pkg:vcpkg/[email protected]?triplet=arm64-ohos-qt",
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
FREETYPE_RESOURCE = {
|
||||
"SPDXID": "SPDXRef-resource-0",
|
||||
"name": "freetype/freetype",
|
||||
"downloadLocation": "git+https://gitlab.freedesktop.org//freetype/freetype@VER-2-14-3",
|
||||
}
|
||||
|
||||
MESON_RESOURCE = {
|
||||
"SPDXID": "SPDXRef-resource-0",
|
||||
"name": "meson-1.9.0.tar.gz",
|
||||
"downloadLocation": "https://github.com/mesonbuild/meson/archive/1.9.0.tar.gz",
|
||||
}
|
||||
|
||||
|
||||
class TestStripPortVersion(unittest.TestCase):
|
||||
def test_plain_version_is_unchanged(self):
|
||||
self.assertEqual(strip_port_version("2.14.3"), "2.14.3")
|
||||
|
||||
def test_port_version_suffix_is_dropped(self):
|
||||
self.assertEqual(strip_port_version("2.17.1#3"), "2.17.1")
|
||||
|
||||
def test_date_version_is_unchanged(self):
|
||||
self.assertEqual(strip_port_version("2024-04-23"), "2024-04-23")
|
||||
|
||||
def test_empty_stays_empty(self):
|
||||
self.assertEqual(strip_port_version(""), "")
|
||||
|
||||
|
||||
class TestComposeCpe(unittest.TestCase):
|
||||
def test_vendor_and_product_are_inserted(self):
|
||||
self.assertEqual(
|
||||
compose_cpe("libpng:libpng", "1.6.50"),
|
||||
"cpe:2.3:a:libpng:libpng:1.6.50:*:*:*:*:*:*:*",
|
||||
)
|
||||
|
||||
def test_unmapped_port_yields_nothing(self):
|
||||
self.assertIsNone(compose_cpe(None, "1.6.50"))
|
||||
|
||||
def test_missing_version_yields_nothing(self):
|
||||
# A CPE with an empty version field matches no product at all.
|
||||
self.assertIsNone(compose_cpe("libpng:libpng", ""))
|
||||
|
||||
|
||||
class TestLoadCpeMap(unittest.TestCase):
|
||||
def test_shipped_table_has_vendor_and_product_everywhere(self):
|
||||
ports = load_cpe_map(CPE_FILE)
|
||||
self.assertIn("zlib", ports)
|
||||
for port_name, vendor_product in ports.items():
|
||||
with self.subTest(port=port_name):
|
||||
vendor, _, product = vendor_product.partition(":")
|
||||
self.assertTrue(vendor)
|
||||
self.assertTrue(product)
|
||||
self.assertNotIn(":", product)
|
||||
|
||||
|
||||
class TestNormalizeLicense(unittest.TestCase):
|
||||
def test_expression_is_kept(self):
|
||||
self.assertEqual(normalize_license("MIT"), "MIT")
|
||||
|
||||
def test_compound_expression_is_kept(self):
|
||||
self.assertEqual(
|
||||
normalize_license("(FTL OR GPL-2.0-or-later)"), "(FTL OR GPL-2.0-or-later)"
|
||||
)
|
||||
|
||||
def test_noassertion_is_rejected(self):
|
||||
self.assertIsNone(normalize_license("NOASSERTION"))
|
||||
|
||||
def test_vcpkg_null_marker_is_rejected(self):
|
||||
self.assertIsNone(normalize_license("LicenseRef-vcpkg-null"))
|
||||
|
||||
def test_missing_is_rejected(self):
|
||||
self.assertIsNone(normalize_license(None))
|
||||
|
||||
def test_empty_is_rejected(self):
|
||||
self.assertIsNone(normalize_license(""))
|
||||
|
||||
|
||||
class TestFindPurl(unittest.TestCase):
|
||||
def test_purl_is_found(self):
|
||||
self.assertEqual(
|
||||
find_purl(FREETYPE_PORT["externalRefs"]),
|
||||
"pkg:vcpkg/[email protected]?triplet=arm64-ohos-qt",
|
||||
)
|
||||
|
||||
def test_other_reference_types_are_ignored(self):
|
||||
refs = [{"referenceType": "cpe23Type", "referenceLocator": "cpe:2.3:a:x:y:1:"}]
|
||||
self.assertIsNone(find_purl(refs))
|
||||
|
||||
def test_missing_refs_are_tolerated(self):
|
||||
self.assertIsNone(find_purl(None))
|
||||
|
||||
|
||||
class TestSelectDownloadLocation(unittest.TestCase):
|
||||
def test_single_resource_is_used(self):
|
||||
self.assertEqual(
|
||||
select_download_location([FREETYPE_RESOURCE]),
|
||||
"git+https://gitlab.freedesktop.org//freetype/freetype@VER-2-14-3",
|
||||
)
|
||||
|
||||
def test_two_resources_are_ambiguous(self):
|
||||
self.assertIsNone(select_download_location([MESON_RESOURCE, FREETYPE_RESOURCE]))
|
||||
|
||||
def test_no_resources_yields_nothing(self):
|
||||
self.assertIsNone(select_download_location([]))
|
||||
|
||||
|
||||
class TestPortInstallsFiles(unittest.TestCase):
|
||||
def test_library_counts_as_installed(self):
|
||||
lines = [
|
||||
"arm64-ohos-qt/",
|
||||
"arm64-ohos-qt/lib/",
|
||||
"arm64-ohos-qt/lib/libfreetype.a",
|
||||
"arm64-ohos-qt/share/freetype/copyright",
|
||||
]
|
||||
self.assertTrue(port_installs_files(lines, TRIPLET))
|
||||
|
||||
def test_headers_count_as_installed(self):
|
||||
lines = ["arm64-ohos-qt/include/node_api.h"]
|
||||
self.assertTrue(port_installs_files(lines, TRIPLET))
|
||||
|
||||
def test_metaport_installs_nothing(self):
|
||||
lines = [
|
||||
"arm64-ohos-qt/",
|
||||
"arm64-ohos-qt/share/",
|
||||
"arm64-ohos-qt/share/pthread/copyright",
|
||||
"arm64-ohos-qt/share/pthread/vcpkg.spdx.json",
|
||||
]
|
||||
self.assertFalse(port_installs_files(lines, TRIPLET))
|
||||
|
||||
def test_tools_only_installs_nothing_linkable(self):
|
||||
lines = ["arm64-ohos-qt/tools/gperf/gperf"]
|
||||
self.assertFalse(port_installs_files(lines, TRIPLET))
|
||||
|
||||
def test_other_triplets_are_ignored(self):
|
||||
lines = ["x64-linux/lib/libfreetype.a"]
|
||||
self.assertFalse(port_installs_files(lines, TRIPLET))
|
||||
|
||||
|
||||
class TestIndexEntries(unittest.TestCase):
|
||||
def test_triplet_component_is_stripped(self):
|
||||
lines = ["arm64-ohos-qt/lib/libfreetype.a"]
|
||||
self.assertEqual(
|
||||
index_entries(lines, TRIPLET, "freetype"), {"lib/libfreetype.a": "freetype"}
|
||||
)
|
||||
|
||||
def test_bin_entries_are_indexed(self):
|
||||
lines = ["arm64-ohos-qt/bin/libfreetype.so"]
|
||||
self.assertEqual(
|
||||
index_entries(lines, TRIPLET, "freetype"), {"bin/libfreetype.so": "freetype"}
|
||||
)
|
||||
|
||||
def test_headers_are_not_indexed(self):
|
||||
lines = ["arm64-ohos-qt/include/ft2build.h"]
|
||||
self.assertEqual(index_entries(lines, TRIPLET, "freetype"), {})
|
||||
|
||||
def test_share_is_not_indexed(self):
|
||||
lines = ["arm64-ohos-qt/share/freetype/copyright"]
|
||||
self.assertEqual(index_entries(lines, TRIPLET, "freetype"), {})
|
||||
|
||||
def test_directory_entries_are_skipped(self):
|
||||
lines = ["arm64-ohos-qt/lib/"]
|
||||
self.assertEqual(index_entries(lines, TRIPLET, "freetype"), {})
|
||||
|
||||
|
||||
class TestBuildAttribution(unittest.TestCase):
|
||||
def test_full_entry(self):
|
||||
entry = build_attribution(
|
||||
FREETYPE_PORT, [FREETYPE_RESOURCE], TRIPLET, True, "freetype:freetype"
|
||||
)
|
||||
self.assertEqual(entry["Id"], "freetype")
|
||||
self.assertEqual(entry["Name"], "freetype")
|
||||
self.assertEqual(entry["Version"], "2.14.3")
|
||||
self.assertEqual(entry["Description"], "A library to render fonts.")
|
||||
self.assertEqual(entry["Homepage"], "https://www.freetype.org/")
|
||||
self.assertEqual(entry["License"], "(FTL OR GPL-2.0-or-later)")
|
||||
self.assertEqual(entry["LicenseId"], "(FTL OR GPL-2.0-or-later)")
|
||||
self.assertEqual(entry["LicenseFile"], "copyright")
|
||||
self.assertEqual(entry["PURL"], "pkg:vcpkg/[email protected]?triplet=arm64-ohos-qt")
|
||||
self.assertEqual(
|
||||
entry["DownloadLocation"],
|
||||
"git+https://gitlab.freedesktop.org//freetype/freetype@VER-2-14-3",
|
||||
)
|
||||
self.assertEqual(entry["CPE"], "cpe:2.3:a:freetype:freetype:2.14.3:*:*:*:*:*:*:*")
|
||||
self.assertIn(TRIPLET, entry["QtUsage"])
|
||||
|
||||
def test_cpe_uses_the_version_without_the_port_version_suffix(self):
|
||||
port = dict(FREETYPE_PORT)
|
||||
port["versionInfo"] = "2.17.1#3"
|
||||
entry = build_attribution(port, [], TRIPLET, False, "fontconfig_project:fontconfig")
|
||||
self.assertEqual(
|
||||
entry["CPE"], "cpe:2.3:a:fontconfig_project:fontconfig:2.17.1:*:*:*:*:*:*:*"
|
||||
)
|
||||
|
||||
def test_port_absent_from_the_cpe_table_omits_cpe(self):
|
||||
entry = build_attribution(FREETYPE_PORT, [FREETYPE_RESOURCE], TRIPLET, True)
|
||||
self.assertNotIn("CPE", entry)
|
||||
|
||||
def test_port_version_is_stripped_from_version_but_not_purl(self):
|
||||
port = dict(FREETYPE_PORT)
|
||||
port["versionInfo"] = "2.17.1#3"
|
||||
port["externalRefs"] = [
|
||||
{
|
||||
"referenceType": "purl",
|
||||
"referenceLocator": "pkg:vcpkg/[email protected]#3?triplet=arm64-ohos-qt",
|
||||
}
|
||||
]
|
||||
entry = build_attribution(port, [], TRIPLET, False)
|
||||
self.assertEqual(entry["Version"], "2.17.1")
|
||||
self.assertEqual(entry["PURL"], "pkg:vcpkg/[email protected]#3?triplet=arm64-ohos-qt")
|
||||
|
||||
def test_missing_copyright_omits_license_file(self):
|
||||
entry = build_attribution(FREETYPE_PORT, [FREETYPE_RESOURCE], TRIPLET, False)
|
||||
self.assertNotIn("LicenseFile", entry)
|
||||
|
||||
def test_unusable_license_is_omitted(self):
|
||||
port = dict(FREETYPE_PORT)
|
||||
port["licenseConcluded"] = "LicenseRef-vcpkg-null"
|
||||
entry = build_attribution(port, [], TRIPLET, False)
|
||||
self.assertNotIn("License", entry)
|
||||
self.assertNotIn("LicenseId", entry)
|
||||
|
||||
def test_ambiguous_resources_omit_download_location(self):
|
||||
entry = build_attribution(
|
||||
FREETYPE_PORT, [MESON_RESOURCE, FREETYPE_RESOURCE], TRIPLET, False
|
||||
)
|
||||
self.assertNotIn("DownloadLocation", entry)
|
||||
|
||||
def test_sparse_port_yields_minimal_entry(self):
|
||||
port = {"name": "dirent", "SPDXID": "SPDXRef-port", "versionInfo": "1.26"}
|
||||
entry = build_attribution(port, [], TRIPLET, False)
|
||||
self.assertEqual(entry["Id"], "dirent")
|
||||
self.assertEqual(entry["Version"], "1.26")
|
||||
self.assertNotIn("Description", entry)
|
||||
self.assertNotIn("Homepage", entry)
|
||||
self.assertNotIn("License", entry)
|
||||
self.assertNotIn("PURL", entry)
|
||||
|
||||
|
||||
class TestGenerate(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self._temp = tempfile.TemporaryDirectory()
|
||||
self.root = Path(self._temp.name)
|
||||
self.addCleanup(self._temp.cleanup)
|
||||
|
||||
def _write_port(self, port_name, port_package, resources, list_lines=None, copyright_text=None):
|
||||
port_dir = self.root / TRIPLET / "share" / port_name
|
||||
port_dir.mkdir(parents=True)
|
||||
document = {"packages": [port_package] + resources}
|
||||
(port_dir / "vcpkg.spdx.json").write_text(json.dumps(document), encoding="utf-8")
|
||||
if copyright_text is not None:
|
||||
(port_dir / "copyright").write_text(copyright_text, encoding="utf-8")
|
||||
if list_lines is not None:
|
||||
info_dir = self.root / "vcpkg" / "info"
|
||||
info_dir.mkdir(parents=True, exist_ok=True)
|
||||
version = strip_port_version(port_package.get("versionInfo", "0"))
|
||||
list_path = info_dir / f"{port_name}_{version}_{TRIPLET}.list"
|
||||
list_path.write_text("\n".join(list_lines) + "\n", encoding="utf-8")
|
||||
|
||||
def test_writes_attribution_and_index(self):
|
||||
self._write_port(
|
||||
"freetype",
|
||||
FREETYPE_PORT,
|
||||
[FREETYPE_RESOURCE],
|
||||
[
|
||||
f"{TRIPLET}/lib/libfreetype.a",
|
||||
f"{TRIPLET}/include/ft2build.h",
|
||||
f"{TRIPLET}/share/freetype/copyright",
|
||||
],
|
||||
copyright_text="FREETYPE LICENSES\n",
|
||||
)
|
||||
|
||||
generate(self.root, TRIPLET, {"freetype": "freetype:freetype"})
|
||||
|
||||
attribution_path = self.root / TRIPLET / "share" / "freetype" / "qt_attribution.json"
|
||||
entries = json.loads(attribution_path.read_text(encoding="utf-8"))
|
||||
self.assertEqual(len(entries), 1)
|
||||
self.assertEqual(entries[0]["Id"], "freetype")
|
||||
self.assertEqual(entries[0]["Version"], "2.14.3")
|
||||
self.assertEqual(entries[0]["LicenseFile"], "copyright")
|
||||
self.assertEqual(
|
||||
entries[0]["CPE"], "cpe:2.3:a:freetype:freetype:2.14.3:*:*:*:*:*:*:*"
|
||||
)
|
||||
|
||||
index_path = self.root / TRIPLET / "share" / "qt_vcpkg_ports.json"
|
||||
index = json.loads(index_path.read_text(encoding="utf-8"))
|
||||
self.assertEqual(index, {"lib/libfreetype.a": "freetype"})
|
||||
|
||||
def test_metaport_is_skipped(self):
|
||||
metaport = {
|
||||
"name": "pthread",
|
||||
"SPDXID": "SPDXRef-port",
|
||||
"versionInfo": "3.0.0#2",
|
||||
"licenseConcluded": "NOASSERTION",
|
||||
}
|
||||
self._write_port(
|
||||
"pthread", metaport, [], [f"{TRIPLET}/share/pthread/vcpkg.spdx.json"]
|
||||
)
|
||||
|
||||
generate(self.root, TRIPLET)
|
||||
|
||||
self.assertFalse(
|
||||
(self.root / TRIPLET / "share" / "pthread" / "qt_attribution.json").exists()
|
||||
)
|
||||
|
||||
def test_directory_without_spdx_document_is_ignored(self):
|
||||
stray = self.root / TRIPLET / "share" / "unofficial-brotli"
|
||||
stray.mkdir(parents=True)
|
||||
(stray / "unofficial-brotli-config.cmake").write_text("", encoding="utf-8")
|
||||
(self.root / "vcpkg" / "info").mkdir(parents=True)
|
||||
|
||||
generate(self.root, TRIPLET)
|
||||
|
||||
self.assertFalse((stray / "qt_attribution.json").exists())
|
||||
|
||||
def test_missing_list_file_emits_attribution_anyway(self):
|
||||
# The core failure mode this script exists to fix: emit attribution
|
||||
# even when the .list file is missing, so real libraries are not hidden.
|
||||
# The info dir itself still exists here; only this one port's .list is missing.
|
||||
(self.root / "vcpkg" / "info").mkdir(parents=True)
|
||||
self._write_port(
|
||||
"expat",
|
||||
{
|
||||
"name": "expat",
|
||||
"SPDXID": "SPDXRef-port",
|
||||
"versionInfo": "2.6.2",
|
||||
"licenseConcluded": "MIT",
|
||||
},
|
||||
[],
|
||||
list_lines=None, # No .list file
|
||||
)
|
||||
|
||||
generate(self.root, TRIPLET)
|
||||
|
||||
attribution_path = self.root / TRIPLET / "share" / "expat" / "qt_attribution.json"
|
||||
self.assertTrue(attribution_path.exists())
|
||||
entries = json.loads(attribution_path.read_text(encoding="utf-8"))
|
||||
self.assertEqual(len(entries), 1)
|
||||
self.assertEqual(entries[0]["Id"], "expat")
|
||||
|
||||
index_path = self.root / TRIPLET / "share" / "qt_vcpkg_ports.json"
|
||||
index = json.loads(index_path.read_text(encoding="utf-8"))
|
||||
self.assertEqual(index, {}) # No paths to index without .list file
|
||||
|
||||
def test_missing_info_dir_fails(self):
|
||||
# Distinguish "no install database at all" from "one port is missing its
|
||||
# .list": the former must fail loudly rather than silently emptying the
|
||||
# index for every port, which is what Path.glob on a missing dir would do.
|
||||
self._write_port(
|
||||
"expat",
|
||||
{
|
||||
"name": "expat",
|
||||
"SPDXID": "SPDXRef-port",
|
||||
"versionInfo": "2.6.2",
|
||||
"licenseConcluded": "MIT",
|
||||
},
|
||||
[],
|
||||
)
|
||||
|
||||
with self.assertRaises(SystemExit):
|
||||
generate(self.root, TRIPLET)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,8 @@
|
||||
set(VCPKG_ENV_PASSTHROUGH_UNTRACKED OHOS_SDK_ROOT)
|
||||
set(VCPKG_TARGET_ARCHITECTURE x64)
|
||||
set(VCPKG_CRT_LINKAGE dynamic)
|
||||
set(VCPKG_LIBRARY_LINKAGE static)
|
||||
set(VCPKG_CMAKE_SYSTEM_NAME OHOS)
|
||||
set(VCPKG_MAKE_BUILD_TRIPLET "--host=x86_64-unknown-linux-ohos")
|
||||
set(VCPKG_CMAKE_CONFIGURE_OPTIONS -DOHOS_ARCH=x86_64 -DCMAKE_PLATFORM_NO_VERSIONED_SONAME=ON)
|
||||
set(VCPKG_BUILD_TYPE release)
|
||||
@@ -3,7 +3,7 @@
|
||||
"default-registry": {
|
||||
"kind": "git",
|
||||
"repository": "https://git.qt.io/qtbuildsystem/vcpkg",
|
||||
"baseline": "93580fc29654eec8d22804a01d7191284d65f28e"
|
||||
"baseline": "a3e9002baa5eb8ac3bd12ef85818ffe5c0c7322d"
|
||||
},
|
||||
"overlay-triplets": [ "./../triplets" ]
|
||||
}
|
||||
|
||||
@@ -2,14 +2,19 @@
|
||||
"overrides": [
|
||||
{
|
||||
"name": "openssl",
|
||||
"version": "3.0.7",
|
||||
"port-version": 2
|
||||
"version": "3.5.4",
|
||||
"port-version": 0
|
||||
}
|
||||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "openssl",
|
||||
"platform": "!ohos"
|
||||
"platform": "!ohos & !android",
|
||||
"features": [ "tools" ]
|
||||
},
|
||||
{
|
||||
"name": "openssl",
|
||||
"platform": "android"
|
||||
},
|
||||
{
|
||||
"name": "protobuf",
|
||||
|
||||
@@ -0,0 +1,290 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
"""Convert the SPDX documents vcpkg installs into qt_attribution.json files.
|
||||
|
||||
vcpkg writes share/<port>/vcpkg.spdx.json for every installed port; Qt's SBOM
|
||||
machinery reads qt_attribution.json. Bridging the two gets vcpkg-provided
|
||||
third-party libraries into Qt's SBOM with license, version and provenance
|
||||
information, without duplicating that data in Qt repositories.
|
||||
|
||||
vcpkg records no CPEs, so those are composed from the port name to vendor and
|
||||
product table in vcpkg_port_cpes.json.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
# vcpkg's markers for "no license recorded". The second one is what a port whose
|
||||
# manifest says "license": null produces.
|
||||
UNUSABLE_LICENSES = frozenset(["", "NOASSERTION", "NONE", "LicenseRef-vcpkg-null"])
|
||||
|
||||
# A port that installs only into these provides nothing linkable.
|
||||
METADATA_DIRS = ("share/", "tools/")
|
||||
|
||||
# Only these can show up as an IMPORTED_LOCATION, so only these go into the index.
|
||||
INDEXED_DIRS = ("lib/", "bin/")
|
||||
|
||||
CPE_FILE = Path(__file__).resolve().with_name("vcpkg_port_cpes.json")
|
||||
|
||||
|
||||
def strip_port_version(version_info):
|
||||
"""Drop vcpkg's '#N' port-version suffix, keeping the upstream version.
|
||||
|
||||
The suffix is a packaging revision, so leaving it in would break version
|
||||
matching against advisory data.
|
||||
"""
|
||||
return version_info.split("#", 1)[0]
|
||||
|
||||
|
||||
def compose_cpe(vendor_product, version):
|
||||
"""Build a CPE 2.3 string for a 'vendor:product' pair at a given version.
|
||||
|
||||
The version is baked in instead of using Qt's $<VERSION> placeholder, which
|
||||
is substituted with the version find_package reported. For libjpeg-turbo that
|
||||
is libjpeg's API version 62, which would yield a CPE matching nothing.
|
||||
"""
|
||||
if not vendor_product or not version:
|
||||
return None
|
||||
return f"cpe:2.3:a:{vendor_product}:{version}:*:*:*:*:*:*:*"
|
||||
|
||||
|
||||
def load_cpe_map(cpe_file):
|
||||
"""Read the port name to 'vendor:product' table used to compose CPEs."""
|
||||
with open(cpe_file, encoding="utf-8") as handle:
|
||||
return json.load(handle)["ports"]
|
||||
|
||||
|
||||
def normalize_license(expression):
|
||||
"""Return the SPDX license expression, or None when vcpkg recorded none."""
|
||||
if expression is None or expression in UNUSABLE_LICENSES:
|
||||
return None
|
||||
return expression
|
||||
|
||||
|
||||
def find_purl(external_refs):
|
||||
for reference in external_refs or []:
|
||||
if reference.get("referenceType") == "purl":
|
||||
return reference.get("referenceLocator")
|
||||
return None
|
||||
|
||||
|
||||
def select_download_location(resources):
|
||||
"""Return the port's source URL, but only when it is unambiguous.
|
||||
|
||||
vcpkg lists downloads in the order they happened, so build tools, patches and
|
||||
license files share the list with the source, and neither the first nor the
|
||||
last entry identifies it. With one resource there is nothing to confuse.
|
||||
"""
|
||||
if len(resources) != 1:
|
||||
return None
|
||||
return resources[0].get("downloadLocation") or None
|
||||
|
||||
|
||||
def _installed_paths(list_lines, triplet):
|
||||
"""Yield the prefix-relative path of every file in a vcpkg .list file."""
|
||||
prefix = triplet + "/"
|
||||
for line in list_lines:
|
||||
entry = line.strip()
|
||||
if not entry or entry.endswith("/") or not entry.startswith(prefix):
|
||||
continue
|
||||
yield entry[len(prefix):]
|
||||
|
||||
|
||||
def port_installs_files(list_lines, triplet):
|
||||
"""True when the port installs something outside share/ and tools/.
|
||||
|
||||
Metaports such as 'pthread' exist only to depend on other ports, so they can
|
||||
never be linked and have no place in the SBOM.
|
||||
"""
|
||||
for relative in _installed_paths(list_lines, triplet):
|
||||
if not relative.startswith(METADATA_DIRS):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def index_entries(list_lines, triplet, port_name):
|
||||
"""Map prefix-relative library paths to the port that owns them.
|
||||
|
||||
Keys are relative to the prefix so that the same index serves both layouts Qt
|
||||
is configured against: the vcpkg installed tree and the flattened developer
|
||||
archive, which both have lib/ directly under the prefix.
|
||||
"""
|
||||
return {
|
||||
relative: port_name
|
||||
for relative in _installed_paths(list_lines, triplet)
|
||||
if relative.startswith(INDEXED_DIRS)
|
||||
}
|
||||
|
||||
|
||||
def build_attribution(port_package, resources, triplet, has_copyright, vendor_product=None):
|
||||
"""Map a vcpkg SPDXRef-port package onto a qt_attribution.json entry."""
|
||||
name = port_package["name"]
|
||||
entry = {
|
||||
"Id": name,
|
||||
"Name": name,
|
||||
"QtUsage": (
|
||||
f"Provided by vcpkg for the {triplet} triplet. "
|
||||
"Linked into Qt when Qt is built against this vcpkg prefix."
|
||||
),
|
||||
}
|
||||
|
||||
version = strip_port_version(port_package.get("versionInfo", ""))
|
||||
if version:
|
||||
entry["Version"] = version
|
||||
|
||||
for key, source_key in (("Description", "description"), ("Homepage", "homepage")):
|
||||
value = port_package.get(source_key)
|
||||
if value:
|
||||
entry[key] = value
|
||||
|
||||
license_expression = normalize_license(port_package.get("licenseConcluded"))
|
||||
if license_expression:
|
||||
entry["License"] = license_expression
|
||||
entry["LicenseId"] = license_expression
|
||||
|
||||
if has_copyright:
|
||||
entry["LicenseFile"] = "copyright"
|
||||
|
||||
purl = find_purl(port_package.get("externalRefs"))
|
||||
if purl:
|
||||
entry["PURL"] = purl
|
||||
|
||||
cpe = compose_cpe(vendor_product, version)
|
||||
if cpe:
|
||||
entry["CPE"] = cpe
|
||||
|
||||
download_location = select_download_location(resources)
|
||||
if download_location:
|
||||
entry["DownloadLocation"] = download_location
|
||||
|
||||
return entry
|
||||
|
||||
|
||||
def read_port_document(spdx_path):
|
||||
"""Return the SPDXRef-port package and the resource packages of an SPDX document."""
|
||||
with open(spdx_path, encoding="utf-8") as handle:
|
||||
document = json.load(handle)
|
||||
|
||||
packages = document.get("packages", [])
|
||||
port_package = next(
|
||||
(package for package in packages if package.get("SPDXID") == "SPDXRef-port"), None
|
||||
)
|
||||
resources = [
|
||||
package
|
||||
for package in packages
|
||||
if str(package.get("SPDXID", "")).startswith("SPDXRef-resource")
|
||||
]
|
||||
return port_package, resources
|
||||
|
||||
|
||||
def find_list_file(info_dir, port_name, triplet):
|
||||
"""Locate a port's vcpkg .list file.
|
||||
|
||||
The file name omits the port-version altogether (fontconfig's SPDX document
|
||||
says 'versionInfo: 2.17.1#3', but its .list file is
|
||||
'fontconfig_2.17.1_arm64-ohos-qt.list'), so glob on the port and triplet
|
||||
components instead of trying to reconstruct the exact file name.
|
||||
"""
|
||||
matches = sorted(info_dir.glob(f"{port_name}_*_{triplet}.list"))
|
||||
if len(matches) == 1:
|
||||
return matches[0]
|
||||
return None
|
||||
|
||||
|
||||
def generate(install_root, triplet, cpe_map=None):
|
||||
share_dir = install_root / triplet / "share"
|
||||
info_dir = install_root / "vcpkg" / "info"
|
||||
|
||||
if not share_dir.is_dir():
|
||||
raise SystemExit(f"error: no such directory: {share_dir}")
|
||||
|
||||
# Path.glob on a missing directory silently yields nothing, which would otherwise make
|
||||
# every port look like it has no .list file and write an empty index for the whole tree.
|
||||
if not info_dir.is_dir():
|
||||
raise SystemExit(f"error: no such directory: {info_dir}")
|
||||
|
||||
cpe_map = cpe_map or {}
|
||||
index = {}
|
||||
written = []
|
||||
skipped = []
|
||||
unusable_license = []
|
||||
without_cpe = []
|
||||
|
||||
for spdx_path in sorted(share_dir.glob("*/vcpkg.spdx.json")):
|
||||
port_dir = spdx_path.parent
|
||||
port_package, resources = read_port_document(spdx_path)
|
||||
if port_package is None:
|
||||
raise SystemExit(f"error: no SPDXRef-port package in {spdx_path}")
|
||||
|
||||
port_name = port_package["name"]
|
||||
list_file = find_list_file(info_dir, port_name, triplet)
|
||||
|
||||
if list_file is None:
|
||||
# Emitting nothing would hide a real library, which is the very gap
|
||||
# this script exists to close.
|
||||
print(f"warning: no .list file for port '{port_name}' under {info_dir}")
|
||||
list_lines = []
|
||||
else:
|
||||
list_lines = list_file.read_text(encoding="utf-8").splitlines()
|
||||
if not port_installs_files(list_lines, triplet):
|
||||
skipped.append(port_name)
|
||||
continue
|
||||
index.update(index_entries(list_lines, triplet, port_name))
|
||||
|
||||
entry = build_attribution(
|
||||
port_package,
|
||||
resources,
|
||||
triplet,
|
||||
(port_dir / "copyright").is_file(),
|
||||
cpe_map.get(port_name),
|
||||
)
|
||||
if "License" not in entry:
|
||||
unusable_license.append(port_name)
|
||||
if "CPE" not in entry:
|
||||
without_cpe.append(port_name)
|
||||
|
||||
with open(port_dir / "qt_attribution.json", "w", encoding="utf-8") as handle:
|
||||
json.dump([entry], handle, indent=4, sort_keys=True)
|
||||
handle.write("\n")
|
||||
written.append(port_name)
|
||||
|
||||
with open(share_dir / "qt_vcpkg_ports.json", "w", encoding="utf-8") as handle:
|
||||
json.dump(index, handle, indent=4, sort_keys=True)
|
||||
handle.write("\n")
|
||||
|
||||
print(f"Wrote {len(written)} qt_attribution.json file(s) under {share_dir}")
|
||||
print(f"Indexed {len(index)} installed librar(y/ies) in qt_vcpkg_ports.json")
|
||||
if skipped:
|
||||
print(f"Skipped {len(skipped)} port(s) installing no files: {', '.join(skipped)}")
|
||||
if without_cpe:
|
||||
print(f"No CPE for {len(without_cpe)} port(s): {', '.join(without_cpe)}")
|
||||
for port_name in unusable_license:
|
||||
print(f"warning: port '{port_name}' has no usable license expression")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
"--install-root",
|
||||
required=True,
|
||||
type=Path,
|
||||
help="vcpkg install root, the directory holding <triplet>/ and vcpkg/info/",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--triplet", required=True, help="vcpkg triplet, for example arm64-ohos-qt"
|
||||
)
|
||||
arguments = parser.parse_args()
|
||||
|
||||
# Dropping CPEs on a missing table would silently defeat vulnerability scanning,
|
||||
# which is the only thing that reads them.
|
||||
if not CPE_FILE.is_file():
|
||||
raise SystemExit(f"error: no such file: {CPE_FILE}")
|
||||
|
||||
generate(arguments.install_root.resolve(), arguments.triplet, load_cpe_map(CPE_FILE))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"comment": [
|
||||
"Maps a vcpkg port name to the CPE 2.3 vendor and product of the upstream project.",
|
||||
"vcpkg records no CPEs, and Dependency-Track can only scan CPEs, so the attribution",
|
||||
"generator composes one from this table and the port version.",
|
||||
"brotli, fontconfig and icu were looked up in the NVD CPE dictionary at",
|
||||
"https://services.nvd.nist.gov/rest/json/cpes/2.0?keywordSearch=<name> ; the others were",
|
||||
"copied from the matching qt_attribution.json under qtbase/src/3rdparty.",
|
||||
"Never guess an entry: the obvious icu:icu and fontconfig:fontconfig both match nothing in",
|
||||
"NVD, and a CPE that matches nothing produces a clean scan that means nothing. A port that",
|
||||
"is absent here gets no CPE at all, which is the safe outcome."
|
||||
],
|
||||
"ports": {
|
||||
"brotli": "google:brotli",
|
||||
"fontconfig": "fontconfig_project:fontconfig",
|
||||
"freetype": "freetype:freetype",
|
||||
"icu": "icu-project:international_components_for_unicode",
|
||||
"libjpeg-turbo": "libjpeg-turbo:libjpeg-turbo",
|
||||
"libpng": "libpng:libpng",
|
||||
"zlib": "zlib:zlib"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
vcpkg_tool_release_tag=2026-05-27
|
||||
windows_x64_checksum=da75e3312ff6881c89f6171363eedb92933b0f79456cd6ee636316edef860ff7
|
||||
windows_arm64_checksum=371cf5285cc94932b97c8c0774066c90efdb50dfe606113f1686e6e99f928b08
|
||||
unix_checksum=9167b2348ae58bfb707cf5e18f055f51d9cdedc2cc251a475d5c2ca3d901e8ae
|
||||
vcpkg_tool_release_tag=2026-07-27
|
||||
windows_x64_checksum=13b8175e99a884c5ad34249218754b45541a1a63f216e92603aee57a285ac741
|
||||
windows_arm64_checksum=5e8d7acd0f3049411ad1eacd3af2a946014ed430c27010e384ee1289a8e98cbc
|
||||
unix_checksum=cb2ac34ab85008876004b0817c0a82c96f773ce3aaedb9c35e8ebb523ef1754b
|
||||
|
||||
@@ -1 +1 @@
|
||||
vcpkg_version=2026.06.01-qt
|
||||
vcpkg_version=2026.07.29-qt
|
||||
|
||||
@@ -112,7 +112,7 @@ do
|
||||
echo "Starting emulator ${AVD_NAME}, try ${counter}/${EMULATOR_MAX_RETRIES}" \
|
||||
| tee "${EMULATOR_RUN_LOG_PATH}"
|
||||
$EMULATOR_EXEC -avd "$AVD_NAME" \
|
||||
-gpu swiftshader_indirect -no-audio $WINDOW_ARG -no-boot-anim \
|
||||
-gpu swiftshader -no-audio $WINDOW_ARG -no-boot-anim \
|
||||
-cores 4 -memory 16000 -partition-size 4096 \
|
||||
-detect-image-hang -restart-when-stalled -no-snapshot-save \
|
||||
-no-nested-warnings -logcat '*:v' -logcat-output "${LOGCAT_PATH}" \
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
download_ffmpeg() (
|
||||
local version="${1:-"9.0.1"}"
|
||||
local sha1="${2:-89c318905212e6b67e10e42ab10ab8007e0aefda}"
|
||||
local version="${1:-"9.0.2"}"
|
||||
local sha1="${2:-40c70cddcdc2e32b1b0fad2c85915c9145532452}"
|
||||
|
||||
local ffmpeg_name="FFmpeg-n$version"
|
||||
local target_dir="$HOME"
|
||||
|
||||
@@ -8,13 +8,22 @@ source "${BASH_SOURCE%/*}/../unix/SetEnvVar.sh"
|
||||
echo "Installing vcpkg OHOS ports"
|
||||
|
||||
# The vcpkg OHOS toolchain expects OHOS_SDK_ROOT; CI sets HARMONYOS_SDK_ROOT.
|
||||
export OHOS_SDK_ROOT="${OHOS_SDK_ROOT:-$HARMONYOS_SDK_ROOT}"
|
||||
ohosSdkRoot="${OHOS_SDK_ROOT:-$HARMONYOS_SDK_ROOT}"
|
||||
|
||||
if [ -z "$OHOS_SDK_ROOT" ]; then
|
||||
if [ -z "$ohosSdkRoot" ]; then
|
||||
echo "ERROR: Neither OHOS_SDK_ROOT nor HARMONYOS_SDK_ROOT is set." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# On Linux, HARMONYOS_SDK_ROOT points at the command-line-tools root; the vcpkg
|
||||
# toolchain needs the openharmony native SDK inside it. On macOS it already
|
||||
# points there, so only descend when the nested SDK exists.
|
||||
if [ -d "$ohosSdkRoot/sdk/default/openharmony/native" ]; then
|
||||
ohosSdkRoot="$ohosSdkRoot/sdk/default/openharmony"
|
||||
fi
|
||||
|
||||
export OHOS_SDK_ROOT="$ohosSdkRoot"
|
||||
|
||||
# Coin sets TARGET=hdb in the environment. GNU Make imports env vars as make
|
||||
# variables, which breaks ICU's Makefile (it defines its own TARGET variable
|
||||
# for the library path). Unset it before invoking vcpkg.
|
||||
|
||||
@@ -23,6 +23,10 @@ cmake "-DVCPKG_EXECUTABLE=$VCPKG_ROOT/vcpkg"\
|
||||
mkdir -p "$VCPKG_ROOT/installed"
|
||||
cp -R $install_root/* "$VCPKG_ROOT/installed/"
|
||||
|
||||
python3 "${BASH_SOURCE%/*}/../shared/vcpkg_generate_attributions.py" \
|
||||
--install-root "$VCPKG_ROOT/installed" \
|
||||
--triplet "$1"
|
||||
|
||||
SetEnvVar "VCPKG_INSTALLED_DIR" "$VCPKG_ROOT/installed/"
|
||||
|
||||
rm -rf $install_root
|
||||
|
||||
@@ -11,6 +11,15 @@ source "${BASH_SOURCE%/*}/SourceEnvVars.sh"
|
||||
|
||||
# This script will install Google's Protocal Buffers
|
||||
|
||||
# On Intel macOS /usr/local is user-owned by homebrew; using sudo there would
|
||||
# change ownership to root and break later brew installations. On Apple Silicon
|
||||
# homebrew uses /opt/homebrew instead, and /usr/local stays root-owned, so sudo
|
||||
# is still required.
|
||||
SUDO="sudo"
|
||||
if uname -a | grep -q Darwin && [ "$(uname -m)" = "x86_64" ]; then
|
||||
SUDO=""
|
||||
fi
|
||||
|
||||
version="21.9"
|
||||
sha1="3226a0e49d048759b702ae524da79387c59f05cc"
|
||||
internalUrl="http://ci-files01-hki.ci.qt.io/input/automotive_suite/protobuf-all-$version.zip"
|
||||
@@ -20,7 +29,7 @@ targetDir="$HOME/protobuf-$version"
|
||||
targetFile="$targetDir.zip"
|
||||
DownloadURL "$internalUrl" "$externalUrl" "$sha1" "$targetFile"
|
||||
unzip "$targetFile" -d "$HOME"
|
||||
sudo rm "$targetFile"
|
||||
$SUDO rm "$targetFile"
|
||||
|
||||
cd $targetDir
|
||||
|
||||
@@ -81,7 +90,7 @@ cmake "$targetDir" -G"Ninja Multi-Config" \
|
||||
-DCMAKE_CROSS_CONFIGS=all \
|
||||
-DCMAKE_DEFAULT_CONFIGS=all
|
||||
ninja all:all
|
||||
sudo env "PATH=$PATH" ninja install:all
|
||||
$SUDO env "PATH=$PATH" ninja install:all
|
||||
|
||||
SetEnvVar "protobuf_ROOT" "$installPrefix"
|
||||
|
||||
@@ -90,5 +99,5 @@ if uname -a |grep -qv "Darwin"; then
|
||||
sudo ldconfig
|
||||
fi
|
||||
|
||||
sudo rm -r "$targetDir"
|
||||
sudo rm -r "$buildDir"
|
||||
$SUDO rm -r "$targetDir"
|
||||
$SUDO rm -r "$buildDir"
|
||||
|
||||
@@ -38,10 +38,10 @@ zip="/tmp/libclang.7z"
|
||||
destination="/usr/local/libclang-dynlibs-$version"
|
||||
|
||||
DownloadURL "$url_cached" "$url" "$sha1" "$zip"
|
||||
if command -v 7zr &> /dev/null; then
|
||||
sudo 7zr x $zip -o/usr/local/
|
||||
else
|
||||
if command -v 7z &> /dev/null; then
|
||||
sudo 7z x $zswitch $zip -o/usr/local/
|
||||
else
|
||||
sudo 7zr x $zip -o/usr/local/
|
||||
fi
|
||||
sudo mv /usr/local/libclang "$destination"
|
||||
rm -rf $zip
|
||||
|
||||
@@ -59,10 +59,10 @@ zip="/tmp/libclang.7z"
|
||||
destination="/usr/local/libclang-$version"
|
||||
|
||||
DownloadURL $url_cached $url $sha1 $zip
|
||||
if command -v 7zr &> /dev/null; then
|
||||
sudo 7zr x $zip -o/usr/local/
|
||||
else
|
||||
if command -v 7z &> /dev/null; then
|
||||
sudo 7z x $zswitch $zip -o/usr/local/
|
||||
else
|
||||
sudo 7zr x $zip -o/usr/local/
|
||||
fi
|
||||
sudo mv /usr/local/libclang "$destination"
|
||||
rm -rf $zip
|
||||
|
||||
@@ -20,11 +20,22 @@ function Verify-Checksum
|
||||
}
|
||||
}
|
||||
|
||||
function Run-Executable-With-Timeout
|
||||
{
|
||||
Param (
|
||||
[int]$TimeoutSeconds=$(throw("You must specify a timeout.")),
|
||||
[string]$Executable=$(throw("You must specify a program to run.")),
|
||||
[string[]]$Arguments
|
||||
)
|
||||
Run-Executable -Executable $Executable -Arguments $Arguments -TimeoutSeconds $TimeoutSeconds
|
||||
}
|
||||
|
||||
function Run-Executable
|
||||
{
|
||||
Param (
|
||||
[string]$Executable=$(throw("You must specify a program to run.")),
|
||||
[string[]]$Arguments
|
||||
[string[]]$Arguments,
|
||||
[int]$TimeoutSeconds = 0
|
||||
)
|
||||
|
||||
$stdoutFile = [System.IO.Path]::GetTempFileName()
|
||||
@@ -32,13 +43,33 @@ function Run-Executable
|
||||
|
||||
if ([string]::IsNullOrEmpty($Arguments)) {
|
||||
Write-Host "Running `"$Executable`""
|
||||
$p = Start-Process -FilePath "$Executable" -Wait -PassThru `
|
||||
-RedirectStandardOutput $stdoutFile -RedirectStandardError $stderrFile
|
||||
} else {
|
||||
Write-Host "Running `"$Executable`" with arguments `"$Arguments`""
|
||||
$p = Start-Process -FilePath "$Executable" -ArgumentList $Arguments -PassThru `
|
||||
-RedirectStandardOutput $stdoutFile -RedirectStandardError $stderrFile
|
||||
Wait-Process -InputObject $p
|
||||
}
|
||||
|
||||
$startArgs = @{
|
||||
FilePath = $Executable
|
||||
PassThru = $true
|
||||
NoNewWindow = $true
|
||||
RedirectStandardOutput = $stdoutFile
|
||||
RedirectStandardError = $stderrFile
|
||||
}
|
||||
if (-not [string]::IsNullOrEmpty($Arguments)) {
|
||||
$startArgs.ArgumentList = $Arguments
|
||||
}
|
||||
$p = Start-Process @startArgs
|
||||
# Force PowerShell to cache the process handle. Without this, $p.ExitCode
|
||||
# can read back as $null after the process exits.
|
||||
# See https://github.com/PowerShell/PowerShell/issues/5421
|
||||
$null = $p.Handle
|
||||
|
||||
if ($TimeoutSeconds -gt 0) {
|
||||
if (-not $p.WaitForExit($TimeoutSeconds * 1000)) {
|
||||
$p.Kill()
|
||||
throw "Process $($Executable) timed out after $TimeoutSeconds seconds"
|
||||
}
|
||||
} else {
|
||||
$p.WaitForExit()
|
||||
}
|
||||
|
||||
$stdoutContent = [System.IO.File]::ReadAllText($stdoutFile)
|
||||
@@ -74,50 +105,76 @@ function Run-Executable
|
||||
function Extract-tar_gz
|
||||
{
|
||||
Param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
[ValidateScript({ Test-Path $_ -PathType Leaf })]
|
||||
[string]$Source,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Destination
|
||||
)
|
||||
|
||||
Write-Host "Extracting '$Source' to '$Destination'..."
|
||||
|
||||
if ((Get-Command "7z.exe" -ErrorAction SilentlyContinue) -eq $null) {
|
||||
$zipExe = join-path (${env:ProgramFiles(x86)}, ${env:ProgramFiles}, ${env:ProgramW6432} -ne $null)[0] '7-zip\7z.exe'
|
||||
if (-not (test-path $zipExe)) {
|
||||
$zipExe = "C:\Utils\sevenzip\7z.exe"
|
||||
if (-not (test-path $zipExe)) {
|
||||
throw "Could not find 7-zip."
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$zipExe = "7z.exe"
|
||||
$zipExe = Get-SevenZipPath
|
||||
|
||||
# cmd.exe does not treat single quotes as quoting characters, so use double
|
||||
# quotes and wrap the whole command in an extra pair that cmd /C strips.
|
||||
# A trailing backslash (e.g. "C:\") would escape the closing quote when 7z
|
||||
# parses its arguments, so double it.
|
||||
$dest = $Destination -replace '\\$', '\\'
|
||||
Run-Executable "cmd.exe" "/C `"`"$zipExe`" x -y `"$Source`" -so | `"$zipExe`" x -y -aoa -si -ttar `"-o$dest`"`""
|
||||
}
|
||||
|
||||
function Get-SevenZipPath {
|
||||
# Try to find 7z.exe in PATH first
|
||||
$cmd = Get-Command "7z.exe" -ErrorAction SilentlyContinue
|
||||
if ($cmd) {
|
||||
return $cmd.Path
|
||||
}
|
||||
Run-Executable "cmd.exe" "/C $zipExe x -y `"$Source`" -so | $zipExe x -y -aoa -si -ttar `"-o$Destination`""
|
||||
|
||||
# List of common Program Files directories to check
|
||||
$possibleRoots = @(
|
||||
${env:ProgramFiles(x86)},
|
||||
${env:ProgramFiles},
|
||||
${env:ProgramW6432}
|
||||
) | Where-Object { $_ -ne $null }
|
||||
|
||||
foreach ($root in $possibleRoots) {
|
||||
$candidate = Join-Path $root "7-Zip\7z.exe"
|
||||
if (Test-Path $candidate) {
|
||||
return $candidate
|
||||
}
|
||||
}
|
||||
|
||||
# Fallback path
|
||||
$fallback = "C:\Utils\sevenzip\7z.exe"
|
||||
if (Test-Path $fallback) {
|
||||
return $fallback
|
||||
}
|
||||
|
||||
throw "Could not find 7-Zip executable."
|
||||
}
|
||||
|
||||
function Extract-7Zip
|
||||
{
|
||||
Param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
[ValidateScript({ Test-Path $_ -PathType Leaf })]
|
||||
[string]$Source,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Destination,
|
||||
[string]$Filter
|
||||
)
|
||||
|
||||
Write-Host "Extracting '$Source' to '$Destination'..."
|
||||
|
||||
if ((Get-Command "7z.exe" -ErrorAction SilentlyContinue) -eq $null) {
|
||||
$zipExe = join-path (${env:ProgramFiles(x86)}, ${env:ProgramFiles}, ${env:ProgramW6432} -ne $null)[0] '7-zip\7z.exe'
|
||||
if (-not (test-path $zipExe)) {
|
||||
$zipExe = "C:\Utils\sevenzip\7z.exe"
|
||||
if (-not (test-path $zipExe)) {
|
||||
throw "Could not find 7-zip."
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$zipExe = "7z.exe"
|
||||
}
|
||||
$zipExe = Get-SevenZipPath
|
||||
|
||||
# 7-Zip will frequently misinterpret paths that contain whitespaces
|
||||
# unless we explicitly insert quotations.
|
||||
if ([string]::IsNullOrEmpty($Filter)) {
|
||||
Run-Executable "$zipExe" "x -y `"-o$Destination`" `"$Source`""
|
||||
Run-Executable "$zipExe" @("x", "-y", "-o`"$Destination`"", "`"$Source`"")
|
||||
} else {
|
||||
Run-Executable "$zipExe" "x -y -aoa `"-o$Destination`" `"$Source`" $Filter"
|
||||
Run-Executable "$zipExe" @("x", "-y", "-o`"$Destination`"", "`"$Source`"", $Filter)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,6 +259,30 @@ function Is64BitWinHost
|
||||
return [environment]::Is64BitOperatingSystem
|
||||
}
|
||||
|
||||
# Expands "~" and relative paths into a full native Windows path.
|
||||
# The path does not need to exist.
|
||||
function Resolve-FullPath
|
||||
{
|
||||
Param (
|
||||
[string]$Path = $(BadParam("a path"))
|
||||
)
|
||||
return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path)
|
||||
}
|
||||
|
||||
# Translates a native Windows path into an MSYS compatible one,
|
||||
# e.g. "C:\foo\bar" -> "/c/foo/bar".
|
||||
function ConvertTo-MsysPath
|
||||
{
|
||||
Param (
|
||||
[string]$Path = $(BadParam("a path"))
|
||||
)
|
||||
$result = $Path -replace '\\', '/'
|
||||
if ($result -match '^([A-Za-z]):(.*)$') {
|
||||
$result = "/$($Matches[1].ToLower())$($Matches[2])"
|
||||
}
|
||||
return $result
|
||||
}
|
||||
|
||||
enum CpuArch {
|
||||
x64
|
||||
x86
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
. "$PSScriptRoot\install-ffmpeg-common.ps1"
|
||||
|
||||
function InstallAndroidArmv7 {
|
||||
param (
|
||||
[string]$ndk_root,
|
||||
[string]$ffmpeg_dir_android_envvar_name,
|
||||
[string]$ndk_version,
|
||||
[string]$android_openssl_path, # OpenSSL is built for Android using NDK, NDK versions for OpenSSL+FFmpeg should match
|
||||
[string]$android_page_size
|
||||
)
|
||||
$shared=$true
|
||||
$target_toolchain_arch="armv7a-linux-androideabi"
|
||||
$target_arch="armv7-a"
|
||||
$target_cpu="armv7-a"
|
||||
$api_version="24"
|
||||
|
||||
$ndk_dir = ConvertTo-MsysPath $ndk_root
|
||||
|
||||
$toolchain="${ndk_dir}/toolchains/llvm/prebuilt/windows-x86_64"
|
||||
$toolchain_bin="${toolchain}/bin"
|
||||
$sysroot="${toolchain}/sysroot"
|
||||
$cxx="${toolchain_bin}/${target_toolchain_arch}${api_version}-clang++"
|
||||
$cc="${toolchain_bin}/${target_toolchain_arch}${api_version}-clang"
|
||||
$ld="${toolchain_bin}/ld.exe"
|
||||
$ar="${toolchain_bin}/llvm-ar.exe"
|
||||
$ranlib="${toolchain_bin}/llvm-ranlib.exe"
|
||||
$nm="${toolchain_bin}/llvm-nm.exe"
|
||||
$strip="${toolchain_bin}/llvm-strip.exe"
|
||||
|
||||
Write-Host "Copying _3.so's to .so's"
|
||||
Copy-Item -Path ${android_openssl_path}/armeabi-v7a/libcrypto_3.so -Destination ${android_openssl_path}/armeabi-v7a/libcrypto.so
|
||||
Copy-Item -Path ${android_openssl_path}/armeabi-v7a/libssl_3.so -Destination ${android_openssl_path}/armeabi-v7a/libssl.so
|
||||
|
||||
$android_openssl_path_msys = ConvertTo-MsysPath $android_openssl_path
|
||||
|
||||
$config = GetFfmpegDefaultConfiguration
|
||||
$config += " --enable-cross-compile --target-os=android --enable-jni --enable-mediacodec --enable-openssl --enable-pthreads --enable-neon --disable-asm --disable-indev=android_camera"
|
||||
$config += " --arch=$target_arch --cpu=${target_cpu} --sysroot=${sysroot} --sysinclude=${sysroot}/usr/include/"
|
||||
$config += " --cc=${cc} --cxx=${cxx} --ar=${ar} --ranlib=${ranlib}"
|
||||
$config += " --extra-cflags=-I${android_openssl_path_msys}/include --extra-ldflags=-L${android_openssl_path_msys}/armeabi-v7a"
|
||||
if ($android_page_size -eq "use_16kb_page_size"){
|
||||
$config += " --extra-ldflags=-Wl,-z,max-page-size=16384"
|
||||
Write-Host "FFmpeg Android using 16KB page sizes"
|
||||
} elseif ($android_page_size -eq "use_4kb_page_size") {
|
||||
Write-Host "FFmpeg Android using 4KB page sizes"
|
||||
} else {
|
||||
Write-Host "Error: FFmpeg Android page_size must be: use_16kb_page_size or: use_16kb_page_size got: $android_page_size"
|
||||
return false
|
||||
}
|
||||
|
||||
$config += " --strip=$strip"
|
||||
|
||||
$buildSystem = "android-arm"
|
||||
$result= InstallFfmpeg -config $config -buildSystem $buildSystem -msystem "ANDROID_CLANG" -ffmpegDirEnvVar $ffmpeg_dir_android_envvar_name -shared $shared -ndk_ver $ndk_version
|
||||
|
||||
Remove-Item -Path ${android_openssl_path}/armeabi-v7a/libcrypto.so
|
||||
Remove-Item -Path ${android_openssl_path}/armeabi-v7a/libssl.so
|
||||
|
||||
if (-not $shared) {
|
||||
return $result
|
||||
}
|
||||
|
||||
# For Shared ffmpeg we need to change dependencies to stubs
|
||||
Start-Process -NoNewWindow -Wait -PassThru -ErrorAction Stop -FilePath $msys -ArgumentList ("-lc", "`"pacman -Sy --noconfirm binutils`"")
|
||||
Start-Process -NoNewWindow -Wait -PassThru -ErrorAction Stop -FilePath $msys -ArgumentList ("-lc", "`"pacman -Sy --noconfirm autoconf`"")
|
||||
Start-Process -NoNewWindow -Wait -PassThru -ErrorAction Stop -FilePath $msys -ArgumentList ("-lc", "`"pacman -Sy --noconfirm automake`"")
|
||||
Start-Process -NoNewWindow -Wait -PassThru -ErrorAction Stop -FilePath $msys -ArgumentList ("-lc", "`"pacman -Sy --noconfirm libtool`"")
|
||||
|
||||
$patchelf_sha1 = "DDD46A2E2A16A308245C008721D877455B23BBA8"
|
||||
$patchelf_sources = "https://ci-files01-hki.ci.qt.io/input/android/patchelf/0.17.2.tar.gz"
|
||||
$patchelf_download_location = "C:\Windows\Temp\0.17.2.tar.gz"
|
||||
|
||||
try {
|
||||
Invoke-WebRequest -UseBasicParsing $patchelf_sources -OutFile $patchelf_download_location
|
||||
Verify-Checksum $patchelf_download_location $patchelf_sha1
|
||||
Extract-tar_gz $patchelf_download_location $unzip_location
|
||||
Remove $patchelf_download_location
|
||||
} catch {
|
||||
Write-Host "Error grabbing sources when installing patchelf:"
|
||||
Write-Host $_
|
||||
return $false
|
||||
}
|
||||
|
||||
Start-Process -NoNewWindow -Wait -PassThru -ErrorAction Stop -FilePath $msys -ArgumentList ("-lc", "`"cd C:/patchelf-0.17.2 && ./bootstrap.sh && ./configure && make install`"")
|
||||
|
||||
$installDir = ResolveFFmpegInstallDir -buildSystem $buildSystem -ndkVer $ndk_version
|
||||
$installDirForMsys = ConvertTo-MsysPath $installDir
|
||||
$command = "${PSScriptRoot}/../shared/fix_ffmpeg_dependencies.sh ${installDirForMsys} _armeabi-v7a no"
|
||||
$command = $command.Replace("\", "/")
|
||||
$patchResult = Start-Process -NoNewWindow -Wait -PassThru -ErrorAction Stop -FilePath $msys -ArgumentList ("-lc", "`"$command`"")
|
||||
if ($patchResult.ExitCode) {
|
||||
Write-Host "fix_ffmpeg_dependencies.sh did not finish successfully"
|
||||
return $false
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
# Shared variables and helpers for the FFmpeg install scripts
|
||||
|
||||
. "$PSScriptRoot\helpers.ps1"
|
||||
|
||||
$msys = "C:\Utils\msys64\usr\bin\bash"
|
||||
|
||||
$version="9.0.2"
|
||||
$url_public="https://ffmpeg.org/releases/ffmpeg-$version.tar.gz"
|
||||
$sha1="40c70cddcdc2e32b1b0fad2c85915c9145532452"
|
||||
$url_cached="http://ci-files01-hki.ci.qt.io/input/ffmpeg/ffmpeg-$version.tar.gz"
|
||||
$ffmpeg_name="FFmpeg-n$version"
|
||||
|
||||
$download_location = "C:\Windows\Temp\$ffmpeg_name.tar.gz"
|
||||
$unzip_location = "C:\"
|
||||
$ffmpeg_source_dir = "C:\$ffmpeg_name"
|
||||
|
||||
# Downloads and extracts the FFmpeg source into $ffmpeg_source_dir.
|
||||
function GetFfmpegSource {
|
||||
Write-Host "Fetching FFmpeg $version..."
|
||||
|
||||
$extract_temp_dir = "C:\Windows\Temp\FFmpeg-extract-$([System.Guid]::NewGuid().ToString('N'))"
|
||||
|
||||
try {
|
||||
New-Item -ItemType Directory -Path $extract_temp_dir -Force | Out-Null
|
||||
|
||||
Download $url_public $url_cached $download_location
|
||||
Verify-Checksum $download_location $sha1
|
||||
Extract-tar_gz $download_location $extract_temp_dir
|
||||
|
||||
$extracted_dirs = @(Get-ChildItem -Path $extract_temp_dir -Directory)
|
||||
if ($extracted_dirs.Count -ne 1) {
|
||||
throw "Expected exactly one directory in the FFmpeg archive, got: $($extracted_dirs.Name -join ', ')"
|
||||
}
|
||||
|
||||
Remove $ffmpeg_source_dir
|
||||
Move-Item -Path $extracted_dirs[0].FullName -Destination $ffmpeg_source_dir
|
||||
} finally {
|
||||
Remove $download_location
|
||||
Remove $extract_temp_dir
|
||||
}
|
||||
}
|
||||
|
||||
function GetFfmpegDefaultConfiguration {
|
||||
$defaultConfiguration = Get-Content "$PSScriptRoot\..\shared\ffmpeg_config_options.txt"
|
||||
Write-Host "FFmpeg default configuration: $defaultConfiguration"
|
||||
|
||||
return $defaultConfiguration
|
||||
}
|
||||
|
||||
# Returns the absolute installation path of FFmpeg for this build
|
||||
# variant.
|
||||
function ResolveFFmpegInstallDir {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$buildSystem,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$ndkVer
|
||||
)
|
||||
|
||||
if ($ndkVer) {
|
||||
$prefix = "installed-ndk-$ndkVer"
|
||||
} else {
|
||||
$prefix = "installed"
|
||||
}
|
||||
|
||||
return "C:\$ffmpeg_name\build\$buildSystem\$prefix"
|
||||
}
|
||||
|
||||
function InstallFfmpeg {
|
||||
Param (
|
||||
[string]$config,
|
||||
[string]$buildSystem,
|
||||
[string]$msystem,
|
||||
[string]$additionalPath,
|
||||
[string]$ffmpegDirEnvVar,
|
||||
[string]$toolchain,
|
||||
[bool]$shared,
|
||||
[string]$ndk_ver, # Optional param for installing each ffmpeg build with different Android NDK
|
||||
[string]$installDir, # Optional override for where to install the build artifacts
|
||||
[string]$msysBash, # Optional override for the MSYS bash executable
|
||||
[bool]$skipEnvVar = $false # Optional:
|
||||
# Don't assign the FFmpeg dir environment variable.
|
||||
# Allows the function to run without elevated privileges.
|
||||
)
|
||||
|
||||
Write-Host "Configure and compile FFmpeg for $buildSystem with configuration: $config"
|
||||
|
||||
$bash = if ($msysBash) { $msysBash } else { $msys }
|
||||
|
||||
$oldPath = $env:PATH
|
||||
|
||||
if ($additionalPath) {
|
||||
$env:PATH = "$additionalPath;$env:PATH"
|
||||
}
|
||||
$env:MSYS2_PATH_TYPE = "inherit"
|
||||
$env:MSYSTEM = $msystem
|
||||
|
||||
if (-not $installDir) {
|
||||
if ($ndk_ver) {
|
||||
$installDir = ResolveFFmpegInstallDir -buildSystem $buildSystem -ndkVer $ndk_ver
|
||||
} else {
|
||||
$installDir = ResolveFFmpegInstallDir -buildSystem $buildSystem
|
||||
}
|
||||
}
|
||||
$installDirForMsys = ConvertTo-MsysPath $installDir
|
||||
|
||||
$cmd = "cd /c/$ffmpeg_name"
|
||||
$cmd += " && mkdir -p build/$buildSystem && cd build/$buildSystem"
|
||||
$cmd += " && ../../configure --prefix=$installDirForMsys $config"
|
||||
if ($toolchain) {
|
||||
$cmd += " --toolchain=$toolchain"
|
||||
}
|
||||
if ($shared) {
|
||||
$cmd += " --enable-shared --disable-static"
|
||||
}
|
||||
$cmd += " && make install -j"
|
||||
|
||||
Write-Host "MSYS cmd:"
|
||||
Write-Host $cmd
|
||||
$buildResult = Start-Process -NoNewWindow -Wait -PassThru -ErrorAction Stop -FilePath "$bash" -ArgumentList ("-lc", "`"$cmd`"")
|
||||
|
||||
$env:PATH = $oldPath
|
||||
|
||||
if ($buildResult.ExitCode) {
|
||||
Write-Host "Failed to build FFmpeg for $buildSystem"
|
||||
return $false
|
||||
}
|
||||
|
||||
if (-not $skipEnvVar) {
|
||||
Set-EnvironmentVariable $ffmpegDirEnvVar $installDir
|
||||
}
|
||||
return $true
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
. "$PSScriptRoot\install-ffmpeg-common.ps1"
|
||||
|
||||
function InstallLlvmMingwFfmpeg {
|
||||
$config = GetFfmpegDefaultConfiguration
|
||||
return InstallFfmpeg -config $config -buildSystem "llvm-mingw" -msystem "CLANG64" -ffmpegDirEnvVar "FFMPEG_DIR_LLVM_MINGW" -additionalPath "C:\llvm-mingw\bin" -shared $true
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
. "$PSScriptRoot\install-ffmpeg-common.ps1"
|
||||
|
||||
function InstallMingwFfmpeg {
|
||||
$config = GetFfmpegDefaultConfiguration
|
||||
$mingwPath = [System.Environment]::GetEnvironmentVariable("MINGW_PATH", [System.EnvironmentVariableTarget]::Machine)
|
||||
return InstallFfmpeg -config $config -buildSystem "mingw" -msystem "MINGW" -additionalPath "$mingwPath\bin" -ffmpegDirEnvVar "FFMPEG_DIR_MINGW" -shared $true
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
[CmdletBinding(PositionalBinding = $false)]
|
||||
param (
|
||||
[string]$InstallDir,
|
||||
[string]$MsysBash,
|
||||
[string]$ZlibPath,
|
||||
[switch]$SkipEnvVar,
|
||||
[switch]$Help
|
||||
)
|
||||
|
||||
. "$PSScriptRoot\install-ffmpeg-common.ps1"
|
||||
. "$PSScriptRoot\zlib-helpers.ps1"
|
||||
|
||||
$HELP_MESSAGE = @"
|
||||
install-ffmpeg-msvc.ps1 - Builds FFmpeg for Windows using MSVC.
|
||||
|
||||
Builds for the host architecture (amd64 or arm64).
|
||||
|
||||
Usage:
|
||||
install-ffmpeg-msvc.ps1 [-InstallDir <path>] [-MsysBash <path>] [-ZlibPath <path>] [-SkipEnvVar] [-Help]
|
||||
|
||||
Options:
|
||||
-InstallDir <path> Directory to install the built FFmpeg artifacts into.
|
||||
Defaults to a path under the extracted FFmpeg source.
|
||||
-MsysBash <path> Path to the MSYS2 bash executable used to run the build.
|
||||
Defaults to $msys.
|
||||
-ZlibPath <path> Path to the zlib build folder to link against. Defaults
|
||||
to the ZLIB_PATH_<arch> machine environment variable.
|
||||
-SkipEnvVar Build without setting the FFMPEG_DIR_MSVC[_ARM64]
|
||||
environment variable at the end. Allows the script to run
|
||||
without elevated privileges.
|
||||
-Help Show this help and exit.
|
||||
"@
|
||||
|
||||
function ShowHelp {
|
||||
Write-Host $HELP_MESSAGE
|
||||
}
|
||||
|
||||
function InstallMsvcFfmpeg {
|
||||
Param (
|
||||
[Parameter(Mandatory)]
|
||||
[string]$hostArch,
|
||||
[Parameter(Mandatory)]
|
||||
[bool]$isArm64,
|
||||
[string]$installDir, # Optional override for where to install the build artifacts
|
||||
[string]$msysBash, # Optional override for the MSYS bash executable
|
||||
[string]$zlibPath, # Optional override for the zlib build folder
|
||||
[bool]$skipEnvVar = $false # Optional:
|
||||
# Don't assign the FFmpeg dir environment variable.
|
||||
# Allows the function to run without elevated privileges.
|
||||
)
|
||||
|
||||
$arch = "amd64"
|
||||
$buildSystem = "msvc"
|
||||
$ffmpegDirEnvVar = "FFMPEG_DIR_MSVC"
|
||||
|
||||
$config = GetFfmpegDefaultConfiguration
|
||||
|
||||
if ($isArm64) {
|
||||
$arch = "arm64"
|
||||
$buildSystem += "-arm64"
|
||||
$ffmpegDirEnvVar += "_ARM64"
|
||||
$config += " --arch=arm64 --disable-asm"
|
||||
if ($hostArch -eq "amd64") {
|
||||
$config += " --enable-cross-compile"
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $installDir) {
|
||||
$installDir = ResolveFFmpegInstallDir -buildSystem $buildSystem
|
||||
}
|
||||
|
||||
# Fail fast if the bash path does not resolve to an executable
|
||||
$effectiveBash = if ($msysBash) { $msysBash } else { $msys }
|
||||
if (-not (Get-Command $effectiveBash -CommandType Application -ErrorAction SilentlyContinue)) {
|
||||
throw "MSYS bash executable not found: '$effectiveBash'"
|
||||
}
|
||||
|
||||
if (-not $zlibPath) {
|
||||
$zlibPath = GetZlibPathByString -TargetArchitecture $arch
|
||||
}
|
||||
|
||||
# Fail fast if the zlib path is missing or empty
|
||||
if (-not $zlibPath) {
|
||||
throw "No zlib path provided and ZLIB_PATH_$($arch.ToUpper()) is not set"
|
||||
}
|
||||
if (-not (Test-Path -Path $zlibPath -PathType Container) -or
|
||||
-not (Get-ChildItem -Path $zlibPath -Force -ErrorAction SilentlyContinue | Select-Object -First 1)) {
|
||||
throw "zlib path is not a populated directory: '$zlibPath'"
|
||||
}
|
||||
$zlibPathMsys = ConvertTo-MsysPath $zlibPath
|
||||
|
||||
$config += " --enable-zlib"
|
||||
$config += " --extra-cflags=`"-I$zlibPathMsys`""
|
||||
$config += " --extra-ldflags=`"-LIBPATH:$zlibPathMsys`""
|
||||
|
||||
$result = EnterVSDevShell -HostArch $hostArch -Arch $arch
|
||||
if (-Not $result) {
|
||||
return $false
|
||||
}
|
||||
|
||||
# MSVC 2019 workaround: The SSA optimizer (code generation
|
||||
# "pass 2") gets stuck in an infinite loop on some translations
|
||||
# units, such as libavcodec/sanm.c, when compiling FFmpeg n8.1.2 and up.
|
||||
# This only affects the VS2019-based Windows 10 x86_64 image.
|
||||
# VS2022+ hosts build fine. Disabling that optimizer pass lets the
|
||||
# older toolchain finish. This workaround can be dropped once we no
|
||||
# longer build using MSVC 2019.
|
||||
if ($env:VisualStudioVersion -and [version]$env:VisualStudioVersion -lt [version]"17.0") {
|
||||
Write-Host "MSVC $env:VisualStudioVersion (< 2022) detected; adding -d2SSAOptimizer- to avoid build freeze on FFmpeg 8.x"
|
||||
$config += " --extra-cflags=-d2SSAOptimizer-"
|
||||
}
|
||||
|
||||
$result = InstallFfmpeg -config $config -buildSystem $buildSystem -msystem "MSYS" -toolchain "msvc" -ffmpegDirEnvVar $ffmpegDirEnvVar -shared $true -installDir $installDir -msysBash $msysBash -skipEnvVar $skipEnvVar
|
||||
|
||||
if ($result) {
|
||||
# As ffmpeg build system creates lib*.a file we have to rename them to *.lib files to be recognized by WIN32
|
||||
Write-Host "Rename libraries lib*.a -> *.lib"
|
||||
try {
|
||||
Get-ChildItem "$installDir\lib\lib*.a" | ForEach-Object {
|
||||
$NewName = $_.Name -replace 'lib(\w+).a$', '$1.lib'
|
||||
$Destination = Join-Path -Path $_.Directory.FullName -ChildPath $NewName
|
||||
Move-Item -Path $_.FullName -Destination $Destination -Force
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Failed to rename libraries lib*.a -> *.lib"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
# Run as a standalone script (skipped when dot-sourced)
|
||||
if ($MyInvocation.InvocationName -ne '.') {
|
||||
if ($Help) {
|
||||
ShowHelp
|
||||
return
|
||||
}
|
||||
|
||||
# Expand ~ and relative paths so they survive being handed to MSYS/MSVC.
|
||||
if ($InstallDir) { $InstallDir = Resolve-FullPath $InstallDir }
|
||||
if ($ZlibPath) { $ZlibPath = Resolve-FullPath $ZlibPath }
|
||||
if ($MsysBash) { $MsysBash = Resolve-FullPath $MsysBash }
|
||||
|
||||
$cpuArch = Get-CpuArchitecture
|
||||
$hostArch = CpuArchToString -Architecture $cpuArch
|
||||
$isArm64 = $cpuArch -eq [CpuArch]::arm64
|
||||
|
||||
GetFfmpegSource
|
||||
|
||||
$result = InstallMsvcFfmpeg -hostArch $hostArch -isArm64 $isArm64 -installDir $InstallDir -msysBash $MsysBash -zlibPath $ZlibPath -skipEnvVar $SkipEnvVar.IsPresent
|
||||
|
||||
exit $(if ($result) { 0 } else { 1 })
|
||||
}
|
||||
@@ -1,352 +1,43 @@
|
||||
# Copyright (C) 2022 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
|
||||
|
||||
. "$PSScriptRoot\helpers.ps1"
|
||||
. "$PSScriptRoot\zlib-helpers.ps1"
|
||||
# This script will install FFmpeg for all supported build variants.
|
||||
|
||||
# This script will install FFmpeg
|
||||
$msys = "C:\Utils\msys64\usr\bin\bash"
|
||||
. "$PSScriptRoot\install-ffmpeg-common.ps1"
|
||||
. "$PSScriptRoot\install-ffmpeg-mingw.ps1"
|
||||
. "$PSScriptRoot\install-ffmpeg-llvm-mingw.ps1"
|
||||
. "$PSScriptRoot\install-ffmpeg-msvc.ps1"
|
||||
. "$PSScriptRoot\install-ffmpeg-android.ps1"
|
||||
|
||||
$version="9.0.1"
|
||||
$url_public="https://ffmpeg.org/releases/ffmpeg-$version.tar.gz"
|
||||
$sha1="89c318905212e6b67e10e42ab10ab8007e0aefda"
|
||||
$url_cached="http://ci-files01-hki.ci.qt.io/input/ffmpeg/ffmpeg-$version.tar.gz"
|
||||
$ffmpeg_name="FFmpeg-n$version"
|
||||
|
||||
$download_location = "C:\Windows\Temp\$ffmpeg_name.tar.gz"
|
||||
$unzip_location = "C:\"
|
||||
$ffmpeg_source_dir = "C:\$ffmpeg_name"
|
||||
|
||||
Write-Host "Fetching FFmpeg $version..."
|
||||
|
||||
$extract_temp_dir = "C:\Windows\Temp\FFmpeg-extract-$([System.Guid]::NewGuid().ToString('N'))"
|
||||
|
||||
try {
|
||||
New-Item -ItemType Directory -Path $extract_temp_dir -Force | Out-Null
|
||||
|
||||
Download $url_public $url_cached $download_location
|
||||
Verify-Checksum $download_location $sha1
|
||||
Extract-tar_gz $download_location $extract_temp_dir
|
||||
|
||||
$extracted_dirs = @(Get-ChildItem -Path $extract_temp_dir -Directory)
|
||||
if ($extracted_dirs.Count -ne 1) {
|
||||
throw "Expected exactly one directory in the FFmpeg archive, got: $($extracted_dirs.Name -join ', ')"
|
||||
}
|
||||
|
||||
Remove $ffmpeg_source_dir
|
||||
Move-Item -Path $extracted_dirs[0].FullName -Destination $ffmpeg_source_dir
|
||||
} finally {
|
||||
Remove $download_location
|
||||
Remove $extract_temp_dir
|
||||
}
|
||||
|
||||
function GetFfmpegDefaultConfiguration {
|
||||
$defaultConfiguration = Get-Content "$PSScriptRoot\..\shared\ffmpeg_config_options.txt"
|
||||
Write-Host "FFmpeg default configuration: $defaultConfiguration"
|
||||
|
||||
return $defaultConfiguration
|
||||
}
|
||||
|
||||
# Returns the absolute installation path of FFmpeg for this build
|
||||
# variant.
|
||||
function ResolveFFmpegInstallDir {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$buildSystem,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$ndkVer
|
||||
)
|
||||
|
||||
if ($ndkVer) {
|
||||
$prefix = "installed-ndk-$ndkVer"
|
||||
} else {
|
||||
$prefix = "installed"
|
||||
}
|
||||
|
||||
return "C:\$ffmpeg_name\build\$buildSystem\$prefix"
|
||||
}
|
||||
|
||||
# Returns the absolute installation path of FFmpeg for this build
|
||||
# variant. Returns a path that is compatible with MSYS.
|
||||
#
|
||||
# TODO: There is some code duplications here. Make a helper function
|
||||
# that translates native Windows paths into MSYS compatible paths.
|
||||
function ResolveFFmpegInstallDirMsys {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$buildSystem,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string]$ndkVer
|
||||
)
|
||||
if ($ndkVer) {
|
||||
$prefix = "installed-ndk-$ndkVer"
|
||||
} else {
|
||||
$prefix = "installed"
|
||||
}
|
||||
|
||||
return "/c/$ffmpeg_name/build/$buildSystem/$prefix"
|
||||
}
|
||||
|
||||
function InstallFfmpeg {
|
||||
Param (
|
||||
[string]$config,
|
||||
[string]$buildSystem,
|
||||
[string]$msystem,
|
||||
[string]$additionalPath,
|
||||
[string]$ffmpegDirEnvVar,
|
||||
[string]$toolchain,
|
||||
[bool]$shared,
|
||||
[string]$ndk_ver # Optional param for installing each ffmpeg build with different Android NDK
|
||||
)
|
||||
|
||||
Write-Host "Configure and compile FFmpeg for $buildSystem with configuration: $config"
|
||||
|
||||
$oldPath = $env:PATH
|
||||
|
||||
if ($additionalPath) {
|
||||
$env:PATH = "$additionalPath;$env:PATH"
|
||||
}
|
||||
$env:MSYS2_PATH_TYPE = "inherit"
|
||||
$env:MSYSTEM = $msystem
|
||||
|
||||
if ($ndk_ver) {
|
||||
$installDir = ResolveFFmpegInstallDir -buildSystem $buildSystem -ndkVer $ndk_ver
|
||||
$installDirForMsys = ResolveFFmpegInstallDirMsys -buildSystem $buildSystem -ndkVer $ndk_ver
|
||||
} else {
|
||||
$installDir = ResolveFFmpegInstallDir -buildSystem $buildSystem
|
||||
$installDirForMsys = ResolveFFmpegInstallDirMsys -buildSystem $buildSystem
|
||||
}
|
||||
|
||||
$cmd = "cd /c/$ffmpeg_name"
|
||||
$cmd += " && mkdir -p build/$buildSystem && cd build/$buildSystem"
|
||||
$cmd += " && ../../configure --prefix=$installDirForMsys $config"
|
||||
if ($toolchain) {
|
||||
$cmd += " --toolchain=$toolchain"
|
||||
}
|
||||
if ($shared) {
|
||||
$cmd += " --enable-shared --disable-static"
|
||||
}
|
||||
$cmd += " && make install -j"
|
||||
|
||||
Write-Host "MSYS cmd:"
|
||||
Write-Host $cmd
|
||||
$buildResult = Start-Process -NoNewWindow -Wait -PassThru -ErrorAction Stop -FilePath "$msys" -ArgumentList ("-lc", "`"$cmd`"")
|
||||
|
||||
$env:PATH = $oldPath
|
||||
|
||||
if ($buildResult.ExitCode) {
|
||||
Write-Host "Failed to build FFmpeg for $buildSystem"
|
||||
return $false
|
||||
}
|
||||
|
||||
Set-EnvironmentVariable $ffmpegDirEnvVar $installDir
|
||||
return $true
|
||||
}
|
||||
|
||||
function InstallMingwFfmpeg {
|
||||
$config = GetFfmpegDefaultConfiguration
|
||||
$mingwPath = [System.Environment]::GetEnvironmentVariable("MINGW_PATH", [System.EnvironmentVariableTarget]::Machine)
|
||||
return InstallFfmpeg -config $config -buildSystem "mingw" -msystem "MINGW" -additionalPath "$mingwPath\bin" -ffmpegDirEnvVar "FFMPEG_DIR_MINGW" -shared $true
|
||||
}
|
||||
|
||||
|
||||
function InstallMsvcFfmpeg {
|
||||
Param (
|
||||
[string]$hostArch,
|
||||
[bool]$isArm64
|
||||
)
|
||||
|
||||
$arch = "amd64"
|
||||
$buildSystem = "msvc"
|
||||
$ffmpegDirEnvVar = "FFMPEG_DIR_MSVC"
|
||||
|
||||
$config = GetFfmpegDefaultConfiguration
|
||||
|
||||
if ($isArm64) {
|
||||
$arch = "arm64"
|
||||
$buildSystem += "-arm64"
|
||||
$ffmpegDirEnvVar += "_ARM64"
|
||||
$config += " --arch=arm64 --disable-asm"
|
||||
if ($hostArch -eq "amd64") {
|
||||
$config += " --enable-cross-compile"
|
||||
}
|
||||
}
|
||||
|
||||
$zlibPath = GetZlibPathByString -TargetArchitecture $arch
|
||||
$zlibPath = $zlibPath -replace '\\', '/'
|
||||
|
||||
$config += " --enable-zlib"
|
||||
$config += " --extra-cflags=`"-I$zlibPath`""
|
||||
$config += " --extra-ldflags=`"-LIBPATH:$zlibPath`""
|
||||
|
||||
$result = EnterVSDevShell -HostArch $hostArch -Arch $arch
|
||||
if (-Not $result) {
|
||||
return $false
|
||||
}
|
||||
|
||||
# MSVC 2019 workaround: The SSA optimizer (code generation
|
||||
# "pass 2") gets stuck in an infinite loop on some translations
|
||||
# units, such as libavcodec/sanm.c, when compiling FFmpeg n8.1.2 and up.
|
||||
# This only affects the VS2019-based Windows 10 x86_64 image.
|
||||
# VS2022+ hosts build fine. Disabling that optimizer pass lets the
|
||||
# older toolchain finish. This workaround can be dropped once we no
|
||||
# longer build using MSVC 2019.
|
||||
if ($env:VisualStudioVersion -and [version]$env:VisualStudioVersion -lt [version]"17.0") {
|
||||
Write-Host "MSVC $env:VisualStudioVersion (< 2022) detected; adding -d2SSAOptimizer- to avoid build freeze on FFmpeg 8.x"
|
||||
$config += " --extra-cflags=-d2SSAOptimizer-"
|
||||
}
|
||||
|
||||
$result = InstallFfmpeg -config $config -buildSystem $buildSystem -msystem "MSYS" -toolchain "msvc" -ffmpegDirEnvVar $ffmpegDirEnvVar -shared $true
|
||||
|
||||
if ($result) {
|
||||
# As ffmpeg build system creates lib*.a file we have to rename them to *.lib files to be recognized by WIN32
|
||||
Write-Host "Rename libraries lib*.a -> *.lib"
|
||||
try {
|
||||
$msvcDir = [System.Environment]::GetEnvironmentVariable($ffmpegDirEnvVar, [System.EnvironmentVariableTarget]::Machine)
|
||||
Get-ChildItem "$msvcDir\lib\lib*.a" | ForEach-Object {
|
||||
$NewName = $_.Name -replace 'lib(\w+).a$', '$1.lib'
|
||||
$Destination = Join-Path -Path $_.Directory.FullName -ChildPath $NewName
|
||||
Move-Item -Path $_.FullName -Destination $Destination -Force
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Failed to rename libraries lib*.a -> *.lib"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
|
||||
function InstallLlvmMingwFfmpeg {
|
||||
$config = GetFfmpegDefaultConfiguration
|
||||
return InstallFfmpeg -config $config -buildSystem "llvm-mingw" -msystem "CLANG64" -ffmpegDirEnvVar "FFMPEG_DIR_LLVM_MINGW" -additionalPath "C:\llvm-mingw\bin" -shared $true
|
||||
}
|
||||
|
||||
function InstallAndroidArmv7 {
|
||||
param (
|
||||
[string]$ndk_root,
|
||||
[string]$ffmpeg_dir_android_envvar_name,
|
||||
[string]$ndk_version,
|
||||
[string]$android_openssl_path, # OpenSSL is built for Android using NDK, NDK versions for OpenSSL+FFmpeg should match
|
||||
[string]$android_page_size
|
||||
)
|
||||
$shared=$true
|
||||
$target_toolchain_arch="armv7a-linux-androideabi"
|
||||
$target_arch="armv7-a"
|
||||
$target_cpu="armv7-a"
|
||||
$api_version="24"
|
||||
|
||||
$ndk_dir = $ndk_root -replace '\\', '/' -replace '^C:', '/c'
|
||||
|
||||
$toolchain="${ndk_dir}/toolchains/llvm/prebuilt/windows-x86_64"
|
||||
$toolchain_bin="${toolchain}/bin"
|
||||
$sysroot="${toolchain}/sysroot"
|
||||
$cxx="${toolchain_bin}/${target_toolchain_arch}${api_version}-clang++"
|
||||
$cc="${toolchain_bin}/${target_toolchain_arch}${api_version}-clang"
|
||||
$ld="${toolchain_bin}/ld.exe"
|
||||
$ar="${toolchain_bin}/llvm-ar.exe"
|
||||
$ranlib="${toolchain_bin}/llvm-ranlib.exe"
|
||||
$nm="${toolchain_bin}/llvm-nm.exe"
|
||||
$strip="${toolchain_bin}/llvm-strip.exe"
|
||||
$openssl_path = $android_openssl_path.Replace("\", "/")
|
||||
|
||||
Write-Host "Copying _3.so's to .so's"
|
||||
Copy-Item -Path ${openssl_path}/armeabi-v7a/libcrypto_3.so -Destination ${openssl_path}/armeabi-v7a/libcrypto.so
|
||||
Copy-Item -Path ${openssl_path}/armeabi-v7a/libssl_3.so -Destination ${openssl_path}/armeabi-v7a/libssl.so
|
||||
|
||||
|
||||
$config = GetFfmpegDefaultConfiguration
|
||||
$config += " --enable-cross-compile --target-os=android --enable-jni --enable-mediacodec --enable-openssl --enable-pthreads --enable-neon --disable-asm --disable-indev=android_camera"
|
||||
$config += " --arch=$target_arch --cpu=${target_cpu} --sysroot=${sysroot} --sysinclude=${sysroot}/usr/include/"
|
||||
$config += " --cc=${cc} --cxx=${cxx} --ar=${ar} --ranlib=${ranlib}"
|
||||
$config += " --extra-cflags=-I${android_openssl_path}/include --extra-ldflags=-L${android_openssl_path}/armeabi-v7a"
|
||||
$config += " --extra-cflags=-I${openssl_path}/include --extra-ldflags=-L${openssl_path}/armeabi-v7a"
|
||||
if ($android_page_size -eq "use_16kb_page_size"){
|
||||
$config += " --extra-ldflags=-Wl,-z,max-page-size=16384"
|
||||
Write-Host "FFmpeg Android using 16KB page sizes"
|
||||
} elseif ($android_page_size -eq "use_4kb_page_size") {
|
||||
Write-Host "FFmpeg Android using 4KB page sizes"
|
||||
} else {
|
||||
Write-Host "Error: FFmpeg Android page_size must be: use_16kb_page_size or: use_16kb_page_size got: $android_page_size"
|
||||
return false
|
||||
}
|
||||
|
||||
$config += " --strip=$strip"
|
||||
|
||||
$buildSystem = "android-arm"
|
||||
$result= InstallFfmpeg -config $config -buildSystem $buildSystem -msystem "ANDROID_CLANG" -ffmpegDirEnvVar $ffmpeg_dir_android_envvar_name -shared $shared -ndk_ver $ndk_version
|
||||
|
||||
Remove-Item -Path ${openssl_path}/armeabi-v7a/libcrypto.so
|
||||
Remove-Item -Path ${openssl_path}/armeabi-v7a/libssl.so
|
||||
|
||||
if (-not $shared) {
|
||||
return $result
|
||||
}
|
||||
|
||||
# For Shared ffmpeg we need to change dependencies to stubs
|
||||
Start-Process -NoNewWindow -Wait -PassThru -ErrorAction Stop -FilePath $msys -ArgumentList ("-lc", "`"pacman -Sy --noconfirm binutils`"")
|
||||
Start-Process -NoNewWindow -Wait -PassThru -ErrorAction Stop -FilePath $msys -ArgumentList ("-lc", "`"pacman -Sy --noconfirm autoconf`"")
|
||||
Start-Process -NoNewWindow -Wait -PassThru -ErrorAction Stop -FilePath $msys -ArgumentList ("-lc", "`"pacman -Sy --noconfirm automake`"")
|
||||
Start-Process -NoNewWindow -Wait -PassThru -ErrorAction Stop -FilePath $msys -ArgumentList ("-lc", "`"pacman -Sy --noconfirm libtool`"")
|
||||
|
||||
$patchelf_sha1 = "DDD46A2E2A16A308245C008721D877455B23BBA8"
|
||||
$patchelf_sources = "https://ci-files01-hki.ci.qt.io/input/android/patchelf/0.17.2.tar.gz"
|
||||
$patchelf_download_location = "C:\Windows\Temp\0.17.2.tar.gz"
|
||||
|
||||
try {
|
||||
Invoke-WebRequest -UseBasicParsing $patchelf_sources -OutFile $patchelf_download_location
|
||||
Verify-Checksum $patchelf_download_location $patchelf_sha1
|
||||
Extract-tar_gz $patchelf_download_location $unzip_location
|
||||
Remove $patchelf_download_location
|
||||
} catch {
|
||||
Write-Host "Error grabbing sources when installing patchelf:"
|
||||
Write-Host $_
|
||||
return $false
|
||||
}
|
||||
|
||||
Start-Process -NoNewWindow -Wait -PassThru -ErrorAction Stop -FilePath $msys -ArgumentList ("-lc", "`"cd C:/patchelf-0.17.2 && ./bootstrap.sh && ./configure && make install`"")
|
||||
|
||||
$installDirForMsys = ResolveFFmpegInstallDirMsys -buildSystem $buildSystem -ndkVer $ndk_version
|
||||
$command = "${PSScriptRoot}/../shared/fix_ffmpeg_dependencies.sh ${installDirForMsys} _armeabi-v7a no"
|
||||
$command = $command.Replace("\", "/")
|
||||
$patchResult = Start-Process -NoNewWindow -Wait -PassThru -ErrorAction Stop -FilePath $msys -ArgumentList ("-lc", "`"$command`"")
|
||||
if ($patchResult.ExitCode) {
|
||||
Write-Host "fix_ffmpeg_dependencies.sh did not finish successfully"
|
||||
return $false
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
GetFfmpegSource
|
||||
|
||||
function InstallFfmpegsAMD64 {
|
||||
$hostArch = "amd64"
|
||||
$mingwRes = InstallMingwFfmpeg
|
||||
$llvmMingwRes = InstallLlvmMingwFfmpeg
|
||||
if ($env:ANDROID_NDK_ROOT_LATEST) {
|
||||
Write-Host "Install ffmpeg using latest supported Android NDK"
|
||||
Write-Host "Install FFmpeg using latest supported Android NDK"
|
||||
$androidArmV7Res = InstallAndroidArmv7 -ndk_root $env:ANDROID_NDK_ROOT_LATEST -ffmpeg_dir_android_envvar_name "FFMPEG_DIR_ANDROID_ARMV7_NDK_LATEST" -ndk_version "latest" -android_openssl_path $env:OPENSSL_ANDROID_HOME_LATEST -android_page_size "use_4kb_page_size"
|
||||
} else {
|
||||
throw "Error: env.var ANDROID_NDK_ROOT_LATEST is not set for FFmpeg"
|
||||
}
|
||||
if ($env:ANDROID_NDK_ROOT_NIGHTLY1) {
|
||||
Write-Host "Install ffmpeg using older Android NDK for nightly1"
|
||||
Write-Host "Install FFmpeg using older Android NDK for nightly1"
|
||||
InstallAndroidArmv7 -ndk_root $env:ANDROID_NDK_ROOT_NIGHTLY1 -ffmpeg_dir_android_envvar_name "FFMPEG_DIR_ANDROID_ARMV7_NDK_NIGHTLY1" -ndk_version "nightly1" -android_openssl_path $env:OPENSSL_ANDROID_HOME_NIGHTLY1
|
||||
}
|
||||
if ($env:ANDROID_NDK_ROOT_NIGHTLY2) {
|
||||
Write-Host "Install ffmpeg using older Android NDK for nightly2"
|
||||
Write-Host "Install FFmpeg using older Android NDK for nightly2"
|
||||
InstallAndroidArmv7 -ndk_root $env:ANDROID_NDK_ROOT_NIGHTLY2 -ffmpeg_dir_android_envvar_name "FFMPEG_DIR_ANDROID_ARMV7_NDK_NIGHTLY2" -ndk_version "nightly2" -android_openssl_path $env:OPENSSL_ANDROID_HOME_NIGHTLY2
|
||||
}
|
||||
$msvcRes = InstallMsvcFfmpeg -hostArch $hostArch -isArm64 $false
|
||||
try {
|
||||
$msvcRes = InstallMsvcFfmpeg -hostArch $hostArch -isArm64 $false
|
||||
} catch {
|
||||
Write-Host "Failed to build FFmpeg for msvc: $_"
|
||||
$msvcRes = $false
|
||||
}
|
||||
$msvcArm64Res = InstallMsvcFfmpeg -hostArch $hostArch -isArm64 $true
|
||||
|
||||
Write-Host "Ffmpeg installation results:"
|
||||
Write-Host "FFmpeg installation results:"
|
||||
Write-Host " mingw:" $(if ($mingwRes) { "OK" } else { "FAIL" })
|
||||
Write-Host " llvm-mingw:" $(if ($llvmMingwRes) { "OK" } else { "FAIL" })
|
||||
Write-Host " android-armv7:" $(if ($androidArmV7Res) { "OK" } else { "FAIL" })
|
||||
@@ -360,7 +51,7 @@ function InstallFfmpegsARM64 {
|
||||
$hostArch = "arm64"
|
||||
$msvcArm64Res = InstallMsvcFfmpeg -hostArch $hostArch -isArm64 $true
|
||||
|
||||
Write-Host "Ffmpeg installation results:"
|
||||
Write-Host "FFmpeg installation results:"
|
||||
Write-Host " msvc-arm64:" $(if ($msvcArm64Res) { "OK" } else { "FAIL" })
|
||||
|
||||
exit $(if ($msvcArm64Res) { 0 } else { 1 })
|
||||
|
||||
@@ -36,7 +36,7 @@ $nppPackage = "C:\Windows\Temp\npp-$version.exe"
|
||||
|
||||
Download $url_official $url_cache $nppPackage
|
||||
Verify-Checksum $nppPackage $sha1
|
||||
Run-Executable "$nppPackage" "/S"
|
||||
Run-Executable-With-Timeout 1800 "$nppPackage" "/S"
|
||||
|
||||
Write-Host "Cleaning $nppPackage.."
|
||||
Remove "$nppPackage"
|
||||
|
||||
@@ -13,6 +13,9 @@ Run-Executable "$vcpkgExe" "install --triplet armeabi-v7a-android-qt --x-install
|
||||
New-Item -Path "$vcpkgRoot" -Name "installed" -ItemType "directory" -Force
|
||||
Copy-Item -Path "$vcpkgInstallRoot\*" -Destination "$vcpkgRoot\installed" -Recurse -Force
|
||||
|
||||
$pythonExe = "$([System.Environment]::GetEnvironmentVariable('PYTHON3_PATH', 'Machine'))\python.exe"
|
||||
Run-Executable "$pythonExe" "$PSScriptRoot\..\shared\vcpkg_generate_attributions.py --install-root $vcpkgRoot\installed --triplet armeabi-v7a-android-qt"
|
||||
|
||||
Run-Executable "cmake" "-DVCPKG_EXECUTABLE=$vcpkgExe -DVCPKG_INSTALL_ROOT=$vcpkgInstallRoot -DOUTPUT=$env:USERPROFILE\versions.txt -P $PSScriptRoot\..\shared\vcpkg_parse_packages.cmake"
|
||||
|
||||
Remove-Item -Path "$vcpkgInstallRoot" -Recurse -Force
|
||||
|
||||
@@ -16,6 +16,9 @@ Run-Executable "$vcpkgExe" "install --triplet $arch-windows-qt --x-install-root
|
||||
New-Item -Path "$vcpkgRoot" -Name "installed" -ItemType "directory" -Force
|
||||
Copy-Item -Path "$vcpkginstallroot\*" -Destination "$vcpkgRoot\installed" -Recurse -Force
|
||||
|
||||
$pythonExe = "$([System.Environment]::GetEnvironmentVariable('PYTHON3_PATH', 'Machine'))\python.exe"
|
||||
Run-Executable "$pythonExe" "$PSScriptRoot\..\shared\vcpkg_generate_attributions.py --install-root $vcpkgRoot\installed --triplet $arch-windows-qt"
|
||||
|
||||
Run-Executable "cmake" "-DVCPKG_EXECUTABLE=$vcpkgExe -DVCPKG_INSTALL_ROOT=$vcpkgInstallRoot -DOUTPUT=$env:USERPROFILE\versions.txt -P $PSScriptRoot\..\shared\vcpkg_parse_packages.cmake"
|
||||
|
||||
Set-EnvironmentVariable "VCPKG_INSTALLED_DIR" "$vcpkgRoot\installed"
|
||||
|
||||
@@ -28,10 +28,10 @@ $folderName = "qnx710"
|
||||
$targetPath = "$targetFolder$folderName"
|
||||
|
||||
# QNX SDP
|
||||
$cachedUrl = "\\ci-files01-hki.ci.qt.io\provisioning\qnx\qnx710-windows-linux-20260422.tar.xz"
|
||||
$sourceFile = "http://ci-files01-hki.ci.qt.io/input/qnx/qnx710-windows-linux-20260422.tar.xz"
|
||||
$cachedUrl = "\\ci-files01-hki.ci.qt.io\provisioning\qnx\qnx710-windows-linux-20260828.tar.xz"
|
||||
$sourceFile = "http://ci-files01-hki.ci.qt.io/input/qnx/qnx710-windows-linux-20260828.tar.xz"
|
||||
$targetFile = "qnx710.tar.xz"
|
||||
$sha1 = "98b24df7e8c53a104aee76e769011396fa4bdafd"
|
||||
$sha1 = "c37e6f3a49a259d450b601843a9af2818b6feb96"
|
||||
DownloadAndExtract $sourceFile $sha1 $targetFile $targetFolder $cachedUrl
|
||||
|
||||
Copy-Item $aarch64le_toolchain $targetPath
|
||||
|
||||
@@ -28,10 +28,10 @@ $folderName = "qnx800"
|
||||
$targetPath = "$targetFolder$folderName"
|
||||
|
||||
# QNX SDP
|
||||
$cachedUrl = "\\ci-files01-hki.ci.qt.io\provisioning\qnx\qnx800-windows-linux-20260410.tar.xz"
|
||||
$sourceFile = "http://ci-files01-hki.ci.qt.io/input/qnx/qnx800-windows-linux-20260410.tar.xz"
|
||||
$cachedUrl = "\\ci-files01-hki.ci.qt.io\provisioning\qnx\qnx800-windows-linux-20260828.tar.xz"
|
||||
$sourceFile = "http://ci-files01-hki.ci.qt.io/input/qnx/qnx800-windows-linux-20260828.tar.xz"
|
||||
$targetFile = "qnx800.tar.xz"
|
||||
$sha1 = "a3fdcd98e12bc5054d00f18e4088af26288fd020"
|
||||
$sha1 = "f44b66d91625ab33e367cfb62a2950a041607caa"
|
||||
DownloadAndExtract $sourceFile $sha1 $targetFile $targetFolder $cachedUrl
|
||||
|
||||
# IANA timezone database overlay. Packaged separately from the SDP so it can be
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# Copyright (C) 2026 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
|
||||
|
||||
. "$PSScriptRoot\helpers.ps1"
|
||||
|
||||
$version = "9.2.0984"
|
||||
$versioned_dir = "vim92"
|
||||
|
||||
$cpu_arch = Get-CpuArchitecture
|
||||
Write-Host "Installing vim for architecture $cpu_arch"
|
||||
switch ($cpu_arch) {
|
||||
arm64 {
|
||||
$arch = "arm64"
|
||||
$sha1 = "7df12598d95edfc283015e19c430ecf6d75d28a3"
|
||||
Break
|
||||
}
|
||||
x64 {
|
||||
$arch = "x64"
|
||||
$sha1 = "decbdd2b7ad7afb18576fee51ac027f4a9610710"
|
||||
}
|
||||
default {
|
||||
throw "Unknown architecture $cpu_arch"
|
||||
}
|
||||
}
|
||||
|
||||
$filename = "gvim_" + $version + "_" + $arch + "_signed.zip"
|
||||
|
||||
$officialurl = "https://github.com/vim/vim-win32-installer/releases/download/v$version/$filename"
|
||||
$cachedurl = "https://ci-files01-hki.ci.qt.io/input/windows/vim/$filename"
|
||||
|
||||
Download $officialurl $cachedurl $filename
|
||||
Verify-Checksum $filename $sha1
|
||||
Extract-7Zip $filename C:\Utils
|
||||
|
||||
$vim_dir = "C:\Utils\vim\$versioned_dir\"
|
||||
Prepend-Path $vim_dir
|
||||
|
||||
if (-not (Test-Path "$vim_dir\vim.exe")) {
|
||||
throw "vim.exe not found"
|
||||
}
|
||||
@@ -24,9 +24,32 @@
|
||||
# These workarounds allow us to run reproducible, architecture-specific builds in CI without modifying
|
||||
# the original source tree or requiring upstream changes.
|
||||
|
||||
[CmdletBinding(PositionalBinding = $false)]
|
||||
param (
|
||||
[switch] $SkipEnvVar,
|
||||
[string] $InstallDir,
|
||||
[switch] $Help
|
||||
)
|
||||
|
||||
. "$PSScriptRoot\helpers.ps1"
|
||||
. "$PSScriptRoot\zlib-helpers.ps1"
|
||||
|
||||
$HELP_MESSAGE = @"
|
||||
zlib.ps1 - Builds zlib for Windows with multi-architecture support.
|
||||
|
||||
Usage:
|
||||
zlib.ps1 [-InstallDir <path>] [-SkipEnvVar] [-Help]
|
||||
|
||||
Options:
|
||||
-InstallDir <path> Root directory for build artifacts. A per-architecture
|
||||
subfolder is created underneath it. Defaults to a
|
||||
'build' folder inside the extracted zlib source.
|
||||
-SkipEnvVar Build without setting the ZLIB_PATH_* environment
|
||||
variables at the end. Allows the script to run without
|
||||
elevated privileges.
|
||||
-Help Show this help and exit.
|
||||
"@
|
||||
|
||||
$VERSION='1.3.1'
|
||||
$SHA1='f535367b1a11e2f9ac3bec723fb007fbc0d189e5'
|
||||
|
||||
@@ -47,13 +70,15 @@ function BuildZlib {
|
||||
|
||||
function CopySource {
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[string] $BuildRoot,
|
||||
[Parameter(Mandatory)]
|
||||
[CpuArch] $TargetArchitecture
|
||||
)
|
||||
|
||||
$testDirectory='test'
|
||||
|
||||
$buildDirectory = GetBuildDirectory -TargetArchitecture $TargetArchitecture
|
||||
$buildDirectory = GetBuildDirectory -BuildRoot $BuildRoot -TargetArchitecture $TargetArchitecture
|
||||
$win32BuildDirectory = "$buildDirectory\$WIN32_DIRECTORY"
|
||||
$testBuildDirectory = "$buildDirectory\$testDirectory"
|
||||
|
||||
@@ -68,13 +93,15 @@ function CopySource {
|
||||
|
||||
function GetBuildDirectory {
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[string] $BuildRoot,
|
||||
[Parameter(Mandatory)]
|
||||
[CpuArch] $TargetArchitecture
|
||||
)
|
||||
|
||||
$architectureDirectory = CpuArchToString -Architecture $TargetArchitecture
|
||||
|
||||
return "build\$architectureDirectory"
|
||||
return "$BuildRoot\$architectureDirectory"
|
||||
}
|
||||
|
||||
function GetSource {
|
||||
@@ -137,11 +164,13 @@ function PatchZconf {
|
||||
|
||||
function PrepareBuild {
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[string] $BuildRoot,
|
||||
[Parameter(Mandatory)]
|
||||
[CpuArch] $TargetArchitecture
|
||||
)
|
||||
|
||||
CopySource -TargetArchitecture $TargetArchitecture
|
||||
CopySource -BuildRoot $BuildRoot -TargetArchitecture $TargetArchitecture
|
||||
}
|
||||
|
||||
function PrepareBuildEnvironment {
|
||||
@@ -163,35 +192,47 @@ function PrepareBuildEnvironment {
|
||||
function SetZlibEnvironmentVariable {
|
||||
param (
|
||||
[Parameter(Mandatory)]
|
||||
[CpuArch] $TargetArchitecture,
|
||||
[string] $BuildRoot,
|
||||
[Parameter(Mandatory)]
|
||||
[string] $ZlibDirectory
|
||||
[CpuArch] $TargetArchitecture
|
||||
)
|
||||
|
||||
$buildDirectory = GetBuildDirectory -TargetArchitecture $TargetArchitecture
|
||||
$buildDirectory = GetBuildDirectory -BuildRoot $BuildRoot -TargetArchitecture $TargetArchitecture
|
||||
$environmentVariableName = GetZlibEnvironmentVariableName -TargetArchitecture $TargetArchitecture
|
||||
$environmentVariableValue = "$ZlibDirectory\$buildDirectory"
|
||||
|
||||
Set-EnvironmentVariable $environmentVariableName $environmentVariableValue
|
||||
Set-EnvironmentVariable $environmentVariableName $buildDirectory
|
||||
}
|
||||
|
||||
function ShowHelp {
|
||||
Write-Host $HELP_MESSAGE
|
||||
}
|
||||
|
||||
if ($Help) {
|
||||
ShowHelp
|
||||
return
|
||||
}
|
||||
|
||||
$zlibDirectory = GetSource
|
||||
$hostArchitecture = Get-CpuArchitecture
|
||||
$targetArchitectures = GetTargetArchitectures -HostArchitecture $hostArchitecture
|
||||
|
||||
$buildRoot = if ($InstallDir) { $InstallDir } else { "$zlibDirectory\build" }
|
||||
|
||||
Push-Location $zlibDirectory
|
||||
|
||||
try {
|
||||
foreach ($targetArchitecture in $targetArchitectures) {
|
||||
PrepareBuild -TargetArchitecture $targetArchitecture
|
||||
PrepareBuild -BuildRoot $buildRoot -TargetArchitecture $targetArchitecture
|
||||
|
||||
$buildDirectory = GetBuildDirectory -TargetArchitecture $targetArchitecture
|
||||
$buildDirectory = GetBuildDirectory -BuildRoot $buildRoot -TargetArchitecture $targetArchitecture
|
||||
Push-Location $buildDirectory
|
||||
|
||||
try {
|
||||
PatchSource
|
||||
BuildZlib -HostArchitecture $hostArchitecture -TargetArchitecture $targetArchitecture
|
||||
SetZlibEnvironmentVariable -TargetArchitecture $targetArchitecture -ZlibDirectory $zlibDirectory
|
||||
if (-not $SkipEnvVar) {
|
||||
SetZlibEnvironmentVariable -BuildRoot $buildRoot -TargetArchitecture $targetArchitecture
|
||||
}
|
||||
}
|
||||
finally {
|
||||
Pop-Location
|
||||
|
||||
@@ -5,11 +5,7 @@ source "${BASH_SOURCE%/*}/../common/unix/DownloadURL.sh"
|
||||
|
||||
set -ex
|
||||
|
||||
name="p7zip"
|
||||
version="7-11"
|
||||
sudo yum -y install "$name"
|
||||
# p7zip has a pathing bug in rhel-10, install 7zip-standalone-all instead
|
||||
sudo dnf install -y 7zip-standalone-all
|
||||
|
||||
# Link 7za to 7z so we can use existing installation scripts
|
||||
sudo ln -s /usr/bin/7za /usr/bin/7z
|
||||
|
||||
echo "$name = $version" >> ~/versions.txt
|
||||
sudo ln -s /usr/bin/7zz /usr/bin/7z
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user