Compare commits
1403 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
2ad23cd72d | ||
|
1cd79cf429 | ||
|
55edaffa7c | ||
|
60cf2f867b | ||
|
31f1c78b0b | ||
|
f10a8dbf6c | ||
|
a003aafd86 | ||
|
1926f88b24 | ||
|
adda61e87b | ||
|
63093b0410 | ||
|
4a95b7fc60 | ||
|
5b6527c35a | ||
|
0b84ad4e49 | ||
|
1da71e5e7d | ||
|
77a10188a5 | ||
|
500246d988 | ||
|
40d4ea3dcf | ||
|
9911f7c90d | ||
|
d40e353821 | ||
|
f23fd8ddae | ||
|
a3c75cfc52 | ||
|
8bcc3f2ce5 | ||
|
5adb974194 | ||
|
1192a9d81a | ||
|
6a3b653fe6 | ||
|
d8fdcea0d1 | ||
|
9db5beae71 | ||
|
679dc18c43 | ||
|
845aa1e9d1 | ||
|
304089b6da | ||
|
51b75d520f | ||
|
e4e88d9137 | ||
|
09f68238d4 | ||
|
1e486c14d4 | ||
|
a55c9dbabc | ||
|
b9d95d7982 | ||
|
bae42278a0 | ||
|
42dd3bc013 | ||
|
595647cb6c | ||
|
ee9ee08762 | ||
|
a692c8a78d | ||
|
093ab48adf | ||
|
72153bf6ef | ||
|
4630c92cea | ||
|
749bb5240a | ||
|
29688402ce | ||
|
179474de31 | ||
|
0f88982f08 | ||
|
e7247e9acd | ||
|
2dbc92e4ac | ||
|
26e385d881 | ||
|
21cd27b3b9 | ||
|
814587f3cc | ||
|
e9216d9826 | ||
|
8866613373 | ||
|
9842c84f36 | ||
|
fd608b6a6b | ||
|
cca73cecb0 | ||
|
bb8acc8e0e | ||
|
b069dda4da | ||
|
bccbf1be13 | ||
|
12de520677 | ||
|
bc039f3253 | ||
|
233f2340bd | ||
|
b2ad8f05ba | ||
|
518507bcfa | ||
|
d5e902751a | ||
|
7549a5c388 | ||
|
585cdfbd17 | ||
|
4ebb0413f1 | ||
|
c3eaa283c3 | ||
|
b7ad2f3a9f | ||
|
0bd5917b8b | ||
|
2a62697645 | ||
|
b5b172e34f | ||
|
9e1cfb6ad9 | ||
|
662670febd | ||
|
1dc962cbe0 | ||
|
7537bfbadf | ||
|
72e6a5fec0 | ||
|
005e2c7876 | ||
|
942b23f922 | ||
|
c9921d069a | ||
|
111549dca0 | ||
|
eccceef934 | ||
|
8b1b3866ba | ||
|
8e078d8fd2 | ||
|
103c1c3a4c | ||
|
b3a550d976 | ||
|
d6865ad65d | ||
|
f6591e6638 | ||
|
4a8350da23 | ||
|
54d6769456 | ||
|
a223eca4ae | ||
|
4e94132fb0 | ||
|
1e6d93e614 | ||
|
06cec0646c | ||
|
50ef11616d | ||
|
dcd3dee1ac | ||
|
bd288ab255 | ||
|
ae61177c50 | ||
|
2667f57338 | ||
|
d7d2c95eca | ||
|
c4486be6bd | ||
|
b2b48ff26e | ||
|
22dd10e261 | ||
|
df8f7becfc | ||
|
4ea5f55aed | ||
|
4b20e23ed7 | ||
|
f98c49666a | ||
|
da619f9e0b | ||
|
68fb365e82 | ||
|
9909c89677 | ||
|
c78963023a | ||
|
c9ba8760de | ||
|
4f89fbc9a9 | ||
|
bc2f4ace0e | ||
|
cb199ab2aa | ||
|
aa4511af9d | ||
|
62f382f271 | ||
|
df454f51f8 | ||
|
e1d088b1e8 | ||
|
d8fc1a6fa2 | ||
|
aa2e61f325 | ||
|
95f659aeda | ||
|
189d5ebbda | ||
|
3ce44b88e2 | ||
|
14bfa63b48 | ||
|
cb84d80c8a | ||
|
55ea4ebe34 | ||
|
120a987544 | ||
|
d4f4cd2ef2 | ||
|
b50bbd4269 | ||
|
854ef306be | ||
|
a101ffb700 | ||
|
78f4273b97 | ||
|
c971288a04 | ||
|
9520dc55a9 | ||
|
1f2f5ee08c | ||
|
7cd587aff1 | ||
|
304e4e5cc4 | ||
|
95ea70197f | ||
|
f4c1d51cae | ||
|
b7aae99247 | ||
|
7cd1dbce12 | ||
|
f07a3e07d1 | ||
|
dc3659f70f | ||
|
7a8baa2583 | ||
|
5cafb9c760 | ||
|
1ae9914a32 | ||
|
a40fdae4e7 | ||
|
c17f7aed2b | ||
|
cabdf3f94a | ||
|
adbb269eb9 | ||
|
b5582df317 | ||
|
f0dbb0906b | ||
|
ec8f043ec5 | ||
|
a65a730ebf | ||
|
31334da21e | ||
|
79e3416bb0 | ||
|
09747e064e | ||
|
1f2565e96d | ||
|
95fd5fc0d2 | ||
|
c4b7c7b097 | ||
|
4a1de91066 | ||
|
4cd8e96f5f | ||
|
37ba1457f4 | ||
|
6ff7f71c31 | ||
|
9b8655cf0d | ||
|
ab628edbb0 | ||
|
e044a1bf9a | ||
|
d6284de755 | ||
|
72dfe79098 | ||
|
bb46df6a7a | ||
|
c5beecbcc0 | ||
|
a50425de58 | ||
|
a589ec7129 | ||
|
0859415f7d | ||
|
d4cd7bf5ff | ||
|
8e9ef8df5b | ||
|
3e7f2f2048 | ||
|
6a8b3344c0 | ||
|
d4a1448901 | ||
|
2c2135a343 | ||
|
0b08fad61f | ||
|
06a41125b4 | ||
|
62c1f8da1e | ||
|
6d6ee8d6d6 | ||
|
4fe022c408 | ||
|
9a9530fd08 | ||
|
389dab064e | ||
|
f6d8388455 | ||
|
13b833cd1a | ||
|
a6f082df9b | ||
|
adbbd47314 | ||
|
3295e7d52b | ||
|
690243d333 | ||
|
6753ab4723 | ||
|
53692fc9c5 | ||
|
35431fe6e3 | ||
|
a47b7c285d | ||
|
6276f26bda | ||
|
ebb4b0140b | ||
|
13871ee86b | ||
|
b3b836e703 | ||
|
c33044f500 | ||
|
a1b4480c53 | ||
|
53a687e5c3 | ||
|
0c3fa7cd30 | ||
|
227dc87ab1 | ||
|
8dac03db35 | ||
|
d18756589a | ||
|
c46fdbad79 | ||
|
f7ad71f39c | ||
|
541d53f28d | ||
|
08a65966af | ||
|
1432788a12 | ||
|
969fbfb89b | ||
|
40fa39ba83 | ||
|
84841f3bb0 | ||
|
1f354786f1 | ||
|
7d04246b95 | ||
|
56218773ce | ||
|
65768082fe | ||
|
01ff6e19f7 | ||
|
bbe0b18b38 | ||
|
61369b37e1 | ||
|
93933c5761 | ||
|
8121b39921 | ||
|
e6a294a69b | ||
|
c0cee227de | ||
|
fe1863228c | ||
|
0d2fd73c29 | ||
|
a0ed54cb0b | ||
|
ecae579d03 | ||
|
ab6f1ad778 | ||
|
19c4db4201 | ||
|
793a8d9d14 | ||
|
435da40cc0 | ||
|
34e7253d05 | ||
|
09d266af99 | ||
|
76918c1f28 | ||
|
2efeaab1c6 | ||
|
f261357c1a | ||
|
fee3a39fdc | ||
|
73d2a7d29b | ||
|
c818392a59 | ||
|
5e3db40ba3 | ||
|
82cf1c0c16 | ||
|
799237eaae | ||
|
a8f7a100ae | ||
|
414ca19a3f | ||
|
21b219f6b7 | ||
|
5a73a80943 | ||
|
1f5545e6f2 | ||
|
3b175fbecc | ||
|
e98a2b90b9 | ||
|
424de984df | ||
|
caa101c8e0 | ||
|
f234dac1f9 | ||
|
8289d2e889 | ||
|
5ef7bf98a1 | ||
|
3e67c1241a | ||
|
2cafab999d | ||
|
3688d42011 | ||
|
03ac8f8349 | ||
|
f315104924 | ||
|
deebbbba60 | ||
|
cfda487726 | ||
|
5405f6b575 | ||
|
9b9bd00c2b | ||
|
7bf07cc12c | ||
|
8d99d38785 | ||
|
c57d487d9b | ||
|
604a76c8b3 | ||
|
08986f17f6 | ||
|
4a9782f628 | ||
|
6489fc1e52 | ||
|
02fb66f8a5 | ||
|
c1adc5c3ed | ||
|
97bacdaab3 | ||
|
fcf12e50c9 | ||
|
ceefdd6044 | ||
|
a961848c16 | ||
|
c144326b2d | ||
|
d25185fb0d | ||
|
25b71e1fee | ||
|
30fe30550f | ||
|
b15d1ee499 | ||
|
b9fd0b1272 | ||
|
64fd9edb2c | ||
|
013793a783 | ||
|
f2b58861d2 | ||
|
db33112d4d | ||
|
7de18b1467 | ||
|
9e59a924a0 | ||
|
b546ab5af4 | ||
|
75663be3b5 | ||
|
12ea4c92a3 | ||
|
ae0bd2c52d | ||
|
2d6a4293be | ||
|
573c39ff00 | ||
|
af31f1f2c3 | ||
|
13aac36f69 | ||
|
ba9fa54b92 | ||
|
a81f33eff3 | ||
|
4f249a3c89 | ||
|
cd5c10b33b | ||
|
0bdf8cd4f8 | ||
|
00ecdd55c6 | ||
|
d146cfa268 | ||
|
681e3fe5c1 | ||
|
f1bf3cc6ee | ||
|
cf1259a40e | ||
|
4c769f92a8 | ||
|
e014490142 | ||
|
ba9d8cc422 | ||
|
15b3d364ae | ||
|
e215b930e2 | ||
|
81451de0e6 | ||
|
8ebe07a76d | ||
|
c6ae521e5b | ||
|
16755adc05 | ||
|
93047640a2 | ||
|
fc16260be6 | ||
|
3518bb1d28 | ||
|
d05f5a503c | ||
|
7d1903a5d9 | ||
|
1001ff9b94 | ||
|
2c2612d935 | ||
|
0a8737901e | ||
|
ea47e479a2 | ||
|
10d3076a93 | ||
|
0191826f43 | ||
|
18a08d81f4 | ||
|
ae31e6e6ac | ||
|
d94d5bcd61 | ||
|
8f955142ed | ||
|
e1c4af8efd | ||
|
9de65d3d68 | ||
|
75e042173d | ||
|
141f061130 | ||
|
1bf44cc71f | ||
|
0381e77205 | ||
|
137aac07a9 | ||
|
99032b8fa8 | ||
|
9c9146a5cd | ||
|
9747e0a8b1 | ||
|
2c9baee470 | ||
|
2ec89d4908 | ||
|
4a16b18fb4 | ||
|
b3ad704003 | ||
|
988ae2e3a2 | ||
|
cd26d3470a | ||
|
9b67f62950 | ||
|
6a684a53b3 | ||
|
9bde2afb5c | ||
|
00ef067a2d | ||
|
e70fcdfe5b | ||
|
c228b13e76 | ||
|
687c944820 | ||
|
a9418f0ab5 | ||
|
6dc3e49b36 | ||
|
364f01d8f1 | ||
|
56db6d25a4 | ||
|
f39b02ed4b | ||
|
cbc2f2a6ee | ||
|
54e67a13aa | ||
|
db63625c50 | ||
|
ab04b4ba8e | ||
|
b27ba33a66 | ||
|
11721dffdf | ||
|
59905e0678 | ||
|
91fc9fe796 | ||
|
801482208c | ||
|
2eff82ea39 | ||
|
1aed8b0b75 | ||
|
f24dcf7bdb | ||
|
3b8a5859f8 | ||
|
eba728f1a3 | ||
|
081023ec0e | ||
|
b859f192e9 | ||
|
e926cbf218 | ||
|
2cb473b266 | ||
|
5b4e57778a | ||
|
96aa7232c7 | ||
|
c50d67e86f | ||
|
c831210d0b | ||
|
f988f8fc30 | ||
|
8a2ba3b3ac | ||
|
7dbda42554 | ||
|
e495e0ea28 | ||
|
4874a7b13c | ||
|
d3e03d1da0 | ||
|
23a8355991 | ||
|
3383817a2d | ||
|
33eb981101 | ||
|
e2977d2e97 | ||
|
43a4b9c1f2 | ||
|
b630ed4ef8 | ||
|
93e78b87bf | ||
|
1b0b5c3280 | ||
|
f06b8f1779 | ||
|
ce0349b410 | ||
|
504ec42a0f | ||
|
fe7cb24195 | ||
|
842ee4f393 | ||
|
ac67f0dc96 | ||
|
607115f1e2 | ||
|
b10616fe3e | ||
|
4a79ed90f1 | ||
|
bbceab7932 | ||
|
1b119638ac | ||
|
27f59f908d | ||
|
df8ba5c184 | ||
|
af6a417acb | ||
|
4ac20b3e5a | ||
|
01aff4a1c3 | ||
|
3627d0ed2d | ||
|
b758518896 | ||
|
469c071d69 | ||
|
f754cd0ce9 | ||
|
d0665d2628 | ||
|
1f6346df1c | ||
|
657ccdab53 | ||
|
3b8f6bb3d6 | ||
|
70f13cfbb1 | ||
|
b6ab8c113d | ||
|
04cb0a1b55 | ||
|
10e546f015 | ||
|
438516cf34 | ||
|
b3f39fdd55 | ||
|
e0b17563b8 | ||
|
31d64b725d | ||
|
cbce9bbcbf | ||
|
4caff4f064 | ||
|
753e0032dc | ||
|
d027d6d9da | ||
|
dd1349240f | ||
|
4ee61659c3 | ||
|
b15a288f09 | ||
|
25e94ec4b3 | ||
|
a070cb5b91 | ||
|
2d34d2ae9b | ||
|
a833d93f59 | ||
|
8287fb63ef | ||
|
53d8347210 | ||
|
322520ad62 | ||
|
4a296214dd | ||
|
34c5b311fc | ||
|
c6b9d41f78 | ||
|
46c9c90ec4 | ||
|
06b02f003e | ||
|
a6795882d8 | ||
|
3bce1f5946 | ||
|
56976f8f08 | ||
|
89bc556da0 | ||
|
091a54400b | ||
|
ef2731cfc4 | ||
|
5641db1f9f | ||
|
0159e662ee | ||
|
1c708527fb | ||
|
516cce13e2 | ||
|
de02c59757 | ||
|
b4177967dc | ||
|
2054b00216 | ||
|
f92b172757 | ||
|
db36fea295 | ||
|
54cc218f46 | ||
|
6e0d7c4020 | ||
|
23d97f7566 | ||
|
8d0f762177 | ||
|
ef60ea194e | ||
|
5ed1dcd1cc | ||
|
3e2fcff478 | ||
|
2b5e55e161 | ||
|
c376c79b91 | ||
|
49f7778698 | ||
|
275a47b92c | ||
|
e8de198ef7 | ||
|
b82a0cb15f | ||
|
74ef408290 | ||
|
05cab5fdac | ||
|
3d0243711e | ||
|
52b20a1351 | ||
|
cd395a7999 | ||
|
6d2421d812 | ||
|
e02348117c | ||
|
18f0dd9bdf | ||
|
8909279d3e | ||
|
66a10a141e | ||
|
4a352937e3 | ||
|
97b41af2a2 | ||
|
5fb7e0ccbb | ||
|
ed75628c37 | ||
|
a3fb8e9abc | ||
|
e897b68239 | ||
|
72564afb5f | ||
|
b26e30e1b7 | ||
|
598db6f4b1 | ||
|
a069569ea2 | ||
|
55fadd025b | ||
|
ba5e146082 | ||
|
6cdae4ea3e | ||
|
9a8bc72b93 | ||
|
2f3faf7c8e | ||
|
bd2bc4087f | ||
|
cf12826dc4 | ||
|
1921783936 | ||
|
f249a5182f | ||
|
ae145bd28f | ||
|
c90130a72d | ||
|
619af4198e | ||
|
5482f0d0a9 | ||
|
a211cb81ee | ||
|
b330d8e06a | ||
|
5deee1e5ab | ||
|
97567dee25 | ||
|
8af957a950 | ||
|
b6dd07382a | ||
|
45135e303a | ||
|
e1d0213011 | ||
|
431b52d03f | ||
|
9566a199d4 | ||
|
ec386cd2a9 | ||
|
7d8b81a491 | ||
|
fb69590c81 | ||
|
ffc55b734d | ||
|
8dbeacbb5c | ||
|
982483f134 | ||
|
7138834c91 | ||
|
93c37162af | ||
|
477e9216f3 | ||
|
2886996de4 | ||
|
b2feff382d | ||
|
b7ec18cfdb | ||
|
935d1d633c | ||
|
6f4ddfaef3 | ||
|
246c644622 | ||
|
7ee176bcbe | ||
|
b173da88f4 | ||
|
e37e3d9045 | ||
|
8e94b67ba1 | ||
|
8181c4868a | ||
|
d7127c02ff | ||
|
7ad9a2d391 | ||
|
aca60117ee | ||
|
87c790851e | ||
|
e7edc43913 | ||
|
eaff6a7a03 | ||
|
9e18d7ded5 | ||
|
f2cc2c9074 | ||
|
7f01e20c37 | ||
|
a872a3a73c | ||
|
103a636e00 | ||
|
26cda01b29 | ||
|
887c7a4b89 | ||
|
f08721bb39 | ||
|
9c58b6ce1d | ||
|
d4e0f8ee11 | ||
|
8e564bd00f | ||
|
e744561c35 | ||
|
3c1b01ec3e | ||
|
ece3fefdd0 | ||
|
72fddb0935 | ||
|
660a63d739 | ||
|
69cdf3cbbb | ||
|
d7e2d6b22c | ||
|
7394e342f7 | ||
|
6e0139caf7 | ||
|
0c7bea06c4 | ||
|
15ea46495f | ||
|
a6e68f636e | ||
|
07f088d340 | ||
|
c785ab7a62 | ||
|
f45d0214f9 | ||
|
20cca622cc | ||
|
7a7c7322fa | ||
|
01d1a2265c | ||
|
0f4cd43bc2 | ||
|
bf37860a71 | ||
|
3e32c9b55b | ||
|
cb8a6a5ea9 | ||
|
0bdad95d0c | ||
|
8b59467d20 | ||
|
d6802feee0 | ||
|
2125135064 | ||
|
a1a872e2d2 | ||
|
e2129f6548 | ||
|
9a0716b728 | ||
|
2a1a34307d | ||
|
149be782bb | ||
|
4003ca0d32 | ||
|
b338217360 | ||
|
351357c3a0 | ||
|
b172090299 | ||
|
0437f1925b | ||
|
22e66638a6 | ||
|
9cba61e5eb | ||
|
5ad97482a9 | ||
|
de3cf05b77 | ||
|
9433e8b68d | ||
|
bea6b0e944 | ||
|
6deb5098a1 | ||
|
ee8cd91279 | ||
|
192d87010a | ||
|
cdb34e0486 | ||
|
9239e7cdef | ||
|
a234b472d7 | ||
|
8633c8e446 | ||
|
ce7cf1a8b1 | ||
|
bcdd7c260b | ||
|
f87929371a | ||
|
593f69a861 | ||
|
f5de04d9c4 | ||
|
1a4e2e869f | ||
|
0777144b45 | ||
|
cc6074c543 | ||
|
c4618d6020 | ||
|
8e2c6a5904 | ||
|
c653cf1171 | ||
|
dcb72b5315 | ||
|
2769ef7174 | ||
|
35c18eba64 | ||
|
b9169c1210 | ||
|
8159f4626b | ||
|
e71708a6e5 | ||
|
d561d864eb | ||
|
b0e9665e7d | ||
|
37c60080dd | ||
|
5fd8af81ad | ||
|
8a1dcd2bb9 | ||
|
1f8a8da7c2 | ||
|
68856adf1d | ||
|
db7e6d6fed | ||
|
8d8cf0bbfe | ||
|
c276fa45dc | ||
|
21c5970da4 | ||
|
1dc3a9cac2 | ||
|
59745fc798 | ||
|
bccb4c8328 | ||
|
0e7f52c872 | ||
|
18dd4f9479 | ||
|
31e6f4a2ca | ||
|
206a8fec2c | ||
|
54ef8bf929 | ||
|
d47af17a0d | ||
|
d2f48abeb5 | ||
|
79539c50cd | ||
|
926abdce78 | ||
|
143b016277 | ||
|
38835684b3 | ||
|
1fa408f328 | ||
|
0bd6b909ab | ||
|
5f3708e190 | ||
|
dbd149375b | ||
|
34625db91a | ||
|
6f559732cf | ||
|
16639502a7 | ||
|
3fe904e231 | ||
|
ebbf2d298b | ||
|
9593852f24 | ||
|
fab3e958da | ||
|
5518a384b2 | ||
|
e51d03e334 | ||
|
dbfd84ae4c | ||
|
2d51fc3c69 | ||
|
a70a4f65fe | ||
|
b1979646fb | ||
|
1a5499ce5f | ||
|
56c05f47f6 | ||
|
72f41f8756 | ||
|
6cefb8be96 | ||
|
9479f9bbfc | ||
|
646bea85a5 | ||
|
09c093f969 | ||
|
3cd991037d | ||
|
3c178b40e7 | ||
|
81443770ce | ||
|
87e28fc8ec | ||
|
9fbb8e0090 | ||
|
4488dfcbf6 | ||
|
87e53579ea | ||
|
9491249fc6 | ||
|
5581c62922 | ||
|
e7562a50b9 | ||
|
333a08c98f | ||
|
c1bb08ab26 | ||
|
22f33e1bd2 | ||
|
dcf09c0c63 | ||
|
73e9605765 | ||
|
7cab94a4c8 | ||
|
320a3b1328 | ||
|
05b91b1195 | ||
|
4372292136 | ||
|
173eebbd96 | ||
|
aa0e38c607 | ||
|
76783a4487 | ||
|
fd15b2178a | ||
|
4c1aef25ce | ||
|
d83f820ab4 | ||
|
09e4baf5eb | ||
|
af7ca1d159 | ||
|
56993ad559 | ||
|
69f78f3cbe | ||
|
5dddcc3cdc | ||
|
057ef3e1d3 | ||
|
224fc1daaa | ||
|
3009ca730d | ||
|
80b39d24ec | ||
|
770f9e5897 | ||
|
b05f06d5b9 | ||
|
7b0e3fb969 | ||
|
a5bafadf8e | ||
|
0d36941a78 | ||
|
6ad615cd12 | ||
|
e20364d6c9 | ||
|
d61c784273 | ||
|
78dd1c5cd0 | ||
|
3ad691586e | ||
|
f32dbf337d | ||
|
25840bcc32 | ||
|
4ae0667e2b | ||
|
71130a16f8 | ||
|
ac0e10db65 | ||
|
0730c7ea55 | ||
|
a639174daa | ||
|
03fc43b5e9 | ||
|
5adddf6cd9 | ||
|
ea4a6cfdfa | ||
|
c6fdf954e3 | ||
|
ddd0a08490 | ||
|
ff7675817d | ||
|
16b8fc51fe | ||
|
3fd08e19d4 | ||
|
b6d2f86695 | ||
|
5b10a1e8b4 | ||
|
0fef016748 | ||
|
edb8d08e46 | ||
|
b80f632f28 | ||
|
9a634a5c4b | ||
|
6dbb95e69c | ||
|
25107519e5 | ||
|
8014b45a7a | ||
|
80dee1a9f9 | ||
|
afc5747e9b | ||
|
cedaf89b0f | ||
|
7918d0699c | ||
|
1b993a787d | ||
|
4ed56eaafc | ||
|
21a0818903 | ||
|
904023e2de | ||
|
a4d4ef9df5 | ||
|
9fcce29068 | ||
|
a69fdf6410 | ||
|
89ee514a27 | ||
|
3d43223448 | ||
|
6dd6836227 | ||
|
bc533b0fb2 | ||
|
05016926ae | ||
|
7fc08a8a68 | ||
|
b91da6c943 | ||
|
08ef73f94f | ||
|
59a571c75d | ||
|
bbc46bbc7a | ||
|
5b55e8d1f0 | ||
|
90b128e4cc | ||
|
81b3e80840 | ||
|
829b67074e | ||
|
288ef3479e | ||
|
8b2f1b4d1a | ||
|
2a67dcda5e | ||
|
76c50ca167 | ||
|
ee3c82a234 | ||
|
df96b6a707 | ||
|
00caa645ff | ||
|
20646e132c | ||
|
3af7624967 | ||
|
18b56bbae2 | ||
|
f8b100c136 | ||
|
1b245a8a46 | ||
|
6de04b08c4 | ||
|
5985c90d37 | ||
|
260276642e | ||
|
ea55328741 | ||
|
c38718c846 | ||
|
1aef8b9057 | ||
|
a8fe95f0ea | ||
|
33b98002c2 | ||
|
941434e81f | ||
|
6869341dce | ||
|
43eb0dbd38 | ||
|
9f7437fb85 | ||
|
5296136496 | ||
|
055b5a83b4 | ||
|
69738c76b4 | ||
|
5127aef0bb | ||
|
8f837f6e6f | ||
|
0ff3a84bc3 | ||
|
761d516fd4 | ||
|
6a23dfba36 | ||
|
639f5bf5db | ||
|
db1ed43050 | ||
|
ae6b9c0c63 | ||
|
f490b4de05 | ||
|
4be258fd13 | ||
|
775d56f01d | ||
|
1d067db128 | ||
|
6446d865be | ||
|
987ff07a85 | ||
|
01010851cb | ||
|
b2191e4450 | ||
|
df1786d777 | ||
|
e593626788 | ||
|
0e5e850691 | ||
|
267acbc534 | ||
|
56c39a2622 | ||
|
ef42c65ab1 | ||
|
97a1b5ffa4 | ||
|
c0d39fd2ed | ||
|
51bbe63d05 | ||
|
65e9eca63b | ||
|
281c45452b | ||
|
5ca7ad268a | ||
|
624784a729 | ||
|
7328f90e64 | ||
|
711b86fa24 | ||
|
40dc33a9d3 | ||
|
eb13efc4a6 | ||
|
3dff1a3f7b | ||
|
12f39bb2ab | ||
|
0048e8de0e | ||
|
bec66636c8 | ||
|
11599cb379 | ||
|
2ce7e21766 | ||
|
00ddc174b4 | ||
|
67500054d2 | ||
|
09b06a740d | ||
|
2a3c016894 | ||
|
d31a94a70a | ||
|
8c5736e68f | ||
|
86597d2891 | ||
|
d37960b35a | ||
|
d35a1eb1ac | ||
|
d7ff69741b | ||
|
7197992341 | ||
|
69fa60518c | ||
|
f20166d2de | ||
|
d07a849e98 | ||
|
b33813534e | ||
|
7a2b93fc78 | ||
|
c04a7aa2c6 | ||
|
97880102dc | ||
|
4e475b5cc2 | ||
|
ae2502b4ad | ||
|
0ca8024da2 | ||
|
c7f914c68c | ||
|
b6557e4be8 | ||
|
9ffc3b0705 | ||
|
01b90c38e7 | ||
|
9601b5fa5b | ||
|
7e80af2bc2 | ||
|
c965151d4d | ||
|
98065efdfa | ||
|
0ce4cdddb4 | ||
|
7a9f724735 | ||
|
44b706457e | ||
|
6f6c291beb | ||
|
7dca077bb6 | ||
|
d2c4f6df21 | ||
|
605a20b262 | ||
|
dd927a4f3c | ||
|
aefd124efa | ||
|
398c576037 | ||
|
042e713cb7 | ||
|
f3c839ecc4 | ||
|
e48aac4ec6 | ||
|
3f2698ce36 | ||
|
8c93587612 | ||
|
6067b27071 | ||
|
a546662cd8 | ||
|
9120bb9e03 | ||
|
ad014ed702 | ||
|
004c87ced5 | ||
|
fb6b0e5c94 | ||
|
6143ae4012 | ||
|
e4502f3dc1 | ||
|
b5ff268a3b | ||
|
df0d74dca4 | ||
|
6ba8e9875a | ||
|
9df9412335 | ||
|
8146816342 | ||
|
54ed658919 | ||
|
e0529535ca | ||
|
55148eb94d | ||
|
b50f026c55 | ||
|
0479ef1c1c | ||
|
9f1893855b | ||
|
1a6b177ec7 | ||
|
d5c5f9f352 | ||
|
ad867197cf | ||
|
176f9f6ce2 | ||
|
36f091f65d | ||
|
bd1cb1547f | ||
|
4924480944 | ||
|
e00b3bfc86 | ||
|
8ef6d4ede8 | ||
|
8232c837b0 | ||
|
abf6c88a86 | ||
|
779e5faf1d | ||
|
d7736416e8 | ||
|
66ed40dfe4 | ||
|
65a8c2e421 | ||
|
79f96014d1 | ||
|
33d74f3f58 | ||
|
b96994c9eb | ||
|
c4eacb70fd | ||
|
8d791bfb30 | ||
|
0c4b517e6e | ||
|
e50ae83c8c | ||
|
83226ed3d0 | ||
|
bcc0e6124a | ||
|
4bff9e3582 | ||
|
34167f6622 | ||
|
3e0276990d | ||
|
01e5801cec | ||
|
e60b493c2e | ||
|
87dc466e29 | ||
|
cbdd2d7353 | ||
|
0f744e6b2b | ||
|
7782f2ad14 | ||
|
54cb92d58b | ||
|
31c8031847 | ||
|
4661694382 | ||
|
93f52f7980 | ||
|
74c455c8bb | ||
|
d25e08afc2 | ||
|
abbbfa27bd | ||
|
ccbf28a56c | ||
|
2d819c7027 | ||
|
940fc15ec1 | ||
|
fe3b0212ea | ||
|
760688cc75 | ||
|
dcfd35f43b | ||
|
83cd96307f | ||
|
db841d4afe | ||
|
477972b3e0 | ||
|
6a6a1c0fe2 | ||
|
3d4501bea7 | ||
|
69b7c311f3 | ||
|
6e35353c83 | ||
|
7584fe901e | ||
|
a1a77ea7d1 | ||
|
e120fb78c9 | ||
|
49260691b2 | ||
|
10c195b864 | ||
|
7fbc340561 | ||
|
ef2200e327 | ||
|
12f59b27e1 | ||
|
a5f12c1ff9 | ||
|
b579f48790 | ||
|
1c32faa784 | ||
|
bff859c2ed | ||
|
266653fee4 | ||
|
2a734e1971 | ||
|
acbfeca2b3 | ||
|
eac8f36080 | ||
|
1ec2f5df26 | ||
|
a50b3916a2 | ||
|
3f5df82334 | ||
|
98d5581e16 | ||
|
a764da6902 | ||
|
f738fcb1f4 | ||
|
d45687f499 | ||
|
9db4c36a2f | ||
|
430779a287 | ||
|
b8fa115b47 | ||
|
54f5a61fbc | ||
|
9cb8a156fd | ||
|
6fe4ebce70 | ||
|
2f632086e9 | ||
|
1efb618b9a | ||
|
631fa1915e | ||
|
45c9a35d35 | ||
|
e7cc3ccf1d | ||
|
e149129954 | ||
|
1a3efe2249 | ||
|
d135c9ea00 | ||
|
b9c1d1f7a1 | ||
|
faf10af206 | ||
|
94e4f3c532 | ||
|
cd99c6aad5 | ||
|
da4e9b7637 | ||
|
a4dc60e9fc | ||
|
dac4298b72 | ||
|
b0fe7f3479 | ||
|
d10cba961b | ||
|
b93a8dfdfe | ||
|
1ac5e98077 | ||
|
9ed5d93c77 | ||
|
0d4c3c852a | ||
|
133838a7c7 | ||
|
007c0a1854 | ||
|
d1f0e924e9 | ||
|
72c674d253 | ||
|
8e4ca03733 | ||
|
3b5fcd4901 | ||
|
7ab7d88e8a | ||
|
78da1f8d00 | ||
|
2a4604e59e | ||
|
dcac89b5c7 | ||
|
cebb2dd068 | ||
|
c88a8c78bd | ||
|
5dbe3ecde8 | ||
|
1290935fab | ||
|
993c3fc35b | ||
|
2ed35fe889 | ||
|
d07c24d1ba | ||
|
b223437124 | ||
|
858bb5df19 | ||
|
c2e528ef42 | ||
|
84ad506420 | ||
|
82e7d1e56e | ||
|
a97091d699 | ||
|
3bcc785d0c | ||
|
cfe906856b | ||
|
5165a8bacc | ||
|
9521b51eef | ||
|
b51ee7068c | ||
|
ce820174ee | ||
|
e958f05aec | ||
|
10b88f3f20 | ||
|
87330d4bd7 | ||
|
f9bdb80ef1 | ||
|
b69650be3e | ||
|
2db67cb4b6 | ||
|
afc00d2b9b | ||
|
e4d59b698e | ||
|
55f8c072a3 | ||
|
4d34eee362 | ||
|
7920772663 | ||
|
cad8c1e6a7 | ||
|
a2792a934f | ||
|
62b1336c55 | ||
|
2a5d850e48 | ||
|
dc4f7e3ffa | ||
|
09590ee995 | ||
|
ee97f24ef4 | ||
|
8d97598e9c | ||
|
b141854d76 | ||
|
0246c56005 | ||
|
7a579851c2 | ||
|
65e70cec0b | ||
|
423659af18 | ||
|
d5c3460b41 | ||
|
891c1815e8 | ||
|
4f8e1bf151 | ||
|
648dede46c | ||
|
15a1b718e6 | ||
|
fdf4738be3 | ||
|
4ae1b626ef | ||
|
5f98cc3ecd | ||
|
41698bb5c1 | ||
|
5441057cc1 | ||
|
bbcf5a4191 | ||
|
813ea954b3 | ||
|
c804fc386b | ||
|
715ae29080 | ||
|
5dc84d6a21 | ||
|
dc1a5ac3e4 | ||
|
0b0d6b6d36 | ||
|
2bebec177d | ||
|
fbc78ff287 | ||
|
35e027fb62 | ||
|
41047e8b2c | ||
|
e54ece9dbb | ||
|
e26acf0f27 | ||
|
099fcbb56d | ||
|
a46cb99c69 | ||
|
ef2207ae48 | ||
|
37dbdd9b58 | ||
|
b9e8a966ea | ||
|
a256dba802 | ||
|
a2b68996b2 | ||
|
3780e0edc1 | ||
|
ce1a9d8bc9 | ||
|
842f433471 | ||
|
49bf0afdc7 | ||
|
2b2271bea3 | ||
|
562e74e3b4 | ||
|
697b769360 | ||
|
3fda22bd8a | ||
|
1ae6883162 | ||
|
566db56dd3 | ||
|
bead73f2f3 | ||
|
11f94598da | ||
|
1a98e24d0c | ||
|
c465681a86 | ||
|
d968aacde1 | ||
|
ee65d651a4 | ||
|
6d0f277a40 | ||
|
c82464ea75 | ||
|
37c389c779 | ||
|
72d0b8f709 | ||
|
f7efdfac36 | ||
|
92afa1eaf8 | ||
|
99d401220c | ||
|
3fa33cf1f1 | ||
|
25296f86d6 | ||
|
ac7ff59b6a | ||
|
8c8dfce81e | ||
|
b7e0a7bfde | ||
|
936992c404 | ||
|
27f16490fa | ||
|
33b0661cc6 | ||
|
06ab82d945 | ||
|
e50b0337e9 | ||
|
652fe10689 | ||
|
cf9e8434eb | ||
|
aa494a4de7 | ||
|
e09afd3cc0 | ||
|
b7711eb94c | ||
|
2b14b70b43 | ||
|
be31cbfce8 | ||
|
fb1d47b93e | ||
|
840cf0a43a | ||
|
f8adee805b | ||
|
2c4756af80 | ||
|
cddddd753c | ||
|
37a553a3a5 | ||
|
6ce164b3e0 | ||
|
ea6d467c05 | ||
|
2bb83f6b16 | ||
|
197a46313d | ||
|
58221c1955 | ||
|
0cb2413219 | ||
|
65b1756d01 | ||
|
3536eb32bf | ||
|
3660ff9ff8 | ||
|
b2dad9724d | ||
|
ab9021e2d6 | ||
|
3ee0cb32e0 | ||
|
7d0b4be42d | ||
|
b07580da56 | ||
|
b04935ed9f | ||
|
0db648ba3b | ||
|
5e84f22a0a | ||
|
c74f0ccf15 | ||
|
2220e447ca | ||
|
fafb4f11ef | ||
|
21815ae5e5 | ||
|
a32359a101 | ||
|
97775f43a1 | ||
|
5a878ca693 | ||
|
a33ce2a2ca | ||
|
31237ffd5f | ||
|
419979e0dc | ||
|
6ed0b578a8 | ||
|
04c3e5e5a7 | ||
|
6e74281ba3 | ||
|
df5c9259af | ||
|
887601bf0e | ||
|
83cb2ca344 | ||
|
58113ca96e | ||
|
96c5792d5b | ||
|
59420d3a0b | ||
|
30e7ce0fc1 | ||
|
1ed487f1ac | ||
|
a090ecbdd1 | ||
|
087db1d000 | ||
|
b18c3ecdbd | ||
|
85088954de | ||
|
fa8effc7da | ||
|
69277b9ed9 | ||
|
103aa5afb2 | ||
|
37effa5dd3 | ||
|
1426bd170b | ||
|
e342a52613 | ||
|
8b7bf25f7f | ||
|
6a6ce2474e | ||
|
b39b3551b7 | ||
|
96fe113608 | ||
|
875ccc41f4 | ||
|
765aa27aa3 | ||
|
9a1edf52d4 | ||
|
aae66d7518 | ||
|
11abd87046 | ||
|
a892eb50d3 | ||
|
e3feb85abc | ||
|
bded4bd5fc | ||
|
55dc2af21d | ||
|
40608d0a37 | ||
|
b5c3a3fe73 | ||
|
79bd27a82b | ||
|
2a121a9506 | ||
|
1b09c46051 | ||
|
bf535c4c66 | ||
|
5ff8c2eb00 | ||
|
11b9657b08 | ||
|
6dc19b55fc | ||
|
60eaa42a25 | ||
|
7f78908b44 | ||
|
9413c19cc1 | ||
|
2101e91465 | ||
|
a306131977 | ||
|
59861df8ce | ||
|
9db6df1a56 | ||
|
6d8afaac84 | ||
|
64c5043a40 | ||
|
0ce8e1db2b | ||
|
0e14e9042d | ||
|
7b356f0f31 | ||
|
33f37ff637 | ||
|
cffb015be5 | ||
|
8adfacca61 | ||
|
ee432b6431 | ||
|
850ed0222f | ||
|
b72c4988fb | ||
|
cdc8811492 | ||
|
5653829bf8 | ||
|
2378455647 | ||
|
d83081c78e | ||
|
b942110a4a | ||
|
ee533138d8 | ||
|
c35cb5fe9a | ||
|
ffb442db62 | ||
|
5ead2a3d63 | ||
|
ff596bfac8 | ||
|
076a818f74 | ||
|
f13ef41580 | ||
|
7aadf25ccd | ||
|
77de3d45d3 | ||
|
90fab1e4e9 | ||
|
73b8c83ec7 | ||
|
523f711295 | ||
|
c806d2bbbc | ||
|
101fedb17f | ||
|
cc1af8409a | ||
|
88600c3096 | ||
|
02f05bdb5f | ||
|
8dbd0828e9 | ||
|
f2b88b3225 | ||
|
381dca29ff | ||
|
36d260014f | ||
|
01edc916d2 | ||
|
5171b7f488 | ||
|
cc369ad07f | ||
|
11f485ea68 | ||
|
c970909437 | ||
|
5cd16659ff | ||
|
3ea877a844 | ||
|
60a264ed50 | ||
|
884c338355 | ||
|
b06125aa51 | ||
|
bbf78c9636 | ||
|
6790d8d716 | ||
|
d39c493390 | ||
|
b79b2edde8 | ||
|
e23933e868 | ||
|
314c91d94e | ||
|
fba5f806e6 | ||
|
843e2e1309 | ||
|
5e6fa3dbc5 | ||
|
8fdcda4dac | ||
|
09d44fdef3 | ||
|
e6434a71eb | ||
|
353d22756f | ||
|
aff082764a | ||
|
b6108318c2 | ||
|
7b5dbe165d | ||
|
fc29f57a17 | ||
|
4354d7797e | ||
|
6f7b8ada85 | ||
|
4eaaf89db5 | ||
|
4c2f439001 | ||
|
8f1438b1a8 | ||
|
610ee0c504 | ||
|
e266949979 | ||
|
b91edac40d | ||
|
7ce68e59fd | ||
|
651b515074 | ||
|
1319dcf472 | ||
|
9cd2e3ffef | ||
|
ecc31955f1 | ||
|
f349040b39 | ||
|
319b31a5a2 | ||
|
1596b5855c | ||
|
7ab2885594 | ||
|
fc29afbe1a | ||
|
ed1032975e | ||
|
51ed0b024b | ||
|
d1c0eb2291 | ||
|
b2bb9ef0f1 | ||
|
9e22277d28 | ||
|
3b4a7d4881 | ||
|
43ab4d5c7b | ||
|
55a46ec005 | ||
|
f10b13e469 | ||
|
5051e2b97b | ||
|
d5cff9be0e | ||
|
a994bc80fe | ||
|
8c3e5bcd21 | ||
|
9834571282 | ||
|
072f2a2241 | ||
|
da9ff584d1 | ||
|
d328e8eaaf | ||
|
6eb41440cd | ||
|
e63884c593 | ||
|
3c0f08ab70 | ||
|
72f48d0840 | ||
|
ab667d881d | ||
|
5fa520a77c | ||
|
019feea9b1 | ||
|
835475873b | ||
|
abfaf5189c | ||
|
2aaaf7cf12 | ||
|
0a4ff045f1 | ||
|
aac98b795d | ||
|
94928669c1 | ||
|
6cd5ea15ef | ||
|
3339990b4b | ||
|
0dd2561d54 | ||
|
a8b8a6fd6d | ||
|
ad16cd816a | ||
|
c39a944e74 | ||
|
cc2213ab27 | ||
|
e69e53de8e | ||
|
6e3d2ad44f | ||
|
7c332839e0 | ||
|
9610a7cbdc | ||
|
c8ae8244b4 | ||
|
9b2e444811 | ||
|
ee69826054 | ||
|
3c0986a34c | ||
|
9e86f73f82 | ||
|
cdfd686714 | ||
|
78051d03ca | ||
|
eab71ff6b0 | ||
|
07ad8c8444 | ||
|
501f78855e | ||
|
bfb80b7b45 | ||
|
f5e2166bbd | ||
|
9988cd2469 | ||
|
440dcaca27 | ||
|
7ab145a9ef | ||
|
b5ba125fa0 | ||
|
c437c6a4f6 | ||
|
ff303c5cd9 | ||
|
510f8005bc | ||
|
e9509291ae | ||
|
7664b826db | ||
|
8bd0625f54 | ||
|
4d009678ce | ||
|
e2a0ef30da | ||
|
d53feb3da2 | ||
|
7baf9d06b5 | ||
|
9d7fabb6c2 | ||
|
51bfc9da41 | ||
|
1f0dc7635e | ||
|
137da0326a | ||
|
60d28c8c7c | ||
|
e076767bfd | ||
|
c76b845d90 | ||
|
604dcc714a | ||
|
b70e61788f | ||
|
5d2f40a14b | ||
|
eb44663eaa | ||
|
83e18b6540 | ||
|
df2f31b9bf | ||
|
e8605372ba | ||
|
00f6df326f | ||
|
06a209384a | ||
|
b143215c54 | ||
|
31e3012296 | ||
|
bb91219b26 | ||
|
2dfc0cb6f6 | ||
|
2a512fd901 | ||
|
443bdb9620 | ||
|
149150ab47 | ||
|
29e2695676 | ||
|
dbaef86144 | ||
|
9bcbeea2ad | ||
|
7044c32963 | ||
|
8472fc2573 | ||
|
3de6c570fb | ||
|
8b4a8b1e10 | ||
|
609d34d702 | ||
|
49cf61f641 | ||
|
80e581d91b | ||
|
b3c60bd11f | ||
|
8a7ee8d522 | ||
|
d0a3db5d93 | ||
|
67adc2227d | ||
|
0c054f6844 | ||
|
f329dd4e16 | ||
|
75cb14deb8 | ||
|
a77b11c548 | ||
|
43f4706ee8 | ||
|
5c3fd55beb | ||
|
66da88f428 | ||
|
7c3723b2a9 | ||
|
1a737083f1 | ||
|
901731ad78 |
@ -7,7 +7,7 @@ if (NOT DEFINED QT_SUPERBUILD OR DEFINED QT_REPO_MODULE_VERSION)
|
||||
set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_LEAN_HEADERS=1")
|
||||
endif()
|
||||
|
||||
set(QT_REPO_MODULE_VERSION "6.9.0")
|
||||
set(QT_REPO_MODULE_VERSION "6.9.1")
|
||||
set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1")
|
||||
|
||||
set(QT_COPYRIGHT "Copyright (C) The Qt Company Ltd. and other contributors.")
|
||||
|
4
.gitreview
Normal file
4
.gitreview
Normal file
@ -0,0 +1,4 @@
|
||||
[gerrit]
|
||||
host=codereview.qt-project.org
|
||||
project=qt/qtbase
|
||||
defaultbranch=dev
|
@ -24,9 +24,13 @@ project(QtBase
|
||||
VERSION "${QT_REPO_MODULE_VERSION}"
|
||||
DESCRIPTION "Qt Base Libraries"
|
||||
HOMEPAGE_URL "https://qt.io/"
|
||||
LANGUAGES CXX C ASM
|
||||
LANGUAGES CXX C
|
||||
)
|
||||
|
||||
if(UNIX AND NOT ANDROID)
|
||||
enable_language(ASM)
|
||||
endif()
|
||||
|
||||
set(QT_BUILD_EXTRA_IDE_FILE_PATTERNS bin/* libexec/*)
|
||||
|
||||
qt_internal_qtbase_build_repo()
|
||||
|
34
REUSE.toml
34
REUSE.toml
@ -24,9 +24,9 @@ SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GPL-3.0-only"
|
||||
path = ["bin/*", "coin/**","libexec/*","**_clang-format", "**.cmake", "**.conf", "**.cmake.in",
|
||||
"**.prf", "libexec/qt-internal-configure-*", "config.tests/.qmake.conf",
|
||||
"**.pro", "**.pri", "**.yaml", "cmake/**.in", "cmake/ios/LaunchScreen.storyboard",
|
||||
"cmake/**md", "**.yml", "**.dynlist",
|
||||
"cmake/**md", "**.yml", "**.dynlist", "cmake/**.plist",
|
||||
"src/corelib/global/qconfig.cpp.in", "src/corelib/Qt6CoreConfigureFileTemplate.in",
|
||||
"**.cfg"]
|
||||
"**.cfg", "**/Makefile", "**/CMakeLists.txt", "**.qrc", ".tag"]
|
||||
precedence = "closest"
|
||||
comment = "build system"
|
||||
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
|
||||
@ -39,29 +39,42 @@ SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
|
||||
SPDX-License-Identifier = "CC0-1.0"
|
||||
|
||||
[[annotations]]
|
||||
path = [".tag", "**/.gitattributes", "**.gitignore"]
|
||||
path = ["**/.gitattributes", "**.gitignore", "**.gitreview"]
|
||||
precedence = "closest"
|
||||
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
|
||||
SPDX-License-Identifier = "BSD-3-Clause"
|
||||
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
|
||||
|
||||
[[annotations]]
|
||||
path = ["**/snippets/**", "**/doc/**/images/**", "examples/**"]
|
||||
path = ["**/snippets/**", "examples/**", "src/tools/qlalr/examples/**"]
|
||||
comment = "this must be after the build system table because example and snippets take precedence over build system"
|
||||
precedence = "closest"
|
||||
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
|
||||
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
|
||||
|
||||
[[annotations]]
|
||||
path = ["tests/manual/examples/**", "**/snippets/**"]
|
||||
precedence = "closest"
|
||||
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
|
||||
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
|
||||
|
||||
[[annotations]]
|
||||
path = ["**/README*", "src/plugins/**/README*", "examples/**/README*", "tests/**/README*",
|
||||
"src/widgets/doc/snippets/common-table-model/README", "cmake/README.md",
|
||||
"lib/README", "coin/instructions/README.md", "src/3rdparty/README",
|
||||
"**.qdocconf", "**.qdocinc", "config_help.txt",
|
||||
"doc/global/template/style/*"]
|
||||
"doc/global/template/style/*", "**/doc/**/images/**"]
|
||||
comment = "documentation"
|
||||
precedence = "closest"
|
||||
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
|
||||
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"
|
||||
|
||||
[[annotations]]
|
||||
path = ["src/gui/doc/snippets/textdocument-images/images.qrc"]
|
||||
precedence = "closest"
|
||||
comment = "falls under **/doc/**/images/**, which is wrong"
|
||||
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
|
||||
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
|
||||
|
||||
[[annotations]]
|
||||
path = ["src/assets/icons/**.png", "src/assets/icons/**.svg", "src/android/**.xml",
|
||||
"src/gui/**.xml",
|
||||
@ -73,6 +86,13 @@ precedence = "closest"
|
||||
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
|
||||
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only"
|
||||
|
||||
[[annotations]]
|
||||
path = ["tests/auto/tools/rcc/data/legal/legal.qrc"]
|
||||
precedence = "override"
|
||||
comment = "license in file not referring to the file itself"
|
||||
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
|
||||
SPDX-License-Identifier = "BSD-3-Clause"
|
||||
|
||||
[[annotations]]
|
||||
path = ["**/qt_attribution.json"]
|
||||
precedence = "override"
|
||||
@ -83,7 +103,7 @@ SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-on
|
||||
path = ["**.toml", "licenseRule.json"]
|
||||
precedence = "override"
|
||||
SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd."
|
||||
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"
|
||||
SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause"
|
||||
|
||||
[[annotations]]
|
||||
path = ["**LICENSE*", "cmake/3rdparty/**/COPYING-CMAKE-SCRIPTS"]
|
||||
|
@ -0,0 +1,45 @@
|
||||
From cbda7ce74d74539ce0baef4a36198081dfb0265c Mon Sep 17 00:00:00 2001
|
||||
From: Marc Mutz <marc.mutz@qt.io>
|
||||
Date: Fri, 14 Mar 2025 18:29:20 +0100
|
||||
Subject: [PATCH] ECMEnableSanitizers.cmake: fix GCC's "note: variable tracking
|
||||
size limit exceeded" when using asan
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Set the max-vartrack-size parameter to 0 (= unlimited) to avoid GCC's
|
||||
"note: variable tracking size limit exceeded with
|
||||
-fvar-tracking-assignments, retrying without" message you get when you
|
||||
compile with asan sometimes.
|
||||
|
||||
This is reported¹ to speed up compilation, not slow it down.
|
||||
|
||||
¹ https://stackoverflow.com/a/75704837/134841
|
||||
---
|
||||
modules/ECMEnableSanitizers.cmake | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/modules/ECMEnableSanitizers.cmake b/modules/ECMEnableSanitizers.cmake
|
||||
index 07db1c80..45236e6d 100644
|
||||
--- a/modules/ECMEnableSanitizers.cmake
|
||||
+++ b/modules/ECMEnableSanitizers.cmake
|
||||
@@ -117,6 +117,16 @@ macro (enable_sanitizer_flags sanitize_option)
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
set(XSAN_LINKER_FLAGS "asan")
|
||||
endif()
|
||||
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
+ # fixes "note: variable tracking size limit exceeded with
|
||||
+ # -fvar-tracking-assignments, retrying without" (which is
|
||||
+ # another way of saying "I'll go ahead and compile this
|
||||
+ # thing _twice_") by making it unlimited
|
||||
+ # Reference:
|
||||
+ # https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
|
||||
+ # -> max-vartrack-size
|
||||
+ string(APPEND XSAN_COMPILE_FLAGS " --param=max-vartrack-size=0")
|
||||
+ endif ()
|
||||
elseif (${sanitize_option} MATCHES "thread")
|
||||
check_compiler_version("4.8" "3.1" "99.99")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=thread")
|
||||
--
|
||||
2.25.1
|
||||
|
42
cmake/3rdparty/extra-cmake-modules/0002-ECMEnableSanitizers.cmake-replace-tabs-with-spaces.patch
vendored
Normal file
42
cmake/3rdparty/extra-cmake-modules/0002-ECMEnableSanitizers.cmake-replace-tabs-with-spaces.patch
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
From 8907023584ea0936893269aee890af5995746af5 Mon Sep 17 00:00:00 2001
|
||||
From: Marc Mutz <marc.mutz@qt.io>
|
||||
Date: Mon, 17 Mar 2025 10:15:03 +0100
|
||||
Subject: [PATCH] ECMEnableSanitizers.cmake: replace tabs with spaces
|
||||
|
||||
Amends cbda7ce74d74539ce0baef4a36198081dfb0265c.
|
||||
---
|
||||
modules/ECMEnableSanitizers.cmake | 18 +++++++++---------
|
||||
1 file changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/modules/ECMEnableSanitizers.cmake b/modules/ECMEnableSanitizers.cmake
|
||||
index 45236e6d..8686384d 100644
|
||||
--- a/modules/ECMEnableSanitizers.cmake
|
||||
+++ b/modules/ECMEnableSanitizers.cmake
|
||||
@@ -118,15 +118,15 @@ macro (enable_sanitizer_flags sanitize_option)
|
||||
set(XSAN_LINKER_FLAGS "asan")
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
- # fixes "note: variable tracking size limit exceeded with
|
||||
- # -fvar-tracking-assignments, retrying without" (which is
|
||||
- # another way of saying "I'll go ahead and compile this
|
||||
- # thing _twice_") by making it unlimited
|
||||
- # Reference:
|
||||
- # https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
|
||||
- # -> max-vartrack-size
|
||||
- string(APPEND XSAN_COMPILE_FLAGS " --param=max-vartrack-size=0")
|
||||
- endif ()
|
||||
+ # fixes "note: variable tracking size limit exceeded with
|
||||
+ # -fvar-tracking-assignments, retrying without" (which is
|
||||
+ # another way of saying "I'll go ahead and compile this
|
||||
+ # thing _twice_") by making it unlimited
|
||||
+ # Reference:
|
||||
+ # https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
|
||||
+ # -> max-vartrack-size
|
||||
+ string(APPEND XSAN_COMPILE_FLAGS " --param=max-vartrack-size=0")
|
||||
+ endif ()
|
||||
elseif (${sanitize_option} MATCHES "thread")
|
||||
check_compiler_version("4.8" "3.1" "99.99")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=thread")
|
||||
--
|
||||
2.25.1
|
||||
|
@ -120,7 +120,7 @@ list(APPEND CMAKE_REQUIRED_LIBRARIES "${EGL_LIBRARY}")
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${EGL_INCLUDE_DIR}")
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS "${EGL_DEFINITIONS}")
|
||||
|
||||
find_package(PlatformGraphics)
|
||||
find_package(PlatformGraphics QUIET)
|
||||
if(TARGET PlatformGraphics::PlatformGraphics)
|
||||
platform_graphics_extend_check_cxx_source_required_variables()
|
||||
endif()
|
||||
|
@ -118,6 +118,16 @@ macro (enable_sanitizer_flags sanitize_option)
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls")
|
||||
set(XSAN_LINKER_FLAGS "asan")
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
# fixes "note: variable tracking size limit exceeded with
|
||||
# -fvar-tracking-assignments, retrying without" (which is
|
||||
# another way of saying "I'll go ahead and compile this
|
||||
# thing _twice_") by making it unlimited
|
||||
# Reference:
|
||||
# https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
|
||||
# -> max-vartrack-size
|
||||
string(APPEND XSAN_COMPILE_FLAGS " --param=max-vartrack-size=0")
|
||||
endif ()
|
||||
elseif (${sanitize_option} MATCHES "thread")
|
||||
check_compiler_version("4.8" "3.1" "99.99")
|
||||
set(XSAN_COMPILE_FLAGS "-fsanitize=thread")
|
||||
|
@ -21,7 +21,7 @@ else()
|
||||
set(_includes "${CMAKE_REQUIRED_INCLUDES}")
|
||||
list(APPEND CMAKE_REQUIRED_INCLUDES "${GLESv2_INCLUDE_DIR}")
|
||||
|
||||
find_package(PlatformGraphics)
|
||||
find_package(PlatformGraphics QUIET)
|
||||
if(TARGET PlatformGraphics::PlatformGraphics)
|
||||
platform_graphics_extend_check_cxx_source_required_variables()
|
||||
endif()
|
||||
|
@ -25,13 +25,22 @@ if(LIBRESOLV)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBRESOLV}")
|
||||
endif()
|
||||
|
||||
cmake_policy(PUSH)
|
||||
if(POLICY CMP0067)
|
||||
cmake_policy(SET CMP0067 NEW)
|
||||
endif()
|
||||
if(DEFINED CMAKE_CXX_STANDARD)
|
||||
set(_WrapResolv_CMAKE_CXX_STANDARD_back ${CMAKE_CXX_STANDARD})
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <netinet/in.h>
|
||||
#include <resolv.h>
|
||||
|
||||
int main(int, char **argv)
|
||||
{
|
||||
res_state statep = 0;
|
||||
res_state statep = {};
|
||||
int n = res_nmkquery(statep, 0, argv[1], 0, 0, NULL, 0, NULL, NULL, 0);
|
||||
n = res_nsend(statep, NULL, 0, NULL, 0);
|
||||
n = dn_expand(NULL, NULL, NULL, NULL, 0);
|
||||
@ -39,6 +48,14 @@ int main(int, char **argv)
|
||||
}
|
||||
" HAVE_LIBRESOLV_FUNCTIONS)
|
||||
|
||||
if(DEFINED _WrapResolv_CMAKE_CXX_STANDARD_back)
|
||||
set(CMAKE_CXX_STANDARD ${_WrapResolv_CMAKE_CXX_STANDARD_back})
|
||||
unset(_WrapResolv_CMAKE_CXX_STANDARD_back)
|
||||
else()
|
||||
unset(CMAKE_CXX_STANDARD)
|
||||
endif()
|
||||
|
||||
cmake_policy(POP)
|
||||
cmake_pop_check_state()
|
||||
|
||||
if(HAVE_LIBRESOLV_FUNCTIONS)
|
||||
|
@ -9,6 +9,6 @@ $<1: >
|
||||
Name: @pkgconfig_name@
|
||||
Description: @pkgconfig_description@
|
||||
Version: @PROJECT_VERSION@
|
||||
Libs: $<$<NOT:@is_interface_library@>:-L${libdir} -l@pkgconfig_file@> @link_options@
|
||||
Libs: @link_options@
|
||||
Cflags: @include_dirs@ @compile_defs@
|
||||
Requires: $<JOIN:$<REMOVE_DUPLICATES:@target_requires@>, >
|
||||
|
@ -227,7 +227,7 @@ function(qt_internal_add_3rdparty_library target)
|
||||
qt_autogen_tools_initial_setup(${target})
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED arg_EXCEPTIONS)
|
||||
if(NOT arg_EXCEPTIONS)
|
||||
qt_internal_set_exceptions_flags("${target}" "DEFAULT")
|
||||
else()
|
||||
qt_internal_set_exceptions_flags("${target}" "${arg_EXCEPTIONS}")
|
||||
@ -379,7 +379,7 @@ function(qt_internal_add_3rdparty_library target)
|
||||
${__qt_internal_sbom_multi_args}
|
||||
)
|
||||
|
||||
_qt_internal_extend_sbom(${target} ${sbom_args})
|
||||
qt_internal_extend_qt_entity_sbom(${target} ${sbom_args})
|
||||
endif()
|
||||
|
||||
qt_add_list_file_finalizer(qt_internal_finalize_3rdparty_library ${target})
|
||||
|
@ -154,7 +154,7 @@ function(qt_internal_add_app target)
|
||||
${__qt_internal_sbom_multi_args}
|
||||
)
|
||||
|
||||
_qt_internal_extend_sbom(${target} ${sbom_args})
|
||||
qt_internal_extend_qt_entity_sbom(${target} ${sbom_args})
|
||||
endif()
|
||||
|
||||
qt_add_list_file_finalizer(qt_internal_finalize_app ${target})
|
||||
|
@ -152,7 +152,12 @@ function(qt_auto_detect_android)
|
||||
endfunction()
|
||||
|
||||
function(qt_auto_detect_vcpkg)
|
||||
if(QT_USE_VCPKG AND DEFINED ENV{VCPKG_ROOT})
|
||||
if(QT_USE_VCPKG)
|
||||
if(NOT DEFINED ENV{VCPKG_ROOT})
|
||||
message(FATAL_ERROR
|
||||
"Usage of vcpkg was requested but the environment variable VCPKG_ROOT is not set."
|
||||
)
|
||||
endif()
|
||||
set(vcpkg_toolchain_file "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
|
||||
get_filename_component(vcpkg_toolchain_file "${vcpkg_toolchain_file}" ABSOLUTE)
|
||||
|
||||
@ -269,6 +274,9 @@ function(qt_auto_detect_apple)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
_qt_internal_get_apple_sdk_path(apple_sdk_path)
|
||||
set(QT_APPLE_SDK_PATH "${apple_sdk_path}" CACHE STRING "Darwin SDK path.")
|
||||
|
||||
_qt_internal_get_apple_sdk_version(apple_sdk_version)
|
||||
set(QT_MAC_SDK_VERSION "${apple_sdk_version}" CACHE STRING "Darwin SDK version.")
|
||||
|
||||
|
@ -123,10 +123,7 @@ function(qt_manual_moc result)
|
||||
set(dep "${QT_CMAKE_EXPORT_NAMESPACE}::${dep}")
|
||||
endif()
|
||||
|
||||
get_target_property(alias_dep ${dep} ALIASED_TARGET)
|
||||
if(alias_dep)
|
||||
set(dep ${alias_dep})
|
||||
endif()
|
||||
_qt_internal_dealias_target(dep)
|
||||
|
||||
get_target_property(loc ${dep} IMPORTED_LOCATION)
|
||||
string(REGEX REPLACE "(.*)/Qt[^/]+\\.framework.*" "\\1" loc "${loc}")
|
||||
@ -214,3 +211,50 @@ function(qt_make_output_file infile prefix suffix source_dir binary_dir result)
|
||||
file(MAKE_DIRECTORY "${outpath}")
|
||||
set("${result}" "${outpath}/${prefix}${outfilename}${suffix}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Work around AUTOGEN issue when a library is added as a dependency more than once, and the autogen
|
||||
# library dependency results in being discarded. To mitigate that, add all autogen dependencies
|
||||
# manually, based on the passed in dependencies.
|
||||
# CMake 4.0+ has a fix, so we don't need the extra logic.
|
||||
# See https://gitlab.kitware.com/cmake/cmake/-/issues/26700
|
||||
function(qt_internal_work_around_autogen_discarded_dependencies target)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.0
|
||||
OR QT_NO_AUTOGEN_DISCARDED_DEPENDENCIES_WORKAROUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(libraries ${ARGN})
|
||||
set(final_libraries "")
|
||||
|
||||
foreach(lib IN LISTS libraries)
|
||||
# Skip non-target dependencies.
|
||||
if(NOT TARGET "${lib}")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# Resolve alias targets, because AUTOGEN_TARGET_DEPENDS doesn't seem to handle them.
|
||||
_qt_internal_dealias_target(lib)
|
||||
|
||||
# Skip imported targets, they don't have sync_headers targets.
|
||||
get_target_property(imported "${lib}" IMPORTED)
|
||||
if(imported)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# Resolve Qt private modules to their public counterparts.
|
||||
get_target_property(is_private_module "${lib}" _qt_is_private_module)
|
||||
get_target_property(public_module_target "${lib}" _qt_public_module_target_name)
|
||||
|
||||
if(is_private_module AND public_module_target)
|
||||
set(lib "${public_module_target}")
|
||||
endif()
|
||||
|
||||
# Another TARGET check, just in case.
|
||||
if(TARGET "${lib}")
|
||||
list(APPEND final_libraries "${lib}")
|
||||
endif()
|
||||
endforeach()
|
||||
if(final_libraries)
|
||||
set_property(TARGET ${target} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS "${final_libraries}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
@ -187,7 +187,7 @@ function(qt_run_config_test_architecture)
|
||||
list(APPEND QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT TEST_buildAbi)
|
||||
set(QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT ${QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT} CACHE INTERNAL "Test variables that should be exported")
|
||||
|
||||
list(JOIN _sub_architecture " " subarch_summary)
|
||||
list(JOIN sub_architecture_${first_arch} " " subarch_summary)
|
||||
set_property(GLOBAL PROPERTY qt_configure_subarch_summary "${subarch_summary}")
|
||||
endfunction()
|
||||
|
||||
@ -274,6 +274,7 @@ function(qt_internal_print_cmake_darwin_info)
|
||||
endif()
|
||||
message(STATUS "CMAKE_OSX_ARCHITECTURES: \"${CMAKE_OSX_ARCHITECTURES}\"${default_osx_arch}")
|
||||
message(STATUS "CMAKE_OSX_SYSROOT: \"$CACHE{CMAKE_OSX_SYSROOT}\" / \"${CMAKE_OSX_SYSROOT}\"")
|
||||
message(STATUS "QT_APPLE_SDK_PATH: \"${QT_APPLE_SDK_PATH}\"")
|
||||
message(STATUS "CMAKE_OSX_DEPLOYMENT_TARGET: \"${CMAKE_OSX_DEPLOYMENT_TARGET}\"")
|
||||
message(STATUS "QT_MAC_SDK_VERSION: \"${QT_MAC_SDK_VERSION}\"")
|
||||
message(STATUS "QT_MAC_XCODE_VERSION: \"${QT_MAC_XCODE_VERSION}\"")
|
||||
|
@ -258,14 +258,24 @@ qt_copy_or_install(DIRECTORY
|
||||
)
|
||||
|
||||
# Install qt-internal-strip and qt-internal-ninja files.
|
||||
set(__qt_internal_strip_wrappers
|
||||
set(__qt_internal_strip_wrapper_programs
|
||||
libexec/qt-internal-strip.in
|
||||
libexec/qt-internal-strip.bat.in
|
||||
libexec/qt-internal-ninja.in
|
||||
)
|
||||
set(__qt_internal_strip_wrapper_files
|
||||
libexec/qt-internal-strip.bat.in
|
||||
libexec/qt-internal-ninja.bat.in
|
||||
)
|
||||
set(__qt_internal_strip_wrappers
|
||||
${__qt_internal_strip_wrapper_programs}
|
||||
${__qt_internal_strip_wrapper_files}
|
||||
)
|
||||
qt_copy_or_install(PROGRAMS
|
||||
${__qt_internal_strip_wrappers}
|
||||
${__qt_internal_strip_wrapper_programs}
|
||||
DESTINATION "${__GlobalConfig_install_dir}/libexec"
|
||||
)
|
||||
qt_copy_or_install(FILES
|
||||
${__qt_internal_strip_wrapper_files}
|
||||
DESTINATION "${__GlobalConfig_install_dir}/libexec"
|
||||
)
|
||||
if(QT_WILL_INSTALL)
|
||||
@ -366,7 +376,15 @@ if(APPLE)
|
||||
DESTINATION "${__GlobalConfig_build_dir}/${platform_shortname}"
|
||||
)
|
||||
|
||||
if(IOS)
|
||||
if(MACOS)
|
||||
# Test entitlements
|
||||
qt_copy_or_install(FILES "cmake/${platform_shortname}/test.entitlements.plist"
|
||||
DESTINATION "${__GlobalConfig_install_dir}/${platform_shortname}"
|
||||
)
|
||||
file(COPY "cmake/${platform_shortname}/test.entitlements.plist"
|
||||
DESTINATION "${__GlobalConfig_build_dir}/${platform_shortname}"
|
||||
)
|
||||
elseif(IOS)
|
||||
qt_copy_or_install(FILES "cmake/ios/LaunchScreen.storyboard"
|
||||
DESTINATION "${__GlobalConfig_install_dir}/ios"
|
||||
)
|
||||
@ -378,9 +396,23 @@ if(APPLE)
|
||||
elseif(WASM)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/wasmtestrunner/qt-wasmtestrunner.py"
|
||||
"${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-wasmtestrunner.py" @ONLY)
|
||||
|
||||
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-wasmtestrunner.py"
|
||||
DESTINATION "${INSTALL_LIBEXECDIR}")
|
||||
|
||||
if(QT_FEATURE_shared)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/preload/preload_qml_imports.py"
|
||||
"${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qml_imports.py" COPYONLY)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/preload/preload_qt_plugins.py"
|
||||
"${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qt_plugins.py" COPYONLY)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/preload/generate_default_preloads.sh.in"
|
||||
"${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/generate_default_preloads.sh.in" COPYONLY)
|
||||
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qml_imports.py"
|
||||
DESTINATION "${INSTALL_LIBEXECDIR}")
|
||||
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qt_plugins.py"
|
||||
DESTINATION "${INSTALL_LIBEXECDIR}")
|
||||
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/generate_default_preloads.sh.in"
|
||||
DESTINATION "${INSTALL_LIBEXECDIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Install CI support files to libexec.
|
||||
|
@ -246,6 +246,7 @@ function(qt_internal_get_qt_build_private_files_to_install out_var)
|
||||
QtGenerateLibPri.cmake
|
||||
QtGenerateVersionScript.cmake
|
||||
QtModuleConfig.cmake.in
|
||||
QtModuleConfigPrivate.cmake.in
|
||||
QtModuleDependencies.cmake.in
|
||||
QtModuleHeadersCheck.cmake
|
||||
QtModuleToolsConfig.cmake.in
|
||||
@ -292,8 +293,18 @@ function(qt_internal_get_qt_build_public_helpers out_var)
|
||||
QtPublicGitHelpers
|
||||
QtPublicPluginHelpers
|
||||
QtPublicPluginHelpers_v2
|
||||
QtPublicSbomAttributionHelpers
|
||||
QtPublicSbomCpeHelpers
|
||||
QtPublicSbomDepHelpers
|
||||
QtPublicSbomFileHelpers
|
||||
QtPublicSbomGenerationHelpers
|
||||
QtPublicSbomHelpers
|
||||
QtPublicSbomLicenseHelpers
|
||||
QtPublicSbomOpsHelpers
|
||||
QtPublicSbomPurlHelpers
|
||||
QtPublicSbomPythonHelpers
|
||||
QtPublicSbomQtEntityHelpers
|
||||
QtPublicSbomSystemDepHelpers
|
||||
QtPublicTargetHelpers
|
||||
QtPublicTestHelpers
|
||||
QtPublicToolHelpers
|
||||
@ -350,7 +361,8 @@ endfunction()
|
||||
|
||||
macro(qt_internal_setup_find_host_info_package)
|
||||
_qt_internal_determine_if_host_info_package_needed(__qt_build_requires_host_info_package)
|
||||
_qt_internal_find_host_info_package("${__qt_build_requires_host_info_package}")
|
||||
_qt_internal_find_host_info_package("${__qt_build_requires_host_info_package}"
|
||||
${INSTALL_CMAKE_NAMESPACE})
|
||||
endmacro()
|
||||
|
||||
macro(qt_internal_setup_poor_mans_scope_finalizer)
|
||||
@ -478,4 +490,3 @@ macro(qt_internal_setup_build_and_global_variables)
|
||||
|
||||
qt_internal_detect_dirty_features()
|
||||
endmacro()
|
||||
|
||||
|
@ -28,7 +28,7 @@ endif()
|
||||
# Get the project name base on test directory name
|
||||
get_filename_component(project_name "${absolute_project_path}" NAME)
|
||||
|
||||
project(${project_name} VERSION 6.0.0 LANGUAGES C CXX ASM)
|
||||
project(${project_name} VERSION 6.0.0 LANGUAGES C CXX)
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS BuildInternals Core)
|
||||
|
||||
|
@ -344,17 +344,9 @@ endfunction()
|
||||
macro(qt_internal_setup_sbom)
|
||||
qt_internal_compute_sbom_default(_qt_generate_sbom_default)
|
||||
|
||||
option(QT_GENERATE_SBOM "Generate SBOM documents in SPDX v2.3 tag:value format."
|
||||
"${_qt_generate_sbom_default}")
|
||||
|
||||
option(QT_SBOM_GENERATE_JSON
|
||||
"Generate SBOM documents in SPDX v2.3 JSON format if dependencies are available" ON)
|
||||
option(QT_SBOM_REQUIRE_GENERATE_JSON
|
||||
"Error out if JSON SBOM generation dependencies are not found." OFF)
|
||||
|
||||
option(QT_SBOM_VERIFY "Verify generated SBOM documents." ON)
|
||||
option(QT_SBOM_REQUIRE_VERIFY
|
||||
"Error out if SBOM verification dependencies are not found." OFF)
|
||||
_qt_internal_setup_sbom(
|
||||
GENERATE_SBOM_DEFAULT "${_qt_generate_sbom_default}"
|
||||
)
|
||||
endmacro()
|
||||
|
||||
macro(qt_internal_setup_build_examples)
|
||||
|
@ -202,6 +202,15 @@ macro(qt_internal_setup_configure_install_paths)
|
||||
"Module description files directory")
|
||||
qt_configure_process_path(INSTALL_SBOMDIR "${INSTALL_ARCHDATADIR}/sbom"
|
||||
"SBOM [PREFIX/sbom]")
|
||||
|
||||
# INSTALL_PUBLICBINDIR is processed only if it is not empty
|
||||
# See usage in qt_internal_generate_user_facing_tools_info
|
||||
if(NOT "${INSTALL_PUBLICBINDIR}" STREQUAL "")
|
||||
# A default value is not needed because it is always manually defined
|
||||
# but as per the documentation it is typically `bin`
|
||||
qt_configure_process_path(INSTALL_PUBLICBINDIR "bin"
|
||||
"Symlinked user-facing executables")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(qt_internal_set_cmake_install_libdir)
|
||||
|
@ -178,6 +178,10 @@ function(qt_internal_configure_qt)
|
||||
-skip qtactiveqt,qtimageformats,qtlanguageserver,qtsvg
|
||||
--
|
||||
-DWARNINGS_ARE_ERRORS=OFF
|
||||
# When 6.x.y version bumps are not merged in DAG-dependency order, this avoids
|
||||
# blocking integrations due to mismatch of qtools package version and any of its
|
||||
# dependencies.
|
||||
-DQT_NO_PACKAGE_VERSION_INCOMPATIBLE_WARNING=ON
|
||||
--log-level STATUS
|
||||
--fresh
|
||||
-GNinja
|
||||
|
@ -1,52 +1,24 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# The common implementation of qt_configure_file functionality.
|
||||
macro(qt_configure_file_impl)
|
||||
if(NOT arg_OUTPUT)
|
||||
message(FATAL_ERROR "No output file provided to qt_configure_file.")
|
||||
endif()
|
||||
|
||||
# We use this check for the cases when the specified CONTENT is empty. The value of arg_CONTENT
|
||||
# is undefined, but we still want to create a file with empty content.
|
||||
if(NOT "CONTENT" IN_LIST arg_KEYWORDS_MISSING_VALUES)
|
||||
if(arg_INPUT)
|
||||
message(WARNING "Both CONTENT and INPUT are specified. CONTENT will be used to generate"
|
||||
" output")
|
||||
endif()
|
||||
set(template_name "QtFileConfigure.txt.in")
|
||||
# When building qtbase, use the source template file.
|
||||
# Otherwise use the installed file (basically wherever Qt6 package is found).
|
||||
# This should work for non-prefix and superbuilds as well.
|
||||
if(QtBase_SOURCE_DIR)
|
||||
set(input_file "${QtBase_SOURCE_DIR}/cmake/${template_name}")
|
||||
else()
|
||||
set(input_file "${_qt_6_config_cmake_dir}/${template_name}")
|
||||
endif()
|
||||
set(__qt_file_configure_content "${arg_CONTENT}")
|
||||
elseif(arg_INPUT)
|
||||
set(input_file "${arg_INPUT}")
|
||||
else()
|
||||
message(FATAL_ERROR "No input value provided to qt_configure_file.")
|
||||
endif()
|
||||
|
||||
configure_file("${input_file}" "${arg_OUTPUT}" @ONLY)
|
||||
endmacro()
|
||||
|
||||
# qt_configure_file(OUTPUT output-file <INPUT input-file | CONTENT content>)
|
||||
# input-file is relative to ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
# output-file is relative to ${CMAKE_CURRENT_BINARY_DIR}
|
||||
#
|
||||
# This function is similar to file(GENERATE OUTPUT) except it writes the content
|
||||
# to the file at configure time, rather than at generate time.
|
||||
#
|
||||
# TODO: Once we require 3.18+, this can use file(CONFIGURE) in its implementation,
|
||||
# or maybe its usage can be replaced by file(CONFIGURE). Until then, it uses
|
||||
# configure_file() with a generic input file as source, when used with the CONTENT
|
||||
# signature.
|
||||
# This function is the universal replacement for file(CONFIGURE CMake command.
|
||||
function(qt_configure_file)
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "" "OUTPUT;INPUT;CONTENT" "")
|
||||
qt_configure_file_impl()
|
||||
if("CONTENT" IN_LIST ARGV)
|
||||
if(arg_INPUT)
|
||||
message(WARNING "Both CONTENT and INPUT are specified. CONTENT will be used to generate"
|
||||
" output")
|
||||
endif()
|
||||
_qt_internal_configure_file(CONFIGURE OUTPUT "${arg_OUTPUT}" CONTENT "${arg_CONTENT}")
|
||||
elseif(arg_INPUT)
|
||||
_qt_internal_configure_file(CONFIGURE OUTPUT "${arg_OUTPUT}" INPUT "${arg_INPUT}")
|
||||
else()
|
||||
message(FATAL_ERROR "No input value provided to _qt_internal_configure_file.")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# A version of cmake_parse_arguments that makes sure all arguments are processed and errors out
|
||||
|
@ -169,9 +169,8 @@ function(qt_internal_force_allow_unsuitable_cmake_version_for_building_qt out_va
|
||||
# Temporarily allow any version when building in Qt's CI, so we can decouple the provisioning
|
||||
# of the minimum CMake version from the bump of the minimum CMake version.
|
||||
# The COIN_UNIQUE_JOB_ID env var is set in Qt's CI for both build and test work items.
|
||||
# Current state is that this check is enabled.
|
||||
# TODO: Disable it once provisioning is merged.
|
||||
set(allow_any_version_in_ci TRUE)
|
||||
# Current state is that this check is disabled.
|
||||
set(allow_any_version_in_ci FALSE)
|
||||
|
||||
if(allow_any_version_in_ci AND DEFINED ENV{COIN_UNIQUE_JOB_ID})
|
||||
set(allow_any_version TRUE)
|
||||
|
@ -105,7 +105,7 @@ if(MSVC)
|
||||
if(NOT CLANG)
|
||||
# -Ob3 was introduced in Visual Studio 2019 version 16.0
|
||||
# However clang-cl can't recognize it.
|
||||
string(APPEND QT_CFLAGS_OPTIMIZE " -Ob3 ")
|
||||
string(APPEND QT_CFLAGS_OPTIMIZE " -Ob3")
|
||||
endif()
|
||||
set(QT_CFLAGS_OPTIMIZE_DEBUG "-Od")
|
||||
set(QT_CFLAGS_OPTIMIZE_SIZE "-O1")
|
||||
|
@ -39,9 +39,15 @@ if(TARGET @INSTALL_CMAKE_NAMESPACE@::PlatformCommonInternal)
|
||||
if(NOT _qt_platform_internal_common_target)
|
||||
set(_qt_platform_internal_common_target @INSTALL_CMAKE_NAMESPACE@::PlatformCommonInternal)
|
||||
endif()
|
||||
set(_qt_internal_clang_msvc_frontend FALSE)
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
|
||||
CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
|
||||
set(_qt_internal_clang_msvc_frontend TRUE)
|
||||
endif()
|
||||
set_target_properties(${_qt_platform_internal_common_target}
|
||||
PROPERTIES
|
||||
_qt_internal_cmake_generator "${CMAKE_GENERATOR}"
|
||||
_qt_internal_clang_msvc_frontend "${_qt_internal_clang_msvc_frontend}"
|
||||
)
|
||||
unset(_qt_platform_internal_common_target)
|
||||
endif()
|
||||
@ -128,7 +134,12 @@ if(QT_DISABLE_NO_DEFAULT_PATH_IN_QT_PACKAGES)
|
||||
set(__qt_use_no_default_path_for_qt_packages "")
|
||||
endif()
|
||||
|
||||
foreach(module ${@INSTALL_CMAKE_NAMESPACE@_FIND_COMPONENTS})
|
||||
set(__qt_umbrella_find_components ${@INSTALL_CMAKE_NAMESPACE@_FIND_COMPONENTS})
|
||||
__qt_internal_handle_find_all_qt_module_packages(__qt_umbrella_find_components
|
||||
COMPONENTS ${__qt_umbrella_find_components}
|
||||
)
|
||||
|
||||
foreach(module ${__qt_umbrella_find_components})
|
||||
if(NOT "${QT_HOST_PATH}" STREQUAL ""
|
||||
AND "${module}" MATCHES "Tools$"
|
||||
AND NOT "${module}" MATCHES "UiTools$"
|
||||
@ -139,7 +150,7 @@ foreach(module ${@INSTALL_CMAKE_NAMESPACE@_FIND_COMPONENTS})
|
||||
# But don't match QtShaderTools and QtTools which are cross-compiled target package names.
|
||||
# Allow opt out just in case.
|
||||
get_filename_component(__qt_find_package_host_qt_path
|
||||
"${Qt@PROJECT_VERSION_MAJOR@HostInfo_DIR}/.." ABSOLUTE)
|
||||
"${@INSTALL_CMAKE_NAMESPACE@HostInfo_DIR}/.." ABSOLUTE)
|
||||
set(__qt_backup_cmake_prefix_path "${CMAKE_PREFIX_PATH}")
|
||||
set(__qt_backup_cmake_find_root_path "${CMAKE_FIND_ROOT_PATH}")
|
||||
list(PREPEND CMAKE_PREFIX_PATH "${__qt_find_package_host_qt_path}"
|
||||
|
@ -17,7 +17,8 @@ _qt_internal_setup_qt_host_path(
|
||||
"${__qt_platform_requires_host_info_package}"
|
||||
"${__qt_platform_initial_qt_host_path}"
|
||||
"${__qt_platform_initial_qt_host_path_cmake_dir}")
|
||||
_qt_internal_find_host_info_package(${__qt_platform_requires_host_info_package})
|
||||
_qt_internal_find_host_info_package(${__qt_platform_requires_host_info_package}
|
||||
@INSTALL_CMAKE_NAMESPACE@)
|
||||
|
||||
# note: _third_party_deps example: "ICU\\;FALSE\\;1.0\\;i18n uc data;ZLIB\\;FALSE\\;\\;"
|
||||
set(__qt_third_party_deps "@third_party_deps@")
|
||||
|
@ -79,4 +79,9 @@ function(qt_create_qdbusxml2cpp_command target infile)
|
||||
"${header_file_full}"
|
||||
"${source_file_full}"
|
||||
)
|
||||
set_source_files_properties(
|
||||
"${header_file_full}"
|
||||
"${source_file_full}"
|
||||
PROPERTIES
|
||||
_qt_syncqt_exclude_from_docs TRUE)
|
||||
endfunction()
|
||||
|
@ -16,6 +16,43 @@ function(qt_internal_add_doc_tool_dependency doc_target tool_name)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Adds custom build and install targets to generate documentation for a documentation project
|
||||
# identified by a cmake target and a path to a .qdocconf file.
|
||||
#
|
||||
# Creates custom targets of the form:
|
||||
# - generate_docs_${target}
|
||||
# - prepare_docs_${target}
|
||||
# - html_docs_${target}
|
||||
# - install_html_docs_${target}
|
||||
# - etc.
|
||||
#
|
||||
# The first two arguments to the function should be <target> <path-to-qdocconf>.
|
||||
#
|
||||
# Additional options are:
|
||||
# INDEX_DIRECTORIES - a list of index directories to pass to qdoc.
|
||||
#
|
||||
# DEFINES - extra environment variable assignments of the form ENV_VAR=VALUE, which should be set
|
||||
# during qdoc execution.
|
||||
#
|
||||
# QDOC_EXTRA_ARGS - extra command-line arguments to pass to qdoc in both prepare and generate
|
||||
# phases.
|
||||
#
|
||||
# QDOC_PREPARE_EXTRA_ARGS - extra command-line arguments to pass to qdoc in the prepare phase.
|
||||
#
|
||||
# QDOC_GENERATE_EXTRA_ARGS - extra command-line arguments to pass to qdoc in the generate phase.
|
||||
#
|
||||
# SHOW_INTERNAL - if set, the --showinternal option is passed to qdoc.
|
||||
#
|
||||
# Additional environment variables considered:
|
||||
# QT_INSTALL_DOCS - directory path where the qt docs were expected to be installed, used for
|
||||
# linking to other built docs. If not set, defaults to the qtbase or qt5 build directory, or the
|
||||
# install directory extracted from the BuildInternals package.
|
||||
#
|
||||
# QT_QDOC_EXTRA_ARGS, QT_QDOC_PREPARE_EXTRA_ARGS, QT_QDOC_GENERATE_EXTRA_ARGS - same as the options
|
||||
# but can be set as either environment or cmake variables.
|
||||
#
|
||||
# QT_QDOC_SHOW_INTERNAL - same as the option but can be set as either an environment or
|
||||
# cmake variable.
|
||||
function(qt_internal_add_docs)
|
||||
if(NOT QT_BUILD_DOCS)
|
||||
return()
|
||||
@ -23,39 +60,67 @@ function(qt_internal_add_docs)
|
||||
|
||||
if(${ARGC} EQUAL 1)
|
||||
# Function called from old generated CMakeLists.txt that was missing the target parameter
|
||||
if(QT_FEATURE_developer_build)
|
||||
message(AUTHOR_WARNING
|
||||
"qt_internal_add_docs called with old signature. Skipping doc generation.")
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
set(error_msg "qt_add_docs called with wrong number of arguments. ")
|
||||
list(APPEND error_msg
|
||||
"Should be qt_add_docs\(target_name qdocconf "
|
||||
"\[INDEX_DIRECTORIES EXTRA_INDEX_DIRS_LIST_TO_ENABLE_QDOC_RESOLVE_LINKS\]\)")
|
||||
|
||||
if(NOT ${ARGC} GREATER_EQUAL 2)
|
||||
message(FATAL_ERROR ${error_msg})
|
||||
return()
|
||||
message(FATAL_ERROR
|
||||
"qt_internal_add_docs called with a wrong number of arguments. "
|
||||
"The call should be qt_internal_add_docs\(<target> <path-to-qdocconf> [other-options])"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(target ${ARGV0})
|
||||
set(doc_project ${ARGV1})
|
||||
set(qdoc_conf_path ${ARGV1})
|
||||
|
||||
set(opt_args
|
||||
SHOW_INTERNAL
|
||||
)
|
||||
set(single_args "")
|
||||
set(multi_args
|
||||
INDEX_DIRECTORIES
|
||||
DEFINES
|
||||
QDOC_EXTRA_ARGS
|
||||
QDOC_PREPARE_EXTRA_ARGS
|
||||
QDOC_GENERATE_EXTRA_ARGS
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 2 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(qdoc_extra_args "")
|
||||
# Check if there are more than 2 arguments and pass them
|
||||
# as extra --indexdir arguments to qdoc in prepare and
|
||||
|
||||
# The INDEX_DIRECTORIES key should enable passing a list of index
|
||||
# directories as extra command-line arguments to qdoc, in prepare and
|
||||
# generate phases.
|
||||
if (${ARGC} GREATER 2)
|
||||
# The INDEX_DIRECTORIES key should enable passing a list of index
|
||||
# directories as extra command-line arguments to qdoc.
|
||||
set(qdocExtraArgs "INDEX_DIRECTORIES;DEFINES")
|
||||
cmake_parse_arguments(PARSE_ARGV 2 arg "" "" "${qdocExtraArgs}")
|
||||
if(arg_UNPARSED_ARGUMENTS)
|
||||
message(FATAL_ERROR ${error_msg})
|
||||
return()
|
||||
endif()
|
||||
if(arg_INDEX_DIRECTORIES)
|
||||
foreach(index_directory ${arg_INDEX_DIRECTORIES})
|
||||
list(APPEND qdoc_extra_args "--indexdir" ${index_directory})
|
||||
endforeach()
|
||||
endif()
|
||||
if(arg_INDEX_DIRECTORIES)
|
||||
foreach(index_directory ${arg_INDEX_DIRECTORIES})
|
||||
list(APPEND qdoc_extra_args "--indexdir" ${index_directory})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(show_internal_env FALSE)
|
||||
if(DEFINED ENV{QT_QDOC_SHOW_INTERNAL})
|
||||
set(show_internal_env $ENV{QT_QDOC_SHOW_INTERNAL})
|
||||
endif()
|
||||
if(arg_SHOW_INTERNAL OR QT_QDOC_SHOW_INTERNAL OR show_internal_env)
|
||||
list(APPEND qdoc_extra_args "--showinternal")
|
||||
endif()
|
||||
|
||||
if(arg_QDOC_EXTRA_ARGS)
|
||||
list(APPEND qdoc_extra_args ${arg_QDOC_EXTRA_ARGS})
|
||||
endif()
|
||||
|
||||
if(QT_QDOC_EXTRA_ARGS)
|
||||
list(APPEND qdoc_extra_args ${QT_QDOC_EXTRA_ARGS})
|
||||
endif()
|
||||
|
||||
if(DEFINED ENV{QT_QDOC_EXTRA_ARGS})
|
||||
list(APPEND qdoc_extra_args $ENV{QT_QDOC_EXTRA_ARGS})
|
||||
endif()
|
||||
|
||||
# If a target is not built (which can happen for tools when crosscompiling), we shouldn't try
|
||||
# to generate docs.
|
||||
@ -77,7 +142,8 @@ function(qt_internal_add_docs)
|
||||
set(doc_tools_libexec "${QtBase_BINARY_DIR}/${INSTALL_LIBEXECDIR}")
|
||||
else()
|
||||
set(doc_tools_bin "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}")
|
||||
set(doc_tools_libexec "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_LIBEXECDIR}")
|
||||
set(doc_tools_libexec
|
||||
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_LIBEXECDIR}")
|
||||
endif()
|
||||
|
||||
if(CMAKE_HOST_WIN32)
|
||||
@ -121,15 +187,18 @@ function(qt_internal_add_docs)
|
||||
set(include_path_args "")
|
||||
endif()
|
||||
|
||||
get_filename_component(doc_target "${doc_project}" NAME_WLE)
|
||||
get_filename_component(doc_target "${qdoc_conf_path}" NAME_WLE)
|
||||
if (QT_WILL_INSTALL)
|
||||
set(qdoc_output_dir "${CMAKE_BINARY_DIR}/${INSTALL_DOCDIR}/${doc_target}")
|
||||
set(qdoc_qch_output_dir "${CMAKE_BINARY_DIR}/${INSTALL_DOCDIR}")
|
||||
set(index_dir "${CMAKE_BINARY_DIR}/${INSTALL_DOCDIR}")
|
||||
else()
|
||||
set(qdoc_output_dir "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}/${doc_target}")
|
||||
set(qdoc_qch_output_dir "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
|
||||
set(index_dir "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
|
||||
set(qdoc_output_dir
|
||||
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}/${doc_target}")
|
||||
set(qdoc_qch_output_dir
|
||||
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
|
||||
set(index_dir
|
||||
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
|
||||
endif()
|
||||
|
||||
# qtattributionsscanner
|
||||
@ -144,7 +213,7 @@ function(qt_internal_add_docs)
|
||||
# prepare docs target
|
||||
set(prepare_qdoc_args
|
||||
-outputdir "${qdoc_output_dir}"
|
||||
"${target_source_dir}/${doc_project}"
|
||||
"${target_source_dir}/${qdoc_conf_path}"
|
||||
-prepare
|
||||
-indexdir "${index_dir}"
|
||||
-no-link-errors
|
||||
@ -157,6 +226,18 @@ function(qt_internal_add_docs)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(arg_QDOC_PREPARE_EXTRA_ARGS)
|
||||
list(APPEND prepare_qdoc_args ${arg_QDOC_PREPARE_EXTRA_ARGS})
|
||||
endif()
|
||||
|
||||
if(QT_QDOC_PREPARE_EXTRA_ARGS)
|
||||
list(APPEND prepare_qdoc_args ${QT_QDOC_PREPARE_EXTRA_ARGS})
|
||||
endif()
|
||||
|
||||
if(DEFINED ENV{QT_QDOC_PREPARE_EXTRA_ARGS})
|
||||
list(APPEND prepare_qdoc_args $ENV{QT_QDOC_PREPARE_EXTRA_ARGS})
|
||||
endif()
|
||||
|
||||
if(DEFINED ENV{QT_INSTALL_DOCS})
|
||||
if(NOT EXISTS "$ENV{QT_INSTALL_DOCS}")
|
||||
message(FATAL_ERROR
|
||||
@ -167,7 +248,8 @@ function(qt_internal_add_docs)
|
||||
elseif(QT_SUPERBUILD OR "${PROJECT_NAME}" STREQUAL "QtBase")
|
||||
set(qt_install_docs_env "${QtBase_BINARY_DIR}/${INSTALL_DOCDIR}")
|
||||
else()
|
||||
set(qt_install_docs_env "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
|
||||
set(qt_install_docs_env
|
||||
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
|
||||
endif()
|
||||
|
||||
set(qdoc_env_args
|
||||
@ -198,7 +280,7 @@ function(qt_internal_add_docs)
|
||||
# generate docs target
|
||||
set(generate_qdoc_args
|
||||
-outputdir "${qdoc_output_dir}"
|
||||
"${target_source_dir}/${doc_project}"
|
||||
"${target_source_dir}/${qdoc_conf_path}"
|
||||
-generate
|
||||
-indexdir "${index_dir}"
|
||||
"${include_path_args}"
|
||||
@ -210,6 +292,18 @@ function(qt_internal_add_docs)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(arg_QDOC_GENERATE_EXTRA_ARGS)
|
||||
list(APPEND generate_qdoc_args ${arg_QDOC_GENERATE_EXTRA_ARGS})
|
||||
endif()
|
||||
|
||||
if(QT_QDOC_GENERATE_EXTRA_ARGS)
|
||||
list(APPEND generate_qdoc_args ${QT_QDOC_GENERATE_EXTRA_ARGS})
|
||||
endif()
|
||||
|
||||
if(DEFINED ENV{QT_QDOC_GENERATE_EXTRA_ARGS})
|
||||
list(APPEND generate_qdoc_args $ENV{QT_QDOC_GENERATE_EXTRA_ARGS})
|
||||
endif()
|
||||
|
||||
foreach(target_prefix generate_top_level_docs generate_repo_docs generate_docs)
|
||||
set(depends_arg "")
|
||||
if(tool_dependencies_enabled)
|
||||
|
@ -71,7 +71,12 @@ function(qt_internal_add_executable name)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(arg_QT_APP AND QT_FEATURE_debug_and_release AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.19.0")
|
||||
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
|
||||
if(arg_QT_APP
|
||||
AND QT_FEATURE_debug_and_release
|
||||
AND CMAKE_VERSION VERSION_GREATER_EQUAL "3.19.0"
|
||||
AND is_multi_config
|
||||
)
|
||||
set_property(TARGET "${name}"
|
||||
PROPERTY EXCLUDE_FROM_ALL "$<NOT:$<CONFIG:${QT_MULTI_CONFIG_FIRST_CONFIG}>>")
|
||||
endif()
|
||||
@ -183,7 +188,7 @@ function(qt_internal_add_executable name)
|
||||
MACOSX_BUNDLE "${arg_GUI}"
|
||||
)
|
||||
|
||||
if(NOT DEFINED arg_EXCEPTIONS)
|
||||
if(NOT arg_EXCEPTIONS)
|
||||
qt_internal_set_exceptions_flags("${name}" "DEFAULT")
|
||||
else()
|
||||
qt_internal_set_exceptions_flags("${name}" "${arg_EXCEPTIONS}")
|
||||
@ -252,23 +257,6 @@ function(qt_internal_add_executable name)
|
||||
qt_internal_install_pdb_files(${name} "${arg_INSTALL_DIRECTORY}")
|
||||
endif()
|
||||
|
||||
if(QT_GENERATE_SBOM)
|
||||
set(sbom_args "")
|
||||
_qt_internal_forward_function_args(
|
||||
FORWARD_APPEND
|
||||
FORWARD_PREFIX arg
|
||||
FORWARD_OUT_VAR sbom_args
|
||||
FORWARD_OPTIONS
|
||||
${__qt_internal_sbom_optional_args}
|
||||
FORWARD_SINGLE
|
||||
${__qt_internal_sbom_single_args}
|
||||
FORWARD_MULTI
|
||||
${__qt_internal_sbom_multi_args}
|
||||
)
|
||||
|
||||
_qt_internal_extend_sbom(${name} ${sbom_args})
|
||||
endif()
|
||||
|
||||
qt_add_list_file_finalizer(qt_internal_finalize_executable "${name}")
|
||||
endfunction()
|
||||
|
||||
|
@ -353,6 +353,15 @@ function(qt_feature_check_and_save_user_provided_value
|
||||
set("FEATURE_${feature}" "${result}" CACHE BOOL "${label}")
|
||||
endif()
|
||||
|
||||
# Check for potential typo
|
||||
get_property(original_name GLOBAL PROPERTY "QT_FEATURE_ORIGINAL_NAME_${feature}")
|
||||
if(NOT original_name STREQUAL feature AND DEFINED "FEATURE_${original_name}")
|
||||
unset("FEATURE_${original_name}" CACHE)
|
||||
qt_configure_add_report_error(
|
||||
"FEATURE_${original_name} does not exist. Consider using: FEATURE_${feature}"
|
||||
)
|
||||
endif()
|
||||
|
||||
set("${resultVar}" "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
@ -162,10 +162,7 @@ macro(qt_find_package)
|
||||
foreach(qt_find_package_target_name ${arg_PROVIDED_TARGETS})
|
||||
if(TARGET ${qt_find_package_target_name})
|
||||
# Allow usage of aliased targets by setting properties on the actual target
|
||||
get_target_property(aliased_target ${qt_find_package_target_name} ALIASED_TARGET)
|
||||
if(aliased_target)
|
||||
set(qt_find_package_target_name ${aliased_target})
|
||||
endif()
|
||||
_qt_internal_dealias_target(qt_find_package_target_name)
|
||||
|
||||
if("${qt_find_package_target_name}" MATCHES "${QT_CMAKE_EXPORT_NAMESPACE}::"
|
||||
AND QT_FEATURE_developer_build
|
||||
@ -387,6 +384,8 @@ endfunction()
|
||||
# dep_target_name = EntryPointPrivate
|
||||
# This is just a convenience function that deals with Qt targets and their associated packages
|
||||
# instead of raw package names.
|
||||
#
|
||||
# Deprecated since 6.9.
|
||||
function(qt_record_extra_qt_package_dependency main_target_name dep_target_name
|
||||
dep_package_version)
|
||||
# EntryPointPrivate -> Qt6EntryPointPrivate.
|
||||
@ -571,17 +570,26 @@ function(qt_internal_get_package_name_of_target target package_name_out_var)
|
||||
set(${package_name_out_var} "${package_name}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# This function stores the list of Qt targets a library depend on,
|
||||
# along with their version info, for usage in ${target}Depends.cmake file
|
||||
function(qt_register_target_dependencies target public_libs private_libs)
|
||||
# This function collects the list of Qt targets a library depend on,
|
||||
# along with their version info, for usage in ${target}Dependencies.cmake file
|
||||
# Multi-value Arguments:
|
||||
# PUBLIC
|
||||
# public dependencies
|
||||
# PRIVATE
|
||||
# private dependencies
|
||||
function(qt_internal_register_target_dependencies target)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "" "" "PUBLIC;PRIVATE")
|
||||
get_target_property(target_deps "${target}" _qt_target_deps)
|
||||
if(NOT target_deps)
|
||||
set(target_deps "")
|
||||
endif()
|
||||
|
||||
get_target_property(target_type ${target} TYPE)
|
||||
set(lib_list ${public_libs})
|
||||
set(lib_list "")
|
||||
if(arg_PUBLIC)
|
||||
set(lib_list "${arg_PUBLIC}")
|
||||
endif()
|
||||
|
||||
get_target_property(target_type ${target} TYPE)
|
||||
set(target_is_shared FALSE)
|
||||
set(target_is_static FALSE)
|
||||
if(target_type STREQUAL "SHARED_LIBRARY")
|
||||
@ -595,8 +603,8 @@ function(qt_register_target_dependencies target public_libs private_libs)
|
||||
#
|
||||
# Private static library dependencies will become $<LINK_ONLY:> dependencies in
|
||||
# INTERFACE_LINK_LIBRARIES.
|
||||
if(target_is_static)
|
||||
list(APPEND lib_list ${private_libs})
|
||||
if(target_is_static AND arg_PRIVATE)
|
||||
list(APPEND lib_list ${arg_PRIVATE})
|
||||
endif()
|
||||
|
||||
foreach(lib IN LISTS lib_list)
|
||||
@ -622,8 +630,8 @@ function(qt_register_target_dependencies target public_libs private_libs)
|
||||
# See QTBUG-86533 for some details.
|
||||
# We filter out static libraries and common platform targets, but include both SHARED and
|
||||
# INTERFACE libraries. INTERFACE libraries in most cases will be FooPrivate libraries.
|
||||
if(target_is_shared AND private_libs)
|
||||
foreach(lib IN LISTS private_libs)
|
||||
if(target_is_shared AND arg_PRIVATE)
|
||||
foreach(lib IN LISTS arg_PRIVATE)
|
||||
set(lib_namespaced "${lib}")
|
||||
if("${lib}" MATCHES "^Qt::(.*)")
|
||||
set(lib "${CMAKE_MATCH_1}")
|
||||
|
@ -465,21 +465,21 @@ endfunction()
|
||||
function(qt_internal_print_optimization_flags_values_helper languages configs target_link_types)
|
||||
foreach(lang ${languages})
|
||||
set(flag_var_name "CMAKE_${lang}_FLAGS")
|
||||
message(STATUS "${flag_var_name}: ${${flag_var_name}}")
|
||||
message(STATUS "${flag_var_name}: '${${flag_var_name}}'")
|
||||
|
||||
foreach(config ${configs})
|
||||
set(flag_var_name "CMAKE_${lang}_FLAGS_${config}")
|
||||
message(STATUS "${flag_var_name}: ${${flag_var_name}}")
|
||||
message(STATUS "${flag_var_name}: '${${flag_var_name}}'")
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
foreach(t ${target_link_types})
|
||||
set(flag_var_name "CMAKE_${t}_LINKER_FLAGS")
|
||||
message(STATUS "${flag_var_name}: ${${flag_var_name}}")
|
||||
message(STATUS "${flag_var_name}: '${${flag_var_name}}'")
|
||||
|
||||
foreach(config ${configs})
|
||||
set(flag_var_name "CMAKE_${t}_LINKER_FLAGS_${config}")
|
||||
message(STATUS "${flag_var_name}: ${${flag_var_name}}")
|
||||
message(STATUS "${flag_var_name}: '${${flag_var_name}}'")
|
||||
endforeach()
|
||||
endforeach()
|
||||
endfunction()
|
||||
@ -713,6 +713,356 @@ function(qt_internal_remove_compiler_flags flags)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# Add a series of compile options as generator expressions
|
||||
#
|
||||
# Each condition and compiler requirement are glued by $<AND:> genex.
|
||||
#
|
||||
# Synopsis
|
||||
#
|
||||
# qt_internal_add_compiler_dependent_flags(<target> <INTERFACE|PUBLIC|PRIVATE>
|
||||
# COMPILERS <compiler> ...
|
||||
# [ CONDITIONS <condition> ... ]
|
||||
# OPTIONS <items> ...
|
||||
# [ CONDITIONS <condition> ...
|
||||
# OPTIONS <items> ... ]
|
||||
# [ COMPILERS ... ]
|
||||
#
|
||||
# [LANGUAGES <lang> ...]
|
||||
# [COMMON_CONDITIONS <condition_genex> ...]
|
||||
# )
|
||||
#
|
||||
# Example
|
||||
# qt_internal_add_compiler_dependent_flags(tgt PUBLIC
|
||||
# COMPILERS ALL
|
||||
# OPTIONS -Werror
|
||||
# CONDITIONS $<TARGET_PROPERTY:foo> OR $<TARGET_PROPERTY:bar>
|
||||
# OPTIONS -bar -baz
|
||||
# COMPILERS GNU
|
||||
# CONDITIONS VERSION_GREATER_EQUAL 10
|
||||
# OPTIONS -baz
|
||||
# )
|
||||
#
|
||||
# Is equivalent to:
|
||||
#
|
||||
# target_compile_options(tgt PUBLIC
|
||||
# $<$<AND:$<COMPILE_LANGUAGE:CXX>>:-Werror>
|
||||
# $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<OR:$<TARGET_PROPERTY:foo>,$<TARGET_PROPERTY:bar>>>:-bar;-baz>
|
||||
# $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:GNU>,$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,10>>:-baz>
|
||||
# )
|
||||
#
|
||||
# Arguments
|
||||
#
|
||||
# `<target>`
|
||||
# Equivalent to `target_compile_options(<target>)`.
|
||||
#
|
||||
# `<INTERFACE|PUBLIC|PRIVATE>`
|
||||
# Equivalent to `target_compile_options(<INTERFACE|PUBLIC|PRIVATE>)`.
|
||||
#
|
||||
# Unlike `target_compile_options`, only one set of target scope is implemented.
|
||||
#
|
||||
# `COMPILERS`
|
||||
# Starts a new set of compiler specific set of options gated by `$<${lang}_COMPILER_ID>`.
|
||||
# See `LANGUAGES` for how `${lang}` is determined.
|
||||
#
|
||||
# Can be any value defined in `CMAKE_<LANG>_COMPILER_ID`, or one of the following shortcuts
|
||||
# - `ALL`: drops the compiler specific condition
|
||||
# - `CLANG`: `Clang` and `IntelLLVM` (does not include `AppleClang`)
|
||||
#
|
||||
# At least one `COMPILERS` set *must* be defined.
|
||||
#
|
||||
# `CONDITIONS`
|
||||
# Starts a new set of `<condition>` gated options.
|
||||
#
|
||||
# `<condition>` can be one of:
|
||||
# - `VERSION_* <version>`: Equivalent to `$<VERSION_*:$<${lang}_COMPILER_VERSION:>,<version>>`
|
||||
# See `LANGUAGES` for how `${lang}` is determined.
|
||||
# - Any genex matching regex: `\$<.*>`
|
||||
#
|
||||
# You can use `AND` and `OR` as well as parenthesis `()` to join multiple `<condition>`.
|
||||
#
|
||||
# If no `<condition>` is added, the current set only checks for compiler condition and the
|
||||
# `COMMON_CONDITIONS`.
|
||||
#
|
||||
# `OPTIONS`
|
||||
# Starts the list of compiler options for the current set of `COMPILERS` and `CONDITIONS`
|
||||
#
|
||||
# Equivalent to `target_compile_options(<items>)`.
|
||||
#
|
||||
# At least one `COMPILERS` set *must* be defined.
|
||||
#
|
||||
# `LANGUAGES`
|
||||
# Language conditions applied to all options.
|
||||
#
|
||||
# - If no `LANGUAGES` is passed `$<CXX_COMPILER_*>` is used to compute compiler-dependent
|
||||
# variables such as `$<CXX_COMPILER_VERSION>`
|
||||
# - If exactly 1 `LANGUAGES` is passed, this language is used in `$<${lang}_COMPILER_>` like
|
||||
# variables
|
||||
#
|
||||
# `COMMON_CONDITIONS`
|
||||
# Additional genex conditions to include for all compiler flags.
|
||||
function(qt_internal_add_compiler_dependent_flags target target_scope)
|
||||
# We cannot use `cmake_parse_arguments` to parse all the other arguments. We use a special
|
||||
# parsing for that with the remaining `arg_UNPARSED_ARGUMENTS`
|
||||
set(option_args "")
|
||||
set(single_args "")
|
||||
set(multi_args
|
||||
LANGUAGES
|
||||
COMMON_CONDITIONS
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 2 arg
|
||||
"${option_args}" "${single_args}" "${multi_args}"
|
||||
)
|
||||
|
||||
# For debugging purposes we save the original list of arg_UNPARSED_ARGUMENTS
|
||||
set(arg_UNPARSED_ARGUMENTS_original ${arg_UNPARSED_ARGUMENTS})
|
||||
# Set the language for the compiler checks
|
||||
set(lang CXX)
|
||||
list(LENGTH arg_LANGUAGES arg_LANGUAGES_length)
|
||||
if(arg_LANGUAGES_length EQUAL 1)
|
||||
set(lang ${arg_LANGUAGES})
|
||||
endif()
|
||||
# Always add a language genex
|
||||
set(lang_ex "$<COMPILE_LANGUAGE:${lang}>")
|
||||
if(arg_LANGUAGES_length GREATER 1)
|
||||
list(JOIN arg_LANGUAGES "," arg_LANGUAGES_comma_list)
|
||||
set(lang_ex "$<COMPILE_LANGUAGE:${arg_LANGUAGES_comma_list}>")
|
||||
endif()
|
||||
|
||||
# Helper debugging function
|
||||
function(_qt_internal_add_compiler_dependent_flags_error msg)
|
||||
# If you are hitting such a function, something must have gone wrong with
|
||||
# `qt_internal_add_compiler_flags` implementation.
|
||||
message(FATAL_ERROR
|
||||
"${msg}\n"
|
||||
" curr_arg = ${curr_arg}\n"
|
||||
" arg_UNPARSED_ARGUMENTS = ${arg_UNPARSED_ARGUMENTS}\n"
|
||||
" arg_UNPARSED_ARGUMENTS_original = ${arg_UNPARSED_ARGUMENTS_original}"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# Helper function finalizing each keyword set
|
||||
# COMPILERS
|
||||
function(_qt_internal_add_compiler_dependent_flags_do_COMPILERS)
|
||||
set(compiler_ex "")
|
||||
if(NOT curr_COMPILERS)
|
||||
_qt_internal_add_compiler_dependent_flags_error(
|
||||
"COMPILERS set cannot be empty"
|
||||
)
|
||||
endif()
|
||||
# If ALL compilers is passed, we can ignore the compiler check
|
||||
if(NOT "ALL" IN_LIST curr_COMPILERS)
|
||||
# Check for other aliases
|
||||
if("CLANG" IN_LIST curr_COMPILERS)
|
||||
list(REMOVE_ITEM curr_COMPILERS CLANG)
|
||||
list(APPEND curr_COMPILERS Clang IntelLLVM)
|
||||
endif()
|
||||
# Create compiler genex
|
||||
list(REMOVE_DUPLICATES curr_COMPILERS)
|
||||
list(JOIN curr_COMPILERS "," compilers)
|
||||
set(compiler_ex "$<${lang}_COMPILER_ID:${compilers}>" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
# CONDITIONS
|
||||
function(_qt_internal_add_compiler_dependent_flags_do_CONDITIONS)
|
||||
function(_qt_internal_add_compiler_dependent_flags_do_CONDITIONS_end_stack
|
||||
stack_in stack_out
|
||||
)
|
||||
# Resolve the current stack into a genex list
|
||||
set(stack_conditions_ex)
|
||||
set(prev_glue_word)
|
||||
set(glue_word)
|
||||
list(POP_FRONT ${stack_in} stack_conditions_ex)
|
||||
while(${stack_in})
|
||||
list(POP_FRONT ${stack_in} glue_word)
|
||||
if(NOT (glue_word STREQUAL "AND" OR glue_word STREQUAL "OR"))
|
||||
_qt_internal_add_compiler_dependent_flags_error(
|
||||
"Expected AND/OR glue word, instead got: ${glue_word}"
|
||||
)
|
||||
endif()
|
||||
list(POP_FRONT ${stack_in} next_condition)
|
||||
if(NOT next_condition)
|
||||
_qt_internal_add_compiler_dependent_flags_error(
|
||||
"No other condition provided after ${glue_word}"
|
||||
)
|
||||
endif()
|
||||
if(prev_glue_word STREQUAL glue_word)
|
||||
# If the glue words are the same, we just add to current genex $<${glue_word}:>
|
||||
# First trim the last `>` character
|
||||
string(LENGTH "${stack_conditions_ex}" stack_conditions_ex_length)
|
||||
math(EXPR stack_conditions_ex_length "${stack_conditions_ex_length} - 1")
|
||||
string(SUBSTRING "${stack_conditions_ex}" 0 ${stack_conditions_ex_length}
|
||||
stack_conditions_ex
|
||||
)
|
||||
set(stack_conditions_ex "${stack_conditions_ex},${next_condition}>")
|
||||
else()
|
||||
# Otherwise create a new $<${glue_word}:>
|
||||
set(stack_conditions_ex
|
||||
"$<${glue_word}:${stack_conditions_ex},${next_condition}>"
|
||||
)
|
||||
endif()
|
||||
set(prev_glue_word "${glue_word}")
|
||||
endwhile()
|
||||
if(NOT stack_conditions_ex)
|
||||
_qt_internal_add_compiler_dependent_flags_error(
|
||||
"Empty parenthesis stack"
|
||||
)
|
||||
endif()
|
||||
# Add the current
|
||||
list(APPEND ${stack_out} "${stack_conditions_ex}")
|
||||
set(${stack_out} "${${stack_out}}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
set(conditions_ex "")
|
||||
set(stack_level 0)
|
||||
set(stack_0)
|
||||
while(curr_CONDITIONS)
|
||||
list(POP_FRONT curr_CONDITIONS condition_kw)
|
||||
# Parenthesis evaluation
|
||||
if(condition_kw MATCHES "^\\((.*)")
|
||||
# Start a new stack
|
||||
math(EXPR stack_level "${stack_level} + 1")
|
||||
set(stack_${stack_level})
|
||||
# Check if the parenthesis was glued to another keyword
|
||||
# Resolve the remaining keyword in the next loop
|
||||
if(CMAKE_MATCH_1)
|
||||
list(PREPEND curr_CONDITIONS "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
continue()
|
||||
elseif(condition_kw MATCHES "(.*)\\)$")
|
||||
# Check if the parenthesis was glued to another keyword
|
||||
# Separate them and evaluate each one individually
|
||||
if(CMAKE_MATCH_1)
|
||||
set(condition_kw "${CMAKE_MATCH_1}")
|
||||
list(PREPEND curr_CONDITIONS "${CMAKE_MATCH_1}" ")")
|
||||
endif()
|
||||
# Finalize the current stack making it a genex for the next loop
|
||||
set(curr_stack stack_${stack_level})
|
||||
math(EXPR stack_level "${stack_level} - 1")
|
||||
set(prev_stack stack_${stack_level})
|
||||
_qt_internal_add_compiler_dependent_flags_do_CONDITIONS_end_stack(
|
||||
${curr_stack} ${prev_stack}
|
||||
)
|
||||
if(stack_level LESS 0)
|
||||
_qt_internal_add_compiler_dependent_flags_error(
|
||||
"Unbalanced parenthesis."
|
||||
)
|
||||
endif()
|
||||
continue()
|
||||
endif()
|
||||
# Glue word evaluation
|
||||
if(condition_kw STREQUAL "AND" OR condition_kw STREQUAL "OR")
|
||||
# Insert the operator
|
||||
list(APPEND stack_${stack_level} "${condition_kw}")
|
||||
continue()
|
||||
endif()
|
||||
# Main condition keyword evaluation
|
||||
if(condition_kw MATCHES "^VERSION_.*")
|
||||
# Shortcut for VERSION_* keyword
|
||||
list(POP_FRONT curr_CONDITIONS version)
|
||||
list(APPEND stack_${stack_level}
|
||||
"$<${condition_kw}:$<${lang}_COMPILER_VERSION>,${version}>"
|
||||
)
|
||||
continue()
|
||||
elseif(condition_kw MATCHES "^\\$<.*>$")
|
||||
# genex expression are added as-is
|
||||
list(APPEND stack_${stack_level} "${condition_kw}")
|
||||
continue()
|
||||
else()
|
||||
# All other unrecognized forms we do not know how to deal with
|
||||
_qt_internal_add_compiler_dependent_flags_error(
|
||||
"Unrecognized condition form: ${condition_kw}"
|
||||
)
|
||||
endif()
|
||||
endwhile()
|
||||
# Finalize the top-level stack and put it in `conditions_ex`
|
||||
if(NOT stack_level EQUAL 0)
|
||||
_qt_internal_add_compiler_dependent_flags_error(
|
||||
"Unbalanced parenthesis."
|
||||
)
|
||||
endif()
|
||||
_qt_internal_add_compiler_dependent_flags_do_CONDITIONS_end_stack(stack_0 conditions_ex)
|
||||
set(conditions_ex "${conditions_ex}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
# OPTIONS
|
||||
function(_qt_internal_add_compiler_dependent_flags_do_OPTIONS)
|
||||
# Check for required keywords
|
||||
foreach(required_keyword IN ITEMS OPTIONS COMPILERS)
|
||||
if(curr_${required_keyword} STREQUAL "MISSING")
|
||||
_qt_internal_add_compiler_dependent_flags_error(
|
||||
"${required_keyword} keyword was not passed"
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
# Only handle the current set if the OPTIONS did not evaluate to empty, otherwise
|
||||
# it is considered a no-op
|
||||
if(curr_OPTIONS)
|
||||
# No need to check the length of `all_conditions_ex` because `lang_ex` is
|
||||
# always defined.
|
||||
list(JOIN curr_OPTIONS ";" options)
|
||||
# Combine all conditions in an `AND` statement
|
||||
set(all_conditions_ex "")
|
||||
list(APPEND all_conditions_ex
|
||||
${arg_COMMON_CONDITIONS}
|
||||
${lang_ex}
|
||||
${compiler_ex}
|
||||
${conditions_ex}
|
||||
)
|
||||
list(JOIN all_conditions_ex "," all_conditions_ex)
|
||||
list(APPEND flags
|
||||
"$<$<AND:${all_conditions_ex}>:${options}>"
|
||||
)
|
||||
endif()
|
||||
# Reset all loop variables
|
||||
# curr_COMPILERS is inherited from the last loop
|
||||
set(curr_CONDITIONS "" PARENT_SCOPE)
|
||||
set(curr_OPTIONS "MISSING" PARENT_SCOPE)
|
||||
set(conditions_ex "" PARENT_SCOPE)
|
||||
set(flags "${flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Set initial loop variables
|
||||
set(compiler_ex "")
|
||||
set(conditions_ex "")
|
||||
set(flags "")
|
||||
# We set (REQUIRED) curr_* loop variables to a special keyword MISSING to identify when
|
||||
# the keyword was not passed
|
||||
set(curr_COMPILERS "MISSING")
|
||||
set(curr_CONDITIONS "")
|
||||
set(curr_OPTIONS "MISSING")
|
||||
set(curr_keyword "")
|
||||
# Parse the remaining arguments
|
||||
while(arg_UNPARSED_ARGUMENTS)
|
||||
list(POP_FRONT arg_UNPARSED_ARGUMENTS curr_arg)
|
||||
# Check for separator keywords
|
||||
if(curr_arg MATCHES "^(COMPILERS|CONDITIONS|OPTIONS)$")
|
||||
# Resolve the previous keyword set
|
||||
# Implicitly we skip the initial loop where curr_keyword == ""
|
||||
if(curr_keyword STREQUAL "COMPILERS")
|
||||
_qt_internal_add_compiler_dependent_flags_do_COMPILERS()
|
||||
elseif(curr_keyword STREQUAL "CONDITIONS")
|
||||
_qt_internal_add_compiler_dependent_flags_do_CONDITIONS()
|
||||
elseif(curr_keyword STREQUAL "OPTIONS")
|
||||
_qt_internal_add_compiler_dependent_flags_do_OPTIONS()
|
||||
endif()
|
||||
# Set the new keyword to accumulate the current `curr_*` variable
|
||||
set(curr_keyword "${curr_arg}")
|
||||
set(curr_${curr_keyword} "")
|
||||
continue()
|
||||
endif()
|
||||
# If no separator keyword is passed, add the current values to `curr_*` loop variable
|
||||
# and move on to the next loop
|
||||
if(NOT curr_keyword)
|
||||
_qt_internal_add_compiler_dependent_flags_error(
|
||||
"No keyword was passed: COMPILERS/CONDITIONS/OPTIONS"
|
||||
)
|
||||
endif()
|
||||
list(APPEND curr_${curr_keyword} "${curr_arg}")
|
||||
endwhile()
|
||||
# finalize the last set
|
||||
_qt_internal_add_compiler_dependent_flags_do_OPTIONS()
|
||||
# Finally add all of the flags to `target_compile_options`
|
||||
target_compile_options("${target}" ${target_scope} ${flags})
|
||||
endfunction()
|
||||
|
||||
# Adds compiler flags for the given CONFIGS in the calling scope. Can also update the cache
|
||||
# if asked to do so. The flag variables are always updated in the calling scope, even if they
|
||||
# did not exist beforehand.
|
||||
|
@ -38,6 +38,7 @@ macro(qt_find_apple_system_frameworks)
|
||||
qt_internal_find_apple_system_framework(FWEventKit EventKit)
|
||||
qt_internal_find_apple_system_framework(FWHealthKit HealthKit)
|
||||
qt_internal_find_apple_system_framework(FWUniformTypeIdentifiers UniformTypeIdentifiers)
|
||||
qt_internal_find_apple_system_framework(FWOpenGL OpenGL)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@ -169,7 +170,7 @@ function(qt_internal_generate_fake_framework_header target)
|
||||
file(GENERATE OUTPUT "${fake_header}" CONTENT "// ignore this file\n"
|
||||
CONDITION "$<CONFIG:${main_config}>")
|
||||
target_sources(${target} PRIVATE "${fake_header}")
|
||||
set_source_files_properties("${fake_header}" PROPERTIES GENERATED ON)
|
||||
_qt_internal_set_source_file_generated(SOURCES "${fake_header}")
|
||||
set_property(TARGET ${target} APPEND PROPERTY PUBLIC_HEADER "${fake_header}")
|
||||
endfunction()
|
||||
|
||||
|
@ -10,7 +10,8 @@ function(qt_get_library_name_without_prefix_and_suffix out_var file_path)
|
||||
if(NOT file_path MATCHES "^-") # not a linker flag
|
||||
get_filename_component(basename "${file_path}" NAME_WE)
|
||||
get_filename_component(ext "${file_path}" EXT)
|
||||
if(NOT ext) # seems like a library name without prefix and suffix
|
||||
if(NOT ext AND NOT IS_ABSOLUTE "${file_path}")
|
||||
# seems like a library name without prefix and suffix
|
||||
set(${out_var} "${file_path}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
@ -93,12 +93,11 @@ handle_type(cpp EXTENSIONS .c .cc .cpp .cxx .h .hh .hxx .hpp MODULES Core TEMPLA
|
||||
handle_type(qml EXTENSIONS .qml .js .mjs MODULES Gui Qml Quick TEMPLATE
|
||||
"\n\nqt_add_qml_module(${project_name}
|
||||
URI ${project_name}
|
||||
OUTPUT_DIRECTORY qml
|
||||
VERSION 1.0
|
||||
RESOURCE_PREFIX /qt/qml
|
||||
QML_FILES
|
||||
@files@
|
||||
)"
|
||||
)
|
||||
set_property(TARGET ${project_name} PROPERTY RUNTIME_OUTPUT_NAME \"${project_name}app\")
|
||||
"
|
||||
)
|
||||
|
||||
handle_type(ui EXTENSIONS .ui MODULES Gui Widgets DEPENDS cpp TEMPLATE
|
||||
@ -162,7 +161,7 @@ set(content
|
||||
project(${project_name} LANGUAGES CXX)
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS ${packages_string})
|
||||
qt_standard_project_setup()"
|
||||
qt_standard_project_setup(REQUIRES 6.8)"
|
||||
)
|
||||
|
||||
set(has_useful_sources FALSE)
|
||||
|
@ -14,3 +14,4 @@ set(QT@PROJECT_VERSION_MAJOR@_INSTALL_PLUGINS "@INSTALL_PLUGINSDIR@")
|
||||
set(QT@PROJECT_VERSION_MAJOR@_INSTALL_QML "@INSTALL_QMLDIR@")
|
||||
set(QT@PROJECT_VERSION_MAJOR@_INSTALL_TESTS "@INSTALL_TESTSDIR@")
|
||||
set(QT@PROJECT_VERSION_MAJOR@_INSTALL_TRANSLATIONS "@INSTALL_TRANSLATIONSDIR@")
|
||||
set(QT@PROJECT_VERSION_MAJOR@_INSTALL_DESCRIPTIONSDIR "@INSTALL_DESCRIPTIONSDIR@")
|
||||
|
@ -3,85 +3,124 @@
|
||||
|
||||
|
||||
function(qt_internal_set_warnings_are_errors_flags target target_scope)
|
||||
set(flags "")
|
||||
if (CLANG AND NOT MSVC)
|
||||
list(APPEND flags -Werror -Wno-error=\#warnings -Wno-error=deprecated-declarations)
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # as in: not AppleClang
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "10.0.0")
|
||||
# We do mixed enum arithmetic all over the place:
|
||||
list(APPEND flags -Wno-error=deprecated-enum-enum-conversion)
|
||||
endif()
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "14.0.0")
|
||||
# Clang 14 introduced these two but we are not clean for it.
|
||||
list(APPEND flags -Wno-error=deprecated-copy-with-user-provided-copy)
|
||||
list(APPEND flags -Wno-error=unused-but-set-variable)
|
||||
endif()
|
||||
endif()
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
# using GCC
|
||||
list(APPEND flags -Werror -Wno-error=cpp -Wno-error=deprecated-declarations)
|
||||
|
||||
# GCC prints this bogus warning, after it has inlined a lot of code
|
||||
# error: assuming signed overflow does not occur when assuming that (X + c) < X is always false
|
||||
list(APPEND flags -Wno-error=strict-overflow)
|
||||
|
||||
# GCC 7 includes -Wimplicit-fallthrough in -Wextra, but Qt is not yet free of implicit fallthroughs.
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0.0")
|
||||
list(APPEND flags -Wno-error=implicit-fallthrough)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "9.0.0")
|
||||
# GCC 9 introduced these but we are not clean for it.
|
||||
list(APPEND flags -Wno-error=deprecated-copy -Wno-error=redundant-move -Wno-error=init-list-lifetime)
|
||||
# GCC 9 introduced -Wformat-overflow in -Wall, but it is buggy:
|
||||
list(APPEND flags -Wno-error=format-overflow)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "10.0.0")
|
||||
# GCC 10 has a number of bugs in -Wstringop-overflow. Do not make them an error.
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92955
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94335
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101134
|
||||
list(APPEND flags -Wno-error=stringop-overflow)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "11.0.0")
|
||||
# Ditto
|
||||
list(APPEND flags -Wno-error=stringop-overread)
|
||||
|
||||
# We do mixed enum arithmetic all over the place:
|
||||
list(APPEND flags -Wno-error=deprecated-enum-enum-conversion -Wno-error=deprecated-enum-float-conversion)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "11.0.0" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "11.2.0")
|
||||
# GCC 11.1 has a regression in the integrated preprocessor, so disable it as a workaround (QTBUG-93360)
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100796
|
||||
# This in turn triggers a fallthrough warning in cborparser.c, so we disable this warning.
|
||||
list(APPEND flags -no-integrated-cpp -Wno-implicit-fallthrough)
|
||||
endif()
|
||||
|
||||
# Work-around for bug https://code.google.com/p/android/issues/detail?id=58135
|
||||
if (ANDROID)
|
||||
list(APPEND flags -Wno-error=literal-suffix)
|
||||
endif()
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
# Only enable for versions of MSVC that are known to work
|
||||
# 1941 is Visual Studio 2022 version 17.11
|
||||
if(MSVC_VERSION LESS_EQUAL 1941)
|
||||
list(APPEND flags /WX)
|
||||
endif()
|
||||
endif()
|
||||
set(warnings_are_errors_enabled_genex
|
||||
"$<NOT:$<BOOL:$<TARGET_PROPERTY:QT_SKIP_WARNINGS_ARE_ERRORS>>>")
|
||||
|
||||
# Gate everything by the target property
|
||||
set(common_conditions "$<NOT:$<BOOL:$<TARGET_PROPERTY:QT_SKIP_WARNINGS_ARE_ERRORS>>>")
|
||||
# Apparently qmake only adds -Werror to CXX and OBJCXX files, not C files. We have to do the
|
||||
# same otherwise MinGW builds break when building 3rdparty\md4c\md4c.c (and probably on other
|
||||
# platforms too).
|
||||
set(cxx_only_genex "$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:OBJCXX>>")
|
||||
set(final_condition_genex "$<AND:${warnings_are_errors_enabled_genex},${cxx_only_genex}>")
|
||||
set(flags_generator_expression "$<${final_condition_genex}:${flags}>")
|
||||
|
||||
target_compile_options("${target}" ${target_scope} "${flags_generator_expression}")
|
||||
set(language_args LANGUAGES CXX OBJCXX)
|
||||
# This property is set to True only if we are using Clang and frontend is MSVC
|
||||
# Currently we do not set any error flags
|
||||
set(clang_msvc_frontend_args
|
||||
"$<NOT:$<BOOL:$<TARGET_PROPERTY:Qt6::PlatformCommonInternal,_qt_internal_clang_msvc_frontend>>>"
|
||||
)
|
||||
if(GCC OR CLANG OR WIN32)
|
||||
# Note: the if check is included to mimic the previous selective gating. These need to
|
||||
# balance reducing unnecessary compile flags that are evaluated by the genex, and making
|
||||
# sure the developer has appropriate Werror flags enabled when building a module with
|
||||
# different environment
|
||||
qt_internal_add_compiler_dependent_flags("${target}" ${target_scope}
|
||||
COMPILERS CLANG AppleClang
|
||||
OPTIONS
|
||||
-Werror -Wno-error=\#warnings -Wno-error=deprecated-declarations
|
||||
COMPILERS CLANG
|
||||
CONDITIONS VERSION_GREATER_EQUAL 10
|
||||
OPTIONS
|
||||
# We do mixed enum arithmetic all over the place:
|
||||
-Wno-error=deprecated-enum-enum-conversion
|
||||
CONDITIONS VERSION_GREATER_EQUAL 14
|
||||
OPTIONS
|
||||
# Clang 14 introduced these two but we are not clean for it.
|
||||
-Wno-error=deprecated-copy-with-user-provided-copy
|
||||
-Wno-error=unused-but-set-variable
|
||||
COMMON_CONDITIONS
|
||||
${common_conditions}
|
||||
${clang_msvc_frontend_args}
|
||||
${language_args}
|
||||
)
|
||||
qt_internal_add_compiler_dependent_flags("${target}" ${target_scope}
|
||||
COMPILERS GNU
|
||||
OPTIONS
|
||||
-Werror -Wno-error=cpp -Wno-error=deprecated-declarations
|
||||
# GCC prints this bogus warning, after it has inlined a lot of code
|
||||
# error: assuming signed overflow does not occur when assuming that (X + c) < X
|
||||
# is always false
|
||||
-Wno-error=strict-overflow
|
||||
CONDITIONS VERSION_GREATER_EQUAL 7
|
||||
OPTIONS
|
||||
# GCC 7 includes -Wimplicit-fallthrough in -Wextra, but Qt is not yet free of
|
||||
# implicit fallthroughs.
|
||||
-Wno-error=implicit-fallthrough
|
||||
CONDITIONS VERSION_GREATER_EQUAL 9
|
||||
OPTIONS
|
||||
# GCC 9 introduced these but we are not clean for it.
|
||||
-Wno-error=deprecated-copy
|
||||
-Wno-error=redundant-move
|
||||
-Wno-error=init-list-lifetime
|
||||
# GCC 9 introduced -Wformat-overflow in -Wall, but it is buggy:
|
||||
-Wno-error=format-overflow
|
||||
CONDITIONS VERSION_GREATER_EQUAL 10
|
||||
OPTIONS
|
||||
# GCC 10 has a number of bugs in -Wstringop-overflow. Do not make them an error.
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92955
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94335
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101134
|
||||
-Wno-error=stringop-overflow
|
||||
CONDITIONS VERSION_GREATER_EQUAL 11
|
||||
OPTIONS
|
||||
# Ditto
|
||||
-Wno-error=stringop-overread
|
||||
# We do mixed enum arithmetic all over the place:
|
||||
-Wno-error=deprecated-enum-enum-conversion
|
||||
-Wno-error=deprecated-enum-float-conversion
|
||||
CONDITIONS VERSION_GREATER_EQUAL 11.0 AND VERSION_LESS 11.2
|
||||
OPTIONS
|
||||
# GCC 11.1 has a regression in the integrated preprocessor, so disable it as a
|
||||
# workaround (QTBUG-93360)
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100796
|
||||
# This in turn triggers a fallthrough warning in cborparser.c, so we disable
|
||||
# this warning.
|
||||
-no-integrated-cpp -Wno-implicit-fallthrough
|
||||
CONDITIONS VERSION_LESS 15.1
|
||||
AND $<BOOL:${QT_FEATURE_sanitize_thread}>
|
||||
AND $<BOOL:${BUILD_WITH_PCH}>
|
||||
OPTIONS
|
||||
# GCC < 15 raises a TSAN warning from Qt's own PCHs, despite the warning
|
||||
# being suppressed (QTBUG-134415)
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64117
|
||||
-Wno-error=tsan
|
||||
COMMON_CONDITIONS
|
||||
${common_conditions}
|
||||
${language_args}
|
||||
)
|
||||
endif()
|
||||
# Other options are gated at compile time that are not likely to change between different build
|
||||
# environments of other modules.
|
||||
if(ANDROID)
|
||||
qt_internal_add_compiler_dependent_flags("${target}" ${target_scope}
|
||||
COMPILERS GNU
|
||||
CONDITIONS $<PLATFORM_ID:ANDROID>
|
||||
OPTIONS
|
||||
# Work-around for bug https://code.google.com/p/android/issues/detail?id=58135
|
||||
-Wno-error=literal-suffix
|
||||
COMMON_CONDITIONS
|
||||
${common_conditions}
|
||||
${language_args}
|
||||
)
|
||||
endif()
|
||||
if(WIN32)
|
||||
qt_internal_add_compiler_dependent_flags("${target}" ${target_scope}
|
||||
COMPILERS MSVC
|
||||
# Only enable for versions of MSVC that are known to work
|
||||
# 1941 is Visual Studio 2022 version 17.11
|
||||
CONDITIONS VERSION_LESS_EQUAL 17.11
|
||||
OPTIONS
|
||||
/WX
|
||||
COMMON_CONDITIONS
|
||||
${common_conditions}
|
||||
${language_args}
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# The function adds a global 'definition' to the platform internal targets and the target
|
||||
@ -97,7 +136,7 @@ endfunction()
|
||||
# APP - set the definition for all Qt applications
|
||||
# TODO: Add a tests specific platform target and the definition scope for it.
|
||||
function(qt_internal_add_global_definition definition)
|
||||
set(optional_args)
|
||||
set(optional_args "")
|
||||
set(single_value_args VALUE)
|
||||
set(multi_value_args SCOPE)
|
||||
cmake_parse_arguments(arg
|
||||
@ -310,6 +349,16 @@ if (MSVC AND NOT CLANG)
|
||||
)
|
||||
endif()
|
||||
|
||||
set(_qt_internal_clang_msvc_frontend False)
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
|
||||
CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
|
||||
set(_qt_internal_clang_msvc_frontend True)
|
||||
endif()
|
||||
set_target_properties(PlatformCommonInternal
|
||||
PROPERTIES
|
||||
_qt_internal_clang_msvc_frontend "${_qt_internal_clang_msvc_frontend}"
|
||||
)
|
||||
|
||||
if(MINGW)
|
||||
target_compile_options(PlatformCommonInternal INTERFACE -Wa,-mbig-obj)
|
||||
endif()
|
||||
|
@ -29,10 +29,67 @@ endif()
|
||||
|
||||
if (NOT QT_NO_CREATE_TARGETS AND @INSTALL_CMAKE_NAMESPACE@@target@_FOUND)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake"
|
||||
OPTIONAL)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@ExtraProperties.cmake"
|
||||
OPTIONAL)
|
||||
endif()
|
||||
|
||||
# Find the private module counterpart.
|
||||
# For now, always load the private module. In a future Qt version we plan to require users to
|
||||
# find_package the private module explicitly.
|
||||
set(__qt_@target@_always_load_private_module ON)
|
||||
set(__qt_@target@_save_QT_NO_PRIVATE_MODULE_WARNING ${QT_NO_PRIVATE_MODULE_WARNING})
|
||||
set(QT_NO_PRIVATE_MODULE_WARNING ON)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@-build.cmake" OPTIONAL)
|
||||
if (@INSTALL_CMAKE_NAMESPACE@@target@_FOUND
|
||||
AND NOT @INSTALL_CMAKE_NAMESPACE@@target_private@_FOUND
|
||||
AND NOT @arg_NO_PRIVATE_MODULE@
|
||||
AND (
|
||||
__qt_@target@_always_load_private_module
|
||||
OR DEFINED QT_REPO_MODULE_VERSION
|
||||
OR QT_FIND_PRIVATE_MODULES
|
||||
)
|
||||
)
|
||||
if("${_qt_cmake_dir}" STREQUAL "")
|
||||
set(_qt_cmake_dir "${QT_TOOLCHAIN_RELOCATABLE_CMAKE_DIR}")
|
||||
endif()
|
||||
set(__qt_use_no_default_path_for_qt_packages "NO_DEFAULT_PATH")
|
||||
if(QT_DISABLE_NO_DEFAULT_PATH_IN_QT_PACKAGES)
|
||||
set(__qt_use_no_default_path_for_qt_packages "")
|
||||
endif()
|
||||
find_package(@INSTALL_CMAKE_NAMESPACE@@target_private@ "@PROJECT_VERSION@" EXACT
|
||||
QUIET
|
||||
CONFIG
|
||||
PATHS
|
||||
${QT_BUILD_CMAKE_PREFIX_PATH}
|
||||
"${CMAKE_CURRENT_LIST_DIR}/.."
|
||||
"${_qt_cmake_dir}"
|
||||
${_qt_additional_packages_prefix_paths}
|
||||
${__qt_use_no_default_path_for_qt_packages}
|
||||
)
|
||||
|
||||
if(NOT @INSTALL_CMAKE_NAMESPACE@@target_private@_FOUND)
|
||||
get_property(@INSTALL_CMAKE_NAMESPACE@@target_private@_warning_shown GLOBAL PROPERTY
|
||||
@INSTALL_CMAKE_NAMESPACE@@target_private@_warning_shown
|
||||
)
|
||||
if(NOT @INSTALL_CMAKE_NAMESPACE@@target_private@_warning_shown)
|
||||
message(VERBOSE
|
||||
"The private module package '@INSTALL_CMAKE_NAMESPACE@@target_private@' "
|
||||
"could not be found. It possibly needs to be installed separately with your "
|
||||
"package manager."
|
||||
)
|
||||
set_property(GLOBAL PROPERTY
|
||||
@INSTALL_CMAKE_NAMESPACE@@target_private@_warning_shown ON
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
set(QT_NO_PRIVATE_MODULE_WARNING ${__qt_@target@_save_QT_NO_PRIVATE_MODULE_WARNING})
|
||||
unset(__qt_@target@_save_QT_NO_PRIVATE_MODULE_WARNING)
|
||||
unset(__qt_@target@_always_load_private_module)
|
||||
|
||||
if (NOT QT_NO_CREATE_TARGETS AND @INSTALL_CMAKE_NAMESPACE@@target@_FOUND)
|
||||
# DEPRECATED
|
||||
# Provide old style variables for includes, compile definitions, etc.
|
||||
# These variables are deprecated and only provided on a best-effort basis to facilitate porting.
|
||||
@ -120,18 +177,28 @@ if (TARGET @QT_CMAKE_EXPORT_NAMESPACE@::@target@)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Plugins.cmake")
|
||||
endif()
|
||||
|
||||
list(APPEND QT_ALL_MODULES_FOUND_VIA_FIND_PACKAGE "@target@")
|
||||
if(NOT "@target@" IN_LIST QT_ALL_MODULES_FOUND_VIA_FIND_PACKAGE)
|
||||
list(APPEND QT_ALL_MODULES_FOUND_VIA_FIND_PACKAGE "@target@")
|
||||
list(APPEND QT_ALL_MODULES_VERSIONED_FOUND_VIA_FIND_PACKAGE
|
||||
"@INSTALL_CMAKE_NAMESPACE@::@target@")
|
||||
endif()
|
||||
|
||||
get_target_property(_qt_module_target_type "@INSTALL_CMAKE_NAMESPACE@::@target@" TYPE)
|
||||
if(NOT _qt_module_target_type STREQUAL "INTERFACE_LIBRARY")
|
||||
get_target_property(_qt_module_plugin_types
|
||||
@INSTALL_CMAKE_NAMESPACE@::@target@ MODULE_PLUGIN_TYPES)
|
||||
if(_qt_module_plugin_types)
|
||||
list(APPEND QT_ALL_PLUGIN_TYPES_FOUND_VIA_FIND_PACKAGE "${_qt_module_plugin_types}")
|
||||
foreach(_qt_module_plugin_type IN LISTS _qt_module_plugin_types)
|
||||
if(NOT "${_qt_module_plugin_type}"
|
||||
IN_LIST QT_ALL_PLUGIN_TYPES_FOUND_VIA_FIND_PACKAGE)
|
||||
list(APPEND QT_ALL_PLUGIN_TYPES_FOUND_VIA_FIND_PACKAGE
|
||||
"${_qt_module_plugin_type}")
|
||||
endif()
|
||||
endforeach()
|
||||
unset(_qt_module_plugin_type)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# Load Module's BuildInternals should any exist
|
||||
if (@INSTALL_CMAKE_NAMESPACE@BuildInternals_DIR AND
|
||||
EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@BuildInternals.cmake")
|
||||
|
64
cmake/QtModuleConfigPrivate.cmake.in
Normal file
64
cmake/QtModuleConfigPrivate.cmake.in
Normal file
@ -0,0 +1,64 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
cmake_minimum_required(VERSION @min_new_policy_version@...@max_new_policy_version@)
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
# Find required dependencies, if any.
|
||||
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@Dependencies.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@Dependencies.cmake")
|
||||
_qt_internal_suggest_dependency_debugging(@target_private@
|
||||
__qt_@target_private@_pkg ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE)
|
||||
endif()
|
||||
|
||||
# If *ConfigDependencies.cmake exists, the variable value will be defined there.
|
||||
# Don't override it in that case.
|
||||
if(NOT DEFINED "@INSTALL_CMAKE_NAMESPACE@@target_private@_FOUND")
|
||||
set("@INSTALL_CMAKE_NAMESPACE@@target_private@_FOUND" TRUE)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED QT_REPO_MODULE_VERSION
|
||||
AND NOT QT_NO_PRIVATE_MODULE_WARNING
|
||||
AND NOT __qt_private_module_@target_private@_warning_shown)
|
||||
message(WARNING
|
||||
"This project is using headers of the @target_private@ module and will therefore be tied "
|
||||
"to this specific Qt module build version. "
|
||||
"Running this project against other versions of the Qt modules may crash at any arbitrary "
|
||||
"point. This is not a bug, but a result of using Qt internals. You have been warned! "
|
||||
"\nYou can disable this warning by setting QT_NO_PRIVATE_MODULE_WARNING to ON."
|
||||
)
|
||||
set(__qt_private_module_@target_private@_warning_shown TRUE)
|
||||
endif()
|
||||
|
||||
if(NOT QT_NO_CREATE_TARGETS AND @INSTALL_CMAKE_NAMESPACE@@target_private@_FOUND)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@Targets.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@AdditionalTargetInfo.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@ExtraProperties.cmake"
|
||||
OPTIONAL)
|
||||
endif()
|
||||
|
||||
if(TARGET @QT_CMAKE_EXPORT_NAMESPACE@::@target_private@)
|
||||
if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.18 OR QT_USE_OLD_VERSION_LESS_TARGETS)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@VersionlessTargets.cmake")
|
||||
else()
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@VersionlessAliasTargets.cmake")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
set(@INSTALL_CMAKE_NAMESPACE@@target_private@_FOUND FALSE)
|
||||
if(NOT DEFINED @INSTALL_CMAKE_NAMESPACE@@target_private@_NOT_FOUND_MESSAGE)
|
||||
set(@INSTALL_CMAKE_NAMESPACE@@target_private@_NOT_FOUND_MESSAGE
|
||||
"Target \"@QT_CMAKE_EXPORT_NAMESPACE@::@target_private@\" was not found.")
|
||||
|
||||
if(QT_NO_CREATE_TARGETS)
|
||||
string(APPEND @INSTALL_CMAKE_NAMESPACE@@target_private@_NOT_FOUND_MESSAGE
|
||||
"Possibly due to QT_NO_CREATE_TARGETS being set to TRUE and thus "
|
||||
"${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target_private@Targets.cmake was not "
|
||||
"included to define the target.")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
@ -32,16 +32,20 @@ endif()
|
||||
set(__qt_@target@_third_party_deps "@third_party_deps@")
|
||||
@third_party_deps_extra_info@
|
||||
_qt_internal_find_third_party_dependencies("@target@" __qt_@target@_third_party_deps)
|
||||
unset(__qt_@target@_third_party_deps)
|
||||
|
||||
# Find Qt tool package.
|
||||
set(__qt_@target@_tool_deps "@main_module_tool_deps@")
|
||||
_qt_internal_find_tool_dependencies("@target@" __qt_@target@_tool_deps)
|
||||
unset(__qt_@target@_tool_deps)
|
||||
|
||||
# note: target_deps example: "Qt6Core\;5.12.0;Qt6Gui\;5.12.0"
|
||||
set(__qt_@target@_target_deps "@target_deps@")
|
||||
set(__qt_@target@_find_dependency_paths "${CMAKE_CURRENT_LIST_DIR}/.." "${_qt_cmake_dir}")
|
||||
_qt_internal_find_qt_dependencies("@target@" __qt_@target@_target_deps
|
||||
__qt_@target@_find_dependency_paths)
|
||||
unset(__qt_@target@_target_deps)
|
||||
unset(__qt_@target@_find_dependency_paths)
|
||||
|
||||
set(_@QT_CMAKE_EXPORT_NAMESPACE@@target@_MODULE_DEPENDENCIES "@qt_module_dependencies@")
|
||||
set(@INSTALL_CMAKE_NAMESPACE@@target@_FOUND TRUE)
|
||||
|
@ -81,7 +81,6 @@ endfunction()
|
||||
# Options:
|
||||
# NO_ADDITIONAL_TARGET_INFO
|
||||
# Don't generate a Qt6*AdditionalTargetInfo.cmake file.
|
||||
# The caller is responsible for creating one.
|
||||
#
|
||||
# MODULE_INTERFACE_NAME
|
||||
# The custom name of the module interface. This name is used as a part of the include paths
|
||||
@ -251,10 +250,9 @@ function(qt_internal_add_module target)
|
||||
set(module_config_private_header "qt${arg_CONFIG_MODULE_NAME}-config_p.h")
|
||||
# qt<module>-config.h/-config_p.h header files are not marked as GENERATED automatically
|
||||
# for old CMake versions. Set the property explicitly here.
|
||||
set_source_files_properties("${module_config_header}" "${module_config_private_header}"
|
||||
PROPERTIES
|
||||
GENERATED TRUE
|
||||
SKIP_AUTOGEN TRUE
|
||||
_qt_internal_set_source_file_generated(
|
||||
SOURCES "${module_config_header}" "${module_config_private_header}"
|
||||
SKIP_AUTOGEN
|
||||
)
|
||||
|
||||
# Module define needs to take into account the config module name.
|
||||
@ -327,7 +325,7 @@ function(qt_internal_add_module target)
|
||||
set_target_properties(${target_private} PROPERTIES
|
||||
_qt_config_module_name ${arg_CONFIG_MODULE_NAME}_private
|
||||
_qt_package_version "${PROJECT_VERSION}"
|
||||
_qt_package_name "${INSTALL_CMAKE_NAMESPACE}${target}"
|
||||
_qt_package_name "${INSTALL_CMAKE_NAMESPACE}${target}Private"
|
||||
_qt_is_private_module TRUE
|
||||
_qt_public_module_target_name "${target}"
|
||||
)
|
||||
@ -340,6 +338,9 @@ function(qt_internal_add_module target)
|
||||
)
|
||||
set_property(TARGET "${target_private}" APPEND PROPERTY
|
||||
EXPORT_PROPERTIES "${export_properties}")
|
||||
|
||||
# Let find_package(Qt6FooPrivate) also find_package(Qt6Foo).
|
||||
qt_internal_register_target_dependencies("${target_private}" PUBLIC "Qt::${target}")
|
||||
endif()
|
||||
|
||||
# FIXME: This workaround is needed because the deployment logic
|
||||
@ -442,7 +443,7 @@ function(qt_internal_add_module target)
|
||||
|
||||
set(module_depends_header
|
||||
"${module_build_interface_include_dir}/${module_include_name}Depends")
|
||||
set_source_files_properties("${module_depends_header}" PROPERTIES GENERATED TRUE)
|
||||
_qt_internal_set_source_file_generated(SOURCES "${module_depends_header}")
|
||||
set_target_properties(${target} PROPERTIES _qt_module_depends_header
|
||||
"${module_depends_header}")
|
||||
if(NOT arg_HEADER_MODULE)
|
||||
@ -659,7 +660,7 @@ function(qt_internal_add_module target)
|
||||
# thus we can't use qt_internal_extend_target()'s PUBLIC_DEFINES option.
|
||||
target_compile_definitions(${target} INTERFACE QT_${module_define_infix}_LIB)
|
||||
|
||||
if(NOT DEFINED arg_EXCEPTIONS)
|
||||
if(NOT arg_EXCEPTIONS)
|
||||
qt_internal_set_exceptions_flags("${target}" "DEFAULT")
|
||||
else()
|
||||
qt_internal_set_exceptions_flags("${target}" "${arg_EXCEPTIONS}")
|
||||
@ -691,6 +692,12 @@ function(qt_internal_add_module target)
|
||||
set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${target}")
|
||||
qt_path_join(config_build_dir ${QT_CONFIG_BUILD_DIR} ${path_suffix})
|
||||
qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${path_suffix})
|
||||
if(NOT arg_NO_PRIVATE_MODULE)
|
||||
set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${target_private}")
|
||||
qt_path_join(private_config_build_dir ${QT_CONFIG_BUILD_DIR} ${path_suffix})
|
||||
qt_path_join(private_config_install_dir ${QT_CONFIG_INSTALL_DIR} ${path_suffix})
|
||||
endif()
|
||||
unset(path_suffix)
|
||||
|
||||
set(extra_cmake_files)
|
||||
set(extra_cmake_includes)
|
||||
@ -739,9 +746,17 @@ set(QT_ALLOW_MISSING_TOOLS_PACKAGES TRUE)")
|
||||
endif()
|
||||
|
||||
foreach(cmake_file IN LISTS arg_EXTRA_CMAKE_FILES)
|
||||
get_filename_component(basename ${cmake_file} NAME)
|
||||
file(COPY ${cmake_file} DESTINATION ${config_build_dir})
|
||||
list(APPEND extra_cmake_files "${config_build_dir}/${basename}")
|
||||
get_source_file_property(install_path ${cmake_file} QT_INSTALL_PATH)
|
||||
if(NOT install_path)
|
||||
# Sanitize the install_path from `NOTFOUND` to ""
|
||||
set(install_path "")
|
||||
endif()
|
||||
file(COPY ${cmake_file} DESTINATION "${config_build_dir}/${install_path}")
|
||||
qt_install(FILES
|
||||
${cmake_file}
|
||||
DESTINATION "${config_install_dir}/${install_path}"
|
||||
COMPONENT Devel
|
||||
)
|
||||
|
||||
# Make sure touched extra cmake files cause a reconfigure, so they get re-copied.
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${cmake_file}")
|
||||
@ -781,10 +796,16 @@ set(QT_ALLOW_MISSING_TOOLS_PACKAGES TRUE)")
|
||||
|
||||
qt_internal_get_min_new_policy_cmake_version(min_new_policy_version)
|
||||
qt_internal_get_max_new_policy_cmake_version(max_new_policy_version)
|
||||
configure_package_config_file(
|
||||
"${QT_CMAKE_DIR}/QtModuleConfig.cmake.in"
|
||||
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake"
|
||||
INSTALL_DESTINATION "${config_install_dir}"
|
||||
|
||||
if(is_static_lib)
|
||||
set(write_basic_module_package_args IS_STATIC_LIB)
|
||||
else()
|
||||
set(write_basic_module_package_args "")
|
||||
endif()
|
||||
qt_internal_write_basic_module_package("${target}" "${target_private}"
|
||||
${write_basic_module_package_args}
|
||||
CONFIG_BUILD_DIR ${config_build_dir}
|
||||
CONFIG_INSTALL_DIR ${config_install_dir}
|
||||
)
|
||||
|
||||
if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/${INSTALL_CMAKE_NAMESPACE}${target}BuildInternals.cmake")
|
||||
@ -794,38 +815,45 @@ set(QT_ALLOW_MISSING_TOOLS_PACKAGES TRUE)")
|
||||
list(APPEND extra_cmake_files "${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}BuildInternals.cmake")
|
||||
endif()
|
||||
|
||||
write_basic_package_version_file(
|
||||
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersionImpl.cmake"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
qt_internal_write_qt_package_version_file(
|
||||
"${INSTALL_CMAKE_NAMESPACE}${target}"
|
||||
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake"
|
||||
)
|
||||
qt_install(FILES
|
||||
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake"
|
||||
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersion.cmake"
|
||||
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}ConfigVersionImpl.cmake"
|
||||
${extra_cmake_files}
|
||||
DESTINATION "${config_install_dir}"
|
||||
COMPONENT Devel
|
||||
)
|
||||
|
||||
file(COPY ${extra_cmake_files} DESTINATION "${config_build_dir}")
|
||||
set(exported_targets ${target})
|
||||
if(NOT ${arg_NO_PRIVATE_MODULE})
|
||||
list(APPEND exported_targets ${target_private})
|
||||
if(NOT arg_NO_PRIVATE_MODULE)
|
||||
qt_internal_write_basic_module_package("${target}" "${target_private}"
|
||||
${write_basic_module_package_args}
|
||||
PRIVATE
|
||||
CONFIG_BUILD_DIR ${private_config_build_dir}
|
||||
CONFIG_INSTALL_DIR ${private_config_install_dir}
|
||||
)
|
||||
endif()
|
||||
set(export_name "${INSTALL_CMAKE_NAMESPACE}${target}Targets")
|
||||
|
||||
qt_install(TARGETS ${exported_targets}
|
||||
EXPORT ${export_name}
|
||||
RUNTIME DESTINATION ${INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${INSTALL_LIBDIR}
|
||||
FRAMEWORK DESTINATION ${INSTALL_LIBDIR}
|
||||
file(COPY ${extra_cmake_files} DESTINATION "${config_build_dir}")
|
||||
|
||||
set(targets_to_export ${target})
|
||||
if(NOT ${arg_NO_PRIVATE_MODULE})
|
||||
list(APPEND targets_to_export ${target_private})
|
||||
endif()
|
||||
|
||||
_qt_internal_forward_function_args(
|
||||
FORWARD_PREFIX arg
|
||||
FORWARD_OUT_VAR export_module_args
|
||||
FORWARD_OPTIONS NO_ADDITIONAL_TARGET_INFO
|
||||
)
|
||||
qt_internal_export_module(${target}
|
||||
${export_module_args}
|
||||
CONFIG_BUILD_DIR ${config_build_dir}
|
||||
CONFIG_INSTALL_DIR ${config_install_dir}
|
||||
)
|
||||
if(NOT arg_NO_PRIVATE_MODULE)
|
||||
qt_internal_export_module(${target_private}
|
||||
${export_module_args}
|
||||
CONFIG_BUILD_DIR ${private_config_build_dir}
|
||||
CONFIG_INSTALL_DIR ${private_config_install_dir}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
qt_apply_rpaths(TARGET "${target}" INSTALL_PATH "${INSTALL_LIBDIR}" RELATIVE_RPATH)
|
||||
@ -839,29 +867,6 @@ set(QT_ALLOW_MISSING_TOOLS_PACKAGES TRUE)")
|
||||
QT_ANDROID_MODULE_INSTALL_DIR ${INSTALL_LIBDIR})
|
||||
endif()
|
||||
|
||||
qt_install(EXPORT ${export_name}
|
||||
NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE}::
|
||||
DESTINATION ${config_install_dir})
|
||||
|
||||
if(NOT arg_NO_ADDITIONAL_TARGET_INFO)
|
||||
qt_internal_export_additional_targets_file(
|
||||
TARGETS ${exported_targets}
|
||||
EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target}
|
||||
CONFIG_INSTALL_DIR "${config_install_dir}")
|
||||
endif()
|
||||
|
||||
qt_internal_export_modern_cmake_config_targets_file(
|
||||
TARGETS ${exported_targets}
|
||||
EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target}
|
||||
CONFIG_BUILD_DIR "${config_build_dir}"
|
||||
CONFIG_INSTALL_DIR "${config_install_dir}"
|
||||
)
|
||||
|
||||
qt_internal_export_genex_properties(TARGETS ${target}
|
||||
EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target}
|
||||
CONFIG_INSTALL_DIR "${config_install_dir}"
|
||||
)
|
||||
|
||||
### fixme: cmake is missing a built-in variable for this. We want to apply it only to modules and plugins
|
||||
# that belong to Qt.
|
||||
if(NOT arg_HEADER_MODULE)
|
||||
@ -980,12 +985,125 @@ set(QT_ALLOW_MISSING_TOOLS_PACKAGES TRUE)")
|
||||
${__qt_internal_sbom_multi_args}
|
||||
)
|
||||
|
||||
_qt_internal_extend_sbom(${target} ${sbom_args})
|
||||
qt_internal_extend_qt_entity_sbom(${target} ${sbom_args})
|
||||
endif()
|
||||
|
||||
qt_add_list_file_finalizer(qt_finalize_module ${target} ${arg_INTERNAL_MODULE} ${arg_NO_PRIVATE_MODULE})
|
||||
endfunction()
|
||||
|
||||
# Write and install the basic Qt6Foo and Qt6FooPrivate packages.
|
||||
#
|
||||
# If PRIVATE is specified, write Qt6FooPrivate.
|
||||
# Otherwise write its public counterpart.
|
||||
function(qt_internal_write_basic_module_package target target_private)
|
||||
set(no_value_options
|
||||
IS_STATIC_LIB
|
||||
PRIVATE
|
||||
)
|
||||
set(single_value_options
|
||||
CONFIG_BUILD_DIR
|
||||
CONFIG_INSTALL_DIR
|
||||
)
|
||||
set(multi_value_options "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg
|
||||
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
|
||||
)
|
||||
|
||||
if(arg_PRIVATE)
|
||||
set(package_name "${INSTALL_CMAKE_NAMESPACE}${target_private}")
|
||||
set(module_config_input_file "QtModuleConfigPrivate.cmake.in")
|
||||
else()
|
||||
set(package_name "${INSTALL_CMAKE_NAMESPACE}${target}")
|
||||
set(module_config_input_file "QtModuleConfig.cmake.in")
|
||||
endif()
|
||||
|
||||
if(arg_IS_STATIC_LIB AND NOT arg_PRIVATE AND CMAKE_VERSION VERSION_LESS "3.26")
|
||||
# We auto-load the private module package from the public module package if we have a static
|
||||
# Qt module and CMake's version is < 3.26. This is needed for the case "Qt6Foo links against
|
||||
# Qt6BarPrivate", because CMake generates a check for the target Qt6::BarPrivate in
|
||||
# Qt6FooTargets.cmake. Once we can require CMake 3.26, we can simply link against
|
||||
# $<BUILD_LOCAL_INTERFACE:Qt6BarPrivate> in qt_internal_extend_target.
|
||||
#
|
||||
# For older CMake versions, we create an additional CMake file that's optionally included by
|
||||
# Qt6FooConfig.cmake to work around the lack of BUILD_LOCAL_INTERFACE.
|
||||
file(CONFIGURE
|
||||
OUTPUT "${arg_CONFIG_BUILD_DIR}/${package_name}-build.cmake"
|
||||
CONTENT "# This file marks this directory as part of Qt's build tree.
|
||||
set(__qt_${target}_always_load_private_module ON)
|
||||
"
|
||||
)
|
||||
endif()
|
||||
|
||||
configure_package_config_file(
|
||||
"${QT_CMAKE_DIR}/${module_config_input_file}"
|
||||
"${arg_CONFIG_BUILD_DIR}/${package_name}Config.cmake"
|
||||
INSTALL_DESTINATION "${arg_CONFIG_INSTALL_DIR}"
|
||||
)
|
||||
write_basic_package_version_file(
|
||||
"${arg_CONFIG_BUILD_DIR}/${package_name}ConfigVersionImpl.cmake"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
qt_internal_write_qt_package_version_file(
|
||||
"${package_name}"
|
||||
"${arg_CONFIG_BUILD_DIR}/${package_name}ConfigVersion.cmake"
|
||||
)
|
||||
qt_install(FILES
|
||||
"${arg_CONFIG_BUILD_DIR}/${package_name}Config.cmake"
|
||||
"${arg_CONFIG_BUILD_DIR}/${package_name}ConfigVersion.cmake"
|
||||
"${arg_CONFIG_BUILD_DIR}/${package_name}ConfigVersionImpl.cmake"
|
||||
DESTINATION "${arg_CONFIG_INSTALL_DIR}"
|
||||
COMPONENT Devel
|
||||
)
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_export_module target)
|
||||
set(no_value_options
|
||||
NO_ADDITIONAL_TARGET_INFO
|
||||
)
|
||||
set(single_value_options
|
||||
CONFIG_BUILD_DIR
|
||||
CONFIG_INSTALL_DIR
|
||||
)
|
||||
set(multi_value_options "")
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg
|
||||
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
|
||||
)
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(export_name "${INSTALL_CMAKE_NAMESPACE}${target}Targets")
|
||||
qt_install(TARGETS ${target}
|
||||
EXPORT ${export_name}
|
||||
RUNTIME DESTINATION ${INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${INSTALL_LIBDIR}
|
||||
FRAMEWORK DESTINATION ${INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
qt_install(EXPORT ${export_name}
|
||||
NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE}::
|
||||
DESTINATION ${arg_CONFIG_INSTALL_DIR})
|
||||
|
||||
if(NOT arg_NO_ADDITIONAL_TARGET_INFO)
|
||||
qt_internal_export_additional_targets_file(
|
||||
TARGETS ${target}
|
||||
EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target}
|
||||
CONFIG_INSTALL_DIR "${arg_CONFIG_INSTALL_DIR}")
|
||||
endif()
|
||||
|
||||
qt_internal_export_modern_cmake_config_targets_file(
|
||||
TARGETS ${target}
|
||||
EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target}
|
||||
CONFIG_BUILD_DIR "${arg_CONFIG_BUILD_DIR}"
|
||||
CONFIG_INSTALL_DIR "${arg_CONFIG_INSTALL_DIR}"
|
||||
)
|
||||
|
||||
qt_internal_export_genex_properties(TARGETS ${target}
|
||||
EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target}
|
||||
CONFIG_INSTALL_DIR "${arg_CONFIG_INSTALL_DIR}"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_apply_apple_privacy_manifest target)
|
||||
# Avoid "INTERFACE_LIBRARY targets may only have whitelisted properties" error on CMake < 3.17.
|
||||
get_target_property(target_type ${target} TYPE)
|
||||
@ -1016,8 +1134,11 @@ function(qt_finalize_module target)
|
||||
# property which supposed to be updated inside every qt_internal_install_module_headers
|
||||
# call.
|
||||
qt_internal_add_headersclean_target(${target} "${module_headers_public}")
|
||||
qt_internal_target_sync_headers(${target} "${module_headers_all}"
|
||||
"${module_headers_generated}")
|
||||
qt_internal_target_sync_headers(${target}
|
||||
"${module_headers_all}"
|
||||
"${module_headers_generated}"
|
||||
"${module_headers_exclude_from_docs}"
|
||||
)
|
||||
get_target_property(module_depends_header ${target} _qt_module_depends_header)
|
||||
qt_internal_install_module_headers(${target}
|
||||
PUBLIC ${module_headers_public} "${module_depends_header}"
|
||||
@ -1231,7 +1352,12 @@ function(qt_describe_module target)
|
||||
qt_path_join(install_dir ${QT_INSTALL_DIR} ${path_suffix})
|
||||
|
||||
set(descfile_in "${QT_CMAKE_DIR}/ModuleDescription.json.in")
|
||||
|
||||
# IMPORTANT: If you adjust the file name not to be the exact target name and thus the CMake
|
||||
# package name, it needs to consider also the code in QtConfig.cmake.in that globs the json
|
||||
# files.
|
||||
set(descfile_out "${build_dir}/${target}.json")
|
||||
|
||||
string(TOLOWER "${PROJECT_NAME}" lower_case_project_name)
|
||||
set(extra_module_information "")
|
||||
set(platforms_information "")
|
||||
@ -1379,6 +1505,11 @@ function(qt_internal_generate_cpp_global_exports target module_define_infix)
|
||||
|
||||
set(${out_public_header} "${generated_header_path}" PARENT_SCOPE)
|
||||
target_sources(${target} PRIVATE "${generated_header_path}")
|
||||
_qt_internal_set_source_file_generated(
|
||||
SOURCES "${generated_header_path}"
|
||||
CONFIGURE_GENERATED
|
||||
)
|
||||
# `GENERATED` property is set in order to be processed by `qt_internal_collect_module_headers`
|
||||
set_source_files_properties("${generated_header_path}" PROPERTIES GENERATED TRUE)
|
||||
endfunction()
|
||||
|
||||
@ -1437,6 +1568,7 @@ endfunction()
|
||||
function(qt_internal_collect_module_headers out_var target)
|
||||
set(${out_var}_public "")
|
||||
set(${out_var}_private "")
|
||||
set(${out_var}_exclude_from_docs "")
|
||||
set(${out_var}_qpa "")
|
||||
set(${out_var}_rhi "")
|
||||
set(${out_var}_ssg "")
|
||||
@ -1511,6 +1643,12 @@ function(qt_internal_collect_module_headers out_var target)
|
||||
set(is_3rdparty_header FALSE)
|
||||
endif()
|
||||
list(APPEND ${out_var}_all "${file_path}")
|
||||
|
||||
get_source_file_property(exclude_from_docs "${file_path}" _qt_syncqt_exclude_from_docs)
|
||||
if(exclude_from_docs)
|
||||
list(APPEND ${out_var}_exclude_from_docs "${file_path}")
|
||||
endif()
|
||||
|
||||
if(qpa_filter AND file_name MATCHES "${qpa_filter}")
|
||||
list(APPEND ${out_var}_qpa "${file_path}")
|
||||
elseif(rhi_filter AND file_name MATCHES "${rhi_filter}")
|
||||
@ -1553,6 +1691,7 @@ function(qt_internal_collect_module_headers out_var target)
|
||||
endforeach()
|
||||
set(${out_var}_all "${${out_var}_all}" PARENT_SCOPE)
|
||||
set(${out_var}_generated "${${out_var}_generated}" PARENT_SCOPE)
|
||||
set(${out_var}_exclude_from_docs "${${out_var}_exclude_from_docs}" PARENT_SCOPE)
|
||||
|
||||
if(has_header_types_properties)
|
||||
set_target_properties(${target} PROPERTIES ${has_header_types_properties})
|
||||
|
@ -2,15 +2,10 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# Find "ModuleTools" dependencies, which are other ModuleTools packages.
|
||||
set(@INSTALL_CMAKE_NAMESPACE@@target@_FOUND FALSE)
|
||||
set(__qt_@target@_tool_deps "@package_deps@")
|
||||
foreach(__qt_@target@_target_dep ${__qt_@target@_tool_deps})
|
||||
list(GET __qt_@target@_target_dep 0 __qt_@target@_pkg)
|
||||
list(GET __qt_@target@_target_dep 1 __qt_@target@_version)
|
||||
|
||||
if (NOT ${__qt_@target@_pkg}_FOUND)
|
||||
find_dependency(${__qt_@target@_pkg} ${__qt_@target@_version})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(@INSTALL_CMAKE_NAMESPACE@@target@_FOUND TRUE)
|
||||
|
||||
set(__qt_@target@_tool_third_party_deps "@third_party_deps@")
|
||||
_qt_internal_find_third_party_dependencies("@target@" __qt_@target@_tool_third_party_deps)
|
||||
|
||||
set(__qt_@target@_tool_deps "@package_deps@")
|
||||
_qt_internal_find_tool_dependencies("@target@" __qt_@target@_tool_deps)
|
||||
|
@ -22,8 +22,7 @@ endmacro()
|
||||
# Create a Qt6*.pc file intended for pkg-config consumption.
|
||||
function(qt_internal_generate_pkg_config_file module)
|
||||
# TODO: PkgConfig is supported under MSVC with pkgconf (github.com/pkgconf/pkgconf)
|
||||
if((NOT UNIX OR QT_FEATURE_framework)
|
||||
AND NOT MINGW OR CMAKE_VERSION VERSION_LESS "3.20" OR ANDROID)
|
||||
if(NOT UNIX AND NOT MINGW OR CMAKE_VERSION VERSION_LESS "3.20" OR ANDROID)
|
||||
return()
|
||||
endif()
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
@ -34,7 +33,6 @@ function(qt_internal_generate_pkg_config_file module)
|
||||
set(pkgconfig_name "${QT_CMAKE_EXPORT_NAMESPACE} ${module}")
|
||||
set(pkgconfig_description "Qt ${module} module")
|
||||
set(target "${QT_CMAKE_EXPORT_NAMESPACE}::${module}")
|
||||
set(is_interface_library "$<STREQUAL:$<TARGET_PROPERTY:${target},TYPE>,INTERFACE_LIBRARY>")
|
||||
# The flags macro expanded this variables so it's better to set them at
|
||||
# their corresponding PkgConfig string.
|
||||
set(includedir "\${includedir}")
|
||||
@ -50,6 +48,12 @@ function(qt_internal_generate_pkg_config_file module)
|
||||
get_target_property(loose_include_dirs ${target} INTERFACE_INCLUDE_DIRECTORIES)
|
||||
list(TRANSFORM loose_include_dirs REPLACE "${INSTALL_INCLUDEDIR}" "\${includedir}")
|
||||
list(TRANSFORM loose_include_dirs REPLACE "${INSTALL_MKSPECSDIR}" "\${mkspecsdir}")
|
||||
if(QT_FEATURE_framework)
|
||||
# Update the include path for framework headers which are located in INSTALL_LIBDIR,
|
||||
# e.g. this results in -I${libdir}/Qt*.framework/Headers for Qt6*.pc file.
|
||||
set(libdir "\${libdir}")
|
||||
list(TRANSFORM loose_include_dirs REPLACE "${INSTALL_LIBDIR}" "\${libdir}")
|
||||
endif()
|
||||
|
||||
# Remove genex wrapping around gc_sections flag because we can't evaluate genexes like
|
||||
# $<CXX_COMPILER_ID> in file(GENERATE). And given that .pc files don't support dynamic
|
||||
@ -69,6 +73,17 @@ function(qt_internal_generate_pkg_config_file module)
|
||||
set(contains_mkspecs TRUE)
|
||||
endif()
|
||||
|
||||
get_target_property(type ${target} TYPE)
|
||||
if(NOT type STREQUAL "INTERFACE_LIBRARY")
|
||||
get_target_property(is_framework ${target} FRAMEWORK)
|
||||
if(is_framework)
|
||||
qt_internal_get_framework_info(fw ${target})
|
||||
string(PREPEND link_options "-F\${libdir} -framework ${fw_name} ")
|
||||
else()
|
||||
string(PREPEND link_options "-L\${libdir} -l${pkgconfig_file} ")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# TODO: Handle macOS framework builds
|
||||
qt_internal_collect_direct_target_dependencies(${target} loose_target_requires)
|
||||
foreach(dep IN LISTS loose_target_requires)
|
||||
|
@ -23,37 +23,10 @@ if (NOT IS_DIRECTORY "${ANDROID_SDK_ROOT}")
|
||||
message(FATAL_ERROR "Could not find ANDROID_SDK_ROOT or path is not a directory: ${ANDROID_SDK_ROOT}")
|
||||
endif()
|
||||
|
||||
function(qt_internal_sort_android_platforms out_var)
|
||||
if(CMAKE_VERSION GREATER_EQUAL 3.18)
|
||||
set(platforms ${ARGN})
|
||||
list(SORT platforms COMPARE NATURAL)
|
||||
else()
|
||||
# Simulate natural sorting:
|
||||
# - prepend every platform with its version as three digits, zero-padded
|
||||
# - regular sort
|
||||
# - remove the padded version prefix
|
||||
set(platforms)
|
||||
foreach(platform IN LISTS ARGN)
|
||||
set(version "000")
|
||||
if(platform MATCHES ".*-([0-9]+)$")
|
||||
set(version ${CMAKE_MATCH_1})
|
||||
string(LENGTH "${version}" version_length)
|
||||
math(EXPR padding_length "3 - ${version_length}")
|
||||
string(REPEAT "0" ${padding_length} padding)
|
||||
string(PREPEND version ${padding})
|
||||
endif()
|
||||
list(APPEND platforms "${version}~${platform}")
|
||||
endforeach()
|
||||
list(SORT platforms)
|
||||
list(TRANSFORM platforms REPLACE "^.*~" "")
|
||||
endif()
|
||||
set("${out_var}" "${platforms}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# This variable specifies the API level used for building Java code, it can be the same as Qt for
|
||||
# Android's maximum supported Android version or higher.
|
||||
if(NOT QT_ANDROID_API_USED_FOR_JAVA)
|
||||
set(QT_ANDROID_API_USED_FOR_JAVA "android-34")
|
||||
set(QT_ANDROID_API_USED_FOR_JAVA "android-35")
|
||||
endif()
|
||||
|
||||
set(jar_location "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_USED_FOR_JAVA}/android.jar")
|
||||
@ -166,7 +139,7 @@ function(qt_internal_android_test_runner_arguments target out_test_runner out_te
|
||||
set(${out_test_runner} "${QT_HOST_PATH}/${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_BINDIR}/androidtestrunner" PARENT_SCOPE)
|
||||
set(deployment_tool "${QT_HOST_PATH}/${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_BINDIR}/androiddeployqt")
|
||||
|
||||
qt_internal_android_get_target_android_build_dir(${target} android_build_dir)
|
||||
_qt_internal_android_get_target_android_build_dir(android_build_dir ${target})
|
||||
set(${out_test_arguments}
|
||||
"--path" "${android_build_dir}"
|
||||
"--adb" "${ANDROID_SDK_ROOT}/platform-tools/adb"
|
||||
|
@ -29,8 +29,12 @@ if (NOT QT_NO_CREATE_TARGETS)
|
||||
# Find required dependencies, if any.
|
||||
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake")
|
||||
else()
|
||||
set(@target@_FOUND TRUE)
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake")
|
||||
if(@target@_FOUND)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake")
|
||||
endif()
|
||||
endif()
|
||||
|
@ -1,11 +1,12 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
set(@target@_FOUND FALSE)
|
||||
set(@target@_FOUND TRUE)
|
||||
|
||||
# note: _third_party_deps example: "ICU\\;FALSE\\;1.0\\;i18n uc data;ZLIB\\;FALSE\\;\\;"
|
||||
set(__qt_@target@_third_party_deps "@third_party_deps@")
|
||||
_qt_internal_find_third_party_dependencies("@target@" __qt_@target@_third_party_deps)
|
||||
unset(__qt_@target@_third_party_deps)
|
||||
|
||||
set(__qt_use_no_default_path_for_qt_packages "NO_DEFAULT_PATH")
|
||||
if(QT_DISABLE_NO_DEFAULT_PATH_IN_QT_PACKAGES)
|
||||
@ -17,5 +18,9 @@ set(__qt_@target@_target_deps "@target_deps@")
|
||||
set(__qt_@target@_find_dependency_paths "@find_dependency_paths@")
|
||||
_qt_internal_find_qt_dependencies("@target@" __qt_@target@_target_deps
|
||||
__qt_@target@_find_dependency_paths)
|
||||
unset(__qt_@target@_target_deps)
|
||||
unset(__qt_@target@_find_dependency_paths)
|
||||
|
||||
set(@target@_FOUND TRUE)
|
||||
if(__qt_${target}_missing_deps)
|
||||
set(@target@_FOUND FALSE)
|
||||
endif()
|
||||
|
@ -208,10 +208,7 @@ function(qt_internal_add_plugin target)
|
||||
set(plugin_install_package_suffix "${qt_module}")
|
||||
|
||||
|
||||
get_target_property(aliased_target ${qt_module_target} ALIASED_TARGET)
|
||||
if(aliased_target)
|
||||
set(qt_module_target ${aliased_target})
|
||||
endif()
|
||||
_qt_internal_dealias_target(qt_module_target)
|
||||
get_target_property(is_imported_qt_module ${qt_module_target} IMPORTED)
|
||||
|
||||
if(NOT is_imported_qt_module)
|
||||
@ -229,8 +226,6 @@ function(qt_internal_add_plugin target)
|
||||
__qt_internal_add_interface_plugin_target(${qt_module_target} ${target})
|
||||
endif()
|
||||
|
||||
set(plugin_target_versioned "${QT_CMAKE_EXPORT_NAMESPACE}::${target}")
|
||||
get_target_property(type "${plugin_target_versioned}" TYPE)
|
||||
qt_internal_add_autogen_sync_header_dependencies(${target} ${qt_module_target})
|
||||
endif()
|
||||
|
||||
@ -322,7 +317,7 @@ function(qt_internal_add_plugin target)
|
||||
|
||||
qt_internal_add_repo_local_defines("${target}")
|
||||
|
||||
if(NOT DEFINED arg_EXCEPTIONS)
|
||||
if(NOT arg_EXCEPTIONS)
|
||||
qt_internal_set_exceptions_flags("${target}" "DEFAULT")
|
||||
else()
|
||||
qt_internal_set_exceptions_flags("${target}" "${arg_EXCEPTIONS}")
|
||||
@ -337,7 +332,15 @@ function(qt_internal_add_plugin target)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
qt_register_target_dependencies("${target}" "${arg_PUBLIC_LIBRARIES}" "${qt_libs_private}")
|
||||
set(qt_register_target_dependencies_args "")
|
||||
if(arg_PUBLIC_LIBRARIES)
|
||||
list(APPEND qt_register_target_dependencies_args PUBLIC ${arg_PUBLIC_LIBRARIES})
|
||||
endif()
|
||||
if(qt_libs_private)
|
||||
list(APPEND qt_register_target_dependencies_args PRIVATE ${qt_libs_private})
|
||||
endif()
|
||||
qt_internal_register_target_dependencies("${target}"
|
||||
${qt_register_target_dependencies_args})
|
||||
|
||||
if(target_type STREQUAL STATIC_LIBRARY)
|
||||
if(qt_module_target)
|
||||
@ -373,8 +376,8 @@ function(qt_internal_add_plugin target)
|
||||
# when building standalone tests.
|
||||
if(QT_INTERNAL_CONFIGURING_TESTS OR arg_TEST_PLUGIN)
|
||||
if(NOT arg_TEST_PLUGIN)
|
||||
message(WARNING "The installable test plugin ${target} is built as part of test"
|
||||
" suite, but is not marked as TEST_PLUGIN using the repsective argument."
|
||||
message(WARNING "The installable test plugin ${target} is built as part of a test"
|
||||
" suite, but is not marked as TEST_PLUGIN using the respective argument."
|
||||
"\nThis warning will soon become an error."
|
||||
)
|
||||
endif()
|
||||
@ -470,7 +473,7 @@ endif()"
|
||||
${__qt_internal_sbom_multi_args}
|
||||
)
|
||||
|
||||
_qt_internal_extend_sbom(${target} ${sbom_args})
|
||||
qt_internal_extend_qt_entity_sbom(${target} ${sbom_args})
|
||||
endif()
|
||||
|
||||
qt_add_list_file_finalizer(qt_finalize_plugin ${target} ${finalizer_extra_args})
|
||||
|
@ -29,7 +29,7 @@ macro(qt_collect_third_party_deps target)
|
||||
endif()
|
||||
unset(_target_is_static)
|
||||
|
||||
foreach(dep ${${depends_var}} ${optional_public_depends} ${extra_third_party_deps})
|
||||
foreach(dep ${${depends_var}} ${extra_third_party_deps})
|
||||
# Gather third party packages that should be found when using the Qt module.
|
||||
# Also handle nolink target dependencies.
|
||||
string(REGEX REPLACE "_nolink$" "" base_dep "${dep}")
|
||||
@ -48,9 +48,6 @@ macro(qt_collect_third_party_deps target)
|
||||
if(dep_seen EQUAL -1 AND package_name)
|
||||
list(APPEND third_party_deps_seen ${dep})
|
||||
get_target_property(package_is_optional ${dep} INTERFACE_QT_PACKAGE_IS_OPTIONAL)
|
||||
if(NOT package_is_optional AND dep IN_LIST optional_public_depends)
|
||||
set(package_is_optional TRUE)
|
||||
endif()
|
||||
get_target_property(package_version ${dep} INTERFACE_QT_PACKAGE_VERSION)
|
||||
if(NOT package_version)
|
||||
set(package_version "")
|
||||
@ -143,6 +140,13 @@ function(qt_internal_remove_qt_dependency_duplicates out_deps deps)
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_create_module_depends_file target)
|
||||
set(no_value_options "")
|
||||
set(single_value_options "")
|
||||
set(multi_value_options "")
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg
|
||||
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
|
||||
)
|
||||
|
||||
get_target_property(target_type "${target}" TYPE)
|
||||
set(is_interface_lib FALSE)
|
||||
if(target_type STREQUAL "INTERFACE_LIBRARY")
|
||||
@ -156,11 +160,6 @@ function(qt_internal_create_module_depends_file target)
|
||||
|
||||
get_target_property(public_depends "${target}" INTERFACE_LINK_LIBRARIES)
|
||||
|
||||
unset(optional_public_depends)
|
||||
if(TARGET "${target}Private")
|
||||
get_target_property(optional_public_depends "${target}Private" INTERFACE_LINK_LIBRARIES)
|
||||
endif()
|
||||
|
||||
# Used for collecting Qt module dependencies that should be find_package()'d in
|
||||
# ModuleDependencies.cmake.
|
||||
get_target_property(target_deps "${target}" _qt_target_deps)
|
||||
@ -168,8 +167,11 @@ function(qt_internal_create_module_depends_file target)
|
||||
set(qt_module_dependencies "")
|
||||
|
||||
if(NOT is_interface_lib)
|
||||
# TODO: deprecated code path. QT_EXTRA_PACKAGE_DEPENDENCIES shouldn't be used for the Qt
|
||||
# packages.
|
||||
get_target_property(extra_depends "${target}" QT_EXTRA_PACKAGE_DEPENDENCIES)
|
||||
endif()
|
||||
|
||||
if(NOT extra_depends MATCHES "-NOTFOUND$")
|
||||
list(APPEND target_deps "${extra_depends}")
|
||||
endif()
|
||||
@ -337,7 +339,6 @@ function(qt_internal_create_plugin_depends_file target)
|
||||
get_target_property(depends "${target}" LINK_LIBRARIES)
|
||||
get_target_property(public_depends "${target}" INTERFACE_LINK_LIBRARIES)
|
||||
get_target_property(target_deps "${target}" _qt_target_deps)
|
||||
unset(optional_public_depends)
|
||||
set(target_deps_seen "")
|
||||
|
||||
|
||||
@ -398,7 +399,6 @@ function(qt_internal_create_qt6_dependencies_file)
|
||||
set(actual_target Platform)
|
||||
get_target_property(public_depends "${actual_target}" INTERFACE_LINK_LIBRARIES)
|
||||
unset(depends)
|
||||
unset(optional_public_depends)
|
||||
|
||||
set(third_party_deps "")
|
||||
set(third_party_deps_seen "")
|
||||
@ -432,7 +432,7 @@ endif()")
|
||||
# to the target CMAKE_INSTALL_DIR, if at all possible to do so in a reliable way.
|
||||
get_filename_component(qt_host_path_absolute "${QT_HOST_PATH}" ABSOLUTE)
|
||||
get_filename_component(qt_host_path_cmake_dir_absolute
|
||||
"${Qt${PROJECT_VERSION_MAJOR}HostInfo_DIR}/.." ABSOLUTE)
|
||||
"${${INSTALL_CMAKE_NAMESPACE}HostInfo_DIR}/.." ABSOLUTE)
|
||||
endif()
|
||||
|
||||
if(third_party_deps OR platform_requires_host_info_package)
|
||||
@ -467,6 +467,9 @@ function(qt_internal_create_depends_files)
|
||||
|
||||
foreach (target ${repo_known_modules})
|
||||
qt_internal_create_module_depends_file(${target})
|
||||
if(TARGET "${target}Private")
|
||||
qt_internal_create_module_depends_file(${target}Private)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach (target ${QT_KNOWN_PLUGINS})
|
||||
@ -494,67 +497,8 @@ function(qt_internal_create_plugins_auto_inclusion_files)
|
||||
|
||||
if(QT_MODULE STREQUAL "Qml")
|
||||
set(QT_MODULE_PLUGIN_INCLUDES "${QT_MODULE_PLUGIN_INCLUDES}
|
||||
# Qml plugin targets might have dependencies on other qml plugin targets, but the Targets.cmake
|
||||
# files are included in the order that file(GLOB) returns, which means certain targets that are
|
||||
# referenced might not have been created yet, and \${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE
|
||||
# might be set to a message saying those targets don't exist.
|
||||
#
|
||||
# Postpone checking of which targets don't exist until all Qml PluginConfig.cmake files have been
|
||||
# included, by including all the files one more time and checking for errors at each step.
|
||||
#
|
||||
# TODO: Find a better way to deal with this, perhaps by using find_package() instead of include
|
||||
# for the Qml PluginConfig.cmake files.
|
||||
|
||||
# Distributions should probably change this default.
|
||||
if(NOT DEFINED QT_SKIP_AUTO_QML_PLUGIN_INCLUSION)
|
||||
set(QT_SKIP_AUTO_QML_PLUGIN_INCLUSION OFF)
|
||||
endif()
|
||||
|
||||
set(__qt_qml_plugins_config_file_list \"\")
|
||||
set(__qt_qml_plugins_glob_prefixes \"\${CMAKE_CURRENT_LIST_DIR}\")
|
||||
|
||||
# Allow passing additional prefixes where we will glob for PluginConfig.cmake files.
|
||||
if(QT_ADDITIONAL_QML_PLUGIN_GLOB_PREFIXES)
|
||||
foreach(__qt_qml_plugin_glob_prefix IN LISTS QT_ADDITIONAL_QML_PLUGIN_GLOB_PREFIXES)
|
||||
if(__qt_qml_plugin_glob_prefix)
|
||||
list(APPEND __qt_qml_plugins_glob_prefixes \"\${__qt_qml_plugin_glob_prefix}\")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
list(REMOVE_DUPLICATES __qt_qml_plugins_glob_prefixes)
|
||||
|
||||
foreach(__qt_qml_plugin_glob_prefix IN LISTS __qt_qml_plugins_glob_prefixes)
|
||||
file(GLOB __qt_qml_plugins_glob_config_file_list
|
||||
\"\${__qt_qml_plugin_glob_prefix}/QmlPlugins/${INSTALL_CMAKE_NAMESPACE}*Config.cmake\")
|
||||
if(__qt_qml_plugins_glob_config_file_list)
|
||||
list(APPEND __qt_qml_plugins_config_file_list \${__qt_qml_plugins_glob_config_file_list})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (__qt_qml_plugins_config_file_list AND NOT QT_SKIP_AUTO_QML_PLUGIN_INCLUSION)
|
||||
# First round of inclusions ensure all qml plugin targets are brought into scope.
|
||||
foreach(__qt_qml_plugin_config_file \${__qt_qml_plugins_config_file_list})
|
||||
include(\${__qt_qml_plugin_config_file})
|
||||
|
||||
# Temporarily unset any failure markers and mark the Qml package as found.
|
||||
unset(\${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE)
|
||||
set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND TRUE)
|
||||
endforeach()
|
||||
|
||||
# For the second round of inclusions, check and bail out early if there are errors.
|
||||
foreach(__qt_qml_plugin_config_file \${__qt_qml_plugins_config_file_list})
|
||||
include(\${__qt_qml_plugin_config_file})
|
||||
|
||||
if(\${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE)
|
||||
string(APPEND \${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE
|
||||
\"\nThe message was set in \${__qt_qml_plugin_config_file} \")
|
||||
set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
|
||||
return()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
endif()")
|
||||
__qt_internal_include_qml_plugin_packages()
|
||||
")
|
||||
endif()
|
||||
|
||||
get_target_property(module_plugin_types "${QT_MODULE}" MODULE_PLUGIN_TYPES)
|
||||
@ -584,6 +528,11 @@ function(qt_generate_install_prefixes out_var)
|
||||
INSTALL_PLUGINSDIR INSTALL_LIBEXECDIR INSTALL_QMLDIR INSTALL_DATADIR INSTALL_DOCDIR
|
||||
INSTALL_TRANSLATIONSDIR INSTALL_SYSCONFDIR INSTALL_EXAMPLESDIR INSTALL_TESTSDIR
|
||||
INSTALL_DESCRIPTIONSDIR INSTALL_SBOMDIR)
|
||||
# INSTALL_PUBLICBINDIR is processed only if it is not empty
|
||||
# See usage in qt_internal_generate_user_facing_tools_info
|
||||
if(NOT "${INSTALL_PUBLICBINDIR}" STREQUAL "")
|
||||
list(APPEND vars INSTALL_PUBLICBINDIR)
|
||||
endif()
|
||||
|
||||
foreach(var ${vars})
|
||||
get_property(docstring CACHE "${var}" PROPERTY HELPSTRING)
|
||||
@ -617,7 +566,15 @@ function(qt_create_hostinfo_package)
|
||||
INSTALL_DESTINATION "${install_destination}"
|
||||
NO_SET_AND_CHECK_MACRO
|
||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO)
|
||||
qt_install(FILES "${config_file_path}" DESTINATION "${install_destination}")
|
||||
|
||||
set(version_file "${QT_CONFIG_BUILD_DIR}/${package}/${package}ConfigVersion.cmake")
|
||||
write_basic_package_version_file(
|
||||
"${version_file}"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
ARCH_INDEPENDENT
|
||||
)
|
||||
qt_install(FILES "${config_file_path}" "${version_file}" DESTINATION "${install_destination}")
|
||||
endfunction()
|
||||
|
||||
function(qt_generate_build_internals_extra_cmake_code)
|
||||
@ -921,6 +878,7 @@ function(qt_internal_generate_user_facing_tools_info)
|
||||
if("${INSTALL_PUBLICBINDIR}" STREQUAL "")
|
||||
return()
|
||||
endif()
|
||||
qt_path_join(tool_link_base_dir "${CMAKE_INSTALL_PREFIX}" "${INSTALL_PUBLICBINDIR}")
|
||||
get_property(user_facing_tool_targets GLOBAL PROPERTY QT_USER_FACING_TOOL_TARGETS)
|
||||
set(lines "")
|
||||
foreach(target ${user_facing_tool_targets})
|
||||
@ -937,6 +895,7 @@ function(qt_internal_generate_user_facing_tools_info)
|
||||
endif()
|
||||
qt_path_join(tool_target_path "${CMAKE_INSTALL_PREFIX}" "${INSTALL_BINDIR}" "${filename}")
|
||||
qt_path_join(tool_link_path "${INSTALL_PUBLICBINDIR}" "${linkname}${PROJECT_VERSION_MAJOR}")
|
||||
_qt_internal_relative_path(tool_target_path BASE_DIRECTORY ${tool_link_base_dir})
|
||||
list(APPEND lines "${tool_target_path} ${tool_link_path}")
|
||||
endforeach()
|
||||
string(REPLACE ";" "\n" content "${lines}")
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
function(qt_update_precompiled_header target precompiled_header)
|
||||
if (precompiled_header AND BUILD_WITH_PCH)
|
||||
set_property(TARGET "${target}" APPEND PROPERTY "PRECOMPILE_HEADERS" "$<$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:OBJCXX>>:${precompiled_header}>")
|
||||
set_property(TARGET "${target}" APPEND PROPERTY "PRECOMPILE_HEADERS" "$<$<COMPILE_LANGUAGE:CXX,OBJCXX>:${precompiled_header}>")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
@ -871,29 +871,27 @@ function(guess_compiler_from_mkspec)
|
||||
|
||||
check_whether_to_guess_compiler(guess_c_compiler CC CMAKE_C_COMPILER)
|
||||
check_whether_to_guess_compiler(guess_cxx_compiler CXX CMAKE_CXX_COMPILER)
|
||||
if(NOT guess_c_compiler AND NOT guess_cxx_compiler)
|
||||
return()
|
||||
endif()
|
||||
|
||||
string(REGEX MATCH "(^|;)-DQT_QMAKE_TARGET_MKSPEC=\([^;]+\)" m "${cmake_args}")
|
||||
set(mkspec ${CMAKE_MATCH_2})
|
||||
set(c_compiler "")
|
||||
set(cxx_compiler "")
|
||||
if(mkspec MATCHES "-clang-msvc$")
|
||||
set(c_compiler "clang-cl")
|
||||
set(cxx_compiler "clang-cl")
|
||||
elseif(mkspec MATCHES "-clang(-|$)" AND NOT mkspec MATCHES "android")
|
||||
set(c_compiler "clang")
|
||||
set(cxx_compiler "clang++")
|
||||
elseif(mkspec MATCHES "-msvc(-|$)")
|
||||
set(c_compiler "cl")
|
||||
set(cxx_compiler "cl")
|
||||
endif()
|
||||
if(guess_c_compiler AND NOT c_compiler STREQUAL "")
|
||||
push("-DCMAKE_C_COMPILER=${c_compiler}")
|
||||
endif()
|
||||
if(guess_cxx_compiler AND NOT cxx_compiler STREQUAL "")
|
||||
push("-DCMAKE_CXX_COMPILER=${cxx_compiler}")
|
||||
if(guess_c_compiler OR guess_cxx_compiler)
|
||||
set(c_compiler "")
|
||||
set(cxx_compiler "")
|
||||
if(mkspec MATCHES "-clang-msvc$")
|
||||
set(c_compiler "clang-cl")
|
||||
set(cxx_compiler "clang-cl")
|
||||
elseif(mkspec MATCHES "-clang(-|$)" AND NOT mkspec MATCHES "android")
|
||||
set(c_compiler "clang")
|
||||
set(cxx_compiler "clang++")
|
||||
elseif(mkspec MATCHES "-msvc(-|$)")
|
||||
set(c_compiler "cl")
|
||||
set(cxx_compiler "cl")
|
||||
endif()
|
||||
if(guess_c_compiler AND NOT c_compiler STREQUAL "")
|
||||
push("-DCMAKE_C_COMPILER=${c_compiler}")
|
||||
endif()
|
||||
if(guess_cxx_compiler AND NOT cxx_compiler STREQUAL "")
|
||||
push("-DCMAKE_CXX_COMPILER=${cxx_compiler}")
|
||||
endif()
|
||||
endif()
|
||||
if(mkspec MATCHES "-libc\\+\\+$")
|
||||
push("-DFEATURE_stdlib_libcpp=ON")
|
||||
|
@ -10,7 +10,7 @@ function(_qt_internal_detect_latest_android_platform out_var)
|
||||
|
||||
# If list is not empty
|
||||
if(android_platforms)
|
||||
qt_internal_sort_android_platforms(android_platforms ${android_platforms})
|
||||
_qt_internal_sort_android_platforms(android_platforms ${android_platforms})
|
||||
list(REVERSE android_platforms)
|
||||
list(GET android_platforms 0 android_platform_latest)
|
||||
set(${out_var} "${android_platform_latest}" PARENT_SCOPE)
|
||||
@ -18,3 +18,30 @@ function(_qt_internal_detect_latest_android_platform out_var)
|
||||
set(${out_var} "${out_var}-NOTFOUND" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(_qt_internal_sort_android_platforms out_var)
|
||||
if(CMAKE_VERSION GREATER_EQUAL 3.18)
|
||||
set(platforms ${ARGN})
|
||||
list(SORT platforms COMPARE NATURAL)
|
||||
else()
|
||||
# Simulate natural sorting:
|
||||
# - prepend every platform with its version as three digits, zero-padded
|
||||
# - regular sort
|
||||
# - remove the padded version prefix
|
||||
set(platforms)
|
||||
foreach(platform IN LISTS ARGN)
|
||||
set(version "000")
|
||||
if(platform MATCHES ".*-([0-9]+)$")
|
||||
set(version ${CMAKE_MATCH_1})
|
||||
string(LENGTH "${version}" version_length)
|
||||
math(EXPR padding_length "3 - ${version_length}")
|
||||
string(REPEAT "0" ${padding_length} padding)
|
||||
string(PREPEND version ${padding})
|
||||
endif()
|
||||
list(APPEND platforms "${version}~${platform}")
|
||||
endforeach()
|
||||
list(SORT platforms)
|
||||
list(TRANSFORM platforms REPLACE "^.*~" "")
|
||||
endif()
|
||||
set("${out_var}" "${platforms}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
@ -97,9 +97,9 @@ function(_qt_internal_handle_ios_launch_screen target)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(_qt_internal_find_ios_development_team_id out_var)
|
||||
function(_qt_internal_find_apple_development_team_id out_var)
|
||||
get_property(team_id GLOBAL PROPERTY _qt_internal_ios_development_team_id)
|
||||
get_property(team_id_computed GLOBAL PROPERTY _qt_internal_ios_development_team_id_computed)
|
||||
get_property(team_id_computed GLOBAL PROPERTY _qt_internal_apple_development_team_id_computed)
|
||||
if(team_id_computed)
|
||||
# Just in case if the value is non-empty but still booly FALSE.
|
||||
if(NOT team_id)
|
||||
@ -109,17 +109,31 @@ function(_qt_internal_find_ios_development_team_id out_var)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set_property(GLOBAL PROPERTY _qt_internal_ios_development_team_id_computed "TRUE")
|
||||
set_property(GLOBAL PROPERTY _qt_internal_apple_development_team_id_computed "TRUE")
|
||||
|
||||
set(home_dir "$ENV{HOME}")
|
||||
set(xcode_preferences_path "${home_dir}/Library/Preferences/com.apple.dt.Xcode.plist")
|
||||
|
||||
# Extract the first account name (email) from the user's Xcode preferences
|
||||
message(DEBUG "Trying to extract an Xcode development team id from '${xcode_preferences_path}'")
|
||||
execute_process(COMMAND "/usr/libexec/PlistBuddy"
|
||||
-x -c "print IDEProvisioningTeams" "${xcode_preferences_path}"
|
||||
OUTPUT_VARIABLE teams_xml
|
||||
ERROR_VARIABLE plist_error)
|
||||
|
||||
# Try Xcode 16.2 format first
|
||||
_qt_internal_plist_buddy("${xcode_preferences_path}"
|
||||
COMMANDS "print IDEProvisioningTeamByIdentifier"
|
||||
EXTRA_ARGS -x
|
||||
OUTPUT_VARIABLE teams_xml
|
||||
ERROR_VARIABLE plist_error
|
||||
)
|
||||
|
||||
# Then fall back to older format
|
||||
if(plist_error OR NOT teams_xml)
|
||||
_qt_internal_plist_buddy("${xcode_preferences_path}"
|
||||
COMMANDS "print IDEProvisioningTeams"
|
||||
EXTRA_ARGS -x
|
||||
OUTPUT_VARIABLE teams_xml
|
||||
ERROR_VARIABLE plist_error
|
||||
)
|
||||
endif()
|
||||
|
||||
# Parsing state.
|
||||
set(is_free "")
|
||||
@ -152,6 +166,16 @@ function(_qt_internal_find_ios_development_team_id out_var)
|
||||
# ...
|
||||
# </dict>
|
||||
# </array>
|
||||
# <key>AAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE</key>
|
||||
# <array>
|
||||
# <dict>
|
||||
# <key>isFreeProvisioningTeam</key>
|
||||
# <false/>
|
||||
# <key>teamID</key>
|
||||
# <string>CCC</string>
|
||||
# ...
|
||||
# </dict>
|
||||
# </array>
|
||||
#</dict>
|
||||
#</plist>
|
||||
if(teams_xml AND NOT plist_error)
|
||||
@ -270,7 +294,7 @@ function(_qt_internal_get_default_apple_bundle_identifier target out_var)
|
||||
|
||||
# For a better out-of-the-box experience, try to create a unique prefix by appending
|
||||
# the sha1 of the team id, if one is found.
|
||||
_qt_internal_find_ios_development_team_id(team_id)
|
||||
_qt_internal_find_apple_development_team_id(team_id)
|
||||
if(team_id)
|
||||
string(SHA1 hash "${team_id}")
|
||||
string(SUBSTRING "${hash}" 0 8 infix)
|
||||
@ -378,7 +402,7 @@ function(_qt_internal_set_xcode_development_team_id target)
|
||||
if(NOT CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM AND NOT QT_NO_SET_XCODE_DEVELOPMENT_TEAM_ID)
|
||||
get_target_property(existing_team_id "${target}" XCODE_ATTRIBUTE_DEVELOPMENT_TEAM)
|
||||
if(NOT existing_team_id)
|
||||
_qt_internal_find_ios_development_team_id(team_id)
|
||||
_qt_internal_find_apple_development_team_id(team_id)
|
||||
set_target_properties("${target}"
|
||||
PROPERTIES XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${team_id}")
|
||||
endif()
|
||||
@ -635,10 +659,10 @@ endfunction()
|
||||
|
||||
function(_qt_internal_plist_buddy plist_file)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg
|
||||
"" "OUTPUT_VARIABLE;ERROR_VARIABLE" "COMMANDS")
|
||||
"" "OUTPUT_VARIABLE;ERROR_VARIABLE;EXTRA_ARGS" "COMMANDS")
|
||||
foreach(command ${arg_COMMANDS})
|
||||
execute_process(COMMAND "/usr/libexec/PlistBuddy"
|
||||
-c "${command}" "${plist_file}"
|
||||
${arg_EXTRA_ARGS} -c "${command}" "${plist_file}"
|
||||
OUTPUT_VARIABLE plist_buddy_output
|
||||
ERROR_VARIABLE plist_buddy_error)
|
||||
string(STRIP "${plist_buddy_output}" plist_buddy_output)
|
||||
@ -730,6 +754,25 @@ function(_qt_internal_set_ios_simulator_arch target)
|
||||
"x86_64")
|
||||
endfunction()
|
||||
|
||||
function(_qt_internal_set_xcode_entrypoint_attribute target entrypoint)
|
||||
if(CMAKE_XCODE_ATTRIBUTE_LD_ENTRY_POINT
|
||||
OR QT_NO_SET_XCODE_LD_ENTRY_POINT)
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_target_property(existing_entrypoint
|
||||
"${target}" XCODE_ATTRIBUTE_LD_ENTRY_POINT)
|
||||
if(NOT existing_entrypoint MATCHES "-NOTFOUND")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set_target_properties("${target}"
|
||||
PROPERTIES
|
||||
"XCODE_ATTRIBUTE_LD_ENTRY_POINT"
|
||||
"${entrypoint}")
|
||||
endfunction()
|
||||
|
||||
|
||||
# Export Apple platform sdk and xcode version requirements to Qt6ConfigExtras.cmake.
|
||||
# Always exported, even on non-Apple platforms, so that we can use them when building
|
||||
# documentation.
|
||||
@ -768,7 +811,8 @@ endif()")
|
||||
set(${out_var} "${assignments}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_qt_internal_get_apple_sdk_version out_var)
|
||||
function(_qt_internal_get_apple_sdk_name out_var)
|
||||
set(sdk_name "")
|
||||
if(APPLE)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL iOS)
|
||||
set(sdk_name "iphoneos")
|
||||
@ -778,28 +822,99 @@ function(_qt_internal_get_apple_sdk_version out_var)
|
||||
# Default to macOS
|
||||
set(sdk_name "macosx")
|
||||
endif()
|
||||
set(xcrun_version_arg "--show-sdk-version")
|
||||
execute_process(COMMAND /usr/bin/xcrun --sdk ${sdk_name} ${xcrun_version_arg}
|
||||
OUTPUT_VARIABLE sdk_version
|
||||
ERROR_VARIABLE xcrun_error)
|
||||
endif()
|
||||
set(${out_var} "${sdk_name}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_qt_internal_execute_xcrun out_var)
|
||||
set(opt_args "")
|
||||
set(single_args "")
|
||||
set(multi_args
|
||||
XCRUN_ARGS
|
||||
OUT_ERROR_VAR
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
|
||||
set(output "")
|
||||
set(xcrun_error "")
|
||||
|
||||
if(NOT APPLE)
|
||||
message(FATAL_ERROR
|
||||
"Executing xcrun should only happen happen when targeting Apple plaforms")
|
||||
endif()
|
||||
|
||||
find_program(QT_XCRUN xcrun)
|
||||
if(NOT QT_XCRUN)
|
||||
message(FATAL_ERROR "Can't find xcrun in PATH")
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND "${QT_XCRUN}" ${arg_XCRUN_ARGS}
|
||||
OUTPUT_VARIABLE output
|
||||
ERROR_VARIABLE xcrun_error)
|
||||
|
||||
if(arg_OUT_ERROR_VAR)
|
||||
set(${arg_OUT_ERROR_VAR} "${xcrun_error}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
set(${out_var} "${output}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_qt_internal_get_apple_sdk_path out_var)
|
||||
set(sdk_path "")
|
||||
if(APPLE)
|
||||
_qt_internal_get_apple_sdk_name(sdk_name)
|
||||
_qt_internal_execute_xcrun(sdk_path
|
||||
XCRUN_ARGS --sdk ${sdk_name} --show-sdk-path
|
||||
OUT_ERROR_VAR xcrun_error
|
||||
)
|
||||
|
||||
if(NOT sdk_path)
|
||||
message(FATAL_ERROR
|
||||
"Can't determine darwin ${sdk_name} SDK path. Error: ${xcrun_error}")
|
||||
endif()
|
||||
|
||||
string(STRIP "${sdk_path}" sdk_path)
|
||||
endif()
|
||||
set(${out_var} "${sdk_path}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_qt_internal_get_apple_sdk_version out_var)
|
||||
set(sdk_version "")
|
||||
if(APPLE)
|
||||
_qt_internal_get_apple_sdk_name(sdk_name)
|
||||
_qt_internal_execute_xcrun(sdk_version
|
||||
XCRUN_ARGS --sdk ${sdk_name} --show-sdk-version
|
||||
OUT_ERROR_VAR xcrun_error
|
||||
)
|
||||
|
||||
if(NOT sdk_version)
|
||||
message(FATAL_ERROR
|
||||
"Can't determine darwin ${sdk_name} SDK version. Error: ${xcrun_error}")
|
||||
endif()
|
||||
|
||||
string(STRIP "${sdk_version}" sdk_version)
|
||||
set(${out_var} "${sdk_version}" PARENT_SCOPE)
|
||||
endif()
|
||||
set(${out_var} "${sdk_version}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_qt_internal_get_xcode_version_raw out_var)
|
||||
set(xcode_version "")
|
||||
if(APPLE)
|
||||
execute_process(COMMAND /usr/bin/xcrun xcodebuild -version
|
||||
OUTPUT_VARIABLE xcode_version
|
||||
ERROR_VARIABLE xcrun_error)
|
||||
_qt_internal_execute_xcrun(xcode_version
|
||||
XCRUN_ARGS xcodebuild -version
|
||||
OUT_ERROR_VAR xcrun_error
|
||||
)
|
||||
|
||||
string(REPLACE "\n" " " xcode_version "${xcode_version}")
|
||||
string(STRIP "${xcode_version}" xcode_version)
|
||||
set(${out_var} "${xcode_version}" PARENT_SCOPE)
|
||||
|
||||
if(NOT xcode_version)
|
||||
message(FATAL_ERROR
|
||||
"Can't determine Xcode version. Is Xcode installed?"
|
||||
" Error details:\n${xcrun_error}")
|
||||
endif()
|
||||
endif()
|
||||
set(${out_var} "${xcode_version}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_qt_internal_get_xcode_version out_var)
|
||||
@ -844,9 +959,9 @@ function(_qt_internal_get_cached_xcode_version out_var)
|
||||
set(${out_var} "${xcode_version}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Warn when the platform SDK or Xcode version are not supported.
|
||||
# Warn or error out when the platform SDK or Xcode version are not supported.
|
||||
#
|
||||
# The warnings are currently only shown when building Qt, not when building user projects
|
||||
# The messages are currently only shown when building Qt, not when building user projects
|
||||
# with CMake.
|
||||
# The warnings ARE shown for qmake user projects.
|
||||
#
|
||||
@ -891,11 +1006,14 @@ function(_qt_internal_check_apple_sdk_and_xcode_versions)
|
||||
endif()
|
||||
|
||||
# The default differs in different branches.
|
||||
set(failed_check_should_error FALSE)
|
||||
set(failed_check_should_error TRUE)
|
||||
|
||||
if(failed_check_should_error)
|
||||
# Allow downgrading the error into a warning.
|
||||
if(QT_FORCE_WARN_APPLE_SDK_AND_XCODE_CHECK)
|
||||
#
|
||||
# Our cmake build tests might be executed on older not officially supported Xcode or SDK
|
||||
# versions in the CI. Downgrade the error in this case as well.
|
||||
if(QT_FORCE_WARN_APPLE_SDK_AND_XCODE_CHECK OR QT_INTERNAL_IS_CMAKE_BUILD_TEST)
|
||||
set(message_type WARNING)
|
||||
set(extra_message " Due to QT_FORCE_WARN_APPLE_SDK_AND_XCODE_CHECK being ON "
|
||||
"the build will continue, but it will likely fail. Use at your own risk.")
|
||||
@ -995,6 +1113,8 @@ function(_qt_internal_finalize_ios_app target)
|
||||
_qt_internal_set_xcode_targeted_device_family("${target}")
|
||||
_qt_internal_set_xcode_bitcode_enablement("${target}")
|
||||
_qt_internal_set_ios_simulator_arch("${target}")
|
||||
|
||||
_qt_internal_set_xcode_entrypoint_attribute("${target}" "_qt_main_wrapper")
|
||||
endfunction()
|
||||
|
||||
function(_qt_internal_finalize_macos_app target)
|
||||
|
@ -536,8 +536,14 @@ endfunction()
|
||||
|
||||
# Takes a list of path components and joins them into one path separated by forward slashes "/",
|
||||
# and saves the path in out_var.
|
||||
# Filters out any path parts that are bare "."s.
|
||||
function(_qt_internal_path_join out_var)
|
||||
string(JOIN "/" path ${ARGN})
|
||||
set(args ${ARGN})
|
||||
|
||||
# Remove any bare ".", to avoid any CMP0177 warnings for paths passed to install().
|
||||
list(REMOVE_ITEM args ".")
|
||||
|
||||
string(JOIN "/" path ${args})
|
||||
set(${out_var} ${path} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@ -597,6 +603,45 @@ function(_qt_internal_remove_args out_var)
|
||||
set(${out_var} "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(__qt_internal_handle_find_all_qt_module_packages out_var)
|
||||
set(opt_args "")
|
||||
set(single_args "")
|
||||
set(multi_args
|
||||
COMPONENTS
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(NOT arg_COMPONENTS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(components ${arg_COMPONENTS})
|
||||
|
||||
if("ALL_QT_MODULES" IN_LIST components)
|
||||
list(FIND components "ALL_QT_MODULES" all_qt_modules_index)
|
||||
list(REMOVE_AT components ${all_qt_modules_index})
|
||||
|
||||
# Find the path to dir with module.json files. # We consider each file name to be a
|
||||
# Qt package (component) name that contains a target with the same name.
|
||||
set(json_modules_path "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_DESCRIPTIONSDIR}")
|
||||
file(GLOB json_modules "${json_modules_path}/*.json")
|
||||
|
||||
set(all_qt_modules "")
|
||||
|
||||
foreach(json_module IN LISTS json_modules)
|
||||
get_filename_component(module_name "${json_module}" NAME_WE)
|
||||
list(APPEND all_qt_modules ${module_name})
|
||||
endforeach()
|
||||
|
||||
if(all_qt_modules)
|
||||
list(INSERT components "${all_qt_modules_index}" ${all_qt_modules})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(${out_var} "${components}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Append ${ARGN} to ${target}'s ${property_name} property, removing duplicates.
|
||||
function(_qt_internal_append_to_target_property_without_duplicates target property_name)
|
||||
get_target_property(property "${target}" "${property_name}")
|
||||
@ -690,6 +735,7 @@ function(_qt_internal_add_transitive_property target type property)
|
||||
message(FATAL_ERROR "Attempt to assign unknown TRANSITIVE_${type}_PROPERTIES property")
|
||||
endif()
|
||||
|
||||
_qt_internal_dealias_target(target)
|
||||
get_target_property(transitive_properties ${target}
|
||||
TRANSITIVE_${type}_PROPERTIES)
|
||||
if(NOT "${property}" IN_LIST transitive_properties)
|
||||
@ -697,3 +743,129 @@ function(_qt_internal_add_transitive_property target type property)
|
||||
APPEND PROPERTY TRANSITIVE_${type}_PROPERTIES ${property})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Compatibility of `cmake_path(RELATIVE_PATH)`
|
||||
#
|
||||
# In order to be compatible with `file(RELATIVE_PATH)`, path normalization of the result is
|
||||
# always performed, with the trailing slash stripped.
|
||||
#
|
||||
# Synopsis
|
||||
#
|
||||
# _qt_internal_relative_path(<path-var>
|
||||
# [BASE_DIRECTORY <input>]
|
||||
# [OUTPUT_VARIABLE <out-var>]
|
||||
# )
|
||||
#
|
||||
# Arguments
|
||||
#
|
||||
# `path-var`
|
||||
# Equivalent to `cmake_path(RELATIVE_PATH <path-var>)`.
|
||||
#
|
||||
# `BASE_DIRECTORY`
|
||||
# Equivalent to `cmake_path(RELATIVE_PATH BASE_DIRECTORY)`.
|
||||
#
|
||||
# `OUTPUT_VARIABLE`
|
||||
# Equivalent to `cmake_path(RELATIVE_PATH OUTPUT_VARIABLE)`.
|
||||
function(_qt_internal_relative_path path_var)
|
||||
set(option_args "")
|
||||
set(single_args
|
||||
BASE_DIRECTORY
|
||||
OUTPUT_VARIABLE
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${option_args}" "${single_args}" "${multi_args}")
|
||||
|
||||
if(NOT arg_BASE_DIRECTORY)
|
||||
set(arg_BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
if(NOT arg_OUTPUT_VARIABLE)
|
||||
set(arg_OUTPUT_VARIABLE ${path_var})
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.20)
|
||||
file(RELATIVE_PATH ${arg_OUTPUT_VARIABLE}
|
||||
"${arg_BASE_DIRECTORY}"
|
||||
"${${path_var}}")
|
||||
else()
|
||||
cmake_path(RELATIVE_PATH ${path_var}
|
||||
BASE_DIRECTORY "${arg_BASE_DIRECTORY}"
|
||||
OUTPUT_VARIABLE ${arg_OUTPUT_VARIABLE}
|
||||
)
|
||||
cmake_path(NORMAL_PATH ${arg_OUTPUT_VARIABLE})
|
||||
string(REGEX REPLACE "/$" "" ${arg_OUTPUT_VARIABLE}
|
||||
"${${arg_OUTPUT_VARIABLE}}")
|
||||
endif()
|
||||
set(${arg_OUTPUT_VARIABLE} "${${arg_OUTPUT_VARIABLE}}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Configures the file using either the input template or the CONTENT.
|
||||
# Behaves as either file(CONFIGURE or configure_file( command, but do not depend
|
||||
# on CMake version.
|
||||
#
|
||||
# Synopsis
|
||||
# _qt_internal_configure_file(<CONFIGURE|GENERATE>
|
||||
# OUTPUT <path>
|
||||
# <INPUT path|CONTENT data>
|
||||
# )
|
||||
#
|
||||
# Arguments
|
||||
# `CONFIGURE` Run in pure CONFIGURE mode.
|
||||
#
|
||||
# `GENERATE` Configure CONTENT and generate file with the generator expression
|
||||
# support.
|
||||
#
|
||||
# `OUTPUT` The output file name to generate.
|
||||
#
|
||||
# `INPUT` The input template file name.
|
||||
#
|
||||
# `CONTENT` The template content. If both INPUT and CONTENT are specified, INPUT
|
||||
# argument is ignored.
|
||||
function(_qt_internal_configure_file mode)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "" "OUTPUT;INPUT;CONTENT" "")
|
||||
|
||||
if(NOT arg_OUTPUT)
|
||||
message(FATAL_ERROR "No OUTPUT file provided to _qt_internal_configure_file.")
|
||||
endif()
|
||||
|
||||
# Substitute the '@' wrapped variables and generate the file with the
|
||||
# the generator expressions evaluation inside the resulting CONTENT.
|
||||
if(mode STREQUAL "GENERATE")
|
||||
if(arg_INPUT)
|
||||
configure_file("${arg_INPUT}" "${arg_OUTPUT}.tmp" @ONLY)
|
||||
file(GENERATE OUTPUT "${arg_OUTPUT}" INPUT "${arg_OUTPUT}.tmp")
|
||||
else()
|
||||
string(CONFIGURE "${arg_CONTENT}" arg_CONTENT @ONLY)
|
||||
file(GENERATE OUTPUT "${arg_OUTPUT}" CONTENT "${arg_CONTENT}")
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
|
||||
# We use this check for the cases when the specified CONTENT is empty. The value of arg_CONTENT
|
||||
# is undefined, but we still want to create a file with empty content.
|
||||
if("CONTENT" IN_LIST ARGV)
|
||||
if(arg_INPUT)
|
||||
message(WARNING "Both CONTENT and INPUT are specified. CONTENT will be used to generate"
|
||||
" output")
|
||||
endif()
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.18)
|
||||
file(CONFIGURE OUTPUT "${arg_OUTPUT}" CONTENT "${arg_CONTENT}" @ONLY)
|
||||
return()
|
||||
endif()
|
||||
set(template_name "QtFileConfigure.txt.in")
|
||||
# When building qtbase, use the source template file.
|
||||
# Otherwise use the installed file (basically wherever Qt6 package is found).
|
||||
# This should work for non-prefix and superbuilds as well.
|
||||
if(QtBase_SOURCE_DIR)
|
||||
set(input_file "${QtBase_SOURCE_DIR}/cmake/${template_name}")
|
||||
else()
|
||||
set(input_file "${_qt_6_config_cmake_dir}/${template_name}")
|
||||
endif()
|
||||
set(__qt_file_configure_content "${arg_CONTENT}")
|
||||
elseif(arg_INPUT)
|
||||
set(input_file "${arg_INPUT}")
|
||||
else()
|
||||
message(FATAL_ERROR "No input value provided to _qt_internal_configure_file.")
|
||||
endif()
|
||||
|
||||
configure_file("${input_file}" "${arg_OUTPUT}" @ONLY)
|
||||
endfunction()
|
||||
|
@ -55,9 +55,8 @@ function(__qt_internal_force_allow_unsuitable_cmake_version_for_using_qt out_var
|
||||
# Temporarily allow any version when using Qt in Qt's CI, so we can decouple the provisioning
|
||||
# of the minimum CMake version from the bump of the minimum CMake version.
|
||||
# The COIN_UNIQUE_JOB_ID env var is set in Qt's CI for both build and test work items.
|
||||
# Current state is that this check is enabled.
|
||||
# TODO: Disable it once provisioning is merged.
|
||||
set(allow_any_version_in_ci TRUE)
|
||||
# Current state is that this check is disabled.
|
||||
set(allow_any_version_in_ci FALSE)
|
||||
|
||||
if(allow_any_version_in_ci AND DEFINED ENV{COIN_UNIQUE_JOB_ID})
|
||||
set(allow_any_version TRUE)
|
||||
|
@ -34,6 +34,9 @@ macro(_qt_internal_find_third_party_dependencies target target_dep_list)
|
||||
find_package(${__qt_${target}_find_package_args})
|
||||
else()
|
||||
find_dependency(${__qt_${target}_find_package_args})
|
||||
if(NOT ${__qt_${target}_pkg}_FOUND)
|
||||
list(APPEND __qt_${target}_missing_deps "${__qt_${target}_pkg}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
_qt_internal_get_package_components_id(
|
||||
@ -83,15 +86,15 @@ macro(_qt_internal_find_tool_dependencies target target_dep_list)
|
||||
"${_qt_additional_host_packages_root_paths}")
|
||||
endif()
|
||||
|
||||
unset(__qt_${target}_find_package_args)
|
||||
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY)
|
||||
list(APPEND __qt_${target}_find_package_args QUIET)
|
||||
endif()
|
||||
|
||||
foreach(__qt_${target}_target_dep IN LISTS ${target_dep_list})
|
||||
list(GET __qt_${target}_target_dep 0 __qt_${target}_pkg)
|
||||
list(GET __qt_${target}_target_dep 1 __qt_${target}_version)
|
||||
|
||||
unset(__qt_${target}_find_package_args)
|
||||
if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY)
|
||||
list(APPEND __qt_${target}_find_package_args QUIET)
|
||||
endif()
|
||||
|
||||
_qt_internal_save_find_package_context_for_debugging(${target})
|
||||
|
||||
find_package(${__qt_${target}_pkg}
|
||||
@ -129,39 +132,22 @@ macro(_qt_internal_find_qt_dependencies target target_dep_list find_dependency_p
|
||||
list(GET __qt_${target}_target_dep 1 __qt_${target}_version)
|
||||
|
||||
if (NOT ${__qt_${target}_pkg}_FOUND)
|
||||
|
||||
# TODO: Remove Private handling once sufficient time has passed, aka all developers
|
||||
# updated their builds not to contain stale FooDependencies.cmake files without the
|
||||
# _qt_package_name property.
|
||||
set(__qt_${target}_pkg_names ${__qt_${target}_pkg})
|
||||
if(__qt_${target}_pkg MATCHES "(.*)Private$")
|
||||
set(__qt_${target}_pkg_names "${CMAKE_MATCH_1};${__qt_${target}_pkg}")
|
||||
endif()
|
||||
|
||||
_qt_internal_save_find_package_context_for_debugging(${target})
|
||||
|
||||
find_dependency(${__qt_${target}_pkg} ${__qt_${target}_version}
|
||||
NAMES
|
||||
${__qt_${target}_pkg_names}
|
||||
PATHS
|
||||
${QT_BUILD_CMAKE_PREFIX_PATH}
|
||||
${${find_dependency_path_list}}
|
||||
${_qt_additional_packages_prefix_paths}
|
||||
${__qt_use_no_default_path_for_qt_packages}
|
||||
)
|
||||
if(NOT ${__qt_${target}_pkg}_FOUND)
|
||||
list(APPEND __qt_${target}_missing_deps "${__qt_${target}_pkg}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
|
||||
# TODO: Remove once a dependency update completes and most developers have the Dependencies.cmake
|
||||
# files updated in their builds.
|
||||
# The name is too generic, it doesn't look for any kind of dependencies but only Qt package
|
||||
# dependencies.
|
||||
macro(_qt_internal_find_dependencies target_dep_list find_dependency_path_list)
|
||||
_qt_internal_find_qt_dependencies("none" "${target_dep_list}" "${find_dependency_path_list}")
|
||||
endmacro()
|
||||
|
||||
# If a dependency package was not found, provide some hints in the error message on how to debug
|
||||
# the issue.
|
||||
#
|
||||
@ -243,9 +229,9 @@ function(_qt_internal_determine_if_host_info_package_needed out_var)
|
||||
set(${out_var} "${needed}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
macro(_qt_internal_find_host_info_package platform_requires_host_info)
|
||||
macro(_qt_internal_find_host_info_package platform_requires_host_info install_namespace)
|
||||
if(${platform_requires_host_info})
|
||||
find_package(Qt6HostInfo
|
||||
find_package(${install_namespace}HostInfo
|
||||
CONFIG
|
||||
REQUIRED
|
||||
PATHS "${QT_HOST_PATH}"
|
||||
|
@ -49,6 +49,16 @@ function(_qt_internal_query_git_version)
|
||||
set(git_version "${version_git_head}+${version_git_branch}")
|
||||
endif()
|
||||
|
||||
if(QT_SBOM_FAKE_GIT_VERSION)
|
||||
set(version_git_head "fakegithead")
|
||||
set(version_git_hash "fakegithash")
|
||||
set(version_git_branch "fakegitbranch")
|
||||
set(version_git_tag "fakegittag")
|
||||
set(git_version "${version_git_head}+${version_git_branch}")
|
||||
_qt_internal_set_git_query_variables()
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT Git_FOUND)
|
||||
message(STATUS "Git not found, skipping querying git version.")
|
||||
_qt_internal_set_git_query_variables()
|
||||
|
@ -248,10 +248,7 @@ function(__qt_internal_add_static_plugin_init_object_library
|
||||
CONTENT "${import_content}"
|
||||
)
|
||||
|
||||
# CMake versions earlier than 3.18.0 can't find the generated file for some reason,
|
||||
# failing at generation phase.
|
||||
# Explicitly marking the file as GENERATED fixes the issue.
|
||||
set_source_files_properties("${generated_qt_plugin_file_name}" PROPERTIES GENERATED TRUE)
|
||||
_qt_internal_set_source_file_generated(SOURCES "${generated_qt_plugin_file_name}")
|
||||
|
||||
__qt_internal_get_static_plugin_init_target_name("${plugin_target}" plugin_init_target)
|
||||
|
||||
@ -518,6 +515,20 @@ function(__qt_internal_add_interface_plugin_target plugin_module_target plugin_t
|
||||
APPEND PROPERTY INTERFACE_QT_PLUGIN_TARGETS ${plugin_target_name_wrapped})
|
||||
endfunction()
|
||||
|
||||
# TODO: Figure out how to do this more reliably, instead of parsing the file name to get
|
||||
# the target name.
|
||||
function(__qt_internal_get_target_name_from_plugin_config_file_name
|
||||
config_file_path
|
||||
package_prefix_regex
|
||||
out_var)
|
||||
string(REGEX REPLACE
|
||||
"^.*/${QT_CMAKE_EXPORT_NAMESPACE}(${package_prefix_regex})Config.cmake$"
|
||||
"\\1"
|
||||
target "${config_file_path}")
|
||||
|
||||
set(${out_var} "${target}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Include CMake plugin packages that belong to the Qt module ${target} and initialize automatic
|
||||
# linkage of the plugins in static builds.
|
||||
# The variables inside the macro have to be named unique to the module because an included Plugin
|
||||
@ -529,10 +540,7 @@ macro(__qt_internal_include_plugin_packages target)
|
||||
|
||||
# Properties can't be set on aliased targets, so make sure to unalias the target. This is needed
|
||||
# when Qt examples are built as part of the Qt build itself.
|
||||
get_target_property(_aliased_target ${__qt_${target}_plugin_module_target} ALIASED_TARGET)
|
||||
if(_aliased_target)
|
||||
set(__qt_${target}_plugin_module_target ${_aliased_target})
|
||||
endif()
|
||||
_qt_internal_dealias_target(__qt_${target}_plugin_module_target)
|
||||
|
||||
# Ensure that QT_PLUGIN_TARGETS is a known transitive compile property. Works with CMake
|
||||
# versions >= 3.30.
|
||||
@ -546,11 +554,14 @@ macro(__qt_internal_include_plugin_packages target)
|
||||
file(GLOB __qt_${target}_plugin_config_files
|
||||
"${CMAKE_CURRENT_LIST_DIR}/${QT_CMAKE_EXPORT_NAMESPACE}*PluginConfig.cmake")
|
||||
foreach(__qt_${target}_plugin_config_file ${__qt_${target}_plugin_config_files})
|
||||
string(REGEX REPLACE
|
||||
"^.*/${QT_CMAKE_EXPORT_NAMESPACE}(.*Plugin)Config.cmake$"
|
||||
"\\1"
|
||||
__qt_${target}_qt_plugin "${__qt_${target}_plugin_config_file}")
|
||||
include("${__qt_${target}_plugin_config_file}")
|
||||
|
||||
__qt_internal_get_target_name_from_plugin_config_file_name(
|
||||
"${__qt_${target}_plugin_config_file}"
|
||||
"(.*Plugin)"
|
||||
__qt_${target}_qt_plugin
|
||||
)
|
||||
|
||||
if(TARGET "${QT_CMAKE_EXPORT_NAMESPACE}::${__qt_${target}_qt_plugin}")
|
||||
list(APPEND __qt_${target}_plugins ${__qt_${target}_qt_plugin})
|
||||
__qt_internal_add_interface_plugin_target(${__qt_${target}_plugin_module_target}
|
||||
@ -581,10 +592,34 @@ macro(__qt_internal_include_plugin_packages target)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
list(APPEND "QT_ALL_PLUGINS_FOUND_BY_FIND_PACKAGE_${__plugin_type}" "${plugin_target}")
|
||||
set(plugin_target_versioned "${QT_CMAKE_EXPORT_NAMESPACE}::${plugin_target}")
|
||||
|
||||
if(NOT "${plugin_target}"
|
||||
IN_LIST QT_ALL_PLUGINS_FOUND_VIA_FIND_PACKAGE)
|
||||
|
||||
# Old compatibility name.
|
||||
# TODO: Remove once all usages are ported.
|
||||
list(APPEND QT_ALL_PLUGINS_FOUND_BY_FIND_PACKAGE "${plugin_target}")
|
||||
|
||||
# New name consistent with other such variables.
|
||||
list(APPEND QT_ALL_PLUGINS_FOUND_VIA_FIND_PACKAGE "${plugin_target}")
|
||||
list(APPEND QT_ALL_PLUGINS_VERSIONED_FOUND_VIA_FIND_PACKAGE
|
||||
"${plugin_target_versioned}")
|
||||
endif()
|
||||
|
||||
if(NOT "${plugin_target}" IN_LIST QT_ALL_PLUGINS_FOUND_VIA_FIND_PACKAGE_${__plugin_type})
|
||||
# Old compatibility name.
|
||||
# TODO: Remove once all usages are ported.
|
||||
list(APPEND QT_ALL_PLUGINS_FOUND_BY_FIND_PACKAGE_${__plugin_type} "${plugin_target}")
|
||||
|
||||
# New name consistent with other such variables.
|
||||
list(APPEND QT_ALL_PLUGINS_FOUND_VIA_FIND_PACKAGE_${__plugin_type} "${plugin_target}")
|
||||
list(APPEND
|
||||
QT_ALL_PLUGINS_VERSIONED_FOUND_VIA_FIND_PACKAGE_${__plugin_type}
|
||||
"${plugin_target_versioned}")
|
||||
endif()
|
||||
|
||||
# Auto-linkage should be set up only for static plugins.
|
||||
set(plugin_target_versioned "${QT_CMAKE_EXPORT_NAMESPACE}::${plugin_target}")
|
||||
get_target_property(type "${plugin_target_versioned}" TYPE)
|
||||
if(type STREQUAL STATIC_LIBRARY)
|
||||
__qt_internal_add_static_plugin_linkage(
|
||||
@ -597,3 +632,87 @@ macro(__qt_internal_include_plugin_packages target)
|
||||
set_target_properties(
|
||||
${__qt_${target}_plugin_module_target} PROPERTIES __qt_internal_plugins_added TRUE)
|
||||
endmacro()
|
||||
|
||||
# Include Qt Qml plugin CMake packages that are present under the Qml package directory.
|
||||
# TODO: Consider moving this to qtdeclarative somehow.
|
||||
macro(__qt_internal_include_qml_plugin_packages)
|
||||
# Qml plugin targets might have dependencies on other qml plugin targets, but the Targets.cmake
|
||||
# files are included in the order that file(GLOB) returns, which means certain targets that are
|
||||
# referenced might not have been created yet, and ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE
|
||||
# might be set to a message saying those targets don't exist.
|
||||
#
|
||||
# Postpone checking of which targets don't exist until all Qml PluginConfig.cmake files have
|
||||
# been included, by including all the files one more time and checking for errors at each step.
|
||||
#
|
||||
# TODO: Find a better way to deal with this, perhaps by using find_package() instead of include
|
||||
# for the Qml PluginConfig.cmake files.
|
||||
|
||||
# Distributions should probably change this default.
|
||||
if(NOT DEFINED QT_SKIP_AUTO_QML_PLUGIN_INCLUSION)
|
||||
set(QT_SKIP_AUTO_QML_PLUGIN_INCLUSION OFF)
|
||||
endif()
|
||||
|
||||
set(__qt_qml_plugins_config_file_list "")
|
||||
set(__qt_qml_plugins_glob_prefixes "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
# Allow passing additional prefixes where we will glob for PluginConfig.cmake files.
|
||||
if(QT_ADDITIONAL_QML_PLUGIN_GLOB_PREFIXES)
|
||||
foreach(__qt_qml_plugin_glob_prefix IN LISTS QT_ADDITIONAL_QML_PLUGIN_GLOB_PREFIXES)
|
||||
if(__qt_qml_plugin_glob_prefix)
|
||||
list(APPEND __qt_qml_plugins_glob_prefixes "${__qt_qml_plugin_glob_prefix}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
list(REMOVE_DUPLICATES __qt_qml_plugins_glob_prefixes)
|
||||
|
||||
foreach(__qt_qml_plugin_glob_prefix IN LISTS __qt_qml_plugins_glob_prefixes)
|
||||
file(GLOB __qt_qml_plugins_glob_config_file_list
|
||||
"${__qt_qml_plugin_glob_prefix}/QmlPlugins/${INSTALL_CMAKE_NAMESPACE}*Config.cmake")
|
||||
if(__qt_qml_plugins_glob_config_file_list)
|
||||
list(APPEND __qt_qml_plugins_config_file_list ${__qt_qml_plugins_glob_config_file_list})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (__qt_qml_plugins_config_file_list AND NOT QT_SKIP_AUTO_QML_PLUGIN_INCLUSION)
|
||||
# First round of inclusions ensure all qml plugin targets are brought into scope.
|
||||
foreach(__qt_qml_plugin_config_file ${__qt_qml_plugins_config_file_list})
|
||||
include(${__qt_qml_plugin_config_file})
|
||||
|
||||
# Temporarily unset any failure markers and mark the Qml package as found.
|
||||
unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE)
|
||||
set(${CMAKE_FIND_PACKAGE_NAME}_FOUND TRUE)
|
||||
endforeach()
|
||||
|
||||
# For the second round of inclusions, check and bail out early if there are errors.
|
||||
foreach(__qt_qml_plugin_config_file ${__qt_qml_plugins_config_file_list})
|
||||
include(${__qt_qml_plugin_config_file})
|
||||
|
||||
__qt_internal_get_target_name_from_plugin_config_file_name(
|
||||
"${__qt_qml_plugin_config_file}"
|
||||
"(.*)"
|
||||
__qt_qml_plugin_target
|
||||
)
|
||||
set(__qt_qml_plugin_target_versioned
|
||||
"${QT_CMAKE_EXPORT_NAMESPACE}::${__qt_qml_plugin_target}")
|
||||
|
||||
if(TARGET "${__qt_qml_plugin_target_versioned}"
|
||||
AND NOT "${__qt_qml_plugin_target}"
|
||||
IN_LIST QT_ALL_QML_PLUGINS_FOUND_VIA_FIND_PACKAGE)
|
||||
list(APPEND QT_ALL_QML_PLUGINS_FOUND_VIA_FIND_PACKAGE "${__qt_qml_plugin_target}")
|
||||
list(APPEND QT_ALL_QML_PLUGINS_VERSIONED_FOUND_VIA_FIND_PACKAGE
|
||||
"${__qt_qml_plugin_target_versioned}")
|
||||
endif()
|
||||
unset(__qt_qml_plugin_target)
|
||||
unset(__qt_qml_plugin_target_versioned)
|
||||
|
||||
if(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE)
|
||||
string(APPEND ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE
|
||||
"\nThe message was set in ${__qt_qml_plugin_config_file} ")
|
||||
set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
|
||||
return()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
599
cmake/QtPublicSbomAttributionHelpers.cmake
Normal file
599
cmake/QtPublicSbomAttributionHelpers.cmake
Normal file
@ -0,0 +1,599 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# Handles attribution information for a target.
|
||||
#
|
||||
# If CREATE_SBOM_FOR_EACH_ATTRIBUTION is set, a separate sbom target is created for each parsed
|
||||
# attribution entry, and the new targets are added as dependencies to the parent target.
|
||||
#
|
||||
# If CREATE_SBOM_FOR_EACH_ATTRIBUTION is not set, the information read from the first attribution
|
||||
# entry is added directly to the parent target, aka the the values are propagated to the outer
|
||||
# function scope to be read.. The rest of the attribution entries are created as separate targets
|
||||
# and added as dependencies, as if the option was passed.
|
||||
#
|
||||
# Handles multiple attribution files and entries within a file.
|
||||
# Attribution files can be specified either via directories and direct file paths.
|
||||
# If ATTRIBUTION_ENTRY_INDEX is set, only that specific attribution entry will be processed
|
||||
# from the given attribution file.
|
||||
function(_qt_internal_sbom_handle_qt_attribution_files out_prefix_outer)
|
||||
if(NOT QT_GENERATE_SBOM)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION LESS_EQUAL "3.19")
|
||||
message(DEBUG "CMake version is too low, can't parse attribution.json file.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(opt_args "")
|
||||
set(single_args "")
|
||||
set(multi_args "")
|
||||
|
||||
_qt_internal_get_sbom_specific_options(sbom_opt_args sbom_single_args sbom_multi_args)
|
||||
list(APPEND opt_args ${sbom_opt_args})
|
||||
list(APPEND single_args ${sbom_single_args})
|
||||
list(APPEND multi_args ${sbom_multi_args})
|
||||
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(attribution_files "")
|
||||
set(attribution_file_count 0)
|
||||
|
||||
foreach(attribution_file_path IN LISTS arg_ATTRIBUTION_FILE_PATHS)
|
||||
get_filename_component(real_path "${attribution_file_path}" REALPATH)
|
||||
list(APPEND attribution_files "${real_path}")
|
||||
math(EXPR attribution_file_count "${attribution_file_count} + 1")
|
||||
endforeach()
|
||||
|
||||
foreach(attribution_file_dir_path IN LISTS arg_ATTRIBUTION_FILE_DIR_PATHS)
|
||||
get_filename_component(real_path
|
||||
"${attribution_file_dir_path}/qt_attribution.json" REALPATH)
|
||||
list(APPEND attribution_files "${real_path}")
|
||||
math(EXPR attribution_file_count "${attribution_file_count} + 1")
|
||||
endforeach()
|
||||
|
||||
# If CREATE_SBOM_FOR_EACH_ATTRIBUTION is set, that means the parent target is likely not a
|
||||
# 3rd party library, so each attribution entry should create a separate attribution target.
|
||||
# In which case we don't want to proagate options like CPE to the child attribution targets,
|
||||
# because the CPE is meant for the parent target.
|
||||
set(propagate_sbom_options_to_new_attribution_targets TRUE)
|
||||
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_ATTRIBUTION_FILES)
|
||||
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
|
||||
if(is_qt_entity_type)
|
||||
set(arg_CREATE_SBOM_FOR_EACH_ATTRIBUTION TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(arg_CREATE_SBOM_FOR_EACH_ATTRIBUTION)
|
||||
set(propagate_sbom_options_to_new_attribution_targets FALSE)
|
||||
if(NOT arg_ATTRIBUTION_PARENT_TARGET)
|
||||
message(FATAL_ERROR "ATTRIBUTION_PARENT_TARGET must be set")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(arg_ATTRIBUTION_ENTRY_INDEX AND attribution_file_count GREATER 1)
|
||||
message(FATAL_ERROR
|
||||
"ATTRIBUTION_ENTRY_INDEX should only be set if a single attribution "
|
||||
"file is specified."
|
||||
)
|
||||
endif()
|
||||
|
||||
set(ids_to_add "")
|
||||
set(ids_found "")
|
||||
if(arg_ATTRIBUTION_IDS)
|
||||
set(ids_to_add ${arg_ATTRIBUTION_IDS})
|
||||
endif()
|
||||
|
||||
set(file_index 0)
|
||||
set(first_attribution_processed FALSE)
|
||||
foreach(attribution_file_path IN LISTS attribution_files)
|
||||
# Collect all processed attribution files to later create a configure-time dependency on
|
||||
# them so that the SBOM is regenerated (and CMake is re-ran) if they are modified.
|
||||
set_property(GLOBAL APPEND PROPERTY _qt_internal_project_attribution_files
|
||||
"${attribution_file_path}")
|
||||
|
||||
# Set a unique out_prefix that will not overlap when multiple entries are processed.
|
||||
set(out_prefix_file "${out_prefix_outer}_${file_index}")
|
||||
|
||||
# Get the number of entries in the attribution file.
|
||||
_qt_internal_sbom_read_qt_attribution(${out_prefix_file}
|
||||
GET_ATTRIBUTION_ENTRY_COUNT
|
||||
OUT_VAR_VALUE attribution_entry_count
|
||||
FILE_PATH "${attribution_file_path}"
|
||||
)
|
||||
|
||||
# If a specific entry was specified, we will only process it from the file.
|
||||
if(NOT "${arg_ATTRIBUTION_ENTRY_INDEX}" STREQUAL "")
|
||||
set(entry_index ${arg_ATTRIBUTION_ENTRY_INDEX})
|
||||
else()
|
||||
set(entry_index 0)
|
||||
endif()
|
||||
|
||||
# Go through each entry in the attribution file.
|
||||
while("${entry_index}" LESS "${${out_prefix_file}_attribution_entry_count}")
|
||||
# If this is the first entry to be processed, or if CREATE_SBOM_FOR_EACH_ATTRIBUTION
|
||||
# is not set, we read the attribution file entry directly, and propagate the values
|
||||
# to the parent scope.
|
||||
if(NOT first_attribution_processed AND NOT arg_CREATE_SBOM_FOR_EACH_ATTRIBUTION)
|
||||
# Set a prefix without indices, so that the parent scope add_sbom call can
|
||||
# refer to the values directly with the outer prefix, without any index infix.
|
||||
set(out_prefix "${out_prefix_outer}")
|
||||
|
||||
_qt_internal_sbom_read_qt_attribution(${out_prefix}
|
||||
GET_DEFAULT_KEYS
|
||||
ENTRY_INDEX "${entry_index}"
|
||||
OUT_VAR_ASSIGNED_VARIABLE_NAMES variable_names
|
||||
FILE_PATH "${attribution_file_path}"
|
||||
)
|
||||
|
||||
# Check if we need to filter for specific ids.
|
||||
if(ids_to_add AND ${out_prefix}_attribution_id)
|
||||
if("${${out_prefix}_attribution_id}" IN_LIST ids_to_add)
|
||||
list(APPEND ids_found "${${out_prefix}_attribution_id}")
|
||||
else()
|
||||
# Skip to next entry.
|
||||
math(EXPR entry_index "${entry_index} + 1")
|
||||
continue()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Propagate the values to the outer scope.
|
||||
foreach(variable_name IN LISTS variable_names)
|
||||
set(${out_prefix}_${variable_name} "${${out_prefix}_${variable_name}}"
|
||||
PARENT_SCOPE)
|
||||
endforeach()
|
||||
|
||||
get_filename_component(relative_attribution_file_path
|
||||
"${attribution_file_path}" REALPATH)
|
||||
|
||||
set(${out_prefix}_chosen_attribution_file_path "${relative_attribution_file_path}"
|
||||
PARENT_SCOPE)
|
||||
set(${out_prefix}_chosen_attribution_entry_index "${entry_index}"
|
||||
PARENT_SCOPE)
|
||||
|
||||
set(first_attribution_processed TRUE)
|
||||
if(NOT "${arg_ATTRIBUTION_ENTRY_INDEX}" STREQUAL "")
|
||||
# We had a specific index to process, so break right after processing it.
|
||||
break()
|
||||
endif()
|
||||
else()
|
||||
# We are processing the second or later entry, or CREATE_SBOM_FOR_EACH_ATTRIBUTION
|
||||
# was set. Instead of directly reading all the keys from the attribution file,
|
||||
# we get the Id, and create a new sbom target for the entry.
|
||||
# That will recursively call this function with a specific attribution file path
|
||||
# and index, to process the specific entry.
|
||||
|
||||
set(out_prefix "${out_prefix_outer}_${file_index}_${entry_index}")
|
||||
|
||||
# Get the attribution id.
|
||||
_qt_internal_sbom_read_qt_attribution(${out_prefix}
|
||||
GET_KEY
|
||||
KEY Id
|
||||
OUT_VAR_VALUE attribution_id
|
||||
ENTRY_INDEX "${entry_index}"
|
||||
FILE_PATH "${attribution_file_path}"
|
||||
)
|
||||
|
||||
# Check if we need to filter for specific ids
|
||||
if(ids_to_add AND ${out_prefix}_attribution_id)
|
||||
if("${${out_prefix}_attribution_id}" IN_LIST ids_to_add)
|
||||
list(APPEND ids_found "${${out_prefix}_attribution_id}")
|
||||
else()
|
||||
# Skip to next entry.
|
||||
math(EXPR entry_index "${entry_index} + 1")
|
||||
continue()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# If no Id was retrieved, just add a numeric one, to make the sbom target
|
||||
# unique.
|
||||
set(attribution_target "${arg_ATTRIBUTION_PARENT_TARGET}_Attribution_")
|
||||
if(NOT ${out_prefix}_attribution_id)
|
||||
string(APPEND attribution_target "${file_index}_${entry_index}")
|
||||
else()
|
||||
string(APPEND attribution_target "${${out_prefix}_attribution_id}")
|
||||
endif()
|
||||
|
||||
# Sanitize the target name, to avoid issues with slashes and other unsupported chars
|
||||
# in target names.
|
||||
string(REGEX REPLACE "[^a-zA-Z0-9_-]" "_"
|
||||
attribution_target "${attribution_target}")
|
||||
|
||||
set(sbom_args "")
|
||||
|
||||
# Always propagate the package supplier, because we assume the supplier for 3rd
|
||||
# party libs is the same as the current project supplier.
|
||||
# Also propagate the internal qt entity type values like CPE, supplier, PURL
|
||||
# handling options, attribution file values, if set.
|
||||
_qt_internal_forward_function_args(
|
||||
FORWARD_APPEND
|
||||
FORWARD_PREFIX arg
|
||||
FORWARD_OUT_VAR sbom_args
|
||||
FORWARD_OPTIONS
|
||||
USE_ATTRIBUTION_FILES
|
||||
__QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_CPE
|
||||
__QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_SUPPLIER
|
||||
__QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL
|
||||
__QT_INTERNAL_HANDLE_QT_ENTITY_ATTRIBUTION_FILES
|
||||
FORWARD_SINGLE
|
||||
SUPPLIER
|
||||
)
|
||||
|
||||
if(propagate_sbom_options_to_new_attribution_targets)
|
||||
# Filter out the attributtion options, they will be passed mnaually
|
||||
# depending on which file and index is currently being processed.
|
||||
_qt_internal_get_sbom_specific_options(
|
||||
sbom_opt_args sbom_single_args sbom_multi_args)
|
||||
list(REMOVE_ITEM sbom_opt_args
|
||||
NO_CURRENT_DIR_ATTRIBUTION
|
||||
CREATE_SBOM_FOR_EACH_ATTRIBUTION
|
||||
)
|
||||
list(REMOVE_ITEM sbom_single_args ATTRIBUTION_ENTRY_INDEX)
|
||||
list(REMOVE_ITEM sbom_multi_args
|
||||
ATTRIBUTION_IDS
|
||||
ATTRIBUTION_FILE_PATHS
|
||||
ATTRIBUTION_FILE_DIR_PATHS
|
||||
)
|
||||
|
||||
# Also filter out the FRIENDLY_PACKAGE_NAME option, otherwise we'd try to
|
||||
# file(GENERATE) multiple times with the same file name, but different content.
|
||||
list(REMOVE_ITEM sbom_single_args FRIENDLY_PACKAGE_NAME)
|
||||
|
||||
_qt_internal_forward_function_args(
|
||||
FORWARD_APPEND
|
||||
FORWARD_PREFIX arg
|
||||
FORWARD_OUT_VAR sbom_args
|
||||
FORWARD_OPTIONS
|
||||
${sbom_opt_args}
|
||||
FORWARD_SINGLE
|
||||
${sbom_single_args}
|
||||
FORWARD_MULTI
|
||||
${sbom_multi_args}
|
||||
)
|
||||
endif()
|
||||
|
||||
# Create another sbom target with the id as a hint for the target name,
|
||||
# the attribution file passed, and make the new target a dependency of the
|
||||
# parent one.
|
||||
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_ATTRIBUTION_FILES)
|
||||
set(attribution_entity_type QT_THIRD_PARTY_SOURCES)
|
||||
else()
|
||||
set(attribution_entity_type THIRD_PARTY_SOURCES)
|
||||
endif()
|
||||
|
||||
_qt_internal_add_sbom("${attribution_target}"
|
||||
IMMEDIATE_FINALIZATION
|
||||
TYPE "${attribution_entity_type}"
|
||||
ATTRIBUTION_FILE_PATHS "${attribution_file_path}"
|
||||
ATTRIBUTION_ENTRY_INDEX "${entry_index}"
|
||||
NO_CURRENT_DIR_ATTRIBUTION
|
||||
${sbom_args}
|
||||
)
|
||||
|
||||
_qt_internal_extend_sbom_dependencies(${arg_ATTRIBUTION_PARENT_TARGET}
|
||||
SBOM_DEPENDENCIES ${attribution_target}
|
||||
)
|
||||
endif()
|
||||
|
||||
math(EXPR entry_index "${entry_index} + 1")
|
||||
endwhile()
|
||||
|
||||
math(EXPR file_index "${file_index} + 1")
|
||||
endforeach()
|
||||
|
||||
# Show an error if an id is unaccounted for, it might be it has moved to a different file, that
|
||||
# is not referenced.
|
||||
if(ids_to_add)
|
||||
set(attribution_ids_diff ${ids_to_add})
|
||||
list(REMOVE_ITEM attribution_ids_diff ${ids_found})
|
||||
if(attribution_ids_diff)
|
||||
set(error_message
|
||||
"The following required attribution ids were not found in the attribution files")
|
||||
if(arg_ATTRIBUTION_PARENT_TARGET)
|
||||
string(APPEND error_message " for target: ${arg_ATTRIBUTION_PARENT_TARGET}")
|
||||
endif()
|
||||
string(APPEND error_message " ids: ${attribution_ids_diff}")
|
||||
message(FATAL_ERROR "${error_message}")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper to parse a qt_attribution.json file and do various operations:
|
||||
# - GET_DEFAULT_KEYS extracts the license id, copyrights, version, etc.
|
||||
# - GET_KEY extracts a single given json key's value, as specified with KEY and saved into
|
||||
# OUT_VAR_VALUE
|
||||
# - GET_ATTRIBUTION_ENTRY_COUNT returns the number of entries in the json file, set in
|
||||
# OUT_VAR_VALUE
|
||||
#
|
||||
# ENTRY_INDEX can be used to specify the array index to select a specific entry in the json file.
|
||||
#
|
||||
# Any retrieved value is set in the outer scope.
|
||||
# The variables are prefixed with ${out_prefix}.
|
||||
# OUT_VAR_ASSIGNED_VARIABLE_NAMES contains the list of variables set in the parent scope, the
|
||||
# variables names in this list are not prefixed with ${out_prefix}.
|
||||
#
|
||||
# Requires cmake 3.19 for json parsing.
|
||||
function(_qt_internal_sbom_read_qt_attribution out_prefix)
|
||||
if(NOT QT_GENERATE_SBOM)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION LESS_EQUAL "3.19")
|
||||
message(DEBUG "CMake version is too low, can't parse attribution.json file.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(opt_args
|
||||
GET_DEFAULT_KEYS
|
||||
GET_KEY
|
||||
GET_ATTRIBUTION_ENTRY_COUNT
|
||||
)
|
||||
set(single_args
|
||||
FILE_PATH
|
||||
KEY
|
||||
ENTRY_INDEX
|
||||
OUT_VAR_VALUE
|
||||
OUT_VAR_ASSIGNED_VARIABLE_NAMES
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(file_path "${arg_FILE_PATH}")
|
||||
|
||||
if(NOT file_path)
|
||||
message(FATAL_ERROR "qt attribution file path not given")
|
||||
endif()
|
||||
|
||||
file(READ "${file_path}" contents)
|
||||
if(NOT contents)
|
||||
message(FATAL_ERROR "qt attribution file is empty: ${file_path}")
|
||||
endif()
|
||||
|
||||
if(NOT arg_GET_DEFAULT_KEYS AND NOT arg_GET_KEY AND NOT arg_GET_ATTRIBUTION_ENTRY_COUNT)
|
||||
message(FATAL_ERROR
|
||||
"No valid operation specified to _qt_internal_sbom_read_qt_attribution call.")
|
||||
endif()
|
||||
|
||||
if(arg_GET_KEY)
|
||||
if(NOT arg_KEY)
|
||||
message(FATAL_ERROR "KEY must be set")
|
||||
endif()
|
||||
if(NOT arg_OUT_VAR_VALUE)
|
||||
message(FATAL_ERROR "OUT_VAR_VALUE must be set")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
get_filename_component(attribution_file_dir "${file_path}" DIRECTORY)
|
||||
|
||||
# Parse the json file.
|
||||
# The first element might be an array, or an object. We need to detect which one.
|
||||
# Do that by trying to query index 0 of the potential root array.
|
||||
# If the index is found, that means the root is an array, and elem_error is set to NOTFOUND,
|
||||
# because there was no error.
|
||||
# Otherwise elem_error will be something like 'member '0' not found', and we can assume the
|
||||
# root is an object.
|
||||
string(JSON first_elem_type ERROR_VARIABLE elem_error TYPE "${contents}" 0)
|
||||
if(elem_error STREQUAL "NOTFOUND")
|
||||
# Root is an array. The attribution file might contain multiple entries.
|
||||
# Pick the first one if no specific index was specified, otherwise use the given index.
|
||||
if(NOT "${arg_ENTRY_INDEX}" STREQUAL "")
|
||||
set(indices "${arg_ENTRY_INDEX}")
|
||||
else()
|
||||
set(indices "0")
|
||||
endif()
|
||||
set(is_array TRUE)
|
||||
else()
|
||||
# Root is an object, not an array, which means the file has a single entry.
|
||||
set(indices "")
|
||||
set(is_array FALSE)
|
||||
endif()
|
||||
|
||||
set(variable_names "")
|
||||
|
||||
if(arg_GET_KEY)
|
||||
_qt_internal_sbom_get_attribution_key(${arg_KEY} ${arg_OUT_VAR_VALUE} ${out_prefix})
|
||||
endif()
|
||||
|
||||
if(arg_GET_ATTRIBUTION_ENTRY_COUNT)
|
||||
if(NOT arg_OUT_VAR_VALUE)
|
||||
message(FATAL_ERROR "OUT_VAR_VALUE must be set")
|
||||
endif()
|
||||
|
||||
if(is_array)
|
||||
string(JSON attribution_entry_count ERROR_VARIABLE elem_error LENGTH "${contents}")
|
||||
# There was an error getting the length of the array, so we assume it's empty.
|
||||
if(NOT elem_error STREQUAL "NOTFOUND")
|
||||
set(attribution_entry_count 0)
|
||||
endif()
|
||||
else()
|
||||
set(attribution_entry_count 1)
|
||||
endif()
|
||||
|
||||
set(${out_prefix}_${arg_OUT_VAR_VALUE} "${attribution_entry_count}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if(arg_GET_DEFAULT_KEYS)
|
||||
_qt_internal_sbom_get_attribution_key(Id attribution_id "${out_prefix}")
|
||||
_qt_internal_sbom_get_attribution_key(LicenseId license_id "${out_prefix}")
|
||||
_qt_internal_sbom_get_attribution_key(License license "${out_prefix}")
|
||||
_qt_internal_sbom_get_attribution_key(LicenseFile license_file "${out_prefix}")
|
||||
_qt_internal_sbom_get_attribution_key(Version version "${out_prefix}")
|
||||
_qt_internal_sbom_get_attribution_key(Homepage homepage "${out_prefix}")
|
||||
_qt_internal_sbom_get_attribution_key(Name attribution_name "${out_prefix}")
|
||||
_qt_internal_sbom_get_attribution_key(Description description "${out_prefix}")
|
||||
_qt_internal_sbom_get_attribution_key(QtUsage qt_usage "${out_prefix}")
|
||||
_qt_internal_sbom_get_attribution_key(DownloadLocation download_location "${out_prefix}")
|
||||
_qt_internal_sbom_get_attribution_key(Copyright copyrights "${out_prefix}" IS_MULTI_VALUE)
|
||||
_qt_internal_sbom_get_attribution_key(CopyrightFile copyright_file "${out_prefix}")
|
||||
_qt_internal_sbom_get_attribution_key(PURL purls "${out_prefix}" IS_MULTI_VALUE)
|
||||
_qt_internal_sbom_get_attribution_key(CPE cpes "${out_prefix}" IS_MULTI_VALUE)
|
||||
|
||||
# Some attribution files contain a copyright file that contains the actual list of
|
||||
# copyrights. Read it and use it.
|
||||
set(copyright_file_path "${attribution_file_dir}/${copyright_file}")
|
||||
get_filename_component(copyright_file_path "${copyright_file_path}" REALPATH)
|
||||
if(NOT copyrights AND copyright_file AND EXISTS "${copyright_file_path}")
|
||||
file(READ "${copyright_file_path}" copyright_contents)
|
||||
if(copyright_contents)
|
||||
set(copyright_contents "${copyright_contents}")
|
||||
set(copyrights "${copyright_contents}")
|
||||
set(${out_prefix}_copyrights "${copyright_contents}" PARENT_SCOPE)
|
||||
list(APPEND variable_names "copyrights")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(arg_OUT_VAR_ASSIGNED_VARIABLE_NAMES)
|
||||
set(${arg_OUT_VAR_ASSIGNED_VARIABLE_NAMES} "${variable_names}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Extracts a string or an array of strings from a json index path, depending on the extracted value
|
||||
# type.
|
||||
#
|
||||
# Given the 'contents' of the whole json document and the EXTRACTED_VALUE of a json key specified
|
||||
# by the INDICES path, it tries to determine whether the value is an array, in which case the array
|
||||
# is converted to a cmake list and assigned to ${out_var} in the parent scope.
|
||||
# Otherwise the function assumes the EXTRACTED_VALUE was not an array, and just assigns the value
|
||||
# of EXTRACTED_VALUE to ${out_var}
|
||||
function(_qt_internal_sbom_handle_attribution_json_array contents)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
EXTRACTED_VALUE
|
||||
OUT_VAR
|
||||
)
|
||||
set(multi_args
|
||||
INDICES
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
# Write the original value to the parent scope, in case it was not an array.
|
||||
set(${arg_OUT_VAR} "${arg_EXTRACTED_VALUE}" PARENT_SCOPE)
|
||||
|
||||
if(NOT arg_EXTRACTED_VALUE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
string(JSON element_type TYPE "${contents}" ${arg_INDICES})
|
||||
|
||||
if(NOT element_type STREQUAL "ARRAY")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(json_array "${arg_EXTRACTED_VALUE}")
|
||||
string(JSON array_len LENGTH "${json_array}")
|
||||
|
||||
set(value_list "")
|
||||
|
||||
math(EXPR array_len "${array_len} - 1")
|
||||
foreach(index RANGE 0 "${array_len}")
|
||||
string(JSON value GET "${json_array}" ${index})
|
||||
if(value)
|
||||
list(APPEND value_list "${value}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(value_list)
|
||||
set(${arg_OUT_VAR} "${value_list}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Escapes various characters in json content, so that the generate cmake code to append the content
|
||||
# to the spdx document is syntactically valid.
|
||||
function(_qt_internal_sbom_escape_json_content content out_var)
|
||||
# Escape backslashes
|
||||
string(REPLACE "\\" "\\\\" escaped_content "${content}")
|
||||
|
||||
# Escape quotes
|
||||
string(REPLACE "\"" "\\\"" escaped_content "${escaped_content}")
|
||||
|
||||
set(${out_var} "${escaped_content}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# This macro reads a json key from a qt_attribution.json file, and assigns the escaped value to
|
||||
# out_var.
|
||||
# Also appends the name of the out_var to the parent scope 'variable_names' var.
|
||||
#
|
||||
# Expects 'contents' and 'indices' to already be set in the calling scope.
|
||||
#
|
||||
# If IS_MULTI_VALUE is set, handles the key as if it contained an array of
|
||||
# values, by converting the array of json values to a cmake list.
|
||||
macro(_qt_internal_sbom_get_attribution_key json_key out_var out_prefix)
|
||||
cmake_parse_arguments(arg "IS_MULTI_VALUE" "" "" ${ARGN})
|
||||
|
||||
# Reset any leftover value that might have been set in a previous iteration.
|
||||
set(${out_prefix}_${out_var} "" PARENT_SCOPE)
|
||||
|
||||
string(JSON "${out_var}" ERROR_VARIABLE get_error GET "${contents}" ${indices} "${json_key}")
|
||||
if(NOT "${${out_var}}" STREQUAL "" AND NOT get_error)
|
||||
set(extracted_value "${${out_var}}")
|
||||
|
||||
if(arg_IS_MULTI_VALUE)
|
||||
_qt_internal_sbom_handle_attribution_json_array("${contents}"
|
||||
EXTRACTED_VALUE "${extracted_value}"
|
||||
INDICES ${indices} ${json_key}
|
||||
OUT_VAR value_list
|
||||
)
|
||||
if(value_list)
|
||||
set(extracted_value "${value_list}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_escape_json_content("${extracted_value}" escaped_content)
|
||||
|
||||
set(${out_prefix}_${out_var} "${escaped_content}" PARENT_SCOPE)
|
||||
list(APPEND variable_names "${out_var}")
|
||||
|
||||
unset(extracted_value)
|
||||
unset(escaped_content)
|
||||
unset(value_list)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Replaces placeholders in CPE and PURL strings read from qt_attribution.json files.
|
||||
#
|
||||
# VALUES - list of CPE or PURL strings
|
||||
# OUT_VAR - variable to store the replaced values
|
||||
# VERSION - version to replace in the placeholders
|
||||
|
||||
# Known placeholders:
|
||||
# $<VERSION> - Replaces occurrences of the placeholder with the value passed to the VERSION option.
|
||||
# $<VERSION_DASHED> - Replaces occurrences of the placeholder with the value passed to the VERSION
|
||||
# option, but with dots replaced by dashes.
|
||||
function(_qt_internal_sbom_replace_qa_placeholders)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
OUT_VAR
|
||||
VERSION
|
||||
)
|
||||
set(multi_args
|
||||
VALUES
|
||||
)
|
||||
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(NOT arg_OUT_VAR)
|
||||
message(FATAL_ERROR "OUT_VAR must be set")
|
||||
endif()
|
||||
|
||||
set(result "")
|
||||
|
||||
if(arg_VERSION)
|
||||
string(REPLACE "." "-" dashed_version "${arg_VERSION}")
|
||||
endif()
|
||||
|
||||
foreach(value IN LISTS arg_VALUES)
|
||||
if(arg_VERSION)
|
||||
string(REPLACE "$<VERSION>" "${arg_VERSION}" value "${value}")
|
||||
string(REPLACE "$<VERSION_DASHED>" "${dashed_version}" value "${value}")
|
||||
endif()
|
||||
|
||||
list(APPEND result "${value}")
|
||||
endforeach()
|
||||
|
||||
set(${arg_OUT_VAR} "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
90
cmake/QtPublicSbomCpeHelpers.cmake
Normal file
90
cmake/QtPublicSbomCpeHelpers.cmake
Normal file
@ -0,0 +1,90 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# Computes a security CPE for a given set of attributes.
|
||||
#
|
||||
# When a part is not specified, a wildcard is added.
|
||||
#
|
||||
# References:
|
||||
# https://spdx.github.io/spdx-spec/v2.3/external-repository-identifiers/#f22-cpe23type
|
||||
# https://nvlpubs.nist.gov/nistpubs/Legacy/IR/nistir7695.pdf
|
||||
# https://nvd.nist.gov/products/cpe
|
||||
#
|
||||
# Each attribute means:
|
||||
# 1. part
|
||||
# 2. vendor
|
||||
# 3. product
|
||||
# 4. version
|
||||
# 5. update
|
||||
# 6. edition
|
||||
# 7. language
|
||||
# 8. sw_edition
|
||||
# 9. target_sw
|
||||
# 10. target_hw
|
||||
# 11. other
|
||||
function(_qt_internal_sbom_compute_security_cpe out_cpe)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
PART
|
||||
VENDOR
|
||||
PRODUCT
|
||||
VERSION
|
||||
UPDATE
|
||||
EDITION
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(cpe_template "cpe:2.3:PART:VENDOR:PRODUCT:VERSION:UPDATE:EDITION:*:*:*:*:*")
|
||||
|
||||
set(cpe "${cpe_template}")
|
||||
foreach(attribute_name IN LISTS single_args)
|
||||
if(arg_${attribute_name})
|
||||
set(${attribute_name}_value "${arg_${attribute_name}}")
|
||||
else()
|
||||
if(attribute_name STREQUAL "PART")
|
||||
set(${attribute_name}_value "a")
|
||||
else()
|
||||
set(${attribute_name}_value "*")
|
||||
endif()
|
||||
endif()
|
||||
string(REPLACE "${attribute_name}" "${${attribute_name}_value}" cpe "${cpe}")
|
||||
endforeach()
|
||||
|
||||
set(${out_cpe} "${cpe}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Computes the default security CPE for the Qt framework.
|
||||
function(_qt_internal_sbom_get_cpe_qt out_var)
|
||||
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
|
||||
_qt_internal_sbom_compute_security_cpe(repo_cpe
|
||||
VENDOR "qt"
|
||||
PRODUCT "${repo_project_name_lowercase}"
|
||||
VERSION "${QT_REPO_MODULE_VERSION}"
|
||||
)
|
||||
set(${out_var} "${repo_cpe}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Computes the default security CPE for a given qt repository.
|
||||
function(_qt_internal_sbom_get_cpe_qt_repo out_var)
|
||||
_qt_internal_sbom_compute_security_cpe(qt_cpe
|
||||
VENDOR "qt"
|
||||
PRODUCT "qt"
|
||||
VERSION "${QT_REPO_MODULE_VERSION}"
|
||||
)
|
||||
set(${out_var} "${qt_cpe}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Computes the list of security CPEs for Qt, including both the repo-specific one and generic one.
|
||||
function(_qt_internal_sbom_compute_security_cpe_for_qt out_cpe_list)
|
||||
set(cpe_list "")
|
||||
|
||||
_qt_internal_sbom_get_cpe_qt(repo_cpe)
|
||||
list(APPEND cpe_list "${repo_cpe}")
|
||||
|
||||
_qt_internal_sbom_get_cpe_qt_repo(qt_cpe)
|
||||
list(APPEND cpe_list "${qt_cpe}")
|
||||
|
||||
set(${out_cpe_list} "${cpe_list}" PARENT_SCOPE)
|
||||
endfunction()
|
265
cmake/QtPublicSbomDepHelpers.cmake
Normal file
265
cmake/QtPublicSbomDepHelpers.cmake
Normal file
@ -0,0 +1,265 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# Walks a target's direct dependencies and assembles a list of relationships between the packages
|
||||
# of the target dependencies.
|
||||
# Currently handles various Qt targets and system libraries.
|
||||
function(_qt_internal_sbom_handle_target_dependencies target)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
SPDX_ID
|
||||
OUT_RELATIONSHIPS
|
||||
)
|
||||
set(multi_args
|
||||
LIBRARIES
|
||||
PUBLIC_LIBRARIES
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(NOT arg_SPDX_ID)
|
||||
message(FATAL_ERROR "SPDX_ID must be set")
|
||||
endif()
|
||||
set(package_spdx_id "${arg_SPDX_ID}")
|
||||
|
||||
|
||||
set(libraries "")
|
||||
if(arg_LIBRARIES)
|
||||
list(APPEND libraries "${arg_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
get_target_property(extend_libraries "${target}" _qt_extend_target_libraries)
|
||||
if(extend_libraries)
|
||||
list(APPEND libraries ${extend_libraries})
|
||||
endif()
|
||||
|
||||
get_target_property(target_type ${target} TYPE)
|
||||
set(valid_target_types
|
||||
EXECUTABLE
|
||||
SHARED_LIBRARY
|
||||
MODULE_LIBRARY
|
||||
STATIC_LIBRARY
|
||||
OBJECT_LIBRARY
|
||||
)
|
||||
if(target_type IN_LIST valid_target_types)
|
||||
get_target_property(link_libraries "${target}" LINK_LIBRARIES)
|
||||
if(link_libraries)
|
||||
list(APPEND libraries ${link_libraries})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(public_libraries "")
|
||||
if(arg_PUBLIC_LIBRARIES)
|
||||
list(APPEND public_libraries "${arg_PUBLIC_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
get_target_property(extend_public_libraries "${target}" _qt_extend_target_public_libraries)
|
||||
if(extend_public_libraries)
|
||||
list(APPEND public_libraries ${extend_public_libraries})
|
||||
endif()
|
||||
|
||||
set(sbom_dependencies "")
|
||||
if(arg_SBOM_DEPENDENCIES)
|
||||
list(APPEND sbom_dependencies "${arg_SBOM_DEPENDENCIES}")
|
||||
endif()
|
||||
|
||||
get_target_property(extend_sbom_dependencies "${target}" _qt_extend_target_sbom_dependencies)
|
||||
if(extend_sbom_dependencies)
|
||||
list(APPEND sbom_dependencies ${extend_sbom_dependencies})
|
||||
endif()
|
||||
|
||||
list(REMOVE_DUPLICATES libraries)
|
||||
list(REMOVE_DUPLICATES public_libraries)
|
||||
list(REMOVE_DUPLICATES sbom_dependencies)
|
||||
|
||||
set(all_direct_libraries ${libraries} ${public_libraries} ${sbom_dependencies})
|
||||
list(REMOVE_DUPLICATES all_direct_libraries)
|
||||
|
||||
set(spdx_dependencies "")
|
||||
set(external_spdx_dependencies "")
|
||||
|
||||
# Go through each direct linked lib.
|
||||
foreach(direct_lib IN LISTS all_direct_libraries)
|
||||
if(NOT TARGET "${direct_lib}")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# Check for Qt-specific system library targets. These are marked via qt_find_package calls.
|
||||
get_target_property(is_system_library "${direct_lib}" _qt_internal_sbom_is_system_library)
|
||||
if(is_system_library)
|
||||
|
||||
# We need to check if the dependency is a FindWrap dependency that points either to a
|
||||
# system library or a vendored / bundled library. We need to depend on whichever one
|
||||
# the FindWrap script points to.
|
||||
__qt_internal_walk_libs(
|
||||
"${direct_lib}"
|
||||
lib_walked_targets
|
||||
_discarded_out_var
|
||||
"sbom_targets"
|
||||
"collect_targets")
|
||||
|
||||
# Detect if we are dealing with a vendored / bundled lib.
|
||||
set(bundled_targets_found FALSE)
|
||||
if(lib_walked_targets)
|
||||
foreach(lib_walked_target IN LISTS lib_walked_targets)
|
||||
get_target_property(is_3rdparty_bundled_lib
|
||||
"${lib_walked_target}" _qt_module_is_3rdparty_library)
|
||||
_qt_internal_sbom_get_spdx_id_for_target("${lib_walked_target}" lib_spdx_id)
|
||||
|
||||
# Add a dependency on the vendored lib instead of the Wrap target.
|
||||
if(is_3rdparty_bundled_lib AND lib_spdx_id)
|
||||
list(APPEND spdx_dependencies "${lib_spdx_id}")
|
||||
set(bundled_targets_found TRUE)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(bundled_targets_found)
|
||||
# If we handled a bundled target, we can move on to process the next direct_lib.
|
||||
continue()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT bundled_targets_found)
|
||||
# If we haven't found a bundled target, then it's a regular system library
|
||||
# dependency. Make sure to mark the system library as consumed, so that we later
|
||||
# generate an sbom for it.
|
||||
# Also fall through to the code that actually adds the dependency on the target.
|
||||
_qt_internal_append_to_cmake_property_without_duplicates(
|
||||
_qt_internal_sbom_consumed_system_library_targets
|
||||
"${direct_lib}"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Get the spdx id of the dependency.
|
||||
_qt_internal_sbom_get_spdx_id_for_target("${direct_lib}" lib_spdx_id)
|
||||
if(NOT lib_spdx_id)
|
||||
message(DEBUG "Could not add target dependency on target ${direct_lib} "
|
||||
"because no spdx id for it could be found.")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# Check if the target sbom is defined in an external document.
|
||||
|
||||
_qt_internal_sbom_is_external_target_dependency("${direct_lib}"
|
||||
OUT_VAR is_dependency_in_external_document
|
||||
)
|
||||
|
||||
if(NOT is_dependency_in_external_document)
|
||||
# If the target is not in the external document, it must be one built as part of the
|
||||
# current project.
|
||||
list(APPEND spdx_dependencies "${lib_spdx_id}")
|
||||
else()
|
||||
# Refer to the package in the external document. This can be the case
|
||||
# in a top-level build, where a system library is reused across repos, or for any
|
||||
# regular dependency that was built as part of a different project.
|
||||
_qt_internal_sbom_add_external_target_dependency("${direct_lib}"
|
||||
extra_spdx_dependencies
|
||||
)
|
||||
if(extra_spdx_dependencies)
|
||||
list(APPEND external_spdx_dependencies ${extra_spdx_dependencies})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(relationships "")
|
||||
# Keep the external dependencies first, so they are neatly ordered.
|
||||
foreach(dep_spdx_id IN LISTS external_spdx_dependencies spdx_dependencies)
|
||||
set(relationship
|
||||
"${package_spdx_id} DEPENDS_ON ${dep_spdx_id}"
|
||||
)
|
||||
list(APPEND relationships "${relationship}")
|
||||
endforeach()
|
||||
|
||||
set(${arg_OUT_RELATIONSHIPS} "${relationships}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Checks whether the current target will have its sbom generated into the current repo sbom
|
||||
# document, or whether it is present in an external sbom document.
|
||||
function(_qt_internal_sbom_is_external_target_dependency target)
|
||||
set(opt_args
|
||||
SYSTEM_LIBRARY
|
||||
)
|
||||
set(single_args
|
||||
OUT_VAR
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
get_target_property(is_imported "${target}" IMPORTED)
|
||||
get_target_property(is_custom_sbom_target "${target}" _qt_sbom_is_custom_sbom_target)
|
||||
|
||||
_qt_internal_sbom_get_root_project_name_lower_case(current_repo_project_name)
|
||||
get_property(target_repo_project_name TARGET ${target}
|
||||
PROPERTY _qt_sbom_spdx_repo_project_name_lowercase)
|
||||
|
||||
if(NOT "${target_repo_project_name}" STREQUAL ""
|
||||
AND NOT "${target_repo_project_name}" STREQUAL "${current_repo_project_name}")
|
||||
set(part_of_other_repo TRUE)
|
||||
else()
|
||||
set(part_of_other_repo FALSE)
|
||||
endif()
|
||||
|
||||
set(${arg_OUT_VAR} "${part_of_other_repo}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Handles generating an external document reference SDPX element for each target package that is
|
||||
# located in a different spdx document.
|
||||
function(_qt_internal_sbom_add_external_target_dependency target out_spdx_dependencies)
|
||||
_qt_internal_sbom_get_spdx_id_for_target("${target}" dep_spdx_id)
|
||||
|
||||
if(NOT dep_spdx_id)
|
||||
message(DEBUG "Could not add external target dependency on ${target} "
|
||||
"because no spdx id could be found")
|
||||
set(${out_spdx_dependencies} "" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(spdx_dependencies "")
|
||||
|
||||
# Get the external document path and the repo it belongs to for the given target.
|
||||
get_property(relative_installed_repo_document_path TARGET ${target}
|
||||
PROPERTY _qt_sbom_spdx_relative_installed_repo_document_path)
|
||||
|
||||
get_property(project_name_lowercase TARGET ${target}
|
||||
PROPERTY _qt_sbom_spdx_repo_project_name_lowercase)
|
||||
|
||||
if(relative_installed_repo_document_path AND project_name_lowercase)
|
||||
_qt_internal_sbom_get_external_document_ref_spdx_id(
|
||||
"${project_name_lowercase}" external_document_ref)
|
||||
|
||||
get_cmake_property(known_external_document
|
||||
_qt_known_external_documents_${external_document_ref})
|
||||
|
||||
set(dependency "${external_document_ref}:${dep_spdx_id}")
|
||||
|
||||
list(APPEND spdx_dependencies "${dependency}")
|
||||
|
||||
# Only add a reference to the external document package, if we haven't done so already.
|
||||
if(NOT known_external_document)
|
||||
set(install_prefixes "")
|
||||
|
||||
get_cmake_property(install_prefix _qt_internal_sbom_install_prefix)
|
||||
list(APPEND install_prefixes "${install_prefix}")
|
||||
|
||||
set(external_document "${relative_installed_repo_document_path}")
|
||||
|
||||
_qt_internal_sbom_generate_add_external_reference(
|
||||
EXTERNAL_DOCUMENT_FILE_PATH "${external_document}"
|
||||
EXTERNAL_DOCUMENT_INSTALL_PREFIXES ${install_prefixes}
|
||||
EXTERNAL_DOCUMENT_SPDX_ID "${external_document_ref}"
|
||||
)
|
||||
|
||||
set_property(GLOBAL PROPERTY
|
||||
_qt_known_external_documents_${external_document_ref} TRUE)
|
||||
set_property(GLOBAL APPEND PROPERTY
|
||||
_qt_known_external_documents "${external_document_ref}")
|
||||
endif()
|
||||
else()
|
||||
message(AUTHOR_WARNING
|
||||
"Missing spdx document path for external target dependency: ${target}")
|
||||
endif()
|
||||
|
||||
set(${out_spdx_dependencies} "${spdx_dependencies}" PARENT_SCOPE)
|
||||
endfunction()
|
1149
cmake/QtPublicSbomFileHelpers.cmake
Normal file
1149
cmake/QtPublicSbomFileHelpers.cmake
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
108
cmake/QtPublicSbomLicenseHelpers.cmake
Normal file
108
cmake/QtPublicSbomLicenseHelpers.cmake
Normal file
@ -0,0 +1,108 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# Adds a license id and its text to the sbom.
|
||||
function(_qt_internal_sbom_add_license)
|
||||
if(NOT QT_GENERATE_SBOM)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(opt_args
|
||||
NO_LICENSE_REF_PREFIX
|
||||
)
|
||||
set(single_args
|
||||
LICENSE_ID
|
||||
LICENSE_PATH
|
||||
EXTRACTED_TEXT
|
||||
)
|
||||
set(multi_args
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(NOT arg_LICENSE_ID)
|
||||
message(FATAL_ERROR "LICENSE_ID must be set")
|
||||
endif()
|
||||
|
||||
if(NOT arg_TEXT AND NOT arg_LICENSE_PATH)
|
||||
message(FATAL_ERROR "Either TEXT or LICENSE_PATH must be set")
|
||||
endif()
|
||||
|
||||
# Sanitize the content a bit.
|
||||
if(arg_TEXT)
|
||||
set(text "${arg_TEXT}")
|
||||
string(REPLACE ";" "$<SEMICOLON>" text "${text}")
|
||||
string(REPLACE "\"" "\\\"" text "${text}")
|
||||
else()
|
||||
file(READ "${arg_LICENSE_PATH}" text)
|
||||
string(REPLACE ";" "$<SEMICOLON>" text "${text}")
|
||||
string(REPLACE "\"" "\\\"" text "${text}")
|
||||
endif()
|
||||
|
||||
set(license_id "${arg_LICENSE_ID}")
|
||||
if(NOT arg_NO_LICENSE_REF_PREFIX)
|
||||
set(license_id "LicenseRef-${license_id}")
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_generate_add_license(
|
||||
LICENSE_ID "${license_id}"
|
||||
EXTRACTED_TEXT "<text>${text}</text>"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# Get a qt spdx license expression given the id.
|
||||
function(_qt_internal_sbom_get_spdx_license_expression id out_var)
|
||||
set(license "")
|
||||
|
||||
# The default for modules / plugins
|
||||
if(id STREQUAL "QT_DEFAULT" OR id STREQUAL "QT_COMMERCIAL_OR_LGPL3")
|
||||
set(license "LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only")
|
||||
|
||||
# For commercial only entities
|
||||
elseif(id STREQUAL "QT_COMMERCIAL")
|
||||
set(license "LicenseRef-Qt-Commercial")
|
||||
|
||||
# For GPL3 only modules
|
||||
elseif(id STREQUAL "QT_COMMERCIAL_OR_GPL3")
|
||||
set(license "LicenseRef-Qt-Commercial OR GPL-3.0-only")
|
||||
|
||||
# For tools and apps
|
||||
elseif(id STREQUAL "QT_COMMERCIAL_OR_GPL3_WITH_EXCEPTION")
|
||||
set(license "LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0")
|
||||
|
||||
# For things like the qtmain library
|
||||
elseif(id STREQUAL "QT_COMMERCIAL_OR_BSD3")
|
||||
set(license "LicenseRef-Qt-Commercial OR BSD-3-Clause")
|
||||
|
||||
# For documentation
|
||||
elseif(id STREQUAL "QT_COMMERCIAL_OR_GFDL1_3")
|
||||
set(license "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only")
|
||||
|
||||
# For examples and the like
|
||||
elseif(id STREQUAL "BSD3")
|
||||
set(license "BSD-3-Clause")
|
||||
|
||||
endif()
|
||||
|
||||
if(NOT license)
|
||||
message(FATAL_ERROR "No SPDX license expression found for id: ${id}")
|
||||
endif()
|
||||
|
||||
set(${out_var} "${license}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Joins two license IDs with the given ${op}, avoiding parenthesis when possible.
|
||||
function(_qt_internal_sbom_join_two_license_ids_with_op left_id op right_id out_var)
|
||||
if(NOT left_id)
|
||||
set(${out_var} "${right_id}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT right_id)
|
||||
set(${out_var} "${left_id}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(value "(${left_id}) ${op} (${right_id})")
|
||||
set(${out_var} "${value}" PARENT_SCOPE)
|
||||
endfunction()
|
861
cmake/QtPublicSbomOpsHelpers.cmake
Normal file
861
cmake/QtPublicSbomOpsHelpers.cmake
Normal file
@ -0,0 +1,861 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# Copyright (C) 2023-2024 Jochem Rutgers
|
||||
# SPDX-License-Identifier: MIT AND BSD-3-Clause
|
||||
|
||||
# Handles the look up of Python, Python spdx dependencies and other various post-installation steps
|
||||
# like NTIA validation, auditing, json generation, etc.
|
||||
function(_qt_internal_sbom_setup_project_ops_generation)
|
||||
set(opt_args
|
||||
GENERATE_JSON
|
||||
GENERATE_JSON_REQUIRED
|
||||
GENERATE_SOURCE_SBOM
|
||||
VERIFY_SBOM
|
||||
VERIFY_SBOM_REQUIRED
|
||||
VERIFY_NTIA_COMPLIANT
|
||||
LINT_SOURCE_SBOM
|
||||
LINT_SOURCE_SBOM_NO_ERROR
|
||||
SHOW_TABLE
|
||||
AUDIT
|
||||
AUDIT_NO_ERROR
|
||||
)
|
||||
set(single_args "")
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(arg_GENERATE_JSON AND NOT QT_INTERNAL_NO_SBOM_PYTHON_OPS)
|
||||
set(op_args
|
||||
OP_KEY "GENERATE_JSON"
|
||||
OUT_VAR_DEPS_FOUND deps_found
|
||||
)
|
||||
if(arg_GENERATE_JSON_REQUIRED)
|
||||
list(APPEND op_args REQUIRED)
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_find_and_handle_sbom_op_dependencies(${op_args})
|
||||
if(deps_found)
|
||||
_qt_internal_sbom_generate_json()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(arg_VERIFY_SBOM AND NOT QT_INTERNAL_NO_SBOM_PYTHON_OPS)
|
||||
set(op_args
|
||||
OP_KEY "VERIFY_SBOM"
|
||||
OUT_VAR_DEPS_FOUND deps_found
|
||||
)
|
||||
if(arg_VERIFY_SBOM_REQUIRED)
|
||||
list(APPEND op_args REQUIRED)
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_find_and_handle_sbom_op_dependencies(${op_args})
|
||||
if(deps_found)
|
||||
_qt_internal_sbom_verify_valid()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(arg_VERIFY_NTIA_COMPLIANT AND NOT QT_INTERNAL_NO_SBOM_PYTHON_OPS)
|
||||
_qt_internal_sbom_find_and_handle_sbom_op_dependencies(REQUIRED OP_KEY "RUN_NTIA")
|
||||
_qt_internal_sbom_verify_ntia_compliant()
|
||||
endif()
|
||||
|
||||
if(arg_SHOW_TABLE AND NOT QT_INTERNAL_NO_SBOM_PYTHON_OPS)
|
||||
_qt_internal_sbom_find_python_dependency_program(NAME sbom2doc REQUIRED)
|
||||
_qt_internal_sbom_show_table()
|
||||
endif()
|
||||
|
||||
if(arg_AUDIT AND NOT QT_INTERNAL_NO_SBOM_PYTHON_OPS)
|
||||
set(audit_no_error_option "")
|
||||
if(arg_AUDIT_NO_ERROR)
|
||||
set(audit_no_error_option NO_ERROR)
|
||||
endif()
|
||||
_qt_internal_sbom_find_python_dependency_program(NAME sbomaudit REQUIRED)
|
||||
_qt_internal_sbom_audit(${audit_no_error_option})
|
||||
endif()
|
||||
|
||||
if(arg_GENERATE_SOURCE_SBOM AND NOT QT_INTERNAL_NO_SBOM_PYTHON_OPS)
|
||||
_qt_internal_sbom_find_python_dependency_program(NAME reuse REQUIRED)
|
||||
_qt_internal_sbom_generate_reuse_source_sbom()
|
||||
endif()
|
||||
|
||||
if(arg_LINT_SOURCE_SBOM AND NOT QT_INTERNAL_NO_SBOM_PYTHON_OPS)
|
||||
set(lint_no_error_option "")
|
||||
if(arg_LINT_SOURCE_SBOM_NO_ERROR)
|
||||
set(lint_no_error_option NO_ERROR)
|
||||
endif()
|
||||
_qt_internal_sbom_find_python_dependency_program(NAME reuse REQUIRED)
|
||||
_qt_internal_sbom_run_reuse_lint(
|
||||
${lint_no_error_option}
|
||||
BUILD_TIME_SCRIPT_PATH_OUT_VAR reuse_lint_script
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper to find a python interpreter and a specific python dependency, e.g. to be able to generate
|
||||
# a SPDX JSON SBOM, or run post-installation steps like NTIA verification.
|
||||
# The exact dependency should be specified as the OP_KEY.
|
||||
#
|
||||
# Caches the found python executable in a separate cache var QT_INTERNAL_SBOM_PYTHON_EXECUTABLE, to
|
||||
# avoid conflicts with any other found python interpreter.
|
||||
function(_qt_internal_sbom_find_and_handle_sbom_op_dependencies)
|
||||
set(opt_args
|
||||
REQUIRED
|
||||
)
|
||||
set(single_args
|
||||
OP_KEY
|
||||
OUT_VAR_DEPS_FOUND
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(NOT arg_OP_KEY)
|
||||
message(FATAL_ERROR "OP_KEY is required")
|
||||
endif()
|
||||
|
||||
set(supported_ops "GENERATE_JSON" "VERIFY_SBOM" "RUN_NTIA")
|
||||
|
||||
if(arg_OP_KEY STREQUAL "GENERATE_JSON" OR arg_OP_KEY STREQUAL "VERIFY_SBOM")
|
||||
set(import_statement "import spdx_tools.spdx.clitools.pyspdxtools")
|
||||
elseif(arg_OP_KEY STREQUAL "RUN_NTIA")
|
||||
set(import_statement "import ntia_conformance_checker.main")
|
||||
else()
|
||||
message(FATAL_ERROR "OP_KEY must be one of ${supported_ops}")
|
||||
endif()
|
||||
|
||||
# Return early if we found the dependencies.
|
||||
if(QT_INTERNAL_SBOM_DEPS_FOUND_FOR_${arg_OP_KEY})
|
||||
if(arg_OUT_VAR_DEPS_FOUND)
|
||||
set(${arg_OUT_VAR_DEPS_FOUND} TRUE PARENT_SCOPE)
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
|
||||
# NTIA-compliance checker requires Python 3.9 or later, so we use it as the minimum for all
|
||||
# SBOM OPs.
|
||||
set(required_version "3.9")
|
||||
|
||||
set(python_common_args
|
||||
VERSION "${required_version}"
|
||||
)
|
||||
|
||||
set(everything_found FALSE)
|
||||
|
||||
# On macOS FindPython prefers looking in the system framework location, but that usually would
|
||||
# not have the required dependencies. So we first look in it, and then fallback to any other
|
||||
# non-framework python found.
|
||||
if(CMAKE_HOST_APPLE)
|
||||
set(extra_python_args SEARCH_IN_FRAMEWORKS QUIET)
|
||||
_qt_internal_sbom_find_python_and_dependency_helper_lambda()
|
||||
endif()
|
||||
|
||||
if(NOT everything_found)
|
||||
set(extra_python_args QUIET)
|
||||
_qt_internal_sbom_find_python_and_dependency_helper_lambda()
|
||||
endif()
|
||||
|
||||
# Always save the python interpreter path if it is found, even if the dependencies are not
|
||||
# found. This improves the error message workflow.
|
||||
if(python_found AND NOT QT_INTERNAL_SBOM_PYTHON_EXECUTABLE)
|
||||
set(QT_INTERNAL_SBOM_PYTHON_EXECUTABLE "${python_path}" CACHE INTERNAL
|
||||
"Python interpeter used for SBOM generation.")
|
||||
endif()
|
||||
|
||||
if(NOT everything_found)
|
||||
if(arg_REQUIRED)
|
||||
set(message_type "FATAL_ERROR")
|
||||
else()
|
||||
set(message_type "DEBUG")
|
||||
endif()
|
||||
|
||||
if(NOT python_found)
|
||||
# Look for python one more time, this time without QUIET, to show an error why it
|
||||
# wasn't found.
|
||||
if(arg_REQUIRED)
|
||||
_qt_internal_sbom_find_python_helper(${python_common_args}
|
||||
OUT_VAR_PYTHON_PATH unused_python
|
||||
OUT_VAR_PYTHON_FOUND unused_found
|
||||
)
|
||||
endif()
|
||||
message(${message_type} "Python ${required_version} for running SBOM ops not found.")
|
||||
elseif(NOT dep_found)
|
||||
message(${message_type} "Python dependency for running SBOM op ${arg_OP_KEY} "
|
||||
"not found:\n Python: ${python_path} \n Output: \n${dep_find_output}")
|
||||
endif()
|
||||
else()
|
||||
message(DEBUG "Using Python ${python_path} for running SBOM ops.")
|
||||
|
||||
set(QT_INTERNAL_SBOM_DEPS_FOUND_FOR_${arg_OP_KEY} "TRUE" CACHE INTERNAL
|
||||
"All dependencies found to run SBOM OP ${arg_OP_KEY}")
|
||||
endif()
|
||||
|
||||
if(arg_OUT_VAR_DEPS_FOUND)
|
||||
set(${arg_OUT_VAR_DEPS_FOUND} "${QT_INTERNAL_SBOM_DEPS_FOUND_FOR_${arg_OP_KEY}}"
|
||||
PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper that checks a variable for truthiness, and sets the OUT_VAR_DEPS_FOUND and
|
||||
# OUT_VAR_REASON_FAILURE_MESSAGE variables based on what was passed in.
|
||||
function(_qt_internal_sbom_handle_sbom_op_missing_dependency)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
VAR_TO_CHECK
|
||||
OUT_VAR_DEPS_FOUND
|
||||
OUT_VAR_REASON_FAILURE_MESSAGE
|
||||
)
|
||||
set(multi_args
|
||||
FAILURE_MESSAGE
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(NOT arg_VAR_TO_CHECK)
|
||||
message(FATAL_ERROR "VAR_TO_CHECK is required")
|
||||
endif()
|
||||
|
||||
set(reason "")
|
||||
set(value "${${arg_VAR_TO_CHECK}}")
|
||||
if(NOT value)
|
||||
if(arg_FAILURE_MESSAGE)
|
||||
list(JOIN arg_FAILURE_MESSAGE " " reason)
|
||||
endif()
|
||||
set(deps_found FALSE)
|
||||
else()
|
||||
set(deps_found TRUE)
|
||||
endif()
|
||||
|
||||
if(arg_OUT_VAR_DEPS_FOUND)
|
||||
set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
|
||||
endif()
|
||||
if(arg_OUT_VAR_REASON_FAILURE_MESSAGE)
|
||||
set(${arg_OUT_VAR_REASON_FAILURE_MESSAGE} "${reason}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper to query whether the sbom python interpreter is available, and also the error message if it
|
||||
# is not available.
|
||||
function(_qt_internal_sbom_check_python_interpreter_available)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
OUT_VAR_DEPS_FOUND
|
||||
OUT_VAR_REASON_FAILURE_MESSAGE
|
||||
)
|
||||
set(multi_args
|
||||
FAILURE_MESSAGE_PREFIX
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(failure_message
|
||||
"QT_INTERNAL_SBOM_PYTHON_EXECUTABLE is missing a valid path to a python interpreter")
|
||||
|
||||
if(arg_FAILURE_MESSAGE_PREFIX)
|
||||
list(PREPEND failure_message ${arg_FAILURE_MESSAGE_PREFIX})
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_handle_sbom_op_missing_dependency(
|
||||
VAR_TO_CHECK QT_INTERNAL_SBOM_PYTHON_EXECUTABLE
|
||||
FAILURE_MESSAGE ${failure_message}
|
||||
OUT_VAR_DEPS_FOUND deps_found
|
||||
OUT_VAR_REASON_FAILURE_MESSAGE reason
|
||||
)
|
||||
|
||||
if(arg_OUT_VAR_DEPS_FOUND)
|
||||
set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
|
||||
endif()
|
||||
if(arg_OUT_VAR_REASON_FAILURE_MESSAGE)
|
||||
set(${arg_OUT_VAR_REASON_FAILURE_MESSAGE} "${reason}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper to assert that the python interpreter is available.
|
||||
function(_qt_internal_sbom_assert_python_interpreter_available error_message_prefix)
|
||||
_qt_internal_sbom_check_python_interpreter_available(
|
||||
FAILURE_MESSAGE_PREFIX ${error_message_prefix}
|
||||
OUT_VAR_DEPS_FOUND deps_found
|
||||
OUT_VAR_REASON_FAILURE_MESSAGE reason
|
||||
)
|
||||
|
||||
if(NOT deps_found)
|
||||
message(FATAL_ERROR ${reason})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper to query whether an sbom python dependency is available, and also the error message if it
|
||||
# is not available.
|
||||
function(_qt_internal_sbom_check_python_dependency_available)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
OUT_VAR_DEPS_FOUND
|
||||
OUT_VAR_REASON_FAILURE_MESSAGE
|
||||
VAR_TO_CHECK
|
||||
)
|
||||
set(multi_args
|
||||
FAILURE_MESSAGE_PREFIX
|
||||
FAILURE_MESSAGE_SUFFIX
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(failure_message
|
||||
"Required Python dependencies not found: ")
|
||||
|
||||
if(arg_FAILURE_MESSAGE_PREFIX)
|
||||
list(PREPEND failure_message ${arg_FAILURE_MESSAGE_PREFIX})
|
||||
endif()
|
||||
|
||||
if(arg_FAILURE_MESSAGE_SUFFIX)
|
||||
list(APPEND failure_message ${arg_FAILURE_MESSAGE_SUFFIX})
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_handle_sbom_op_missing_dependency(
|
||||
VAR_TO_CHECK ${arg_VAR_TO_CHECK}
|
||||
FAILURE_MESSAGE ${failure_message}
|
||||
OUT_VAR_DEPS_FOUND deps_found
|
||||
OUT_VAR_REASON_FAILURE_MESSAGE reason
|
||||
)
|
||||
|
||||
if(arg_OUT_VAR_DEPS_FOUND)
|
||||
set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
|
||||
endif()
|
||||
if(arg_OUT_VAR_REASON_FAILURE_MESSAGE)
|
||||
set(${arg_OUT_VAR_REASON_FAILURE_MESSAGE} "${reason}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper to assert that an sbom python dependency is available.
|
||||
function(_qt_internal_sbom_assert_python_dependency_available key dep error_message_prefix)
|
||||
_qt_internal_sbom_check_python_dependency_available(
|
||||
VAR_TO_CHECK QT_INTERNAL_SBOM_DEPS_FOUND_FOR_${key}
|
||||
FAILURE_MESSAGE_PREFIX ${error_message_prefix}
|
||||
FAILURE_MESSAGE_SUFFIX ${dep}
|
||||
OUT_VAR_DEPS_FOUND deps_found
|
||||
OUT_VAR_REASON_FAILURE_MESSAGE reason
|
||||
)
|
||||
|
||||
if(NOT deps_found)
|
||||
message(FATAL_ERROR ${reason})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper to query whether the json sbom generation dependency is available, and also the error
|
||||
# message if it is not available.
|
||||
function(_qt_internal_sbom_check_generate_json_dependency_available)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
OUT_VAR_DEPS_FOUND
|
||||
OUT_VAR_REASON_FAILURE_MESSAGE
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
_qt_internal_sbom_check_python_dependency_available(
|
||||
VAR_TO_CHECK QT_INTERNAL_SBOM_DEPS_FOUND_FOR_GENERATE_JSON
|
||||
FAILURE_MESSAGE_SUFFIX "spdx_tools.spdx.clitools.pyspdxtools"
|
||||
OUT_VAR_DEPS_FOUND deps_found
|
||||
OUT_VAR_REASON_FAILURE_MESSAGE reason
|
||||
)
|
||||
|
||||
if(arg_OUT_VAR_DEPS_FOUND)
|
||||
set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
|
||||
endif()
|
||||
if(arg_OUT_VAR_REASON_FAILURE_MESSAGE)
|
||||
set(${arg_OUT_VAR_REASON_FAILURE_MESSAGE} "${reason}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper to generate a SPDX JSON file from a tag/value format file.
|
||||
# This also implies some additional validity checks, useful to ensure a proper sbom file.
|
||||
function(_qt_internal_sbom_generate_json)
|
||||
set(error_message_prefix "Failed to generate an SBOM json file.")
|
||||
_qt_internal_sbom_assert_python_interpreter_available("${error_message_prefix}")
|
||||
_qt_internal_sbom_assert_python_dependency_available(GENERATE_JSON
|
||||
"spdx_tools.spdx.clitools.pyspdxtools" ${error_message_prefix})
|
||||
|
||||
set(content "
|
||||
message(STATUS \"Generating JSON: \${QT_SBOM_OUTPUT_PATH}.json\")
|
||||
execute_process(
|
||||
COMMAND ${QT_INTERNAL_SBOM_PYTHON_EXECUTABLE} -m spdx_tools.spdx.clitools.pyspdxtools
|
||||
-i \"\${QT_SBOM_OUTPUT_PATH}\" -o \"\${QT_SBOM_OUTPUT_PATH}.json\"
|
||||
RESULT_VARIABLE res
|
||||
)
|
||||
if(NOT res EQUAL 0)
|
||||
message(FATAL_ERROR \"SBOM conversion to JSON failed: \${res}\")
|
||||
endif()
|
||||
")
|
||||
|
||||
_qt_internal_get_current_project_sbom_dir(sbom_dir)
|
||||
set(verify_sbom "${sbom_dir}/convert_to_json.cmake")
|
||||
file(GENERATE OUTPUT "${verify_sbom}" CONTENT "${content}")
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_verify_include_files "${verify_sbom}")
|
||||
endfunction()
|
||||
|
||||
# Helper to query whether the all required dependencies are available to generate a tag / value
|
||||
# document from a json one.
|
||||
function(_qt_internal_sbom_verify_deps_for_generate_tag_value_spdx_document)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
OUT_VAR_DEPS_FOUND
|
||||
OUT_VAR_REASON_FAILURE_MESSAGE
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
# First try to find dependencies, because they might not have been found yet.
|
||||
_qt_internal_sbom_find_and_handle_sbom_op_dependencies(
|
||||
OP_KEY "GENERATE_JSON"
|
||||
)
|
||||
|
||||
_qt_internal_sbom_check_python_interpreter_available(
|
||||
OUT_VAR_DEPS_FOUND python_found
|
||||
OUT_VAR_REASON_FAILURE_MESSAGE python_error
|
||||
)
|
||||
_qt_internal_sbom_check_generate_json_dependency_available(
|
||||
OUT_VAR_DEPS_FOUND dep_found
|
||||
OUT_VAR_REASON_FAILURE_MESSAGE dep_error
|
||||
)
|
||||
|
||||
set(reasons "")
|
||||
if(python_error)
|
||||
string(APPEND reasons "${python_error}\n")
|
||||
endif()
|
||||
if(dep_error)
|
||||
string(APPEND reasons "${dep_error}\n")
|
||||
endif()
|
||||
|
||||
if(python_found AND dep_found)
|
||||
set(deps_found "TRUE")
|
||||
else()
|
||||
set(deps_found "FALSE")
|
||||
endif()
|
||||
|
||||
set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
|
||||
set(${arg_OUT_VAR_REASON_FAILURE_MESSAGE} "${reasons}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Helper to generate a tag/value SPDX file from a SPDX JSON format file.
|
||||
#
|
||||
# Will be used by WebEngine to convert the Chromium JSON file to a tag/value SPDX file.
|
||||
#
|
||||
# This conversion needs to happen before the document is referenced in the SBOM generation process,
|
||||
# so that the file already exists when it is parsed for its unique id and namespace.
|
||||
# It also needs to happen before verification codes are computed for the current document
|
||||
# that will depend on the target one, to ensure the the file exists and its checksum can be
|
||||
# computed.
|
||||
#
|
||||
# OPERATION_ID - a unique id for the operation, used to generate a unique cmake file name for
|
||||
# the SBOM generation process.
|
||||
#
|
||||
# INPUT_JSON_PATH - the absolute path to the input JSON file.
|
||||
#
|
||||
# OUTPUT_FILE_PATH - the absolute path where to create the output tag/value SPDX file.
|
||||
# Note that if the output file path is set, it is up to the caller to also copy / install the file
|
||||
# into the build and install directories where the build system expects to find all external
|
||||
# document references.
|
||||
#
|
||||
# OUTPUT_FILE_NAME - when OUTPUT_FILE_PATH is not specified, the output directory is automatically
|
||||
# set to the SBOM output directory. In this case OUTPUT_FILE_NAME can be used to override the
|
||||
# outout file name. If not specified, it will be derived from the input file name.
|
||||
#
|
||||
# OUT_VAR_OUTPUT_FILE_NAME - output variable where to store the output file.
|
||||
#
|
||||
# OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH - output variable where to store the output file path.
|
||||
# Note that the path will contain an unresolved '${QT_SBOM_OUTPUT_DIR}' which only has a value at
|
||||
# install time. So the path can't be used sensibly during configure time.
|
||||
#
|
||||
# OPTIONAL - whether the operation should return early, if the required python dependencies are
|
||||
# not found. OUT_VAR_DEPS_FOUND is still set in that case.
|
||||
#
|
||||
# OUT_VAR_DEPS_FOUND - output variable where to store whether the python dependencies for the
|
||||
# operation were found, and thus the conversion will be attempted.
|
||||
function(_qt_internal_sbom_generate_tag_value_spdx_document)
|
||||
if(NOT QT_GENERATE_SBOM)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(opt_args
|
||||
OPTIONAL
|
||||
)
|
||||
set(single_args
|
||||
OPERATION_ID
|
||||
INPUT_JSON_FILE_PATH
|
||||
OUTPUT_FILE_PATH
|
||||
OUTPUT_FILE_NAME
|
||||
OUT_VAR_OUTPUT_FILE_NAME
|
||||
OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH
|
||||
OUT_VAR_DEPS_FOUND
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
# First try to find dependencies, because they might not have been found yet.
|
||||
_qt_internal_sbom_find_and_handle_sbom_op_dependencies(
|
||||
OP_KEY "GENERATE_JSON"
|
||||
OUT_VAR_DEPS_FOUND deps_found
|
||||
)
|
||||
|
||||
if(arg_OPTIONAL)
|
||||
set(deps_are_required FALSE)
|
||||
else()
|
||||
set(deps_are_required TRUE)
|
||||
endif()
|
||||
|
||||
# If the operation has to succeed, then the deps are required. Assert they are available.
|
||||
if(deps_are_required)
|
||||
set(error_message_prefix "Failed to generate a tag/value SBOM file from a json SBOM file.")
|
||||
_qt_internal_sbom_assert_python_interpreter_available("${error_message_prefix}")
|
||||
_qt_internal_sbom_assert_python_dependency_available(GENERATE_JSON
|
||||
"spdx_tools.spdx.clitools.pyspdxtools" ${error_message_prefix})
|
||||
|
||||
# If the operation is optional, don't error out if the deps are not found, but silently return
|
||||
# and mention that the deps are not found.
|
||||
elseif(NOT deps_found)
|
||||
set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
|
||||
|
||||
if(NOT arg_OPERATION_ID)
|
||||
message(FATAL_ERROR "OPERATION_ID is required")
|
||||
endif()
|
||||
|
||||
if(NOT arg_INPUT_JSON_FILE_PATH)
|
||||
message(FATAL_ERROR "INPUT_JSON_FILE_PATH is required")
|
||||
endif()
|
||||
|
||||
if(arg_OUTPUT_FILE_PATH)
|
||||
set(output_path "${arg_OUTPUT_FILE_PATH}")
|
||||
else()
|
||||
if(arg_OUTPUT_FILE_NAME)
|
||||
set(output_name "${arg_OUTPUT_FILE_NAME}")
|
||||
else()
|
||||
# Use the input file name without the last extension (without .json) as the output name.
|
||||
get_filename_component(output_name "${arg_INPUT_JSON_FILE_PATH}" NAME_WLE)
|
||||
endif()
|
||||
set(output_path "\${QT_SBOM_OUTPUT_DIR}/${output_name}")
|
||||
endif()
|
||||
|
||||
if(arg_OUT_VAR_OUTPUT_FILE_NAME)
|
||||
get_filename_component(output_name_resolved "${output_path}" NAME)
|
||||
set(${arg_OUT_VAR_OUTPUT_FILE_NAME} "${output_name_resolved}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if(arg_OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH)
|
||||
set(${arg_OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH} "${output_path}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
set(content "
|
||||
message(STATUS
|
||||
\"Generating tag/value SPDX document: ${output_path} from \"
|
||||
\"${arg_INPUT_JSON_FILE_PATH}\")
|
||||
execute_process(
|
||||
COMMAND ${QT_INTERNAL_SBOM_PYTHON_EXECUTABLE} -m spdx_tools.spdx.clitools.pyspdxtools
|
||||
-i \"${arg_INPUT_JSON_FILE_PATH}\" -o \"${output_path}\"
|
||||
RESULT_VARIABLE res
|
||||
)
|
||||
if(NOT res EQUAL 0)
|
||||
message(FATAL_ERROR \"SBOM conversion to tag/value failed: \${res}\")
|
||||
endif()
|
||||
")
|
||||
|
||||
_qt_internal_get_current_project_sbom_dir(sbom_dir)
|
||||
set(convert_sbom "${sbom_dir}/convert_to_tag_value_${arg_OPERATION_ID}.cmake")
|
||||
file(GENERATE OUTPUT "${convert_sbom}" CONTENT "${content}")
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_include_files
|
||||
"${convert_sbom}")
|
||||
endfunction()
|
||||
|
||||
# Helper to verify the generated sbom is valid.
|
||||
function(_qt_internal_sbom_verify_valid)
|
||||
set(error_message_prefix "Failed to verify SBOM file syntax.")
|
||||
_qt_internal_sbom_assert_python_interpreter_available("${error_message_prefix}")
|
||||
_qt_internal_sbom_assert_python_dependency_available(VERIFY_SBOM
|
||||
"spdx_tools.spdx.clitools.pyspdxtools" ${error_message_prefix})
|
||||
|
||||
set(content "
|
||||
message(STATUS \"Verifying: \${QT_SBOM_OUTPUT_PATH}\")
|
||||
execute_process(
|
||||
COMMAND ${QT_INTERNAL_SBOM_PYTHON_EXECUTABLE} -m spdx_tools.spdx.clitools.pyspdxtools
|
||||
-i \"\${QT_SBOM_OUTPUT_PATH}\"
|
||||
RESULT_VARIABLE res
|
||||
)
|
||||
if(NOT res EQUAL 0)
|
||||
message(FATAL_ERROR \"SBOM verification failed: \${res}\")
|
||||
endif()
|
||||
")
|
||||
|
||||
_qt_internal_get_current_project_sbom_dir(sbom_dir)
|
||||
set(verify_sbom "${sbom_dir}/verify_valid.cmake")
|
||||
file(GENERATE OUTPUT "${verify_sbom}" CONTENT "${content}")
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_verify_include_files "${verify_sbom}")
|
||||
endfunction()
|
||||
|
||||
# Helper to verify the generated sbom is NTIA compliant.
|
||||
function(_qt_internal_sbom_verify_ntia_compliant)
|
||||
set(error_message_prefix "Failed to run NTIA checker on SBOM file.")
|
||||
_qt_internal_sbom_assert_python_interpreter_available("${error_message_prefix}")
|
||||
_qt_internal_sbom_assert_python_dependency_available(RUN_NTIA
|
||||
"ntia_conformance_checker.main" ${error_message_prefix})
|
||||
|
||||
set(content "
|
||||
message(STATUS \"Checking for NTIA compliance: \${QT_SBOM_OUTPUT_PATH}\")
|
||||
execute_process(
|
||||
COMMAND ${QT_INTERNAL_SBOM_PYTHON_EXECUTABLE} -m ntia_conformance_checker.main
|
||||
--file \"\${QT_SBOM_OUTPUT_PATH}\"
|
||||
RESULT_VARIABLE res
|
||||
)
|
||||
if(NOT res EQUAL 0)
|
||||
message(FATAL_ERROR \"SBOM NTIA verification failed: \{res}\")
|
||||
endif()
|
||||
")
|
||||
|
||||
_qt_internal_get_current_project_sbom_dir(sbom_dir)
|
||||
set(verify_sbom "${sbom_dir}/verify_ntia.cmake")
|
||||
file(GENERATE OUTPUT "${verify_sbom}" CONTENT "${content}")
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_verify_include_files "${verify_sbom}")
|
||||
endfunction()
|
||||
|
||||
# Helper to show the main sbom document info in the form of a CLI table.
|
||||
function(_qt_internal_sbom_show_table)
|
||||
set(extra_code_begin "")
|
||||
if(DEFINED ENV{COIN_UNIQUE_JOB_ID})
|
||||
# The output of the process dynamically adjusts the width of the shown table based on the
|
||||
# console width. In the CI, the width is very short for some reason, and thus the output
|
||||
# is truncated in the CI log. Explicitly set a bigger width to avoid this.
|
||||
set(extra_code_begin "
|
||||
set(backup_env_columns \$ENV{COLUMNS})
|
||||
set(ENV{COLUMNS} 150)
|
||||
")
|
||||
set(extra_code_end "
|
||||
set(ENV{COLUMNS} \${backup_env_columns})
|
||||
")
|
||||
endif()
|
||||
|
||||
set(content "
|
||||
message(STATUS \"Showing main SBOM document info: \${QT_SBOM_OUTPUT_PATH}\")
|
||||
|
||||
${extra_code_begin}
|
||||
execute_process(
|
||||
COMMAND ${QT_SBOM_PROGRAM_SBOM2DOC} -i \"\${QT_SBOM_OUTPUT_PATH}\"
|
||||
RESULT_VARIABLE res
|
||||
)
|
||||
${extra_code_end}
|
||||
if(NOT res EQUAL 0)
|
||||
message(FATAL_ERROR \"Showing SBOM document failed: \${res}\")
|
||||
endif()
|
||||
")
|
||||
|
||||
_qt_internal_get_current_project_sbom_dir(sbom_dir)
|
||||
set(verify_sbom "${sbom_dir}/show_table.cmake")
|
||||
file(GENERATE OUTPUT "${verify_sbom}" CONTENT "${content}")
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_verify_include_files "${verify_sbom}")
|
||||
endfunction()
|
||||
|
||||
# Helper to audit the generated sbom.
|
||||
function(_qt_internal_sbom_audit)
|
||||
set(opt_args NO_ERROR)
|
||||
set(single_args "")
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(handle_error "")
|
||||
if(NOT arg_NO_ERROR)
|
||||
set(handle_error "
|
||||
if(NOT res EQUAL 0)
|
||||
message(FATAL_ERROR \"SBOM Audit failed: \${res}\")
|
||||
endif()
|
||||
")
|
||||
endif()
|
||||
|
||||
set(content "
|
||||
message(STATUS \"Auditing SBOM: \${QT_SBOM_OUTPUT_PATH}\")
|
||||
execute_process(
|
||||
COMMAND ${QT_SBOM_PROGRAM_SBOMAUDIT} -i \"\${QT_SBOM_OUTPUT_PATH}\"
|
||||
--disable-license-check --cpecheck --offline
|
||||
RESULT_VARIABLE res
|
||||
)
|
||||
${handle_error}
|
||||
")
|
||||
|
||||
_qt_internal_get_current_project_sbom_dir(sbom_dir)
|
||||
set(verify_sbom "${sbom_dir}/audit.cmake")
|
||||
file(GENERATE OUTPUT "${verify_sbom}" CONTENT "${content}")
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_verify_include_files "${verify_sbom}")
|
||||
endfunction()
|
||||
|
||||
# Returns path to project's potential root source reuse.toml file.
|
||||
function(_qt_internal_sbom_get_project_reuse_toml_path out_var)
|
||||
set(reuse_toml_path "${PROJECT_SOURCE_DIR}/REUSE.toml")
|
||||
set(${out_var} "${reuse_toml_path}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Helper to generate and install a source SBOM using reuse.
|
||||
function(_qt_internal_sbom_generate_reuse_source_sbom)
|
||||
set(opt_args NO_ERROR)
|
||||
set(single_args "")
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
_qt_internal_get_current_project_sbom_dir(sbom_dir)
|
||||
set(file_op "${sbom_dir}/generate_reuse_source_sbom.cmake")
|
||||
|
||||
_qt_internal_sbom_get_project_reuse_toml_path(reuse_toml_path)
|
||||
if(NOT EXISTS "${reuse_toml_path}" AND NOT QT_FORCE_SOURCE_SBOM_GENERATION)
|
||||
set(skip_message
|
||||
"Skipping source SBOM generation: No reuse.toml file found at '${reuse_toml_path}'.")
|
||||
message(STATUS "${skip_message}")
|
||||
|
||||
set(content "
|
||||
message(STATUS \"${skip_message}\")
|
||||
")
|
||||
|
||||
file(GENERATE OUTPUT "${file_op}" CONTENT "${content}")
|
||||
set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_post_generation_include_files
|
||||
"${file_op}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(handle_error "")
|
||||
if(NOT arg_NO_ERROR)
|
||||
set(handle_error "
|
||||
if(NOT res EQUAL 0)
|
||||
message(FATAL_ERROR \"Source SBOM generation using reuse tool failed: \${res}\")
|
||||
endif()
|
||||
")
|
||||
endif()
|
||||
|
||||
set(source_sbom_path "\${QT_SBOM_OUTPUT_PATH_WITHOUT_EXT}.source.spdx")
|
||||
file(TO_CMAKE_PATH "$ENV{QT_QA_LICENSE_TEST_DIR}/$ENV{QT_SOURCE_SBOM_TEST_SCRIPT}"
|
||||
full_path_to_license_test)
|
||||
set(verify_source_sbom "
|
||||
if(res EQUAL 0)
|
||||
message(STATUS \"Verifying source SBOM ${source_sbom_path} using qtqa tst_licenses.pl ${full_path_to_license_test}\")
|
||||
if(NOT EXISTS \"${full_path_to_license_test}\")
|
||||
message(FATAL_ERROR \"Source SBOM check has failed: The tst_licenses.pl script could not be found at ${full_path_to_license_test}\")
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND perl \"\$ENV{QT_SOURCE_SBOM_TEST_SCRIPT}\" -sbomonly -sbom \"${source_sbom_path}\"
|
||||
WORKING_DIRECTORY \"\$ENV{QT_QA_LICENSE_TEST_DIR}\"
|
||||
RESULT_VARIABLE res
|
||||
COMMAND_ECHO STDOUT
|
||||
)
|
||||
if(NOT res EQUAL 0)
|
||||
message(FATAL_ERROR \"Source SBOM check has failed: \${res}\")
|
||||
endif()
|
||||
endif()
|
||||
")
|
||||
|
||||
set(extra_reuse_args "")
|
||||
|
||||
get_property(project_supplier GLOBAL PROPERTY _qt_sbom_project_supplier)
|
||||
if(project_supplier)
|
||||
get_property(project_supplier_url GLOBAL PROPERTY _qt_sbom_project_supplier_url)
|
||||
|
||||
# Add the supplier url if available. Add it in parenthesis to stop reuse from adding its
|
||||
# own empty parenthesis.
|
||||
if(project_supplier_url)
|
||||
set(project_supplier "${project_supplier} (${project_supplier_url})")
|
||||
endif()
|
||||
|
||||
# Unfortunately there's no way to silence the addition of the 'Creator: Person' field,
|
||||
# even though 'Creator: Organization' is supplied.
|
||||
list(APPEND extra_reuse_args --creator-organization "${project_supplier}")
|
||||
endif()
|
||||
|
||||
set(content "
|
||||
message(STATUS \"Generating source SBOM using reuse tool: ${source_sbom_path}\")
|
||||
set(extra_reuse_args \"${extra_reuse_args}\")
|
||||
execute_process(
|
||||
COMMAND
|
||||
${QT_SBOM_PROGRAM_REUSE}
|
||||
--root \"${PROJECT_SOURCE_DIR}\"
|
||||
spdx
|
||||
-o ${source_sbom_path}
|
||||
\${extra_reuse_args}
|
||||
RESULT_VARIABLE res
|
||||
)
|
||||
${handle_error}
|
||||
if(\"\$ENV{VERIFY_SOURCE_SBOM}\")
|
||||
${verify_source_sbom}
|
||||
endif()
|
||||
")
|
||||
|
||||
file(GENERATE OUTPUT "${file_op}" CONTENT "${content}")
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_post_generation_include_files "${file_op}")
|
||||
endfunction()
|
||||
|
||||
# Helper to run 'reuse lint' on the project source dir.
|
||||
function(_qt_internal_sbom_run_reuse_lint)
|
||||
set(opt_args
|
||||
NO_ERROR
|
||||
)
|
||||
set(single_args
|
||||
BUILD_TIME_SCRIPT_PATH_OUT_VAR
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
# If no reuse.toml file exists, it means the repo is likely not reuse compliant yet,
|
||||
# so we shouldn't error out during installation when running the lint.
|
||||
_qt_internal_sbom_get_project_reuse_toml_path(reuse_toml_path)
|
||||
if(NOT EXISTS "${reuse_toml_path}" AND NOT QT_FORCE_REUSE_LINT_ERROR)
|
||||
set(arg_NO_ERROR TRUE)
|
||||
endif()
|
||||
|
||||
set(handle_error "")
|
||||
if(NOT arg_NO_ERROR)
|
||||
set(handle_error "
|
||||
if(NOT res EQUAL 0)
|
||||
message(FATAL_ERROR \"Running 'reuse lint' failed: \${res}\")
|
||||
endif()
|
||||
")
|
||||
endif()
|
||||
|
||||
set(content "
|
||||
message(STATUS \"Running 'reuse lint' in '${PROJECT_SOURCE_DIR}'.\")
|
||||
execute_process(
|
||||
COMMAND ${QT_SBOM_PROGRAM_REUSE} --root \"${PROJECT_SOURCE_DIR}\" lint
|
||||
RESULT_VARIABLE res
|
||||
)
|
||||
${handle_error}
|
||||
")
|
||||
|
||||
_qt_internal_get_current_project_sbom_dir(sbom_dir)
|
||||
set(file_op_build "${sbom_dir}/run_reuse_lint_build.cmake")
|
||||
file(GENERATE OUTPUT "${file_op_build}" CONTENT "${content}")
|
||||
|
||||
# Allow skipping running 'reuse lint' during installation. But still allow running it during
|
||||
# build time. This is a fail safe opt-out in case some repo needs it.
|
||||
if(QT_FORCE_SKIP_REUSE_LINT_ON_INSTALL)
|
||||
set(skip_message "Skipping running 'reuse lint' in '${PROJECT_SOURCE_DIR}'.")
|
||||
|
||||
set(content "
|
||||
message(STATUS \"${skip_message}\")
|
||||
")
|
||||
set(file_op_install "${sbom_dir}/run_reuse_lint_install.cmake")
|
||||
file(GENERATE OUTPUT "${file_op_install}" CONTENT "${content}")
|
||||
else()
|
||||
# Just reuse the already generated script for installation as well.
|
||||
set(file_op_install "${file_op_build}")
|
||||
endif()
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_verify_include_files "${file_op_install}")
|
||||
|
||||
if(arg_BUILD_TIME_SCRIPT_PATH_OUT_VAR)
|
||||
set(${arg_BUILD_TIME_SCRIPT_PATH_OUT_VAR} "${file_op_build}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
305
cmake/QtPublicSbomPurlHelpers.cmake
Normal file
305
cmake/QtPublicSbomPurlHelpers.cmake
Normal file
@ -0,0 +1,305 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# Parse purl arguments for a specific purl entry.
|
||||
# arguments_var_name is the variable name that contains the args.
|
||||
# prefix is the prefix passed to cmake_parse_arguments.
|
||||
macro(_qt_internal_sbom_parse_purl_entry_options prefix arguments_var_name)
|
||||
_qt_internal_get_sbom_purl_parsing_options(purl_opt_args purl_single_args purl_multi_args)
|
||||
|
||||
cmake_parse_arguments(${prefix} "${purl_opt_args}" "${purl_single_args}" "${purl_multi_args}"
|
||||
${${arguments_var_name}})
|
||||
_qt_internal_validate_all_args_are_parsed(${prefix})
|
||||
endmacro()
|
||||
|
||||
# Helper macro to prepare forwarding all set purl options to some other function.
|
||||
# Expects the options names to be set in the parent scope by calling
|
||||
# _qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
|
||||
macro(_qt_internal_sbom_forward_purl_handling_options args_var_name)
|
||||
if(NOT opt_args)
|
||||
message(FATAL_ERROR
|
||||
"Expected opt_args to be set by _qt_internal_get_sbom_purl_handling_options")
|
||||
endif()
|
||||
if(NOT single_args)
|
||||
message(FATAL_ERROR
|
||||
"Expected single_args to be set by _qt_internal_get_sbom_purl_handling_options")
|
||||
endif()
|
||||
if(NOT multi_args)
|
||||
message(FATAL_ERROR
|
||||
"Expected multi_args to be set by _qt_internal_get_sbom_purl_handling_options")
|
||||
endif()
|
||||
_qt_internal_forward_function_args(
|
||||
FORWARD_PREFIX arg
|
||||
FORWARD_OUT_VAR ${args_var_name}
|
||||
FORWARD_OPTIONS
|
||||
${opt_args}
|
||||
FORWARD_SINGLE
|
||||
${single_args}
|
||||
FORWARD_MULTI
|
||||
${multi_args}
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# Handles purl arguments specified to functions like qt_internal_add_sbom.
|
||||
#
|
||||
# Synopsis
|
||||
#
|
||||
# qt_internal_add_sbom(<target>
|
||||
# PURLS
|
||||
# [[PURL_ENTRY
|
||||
# PURL_ID <id>
|
||||
# PURL_TYPE <type>
|
||||
# PURL_NAMESPACE <namespace>
|
||||
# PURL_NAME <name>
|
||||
# PURL_VERSION <version>]...]
|
||||
# PURL_VALUES
|
||||
# [purl-string...]
|
||||
# )
|
||||
#
|
||||
# Example
|
||||
#
|
||||
# qt_internal_add_sbom(<target>
|
||||
# PURLS
|
||||
# PURL_ENTRY
|
||||
# PURL_ID "UPSTREAM"
|
||||
# PURL_TYPE "github"
|
||||
# PURL_NAMESPACE "harfbuzz"
|
||||
# PURL_NAME "harfbuzz"
|
||||
# PURL_VERSION "v8.5.0"
|
||||
# PURL_ENTRY
|
||||
# PURL_ID "MIRROR"
|
||||
# PURL_TYPE "git"
|
||||
# PURL_NAMESPACE "harfbuzz"
|
||||
# PURL_NAME "harfbuzz"
|
||||
# PURL_QUALIFIERS "vcs_url=https://code.qt.io/qt/qtbase"
|
||||
# ....
|
||||
# PURL_VALUES
|
||||
# pkg:git/harfbuzz/harfbuzz@v8.5.0
|
||||
# pkg:github/harfbuzz/harfbuzz@v8.5.0
|
||||
# ....
|
||||
#
|
||||
#
|
||||
# PURLS accepts multiple purl entries, each starting with the PURL_ENTRY keyword.
|
||||
# PURL_VALUES takes a list of pre-built purl strings.
|
||||
#
|
||||
# If no arguments are specified, for qt entity types (e.g. libraries built as part of Qt repos),
|
||||
# default purls will be generated.
|
||||
#
|
||||
# There is no limit to the number of purls that can be added to a target.
|
||||
function(_qt_internal_sbom_handle_purl_values target)
|
||||
_qt_internal_get_sbom_purl_handling_options(opt_args single_args multi_args)
|
||||
list(APPEND single_args OUT_VAR)
|
||||
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(NOT arg_OUT_VAR)
|
||||
message(FATAL_ERROR "OUT_VAR must be set")
|
||||
endif()
|
||||
|
||||
_qt_internal_get_sbom_purl_parsing_options(purl_opt_args purl_single_args purl_multi_args)
|
||||
|
||||
set(project_package_options "")
|
||||
|
||||
# Collect each PURL_ENTRY args into a separate variable.
|
||||
set(purl_idx -1)
|
||||
set(purl_entry_indices "")
|
||||
foreach(purl_arg IN LISTS arg_PURLS)
|
||||
if(purl_arg STREQUAL "PURL_ENTRY")
|
||||
math(EXPR purl_idx "${purl_idx}+1")
|
||||
list(APPEND purl_entry_indices "${purl_idx}")
|
||||
elseif(purl_idx GREATER_EQUAL 0)
|
||||
list(APPEND purl_${purl_idx}_args "${purl_arg}")
|
||||
else()
|
||||
message(FATAL_ERROR "Missing PURL_ENTRY keyword.")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Validate the args for each collected entry.
|
||||
foreach(purl_idx IN LISTS purl_entry_indices)
|
||||
list(LENGTH purl_${purl_idx}_args num_args)
|
||||
if(num_args LESS 1)
|
||||
message(FATAL_ERROR "Empty PURL_ENTRY encountered.")
|
||||
endif()
|
||||
_qt_internal_sbom_parse_purl_entry_options(arg purl_${purl_idx}_args)
|
||||
endforeach()
|
||||
|
||||
# Append qt specific placeholder entries when handling Qt entities.
|
||||
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL)
|
||||
_qt_internal_sbom_forward_purl_handling_options(purl_handling_args)
|
||||
_qt_internal_sbom_handle_qt_entity_purl_entries(${purl_handling_args}
|
||||
OUT_VAR_IDS qt_purl_ids
|
||||
)
|
||||
if(qt_purl_ids)
|
||||
# Create purl placeholder indices for each qt purl id.
|
||||
foreach(qt_purl_id IN LISTS qt_purl_ids)
|
||||
math(EXPR purl_idx "${purl_idx}+1")
|
||||
list(APPEND purl_entry_indices "${purl_idx}")
|
||||
list(APPEND purl_${purl_idx}_args PURL_ID "${qt_purl_id}")
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(purl_idx IN LISTS purl_entry_indices)
|
||||
# Clear previous values.
|
||||
foreach(option_name IN LISTS purl_opt_args purl_single_args purl_multi_args)
|
||||
unset(arg_${option_name})
|
||||
endforeach()
|
||||
|
||||
_qt_internal_sbom_parse_purl_entry_options(arg purl_${purl_idx}_args)
|
||||
|
||||
set(purl_args "")
|
||||
|
||||
# Override the purl version with the package version.
|
||||
if(arg_PURL_USE_PACKAGE_VERSION AND arg_PACKAGE_VERSION)
|
||||
set(arg_PURL_VERSION "${arg_PACKAGE_VERSION}")
|
||||
endif()
|
||||
|
||||
# Append a vcs_url to the qualifiers if specified.
|
||||
if(arg_PURL_VCS_URL)
|
||||
list(APPEND arg_PURL_QUALIFIERS "vcs_url=${arg_PURL_VCS_URL}")
|
||||
endif()
|
||||
|
||||
_qt_internal_forward_function_args(
|
||||
FORWARD_APPEND
|
||||
FORWARD_PREFIX arg
|
||||
FORWARD_OUT_VAR purl_args
|
||||
FORWARD_OPTIONS
|
||||
${purl_opt_args}
|
||||
FORWARD_SINGLE
|
||||
${purl_single_args}
|
||||
FORWARD_MULTI
|
||||
${purl_multi_args}
|
||||
)
|
||||
|
||||
# Qt entity types get special treatment to gather the required args.
|
||||
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL
|
||||
AND arg_PURL_ID
|
||||
AND arg_PURL_ID IN_LIST qt_purl_ids)
|
||||
|
||||
_qt_internal_sbom_handle_qt_entity_purl("${target}"
|
||||
${purl_handling_args}
|
||||
PURL_ID "${arg_PURL_ID}"
|
||||
OUT_PURL_ARGS qt_purl_args
|
||||
)
|
||||
if(qt_purl_args)
|
||||
list(APPEND purl_args "${qt_purl_args}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_assemble_purl(${target}
|
||||
${purl_args}
|
||||
OUT_VAR package_manager_external_ref
|
||||
)
|
||||
list(APPEND project_package_options ${package_manager_external_ref})
|
||||
endforeach()
|
||||
|
||||
foreach(purl_value IN LISTS arg_PURL_VALUES)
|
||||
_qt_internal_sbom_get_purl_value_extref(
|
||||
VALUE "${purl_value}" OUT_VAR package_manager_external_ref)
|
||||
|
||||
# The order in which the purls are generated, matters for tools that consume the SBOM.
|
||||
# Some tools can only handle one PURL per package, so the first one should be the
|
||||
# important one.
|
||||
# For now, I deem that the directly specified ones (probably via a qt_attribution.json
|
||||
# file) are the more important ones. So we prepend them.
|
||||
list(PREPEND project_package_options ${package_manager_external_ref})
|
||||
endforeach()
|
||||
|
||||
set(${arg_OUT_VAR} "${project_package_options}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Assembles an external reference purl identifier.
|
||||
# PURL_TYPE and PURL_NAME are required.
|
||||
# Stores the result in the OUT_VAR.
|
||||
# Accepted options:
|
||||
# PURL_TYPE
|
||||
# PURL_NAME
|
||||
# PURL_NAMESPACE
|
||||
# PURL_VERSION
|
||||
# PURL_SUBPATH
|
||||
# PURL_QUALIFIERS
|
||||
function(_qt_internal_sbom_assemble_purl target)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
OUT_VAR
|
||||
)
|
||||
set(multi_args "")
|
||||
|
||||
_qt_internal_get_sbom_purl_parsing_options(purl_opt_args purl_single_args purl_multi_args)
|
||||
list(APPEND opt_args ${purl_opt_args})
|
||||
list(APPEND single_args ${purl_single_args})
|
||||
list(APPEND multi_args ${purl_multi_args})
|
||||
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(purl_scheme "pkg")
|
||||
|
||||
if(NOT arg_PURL_TYPE)
|
||||
message(FATAL_ERROR "PURL_TYPE must be set")
|
||||
endif()
|
||||
|
||||
if(NOT arg_PURL_NAME)
|
||||
message(FATAL_ERROR "PURL_NAME must be set")
|
||||
endif()
|
||||
|
||||
if(NOT arg_OUT_VAR)
|
||||
message(FATAL_ERROR "OUT_VAR must be set")
|
||||
endif()
|
||||
|
||||
# https://github.com/package-url/purl-spec
|
||||
# Spec is 'scheme:type/namespace/name@version?qualifiers#subpath'
|
||||
set(purl "${purl_scheme}:${arg_PURL_TYPE}")
|
||||
|
||||
if(arg_PURL_NAMESPACE)
|
||||
string(APPEND purl "/${arg_PURL_NAMESPACE}")
|
||||
endif()
|
||||
|
||||
string(APPEND purl "/${arg_PURL_NAME}")
|
||||
|
||||
if(arg_PURL_VERSION)
|
||||
string(APPEND purl "@${arg_PURL_VERSION}")
|
||||
endif()
|
||||
|
||||
if(arg_PURL_QUALIFIERS)
|
||||
# TODO: Note that the qualifiers are expected to be URL encoded, which this implementation
|
||||
# is not doing at the moment.
|
||||
list(JOIN arg_PURL_QUALIFIERS "&" qualifiers)
|
||||
string(APPEND purl "?${qualifiers}")
|
||||
endif()
|
||||
|
||||
if(arg_PURL_SUBPATH)
|
||||
string(APPEND purl "#${arg_PURL_SUBPATH}")
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_get_purl_value_extref(VALUE "${purl}" OUT_VAR result)
|
||||
|
||||
set(${arg_OUT_VAR} "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Takes a PURL VALUE and returns an SBOM purl external reference in OUT_VAR.
|
||||
function(_qt_internal_sbom_get_purl_value_extref)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
OUT_VAR
|
||||
VALUE
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(NOT arg_OUT_VAR)
|
||||
message(FATAL_ERROR "OUT_VAR must be set")
|
||||
endif()
|
||||
|
||||
if(NOT arg_VALUE)
|
||||
message(FATAL_ERROR "VALUE must be set")
|
||||
endif()
|
||||
|
||||
# SPDX SBOM External reference type.
|
||||
set(ext_ref_prefix "PACKAGE-MANAGER purl")
|
||||
set(external_ref "${ext_ref_prefix} ${arg_VALUE}")
|
||||
set(result "EXTREF" "${external_ref}")
|
||||
set(${arg_OUT_VAR} "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
250
cmake/QtPublicSbomPythonHelpers.cmake
Normal file
250
cmake/QtPublicSbomPythonHelpers.cmake
Normal file
@ -0,0 +1,250 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# Helper macro to find python and a given dependency. Expects the caller to set all of the vars.
|
||||
# Meant to reduce the line noise due to the repeated calls.
|
||||
macro(_qt_internal_sbom_find_python_and_dependency_helper_lambda)
|
||||
_qt_internal_sbom_find_python_and_dependency_helper(
|
||||
PYTHON_ARGS
|
||||
${extra_python_args}
|
||||
${python_common_args}
|
||||
DEPENDENCY_ARGS
|
||||
DEPENDENCY_IMPORT_STATEMENT "${import_statement}"
|
||||
OUT_VAR_PYTHON_PATH python_path
|
||||
OUT_VAR_PYTHON_FOUND python_found
|
||||
OUT_VAR_DEP_FOUND dep_found
|
||||
OUT_VAR_PYTHON_AND_DEP_FOUND everything_found
|
||||
OUT_VAR_DEP_FIND_OUTPUT dep_find_output
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# Tries to find python and a given dependency based on the args passed to PYTHON_ARGS and
|
||||
# DEPENDENCY_ARGS which are forwarded to the respective finding functions.
|
||||
# Returns the path to the python interpreter, whether it was found, whether the dependency was
|
||||
# found, whether both were found, and the reason why the dependency might not be found.
|
||||
function(_qt_internal_sbom_find_python_and_dependency_helper)
|
||||
set(opt_args)
|
||||
set(single_args
|
||||
OUT_VAR_PYTHON_PATH
|
||||
OUT_VAR_PYTHON_FOUND
|
||||
OUT_VAR_DEP_FOUND
|
||||
OUT_VAR_PYTHON_AND_DEP_FOUND
|
||||
OUT_VAR_DEP_FIND_OUTPUT
|
||||
)
|
||||
set(multi_args
|
||||
PYTHON_ARGS
|
||||
DEPENDENCY_ARGS
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(everything_found_inner FALSE)
|
||||
set(deps_find_output_inner "")
|
||||
|
||||
if(NOT arg_OUT_VAR_PYTHON_PATH)
|
||||
message(FATAL_ERROR "OUT_VAR_PYTHON_PATH var is required")
|
||||
endif()
|
||||
|
||||
if(NOT arg_OUT_VAR_PYTHON_FOUND)
|
||||
message(FATAL_ERROR "OUT_VAR_PYTHON_FOUND var is required")
|
||||
endif()
|
||||
|
||||
if(NOT arg_OUT_VAR_DEP_FOUND)
|
||||
message(FATAL_ERROR "OUT_VAR_DEP_FOUND var is required")
|
||||
endif()
|
||||
|
||||
if(NOT arg_OUT_VAR_PYTHON_AND_DEP_FOUND)
|
||||
message(FATAL_ERROR "OUT_VAR_PYTHON_AND_DEP_FOUND var is required")
|
||||
endif()
|
||||
|
||||
if(NOT arg_OUT_VAR_DEP_FIND_OUTPUT)
|
||||
message(FATAL_ERROR "OUT_VAR_DEP_FIND_OUTPUT var is required")
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_find_python_helper(
|
||||
${arg_PYTHON_ARGS}
|
||||
OUT_VAR_PYTHON_PATH python_path_inner
|
||||
OUT_VAR_PYTHON_FOUND python_found_inner
|
||||
)
|
||||
|
||||
if(python_found_inner AND python_path_inner)
|
||||
_qt_internal_sbom_find_python_dependency_helper(
|
||||
${arg_DEPENDENCY_ARGS}
|
||||
PYTHON_PATH "${python_path_inner}"
|
||||
OUT_VAR_FOUND dep_found_inner
|
||||
OUT_VAR_OUTPUT dep_find_output_inner
|
||||
)
|
||||
|
||||
if(dep_found_inner)
|
||||
set(everything_found_inner TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(${arg_OUT_VAR_PYTHON_PATH} "${python_path_inner}" PARENT_SCOPE)
|
||||
set(${arg_OUT_VAR_PYTHON_FOUND} "${python_found_inner}" PARENT_SCOPE)
|
||||
set(${arg_OUT_VAR_DEP_FOUND} "${dep_found_inner}" PARENT_SCOPE)
|
||||
set(${arg_OUT_VAR_PYTHON_AND_DEP_FOUND} "${everything_found_inner}" PARENT_SCOPE)
|
||||
set(${arg_OUT_VAR_DEP_FIND_OUTPUT} "${dep_find_output_inner}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Tries to find the python intrepreter, given the QT_SBOM_PYTHON_INTERP path hint, as well as
|
||||
# other options.
|
||||
# Ignores any previously found python.
|
||||
# Returns the python interpreter path and whether it was successfully found.
|
||||
#
|
||||
# This is intentionally a function, and not a macro, to prevent overriding the Python3_EXECUTABLE
|
||||
# non-cache variable in a global scope in case if a different python is found and used for a
|
||||
# different purpose (e.g. qtwebengine or qtinterfaceframework).
|
||||
# The reason to use a different python is that an already found python might not be the version we
|
||||
# need, or might lack the dependencies we need.
|
||||
# https://gitlab.kitware.com/cmake/cmake/-/issues/21797#note_901621 claims that finding multiple
|
||||
# python versions in separate directory scopes is possible, and I claim a function scope is as
|
||||
# good as a directory scope.
|
||||
function(_qt_internal_sbom_find_python_helper)
|
||||
set(opt_args
|
||||
SEARCH_IN_FRAMEWORKS
|
||||
QUIET
|
||||
)
|
||||
set(single_args
|
||||
VERSION
|
||||
OUT_VAR_PYTHON_PATH
|
||||
OUT_VAR_PYTHON_FOUND
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(NOT arg_OUT_VAR_PYTHON_PATH)
|
||||
message(FATAL_ERROR "OUT_VAR_PYTHON_PATH var is required")
|
||||
endif()
|
||||
|
||||
if(NOT arg_OUT_VAR_PYTHON_FOUND)
|
||||
message(FATAL_ERROR "OUT_VAR_PYTHON_FOUND var is required")
|
||||
endif()
|
||||
|
||||
# Allow disabling looking for a python interpreter shipped as part of a macOS system framework.
|
||||
if(NOT arg_SEARCH_IN_FRAMEWORKS)
|
||||
set(Python3_FIND_FRAMEWORK NEVER)
|
||||
endif()
|
||||
|
||||
set(required_version "")
|
||||
if(arg_VERSION)
|
||||
set(required_version "${arg_VERSION}")
|
||||
endif()
|
||||
|
||||
set(find_quiet "")
|
||||
if(arg_QUIET)
|
||||
set(find_quiet "QUIET")
|
||||
endif()
|
||||
|
||||
# Locally reset any executable that was possibly already found.
|
||||
# We do this to ensure we always re-do the lookup/
|
||||
# This needs to be set to an empty string, to override any cache variable
|
||||
set(Python3_EXECUTABLE "")
|
||||
|
||||
# This needs to be unset, because the Python module checks whether the variable is defined, not
|
||||
# whether it is empty.
|
||||
unset(_Python3_EXECUTABLE)
|
||||
|
||||
if(QT_SBOM_PYTHON_INTERP)
|
||||
set(Python3_ROOT_DIR ${QT_SBOM_PYTHON_INTERP})
|
||||
endif()
|
||||
|
||||
find_package(Python3 ${required_version} ${find_quiet} COMPONENTS Interpreter)
|
||||
|
||||
set(${arg_OUT_VAR_PYTHON_PATH} "${Python3_EXECUTABLE}" PARENT_SCOPE)
|
||||
set(${arg_OUT_VAR_PYTHON_FOUND} "${Python3_Interpreter_FOUND}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Helper that takes an python import statement to run using the given python interpreter path,
|
||||
# to confirm that the given python dependency can be found.
|
||||
# Returns whether the dependency was found and the output of running the import, for error handling.
|
||||
function(_qt_internal_sbom_find_python_dependency_helper)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
DEPENDENCY_IMPORT_STATEMENT
|
||||
PYTHON_PATH
|
||||
OUT_VAR_FOUND
|
||||
OUT_VAR_OUTPUT
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(NOT arg_PYTHON_PATH)
|
||||
message(FATAL_ERROR "Python interpreter path not given.")
|
||||
endif()
|
||||
|
||||
if(NOT arg_DEPENDENCY_IMPORT_STATEMENT)
|
||||
message(FATAL_ERROR "Python depdendency import statement not given.")
|
||||
endif()
|
||||
|
||||
if(NOT arg_OUT_VAR_FOUND)
|
||||
message(FATAL_ERROR "Out var found variable not given.")
|
||||
endif()
|
||||
|
||||
set(python_path "${arg_PYTHON_PATH}")
|
||||
execute_process(
|
||||
COMMAND
|
||||
${python_path} -c "${arg_DEPENDENCY_IMPORT_STATEMENT}"
|
||||
RESULT_VARIABLE res
|
||||
OUTPUT_VARIABLE output
|
||||
ERROR_VARIABLE output
|
||||
)
|
||||
|
||||
if("${res}" STREQUAL "0")
|
||||
set(found TRUE)
|
||||
set(output "${output}")
|
||||
else()
|
||||
set(found FALSE)
|
||||
string(CONCAT output "SBOM Python dependency ${arg_DEPENDENCY_IMPORT_STATEMENT} not found. "
|
||||
"Error:\n${output}")
|
||||
endif()
|
||||
|
||||
set(${arg_OUT_VAR_FOUND} "${found}" PARENT_SCOPE)
|
||||
if(arg_OUT_VAR_OUTPUT)
|
||||
set(${arg_OUT_VAR_OUTPUT} "${output}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper to find a python installed CLI utility.
|
||||
# Expected to be in PATH.
|
||||
function(_qt_internal_sbom_find_python_dependency_program)
|
||||
set(opt_args
|
||||
REQUIRED
|
||||
)
|
||||
set(single_args
|
||||
NAME
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(program_name "${arg_NAME}")
|
||||
string(TOUPPER "${program_name}" upper_name)
|
||||
set(cache_var "QT_SBOM_PROGRAM_${upper_name}")
|
||||
|
||||
set(hints "")
|
||||
|
||||
# The path to python installed apps is different on Windows compared to UNIX, so we use
|
||||
# a different path than where the python interpreter might be located.
|
||||
if(QT_SBOM_PYTHON_APPS_PATH)
|
||||
list(APPEND hints ${QT_SBOM_PYTHON_APPS_PATH})
|
||||
endif()
|
||||
|
||||
find_program(${cache_var}
|
||||
NAMES ${program_name}
|
||||
HINTS ${hints}
|
||||
)
|
||||
|
||||
if(NOT ${cache_var})
|
||||
if(arg_REQUIRED)
|
||||
set(message_type "FATAL_ERROR")
|
||||
set(prefix "Required ")
|
||||
else()
|
||||
set(message_type "STATUS")
|
||||
set(prefix "Optional ")
|
||||
endif()
|
||||
message(${message_type} "${prefix}SBOM python program '${program_name}' not found.")
|
||||
endif()
|
||||
endfunction()
|
492
cmake/QtPublicSbomQtEntityHelpers.cmake
Normal file
492
cmake/QtPublicSbomQtEntityHelpers.cmake
Normal file
@ -0,0 +1,492 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# Helper macro to prepare forwarding all set sbom options to some other function.
|
||||
# Expects the options names to be set in the parent scope by calling
|
||||
# _qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
|
||||
macro(_qt_internal_sbom_forward_sbom_add_target_options args_var_name)
|
||||
if(NOT opt_args)
|
||||
message(FATAL_ERROR
|
||||
"Expected opt_args to be set by _qt_internal_get_sbom_add_target_options")
|
||||
endif()
|
||||
if(NOT single_args)
|
||||
message(FATAL_ERROR
|
||||
"Expected single_args to be set by _qt_internal_get_sbom_add_target_options")
|
||||
endif()
|
||||
if(NOT multi_args)
|
||||
message(FATAL_ERROR
|
||||
"Expected multi_args to be set by _qt_internal_get_sbom_add_target_options")
|
||||
endif()
|
||||
_qt_internal_forward_function_args(
|
||||
FORWARD_PREFIX arg
|
||||
FORWARD_OUT_VAR ${args_var_name}
|
||||
FORWARD_OPTIONS
|
||||
${opt_args}
|
||||
FORWARD_SINGLE
|
||||
${single_args}
|
||||
FORWARD_MULTI
|
||||
${multi_args}
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# Helper function to add a default supplier for a qt entity type.
|
||||
function(_qt_internal_sbom_handle_qt_entity_supplier target)
|
||||
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
|
||||
list(APPEND single_args OUT_VAR)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
|
||||
_qt_internal_sbom_is_qt_3rd_party_entity_type("${arg_TYPE}" is_qt_3rd_party_entity_type)
|
||||
|
||||
set(supplier "")
|
||||
if(NOT arg_SUPPLIER
|
||||
AND (is_qt_entity_type OR is_qt_3rd_party_entity_type)
|
||||
AND NOT arg_NO_DEFAULT_QT_SUPPLIER)
|
||||
_qt_internal_sbom_get_default_supplier(supplier)
|
||||
endif()
|
||||
|
||||
if(supplier)
|
||||
set(${arg_OUT_VAR} "${supplier}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper function to add a default package for a qt entity type.
|
||||
function(_qt_internal_sbom_handle_qt_entity_package_version target)
|
||||
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
|
||||
list(APPEND single_args OUT_VAR)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
|
||||
|
||||
set(package_version "")
|
||||
if(NOT arg_PACKAGE_VERSION
|
||||
AND is_qt_entity_type
|
||||
AND NOT arg_NO_DEFAULT_QT_PACKAGE_VERSION)
|
||||
_qt_internal_sbom_get_default_qt_package_version(package_version)
|
||||
endif()
|
||||
|
||||
if(package_version)
|
||||
set(${arg_OUT_VAR} "${package_version}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper function to add a default repo download location for a qt entity type.
|
||||
function(_qt_internal_sbom_handle_qt_entity_download_location target)
|
||||
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
|
||||
list(APPEND single_args OUT_VAR)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
|
||||
|
||||
set(download_location "")
|
||||
if(NOT arg_DOWNLOAD_LOCATION AND is_qt_entity_type)
|
||||
_qt_internal_sbom_get_qt_repo_source_download_location(download_location)
|
||||
endif()
|
||||
|
||||
if(download_location)
|
||||
set(${arg_OUT_VAR} "${download_location}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper function to add a default license expression for a qt entity type.
|
||||
function(_qt_internal_sbom_handle_qt_entity_license_expression target)
|
||||
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
|
||||
list(APPEND single_args OUT_VAR)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
|
||||
|
||||
set(license_expression "")
|
||||
|
||||
# For Qt entities, we have some special handling.
|
||||
if(is_qt_entity_type AND NOT arg_NO_DEFAULT_QT_LICENSE AND NOT arg_QT_LICENSE_ID)
|
||||
if(arg_TYPE STREQUAL "QT_TOOL" OR arg_TYPE STREQUAL "QT_APP")
|
||||
if(QT_SBOM_DEFAULT_QT_LICENSE_ID_EXECUTABLES
|
||||
AND NOT arg_NO_DEFAULT_QT_LICENSE_ID_EXECUTABLES)
|
||||
# A repo might contain only the "gpl3" license variant as the default for all
|
||||
# executables, so allow setting it at the repo level to avoid having to repeat it
|
||||
# for each target.
|
||||
_qt_internal_sbom_get_spdx_license_expression(
|
||||
"${QT_SBOM_DEFAULT_QT_LICENSE_ID_EXECUTABLES}" license_expression)
|
||||
else()
|
||||
# For tools and apps, we use the gpl exception variant by default.
|
||||
_qt_internal_sbom_get_spdx_license_expression("QT_COMMERCIAL_OR_GPL3_WITH_EXCEPTION"
|
||||
license_expression)
|
||||
endif()
|
||||
|
||||
elseif(QT_SBOM_DEFAULT_QT_LICENSE_ID_LIBRARIES
|
||||
AND NOT arg_NO_DEFAULT_QT_LICENSE_ID_LIBRARIES)
|
||||
# A repo might contain only the "gpl3" license variant as the default for all modules
|
||||
# and plugins, so allow setting it at the repo level to avoid having to repeat it
|
||||
# for each target.
|
||||
_qt_internal_sbom_get_spdx_license_expression(
|
||||
"${QT_SBOM_DEFAULT_QT_LICENSE_ID_LIBRARIES}" license_expression)
|
||||
|
||||
else()
|
||||
# Otherwise, for modules and plugins we use the default qt license.
|
||||
_qt_internal_sbom_get_spdx_license_expression("QT_DEFAULT" license_expression)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Some Qt entities might request a specific license from the subset that we usually use.
|
||||
if(arg_QT_LICENSE_ID)
|
||||
_qt_internal_sbom_get_spdx_license_expression("${arg_QT_LICENSE_ID}"
|
||||
requested_license_expression)
|
||||
_qt_internal_sbom_join_two_license_ids_with_op(
|
||||
"${license_expression}" "AND" "${requested_license_expression}"
|
||||
license_expression)
|
||||
endif()
|
||||
|
||||
# Allow setting a license expression string per directory scope via a variable.
|
||||
if(is_qt_entity_type AND QT_SBOM_LICENSE_EXPRESSION AND NOT arg_NO_DEFAULT_DIRECTORY_QT_LICENSE)
|
||||
set(qt_license_expression "${QT_SBOM_LICENSE_EXPRESSION}")
|
||||
_qt_internal_sbom_join_two_license_ids_with_op(
|
||||
"${license_expression}" "AND" "${qt_license_expression}"
|
||||
license_expression)
|
||||
endif()
|
||||
|
||||
if(license_expression)
|
||||
set(${arg_OUT_VAR} "${license_expression}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper function to add a default license declared expression for a qt entity type.
|
||||
function(_qt_internal_sbom_handle_qt_entity_license_declared_expression target)
|
||||
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
|
||||
list(APPEND single_args OUT_VAR LICENSE_CONCLUDED_EXPRESSION)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
|
||||
|
||||
set(license_expression "")
|
||||
|
||||
# For qt entities we know the license we provide, so we mark it as declared as well.
|
||||
if(is_qt_entity_type AND arg_LICENSE_CONCLUDED_EXPRESSION)
|
||||
set(license_expression "${arg_LICENSE_CONCLUDED_EXPRESSION}")
|
||||
endif()
|
||||
|
||||
if(license_expression)
|
||||
set(${arg_OUT_VAR} "${license_expression}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Get the default qt copyright.
|
||||
function(_qt_internal_sbom_get_default_qt_copyright_header out_var)
|
||||
set(${out_var}
|
||||
"Copyright (C) The Qt Company Ltd. and other contributors."
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Helper function to add default copyrights for a qt entity type.
|
||||
function(_qt_internal_sbom_handle_qt_entity_copyrights target)
|
||||
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
|
||||
list(APPEND single_args OUT_VAR)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
|
||||
|
||||
set(qt_default_copyright "")
|
||||
if(is_qt_entity_type AND NOT arg_NO_DEFAULT_QT_COPYRIGHTS)
|
||||
_qt_internal_sbom_get_default_qt_copyright_header(qt_default_copyright)
|
||||
endif()
|
||||
|
||||
if(qt_default_copyright)
|
||||
set(${arg_OUT_VAR} "${qt_default_copyright}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper function to add default CPEs for a qt entity type.
|
||||
function(_qt_internal_sbom_handle_qt_entity_cpe target)
|
||||
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
|
||||
list(APPEND single_args OUT_VAR)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
|
||||
_qt_internal_sbom_is_qt_3rd_party_entity_type("${arg_TYPE}" is_qt_3rd_party_entity_type)
|
||||
|
||||
set(cpe_list "")
|
||||
|
||||
# Add the qt-specific CPE if the target is a Qt entity type, or if it's a 3rd party entity type
|
||||
# without any CPE specified.
|
||||
if(is_qt_entity_type OR (is_qt_3rd_party_entity_type AND NOT arg_CPE))
|
||||
_qt_internal_sbom_compute_security_cpe_for_qt(cpe_list)
|
||||
endif()
|
||||
|
||||
if(cpe_list)
|
||||
set(${arg_OUT_VAR} "${cpe_list}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Returns a vcs url for purls where qt entities of the current repo are hosted.
|
||||
function(_qt_internal_sbom_get_qt_entity_vcs_url target)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
REPO_NAME
|
||||
VERSION
|
||||
OUT_VAR
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(NOT arg_REPO_NAME)
|
||||
message(FATAL_ERROR "REPO_NAME must be set")
|
||||
endif()
|
||||
|
||||
if(NOT arg_OUT_VAR)
|
||||
message(FATAL_ERROR "OUT_VAR must be set")
|
||||
endif()
|
||||
|
||||
set(version_part "")
|
||||
if(arg_VERSION)
|
||||
set(version_part "@${arg_VERSION}")
|
||||
endif()
|
||||
|
||||
set(vcs_url "https://code.qt.io/qt/${arg_REPO_NAME}.git${version_part}")
|
||||
set(${arg_OUT_VAR} "${vcs_url}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Returns a relative path to the source where the target was created, to be embedded into a
|
||||
# mirror purl as a subpath.
|
||||
function(_qt_internal_sbom_get_qt_entity_repo_source_dir target)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
OUT_VAR
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(NOT arg_OUT_VAR)
|
||||
message(FATAL_ERROR "OUT_VAR must be set")
|
||||
endif()
|
||||
|
||||
get_target_property(repo_source_dir "${target}" SOURCE_DIR)
|
||||
|
||||
# Get the path relative to the PROJECT_SOURCE_DIR
|
||||
file(RELATIVE_PATH relative_repo_source_dir "${PROJECT_SOURCE_DIR}" "${repo_source_dir}")
|
||||
|
||||
set(sub_path "${relative_repo_source_dir}")
|
||||
set(${arg_OUT_VAR} "${sub_path}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Gets a list of arguments to pass to _qt_internal_sbom_assemble_purl when handling a Qt entity
|
||||
# type. The purl for Qt entity types have Qt-specific defaults, but can be overridden per purl
|
||||
# component.
|
||||
# The arguments are saved in OUT_VAR.
|
||||
function(_qt_internal_sbom_get_qt_entity_purl_args target)
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
NAME
|
||||
REPO_NAME
|
||||
SUPPLIER
|
||||
VERSION
|
||||
OUT_VAR
|
||||
)
|
||||
set(multi_args "")
|
||||
|
||||
_qt_internal_get_sbom_purl_parsing_options(purl_opt_args purl_single_args purl_multi_args)
|
||||
list(APPEND opt_args ${purl_opt_args})
|
||||
list(APPEND single_args ${purl_single_args})
|
||||
list(APPEND multi_args ${purl_multi_args})
|
||||
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(arg_VERSION)
|
||||
set(purl_version "${arg_VERSION}")
|
||||
endif()
|
||||
|
||||
if(arg_PURL_ID STREQUAL "GENERIC")
|
||||
set(purl_type "generic")
|
||||
set(purl_namespace "${arg_SUPPLIER}")
|
||||
set(purl_name "${arg_NAME}")
|
||||
elseif(arg_PURL_ID STREQUAL "GITHUB")
|
||||
set(purl_type "github")
|
||||
set(purl_namespace "qt")
|
||||
set(purl_name "${arg_REPO_NAME}")
|
||||
endif()
|
||||
|
||||
if(arg_PURL_TYPE)
|
||||
set(purl_type "${arg_PURL_TYPE}")
|
||||
endif()
|
||||
|
||||
if(arg_PURL_NAMESPACE)
|
||||
set(purl_namespace "${arg_PURL_NAMESPACE}")
|
||||
endif()
|
||||
|
||||
if(arg_PURL_NAME)
|
||||
set(purl_name "${arg_PURL_NAME}")
|
||||
endif()
|
||||
|
||||
if(arg_PURL_VERSION)
|
||||
set(purl_version "${arg_PURL_VERSION}")
|
||||
endif()
|
||||
|
||||
set(purl_version_option "")
|
||||
if(purl_version)
|
||||
set(purl_version_option PURL_VERSION "${purl_version}")
|
||||
endif()
|
||||
|
||||
set(purl_args
|
||||
PURL_TYPE "${purl_type}"
|
||||
PURL_NAMESPACE "${purl_namespace}"
|
||||
PURL_NAME "${purl_name}"
|
||||
${purl_version_option}
|
||||
)
|
||||
|
||||
if(arg_PURL_QUALIFIERS)
|
||||
list(APPEND purl_args PURL_QUALIFIERS "${arg_PURL_QUALIFIERS}")
|
||||
endif()
|
||||
|
||||
if(arg_PURL_SUBPATH)
|
||||
list(APPEND purl_args PURL_SUBPATH "${arg_PURL_SUBPATH}")
|
||||
endif()
|
||||
|
||||
set(${arg_OUT_VAR} "${purl_args}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Helper to get the list of default purl ids for a qt entity.
|
||||
#
|
||||
# Qt entities have two purls by default:
|
||||
# - a GITHUB one pointing to the qt github mirror
|
||||
# - a GENERIC one pointing to code.qt.io via vcs_url
|
||||
#
|
||||
# Third party libraries vendored in Qt also have the same purls, like regular Qt
|
||||
# libraries, but might also have an upstream one which is specified explicitly.
|
||||
function(_qt_internal_sbom_get_qt_entity_default_purl_ids out_var)
|
||||
set(supported_purl_ids GITHUB GENERIC)
|
||||
set(${out_var} "${supported_purl_ids}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Helper function to decide which purl ids to add for a qt entity.
|
||||
# Returns either a list of qt purl ids, or an empty list if it's not a qt entity type or qt 3rd
|
||||
# party type.
|
||||
function(_qt_internal_sbom_handle_qt_entity_purl_entries)
|
||||
_qt_internal_get_sbom_purl_handling_options(opt_args single_args multi_args)
|
||||
list(APPEND single_args
|
||||
OUT_VAR # This is unused, but added by the calling function.
|
||||
OUT_VAR_IDS
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(purl_ids "")
|
||||
|
||||
_qt_internal_sbom_is_qt_entity_type("${arg_TYPE}" is_qt_entity_type)
|
||||
_qt_internal_sbom_is_qt_3rd_party_entity_type("${arg_TYPE}" is_qt_3rd_party_entity_type)
|
||||
|
||||
if(is_qt_entity_type OR is_qt_3rd_party_entity_type)
|
||||
_qt_internal_sbom_get_qt_entity_default_purl_ids(purl_ids)
|
||||
endif()
|
||||
|
||||
if(purl_ids)
|
||||
set(${arg_OUT_VAR_IDS} "${purl_ids}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helper function to add purl values for a specific purl entry of a qt entity type.
|
||||
function(_qt_internal_sbom_handle_qt_entity_purl target)
|
||||
_qt_internal_get_sbom_purl_handling_options(opt_args single_args multi_args)
|
||||
list(APPEND single_args
|
||||
OUT_VAR # This is unused, but added by the calling function.
|
||||
OUT_PURL_ARGS
|
||||
PURL_ID
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(purl_args "")
|
||||
|
||||
_qt_internal_sbom_get_git_version_vars()
|
||||
|
||||
# Return early if not handling one of the default qt purl ids, or if requested not to add a
|
||||
# default purl.
|
||||
_qt_internal_sbom_get_qt_entity_default_purl_ids(default_purl_ids)
|
||||
|
||||
if(arg_NO_DEFAULT_QT_PURL OR (NOT arg_PURL_ID IN_LIST default_purl_ids))
|
||||
set(${arg_OUT_PURL_ARGS} "${purl_args}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
|
||||
|
||||
# Add a vcs_url to the GENERIC purl entry.
|
||||
if(arg_PURL_ID STREQUAL "GENERIC")
|
||||
set(entity_vcs_url_version_option "")
|
||||
# Can be empty.
|
||||
if(QT_SBOM_GIT_HASH_SHORT)
|
||||
set(entity_vcs_url_version_option VERSION "${QT_SBOM_GIT_HASH_SHORT}")
|
||||
endif()
|
||||
|
||||
_qt_internal_sbom_get_qt_entity_vcs_url(${target}
|
||||
REPO_NAME "${repo_project_name_lowercase}"
|
||||
${entity_vcs_url_version_option}
|
||||
OUT_VAR vcs_url)
|
||||
list(APPEND purl_args PURL_QUALIFIERS "vcs_url=${vcs_url}")
|
||||
endif()
|
||||
|
||||
# Add the subdirectory path where the target was created as a custom qualifier.
|
||||
_qt_internal_sbom_get_qt_entity_repo_source_dir(${target} OUT_VAR sub_path)
|
||||
if(sub_path)
|
||||
list(APPEND purl_args PURL_SUBPATH "${sub_path}")
|
||||
endif()
|
||||
|
||||
# Add the target name as a custom qualifer.
|
||||
list(APPEND purl_args PURL_QUALIFIERS "library_name=${target}")
|
||||
|
||||
# Can be empty.
|
||||
if(QT_SBOM_GIT_HASH_SHORT)
|
||||
list(APPEND purl_args VERSION "${QT_SBOM_GIT_HASH_SHORT}")
|
||||
endif()
|
||||
|
||||
# Get purl args the Qt entity type, taking into account defaults.
|
||||
_qt_internal_sbom_get_qt_entity_purl_args(${target}
|
||||
NAME "${repo_project_name_lowercase}-${target}"
|
||||
REPO_NAME "${repo_project_name_lowercase}"
|
||||
SUPPLIER "${arg_SUPPLIER}"
|
||||
PURL_ID "${arg_PURL_ID}"
|
||||
${purl_args}
|
||||
OUT_VAR purl_args
|
||||
)
|
||||
|
||||
if(purl_args)
|
||||
set(${arg_OUT_PURL_ARGS} "${purl_args}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
# Get the default qt package version.
|
||||
function(_qt_internal_sbom_get_default_qt_package_version out_var)
|
||||
set(${out_var} "${QT_REPO_MODULE_VERSION}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Get the default qt supplier.
|
||||
function(_qt_internal_sbom_get_default_supplier out_var)
|
||||
set(${out_var} "TheQtCompany" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Get the default qt supplier url.
|
||||
function(_qt_internal_sbom_get_default_supplier_url out_var)
|
||||
set(${out_var} "https://qt.io" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Get the default qt download location.
|
||||
# If git info is available, includes the hash.
|
||||
function(_qt_internal_sbom_get_qt_repo_source_download_location out_var)
|
||||
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
|
||||
set(download_location "git://code.qt.io/qt/${repo_project_name_lowercase}.git")
|
||||
|
||||
_qt_internal_sbom_get_git_version_vars()
|
||||
if(QT_SBOM_GIT_HASH)
|
||||
string(APPEND download_location "@${QT_SBOM_GIT_HASH}")
|
||||
endif()
|
||||
set(${out_var} "${download_location}" PARENT_SCOPE)
|
||||
endfunction()
|
165
cmake/QtPublicSbomSystemDepHelpers.cmake
Normal file
165
cmake/QtPublicSbomSystemDepHelpers.cmake
Normal file
@ -0,0 +1,165 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# Records information about a system library target, usually due to a qt_find_package call.
|
||||
# This information is later used to generate packages for the system libraries, but only after
|
||||
# confirming that the library was used (linked) into any of the Qt targets.
|
||||
function(_qt_internal_sbom_record_system_library_usage target)
|
||||
if(NOT QT_GENERATE_SBOM)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
TYPE
|
||||
PACKAGE_VERSION
|
||||
FRIENDLY_PACKAGE_NAME
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
if(NOT arg_TYPE)
|
||||
message(FATAL_ERROR "TYPE must be set")
|
||||
endif()
|
||||
|
||||
# A package might be looked up more than once, make sure to record it once.
|
||||
get_property(already_recorded GLOBAL PROPERTY
|
||||
_qt_internal_sbom_recorded_system_library_target_${target})
|
||||
|
||||
if(already_recorded)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set_property(GLOBAL PROPERTY
|
||||
_qt_internal_sbom_recorded_system_library_target_${target} TRUE)
|
||||
|
||||
# Defer spdx id creation until _qt_internal_sbom_begin_project is called, so we know the
|
||||
# project name. The project name is used in the package infix generation of the system library,
|
||||
# but _qt_internal_sbom_record_system_library_usage might be called before sbom generation
|
||||
# has started, e.g. during _qt_internal_find_third_party_dependencies.
|
||||
set(spdx_options
|
||||
${target}
|
||||
TYPE "${arg_TYPE}"
|
||||
PACKAGE_NAME "${arg_FRIENDLY_PACKAGE_NAME}"
|
||||
)
|
||||
|
||||
get_cmake_property(sbom_repo_begin_called _qt_internal_sbom_repo_begin_called)
|
||||
if(sbom_repo_begin_called AND TARGET "${target}")
|
||||
_qt_internal_sbom_record_system_library_spdx_id(${target} ${spdx_options})
|
||||
else()
|
||||
set_property(GLOBAL PROPERTY
|
||||
_qt_internal_sbom_recorded_system_library_spdx_options_${target} "${spdx_options}")
|
||||
endif()
|
||||
|
||||
# Defer sbom info creation until we detect usage of the system library (whether the library is
|
||||
# linked into any other target).
|
||||
set_property(GLOBAL APPEND PROPERTY
|
||||
_qt_internal_sbom_recorded_system_library_targets "${target}")
|
||||
set_property(GLOBAL PROPERTY
|
||||
_qt_internal_sbom_recorded_system_library_options_${target} "${ARGN}")
|
||||
endfunction()
|
||||
|
||||
# Helper to record spdx ids of all system library targets that were found so far.
|
||||
function(_qt_internal_sbom_record_system_library_spdx_ids)
|
||||
get_property(recorded_targets GLOBAL PROPERTY _qt_internal_sbom_recorded_system_library_targets)
|
||||
|
||||
if(NOT recorded_targets)
|
||||
return()
|
||||
endif()
|
||||
|
||||
foreach(target IN LISTS recorded_targets)
|
||||
get_property(args GLOBAL PROPERTY
|
||||
_qt_internal_sbom_recorded_system_library_spdx_options_${target})
|
||||
|
||||
# qt_find_package PROVIDED_TARGETS might refer to non-existent targets in certain cases,
|
||||
# like zstd::libzstd_shared for qt_find_package(WrapZSTD), because we are not sure what
|
||||
# kind of zstd build was done. Make sure to check if the target exists before recording it.
|
||||
if(TARGET "${target}")
|
||||
set(target_unaliased "${target}")
|
||||
_qt_internal_dealias_target(target_unaliased)
|
||||
|
||||
_qt_internal_sbom_record_system_library_spdx_id(${target_unaliased} ${args})
|
||||
else()
|
||||
message(DEBUG
|
||||
"Skipping recording system library for SBOM because target does not exist: "
|
||||
" ${target}")
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# Helper to record the spdx id of a system library target.
|
||||
function(_qt_internal_sbom_record_system_library_spdx_id target)
|
||||
# Save the spdx id before the sbom info is added, so we can refer to it in relationships.
|
||||
_qt_internal_sbom_record_target_spdx_id(${ARGN} OUT_VAR package_spdx_id)
|
||||
|
||||
if(NOT package_spdx_id)
|
||||
message(FATAL_ERROR "Could not generate spdx id for system library target: ${target}")
|
||||
endif()
|
||||
|
||||
set_target_properties("${target}" PROPERTIES _qt_internal_sbom_is_system_library TRUE)
|
||||
|
||||
set_property(GLOBAL PROPERTY
|
||||
_qt_internal_sbom_recorded_system_library_package_${target} "${package_spdx_id}")
|
||||
endfunction()
|
||||
|
||||
# Goes through the list of consumed system libraries (those that were linked in) and creates
|
||||
# sbom packages for them.
|
||||
# Uses information from recorded system libraries (calls to qt_find_package).
|
||||
function(_qt_internal_sbom_add_recorded_system_libraries)
|
||||
get_property(recorded_targets GLOBAL PROPERTY _qt_internal_sbom_recorded_system_library_targets)
|
||||
get_property(consumed_targets GLOBAL PROPERTY _qt_internal_sbom_consumed_system_library_targets)
|
||||
|
||||
set(unconsumed_targets "${recorded_targets}")
|
||||
set(generated_package_names "")
|
||||
|
||||
message(DEBUG
|
||||
"System libraries that were marked consumed "
|
||||
"(some target linked to them): ${consumed_targets}")
|
||||
message(DEBUG
|
||||
"System libraries that were recorded "
|
||||
"(they were marked with qt_find_package()): ${recorded_targets}")
|
||||
|
||||
foreach(target IN LISTS consumed_targets)
|
||||
# Some system targets like qtspeech SpeechDispatcher::SpeechDispatcher might be aliased,
|
||||
# and we can't set properties on them, so unalias the target name.
|
||||
set(target_original "${target}")
|
||||
_qt_internal_dealias_target(target)
|
||||
|
||||
get_property(args GLOBAL PROPERTY
|
||||
_qt_internal_sbom_recorded_system_library_options_${target})
|
||||
get_property(package_name GLOBAL PROPERTY
|
||||
_qt_internal_sbom_recorded_system_library_package_${target})
|
||||
|
||||
set_property(GLOBAL PROPERTY _qt_internal_sbom_recorded_system_library_target_${target} "")
|
||||
set_property(GLOBAL PROPERTY _qt_internal_sbom_recorded_system_library_options_${target} "")
|
||||
set_property(GLOBAL PROPERTY _qt_internal_sbom_recorded_system_library_package_${target} "")
|
||||
|
||||
# Guard against generating a package multiple times. Can happen when multiple targets belong
|
||||
# to the same package.
|
||||
if(sbom_generated_${package_name})
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# Automatic system library sbom recording happens at project root source dir scope, which
|
||||
# means it might accidentally pick up a qt_attribution.json file from the project root,
|
||||
# that is not intended to be use for system libraries.
|
||||
# For now, explicitly disable using the root attribution file.
|
||||
list(APPEND args NO_CURRENT_DIR_ATTRIBUTION)
|
||||
|
||||
list(APPEND generated_package_names "${package_name}")
|
||||
set(sbom_generated_${package_name} TRUE)
|
||||
|
||||
_qt_internal_extend_sbom(${target} ${args})
|
||||
_qt_internal_finalize_sbom(${target})
|
||||
|
||||
list(REMOVE_ITEM unconsumed_targets "${target_original}")
|
||||
endforeach()
|
||||
|
||||
message(DEBUG "System libraries that were recorded, but not consumed: ${unconsumed_targets}")
|
||||
message(DEBUG "Generated SBOMs for the following system packages: ${generated_package_names}")
|
||||
|
||||
# Clean up, before configuring next repo project.
|
||||
set_property(GLOBAL PROPERTY _qt_internal_sbom_consumed_system_library_targets "")
|
||||
set_property(GLOBAL PROPERTY _qt_internal_sbom_recorded_system_library_targets "")
|
||||
endfunction()
|
@ -62,10 +62,7 @@ function(__qt_internal_set_link_order_matters target link_order_matters)
|
||||
message(FATAL_ERROR "Unable to set _qt_link_order_matters flag. ${target} is not a target.")
|
||||
endif()
|
||||
|
||||
get_target_property(aliased_target ${target} ALIASED_TARGET)
|
||||
if(aliased_target)
|
||||
set(target "${aliased_target}")
|
||||
endif()
|
||||
_qt_internal_dealias_target(target)
|
||||
|
||||
if(link_order_matters)
|
||||
set(link_order_matters TRUE)
|
||||
@ -101,10 +98,7 @@ endfunction()
|
||||
|
||||
function(__qt_internal_check_cmp0099_available)
|
||||
set(platform_target ${QT_CMAKE_EXPORT_NAMESPACE}::Platform)
|
||||
get_target_property(aliased_target ${platform_target} ALIASED_TARGET)
|
||||
if(aliased_target)
|
||||
set(platform_target "${aliased_target}")
|
||||
endif()
|
||||
_qt_internal_dealias_target(platform_target)
|
||||
|
||||
__qt_internal_get_cmp0099_genex_check(cmp0099_check)
|
||||
set_target_properties(${platform_target} PROPERTIES
|
||||
@ -224,10 +218,7 @@ function(__qt_internal_collect_object_libraries_recursively out_var target initi
|
||||
set(lib "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
if(TARGET ${lib})
|
||||
get_target_property(aliased_target ${lib} ALIASED_TARGET)
|
||||
if(aliased_target)
|
||||
set(lib ${aliased_target})
|
||||
endif()
|
||||
_qt_internal_dealias_target(lib)
|
||||
|
||||
if(${lib} IN_LIST processed_object_libraries)
|
||||
continue()
|
||||
@ -424,3 +415,109 @@ function(_qt_internal_warn_about_example_add_subdirectory)
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Mark source files as generated.
|
||||
#
|
||||
# This sets `GENERATED` property to TRUE, along with other Qt relevant properties,
|
||||
# e.g. `SKIP_LINTING`.
|
||||
#
|
||||
# Synopsis
|
||||
#
|
||||
# _qt_internal_set_source_file_generated(SOURCE <src1> ...
|
||||
# [CONFIGURE_GENERATED]
|
||||
# [SKIP_AUTOGEN]
|
||||
# [DIRECTORY <dirs> ...]
|
||||
# [TARGET_DIRECTORY <targets> ...]
|
||||
# )
|
||||
#
|
||||
# Arguments
|
||||
#
|
||||
# `SOURCES`
|
||||
# Source files that are generated.
|
||||
#
|
||||
# Equivalent to `set_source_files_properties(<files>)`.
|
||||
#
|
||||
# `DIRECTORY`
|
||||
# Equivalent to `set_source_files_properties(DIRECTORY)`.
|
||||
#
|
||||
# `TARGET_DIRECTORY`
|
||||
# Equivalent to `set_source_files_properties(TARGET_DIRECTORY)`.
|
||||
#
|
||||
# `SKIP_AUTOGEN`
|
||||
# Set SKIP_AUTOGEN property to True as well.
|
||||
#
|
||||
# `CONFIGURE_GENERATED`
|
||||
# Files are generated with `configure_file`.
|
||||
# Does not set `GENERATED TRUE` property. This is needed to avoid removing the file when
|
||||
# running the clean target.
|
||||
function(_qt_internal_set_source_file_generated)
|
||||
set(option_args
|
||||
SKIP_AUTOGEN
|
||||
CONFIGURE_GENERATED
|
||||
)
|
||||
set(single_args "")
|
||||
set(multi_args
|
||||
SOURCES
|
||||
DIRECTORY
|
||||
TARGET_DIRECTORY
|
||||
)
|
||||
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg
|
||||
"${option_args}" "${single_args}" "${multi_args}"
|
||||
)
|
||||
# Parse required variables
|
||||
if(NOT arg_SOURCES AND QT_FEATURE_developer_build)
|
||||
message(WARNING
|
||||
"Unexpected call _qt_internal_set_source_file_generated with empty `SOURCES`."
|
||||
)
|
||||
endif()
|
||||
# Prepend again the appropriate keywords to pass to `set_source_files_properties`
|
||||
if(arg_DIRECTORY)
|
||||
list(PREPEND arg_DIRECTORY DIRECTORY)
|
||||
endif()
|
||||
if(arg_TARGET_DIRECTORY)
|
||||
list(PREPEND arg_TARGET_DIRECTORY TARGET_DIRECTORY)
|
||||
endif()
|
||||
|
||||
# Construct the properties list
|
||||
set(properties "")
|
||||
if(NOT arg_CONFIGURE_GENERATED)
|
||||
list(APPEND properties
|
||||
GENERATED TRUE
|
||||
)
|
||||
endif()
|
||||
if(arg_SKIP_AUTOGEN)
|
||||
list(APPEND properties
|
||||
SKIP_AUTOGEN TRUE
|
||||
)
|
||||
endif()
|
||||
# Add SKIP_LINTING if possible. We do not add it unconditionally here to avoid
|
||||
# confusion when CMake ignores this variable.
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.27" AND NOT QT_FEATURE_lint_generated_code)
|
||||
list(APPEND properties
|
||||
SKIP_LINTING TRUE
|
||||
)
|
||||
endif()
|
||||
|
||||
set_source_files_properties(${arg_SOURCES}
|
||||
${arg_DIRECTORY}
|
||||
${arg_TARGET_DIRECTORY}
|
||||
PROPERTIES ${properties}
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# Get the real target checking for ALIASED_TARGET
|
||||
function(_qt_internal_get_real_target out_var target)
|
||||
get_target_property(aliased_target "${target}" ALIASED_TARGET)
|
||||
if(aliased_target)
|
||||
set(${out_var} "${aliased_target}" PARENT_SCOPE)
|
||||
else()
|
||||
set(${out_var} "${target}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Helpful shortcut to `_qt_internal_get_real_target` if we just need to dealias
|
||||
function(_qt_internal_dealias_target target_var)
|
||||
_qt_internal_get_real_target(${target_var} ${${target_var}})
|
||||
set(${target_var} "${${target_var}}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
@ -68,7 +68,10 @@ is not specified")
|
||||
# It's necessary to call actual test inside 'cmd.exe', because 'execute_process' uses
|
||||
# SW_HIDE to avoid showing a console window, it affects other GUI as well.
|
||||
# See https://gitlab.kitware.com/cmake/cmake/-/issues/17690 for details.
|
||||
set(extra_runner "cmd /c")
|
||||
#
|
||||
# Run the command using the proxy 'call' command to avoid issues related to invalid
|
||||
# processing of quotes and spaces in cmd.exe arguments.
|
||||
set(extra_runner "cmd /c call")
|
||||
endif()
|
||||
|
||||
if(arg_PRE_RUN)
|
||||
@ -118,3 +121,35 @@ endfunction()
|
||||
function(_qt_internal_test_batch_target_name out)
|
||||
set(${out} "test_batch" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Create a *_check target of the ctest execution for alternative execution
|
||||
# Arguments:
|
||||
# : CTEST_TEST_NAME: (default: ${testname})
|
||||
# name of the ctest test used
|
||||
function(_qt_internal_make_check_target testname)
|
||||
set(options "")
|
||||
set(singleOpts CTEST_TEST_NAME)
|
||||
set(multiOpts "")
|
||||
|
||||
cmake_parse_arguments(PARSE_ARGV 1 arg
|
||||
"${options}" "${singleOpts}" "${multiOpts}"
|
||||
)
|
||||
if(NOT arg_CTEST_TEST_NAME)
|
||||
set(arg_CTEST_TEST_NAME ${testname})
|
||||
endif()
|
||||
|
||||
set(test_config_options "")
|
||||
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
|
||||
if(is_multi_config)
|
||||
set(test_config_options -C $<CONFIG>)
|
||||
endif()
|
||||
# Note: By default the working directory here is CMAKE_CURRENT_BINARY_DIR, which will
|
||||
# work as long as this is called anywhere up or down the path where the equivalent
|
||||
# `add_test` is called (not down a different branch path).
|
||||
add_custom_target(${testname}_check
|
||||
VERBATIM
|
||||
COMMENT "Running ctest -V -R \"^${arg_CTEST_TEST_NAME}$\" ${test_config_options}"
|
||||
COMMAND
|
||||
"${CMAKE_CTEST_COMMAND}" -V -R "^${arg_CTEST_TEST_NAME}$" ${test_config_options}
|
||||
)
|
||||
endfunction()
|
||||
|
@ -139,7 +139,7 @@ macro(_qt_internal_execute_proccess_in_qt_env execute_process_args_var)
|
||||
# We avoid escaping issues this way.
|
||||
execute_process(${${execute_process_args_var}})
|
||||
if(CMAKE_HOST_WIN32)
|
||||
set(ENV{PATH} "${path_backup}")
|
||||
set(ENV{PATH} "${_qt_internal_execute_proccess_in_qt_env_path_backup}")
|
||||
unset(_qt_internal_execute_proccess_in_qt_env_path_backup)
|
||||
endif()
|
||||
endmacro()
|
||||
|
@ -153,9 +153,16 @@ function(__qt_internal_walk_libs
|
||||
lib "${lib}")
|
||||
endwhile()
|
||||
|
||||
# Skip static plugins.
|
||||
# Skip processing static plugins.
|
||||
# There are some abuses of this genex marker, because the more generic one below did
|
||||
# not exist yet.
|
||||
set(_is_plugin_marker_genex "\\$<BOOL:QT_IS_PLUGIN_GENEX>")
|
||||
if(lib MATCHES "${_is_plugin_marker_genex}")
|
||||
|
||||
# Skip any genex expressions that contain the marker. Useful in cases like processing
|
||||
# link expressions for prl file generation, where some link expressions should be
|
||||
# skipped either because they don't make sense or they are handled differently.
|
||||
set(_is_skip_marker_genex "\\$<BOOL:QT_SKIP_WALK_LIBS_PROCESSING>")
|
||||
if(lib MATCHES "${_is_plugin_marker_genex}" OR lib MATCHES "${_is_skip_marker_genex}")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
@ -172,10 +179,24 @@ function(__qt_internal_walk_libs
|
||||
if(lib MATCHES "^\\$<TARGET_OBJECTS:")
|
||||
# Skip object files.
|
||||
continue()
|
||||
elseif(lib MATCHES "^\\$<LINK_ONLY:(.*)>$")
|
||||
set(lib_target ${CMAKE_MATCH_1})
|
||||
else()
|
||||
set(lib_target ${lib})
|
||||
endif()
|
||||
|
||||
set(lib_target "${lib}")
|
||||
|
||||
# Unwrap targets like $<LINK_ONLY:$<BUILD_INTERFACE:Qt6::CorePrivate>>
|
||||
while(lib_target
|
||||
MATCHES "^\\$<(LINK_ONLY|BUILD_INTERFACE|BUILD_LOCAL_INTERFACE):(.*)>$")
|
||||
set(lib_target "${CMAKE_MATCH_2}")
|
||||
endwhile()
|
||||
|
||||
# If one of the values is "$<LINK_ONLY:$<BUILD_LOCAL_INTERFACE:Foo>>", this will be
|
||||
# exported by cmake as "$<LINK_ONLY:>", which will become an empty value after the
|
||||
# unwrapping above.
|
||||
# In that case, skip the processing. Otherwise in some weird unknown conditions,
|
||||
# CMake might consider the empty name to be a valid target, and cause errors further
|
||||
# down.
|
||||
if("${lib_target}" STREQUAL "")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# Skip CMAKE_DIRECTORY_ID_SEP. If a target_link_libraries is applied to a target
|
||||
@ -240,10 +261,7 @@ function(__qt_internal_walk_libs
|
||||
endif()
|
||||
if(operation STREQUAL "promote_3rd_party_global")
|
||||
set(lib_target_unaliased "${lib_target}")
|
||||
get_target_property(aliased_target ${lib_target} ALIASED_TARGET)
|
||||
if(aliased_target)
|
||||
set(lib_target_unaliased ${aliased_target})
|
||||
endif()
|
||||
_qt_internal_dealias_target(lib_target_unaliased)
|
||||
|
||||
get_property(is_imported TARGET ${lib_target_unaliased} PROPERTY IMPORTED)
|
||||
|
||||
|
@ -53,7 +53,7 @@ endfunction()
|
||||
|
||||
function(__qt_internal_get_emcc_recommended_version out_var)
|
||||
# This version of Qt needs this version of emscripten.
|
||||
set(QT_EMCC_RECOMMENDED_VERSION "3.1.56")
|
||||
set(QT_EMCC_RECOMMENDED_VERSION "3.1.70")
|
||||
set(${out_var} "${QT_EMCC_RECOMMENDED_VERSION}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
@ -33,11 +33,10 @@ function(qt6_add_win_app_sdk target)
|
||||
|
||||
set(generated_headers_path "${CMAKE_CURRENT_BINARY_DIR}/winrt_includes")
|
||||
|
||||
find_path(WINAPPSDK_GENERATED_INCLUDE_DIR
|
||||
NAMES winrt/Microsoft.UI.h
|
||||
HINTS "${generated_headers_path}")
|
||||
set(winappsdk_generated_include_dir "${generated_headers_path}/winrt")
|
||||
# If headers are not already generated
|
||||
if(NOT WINAPPSDK_GENERATED_INCLUDE_DIR)
|
||||
if(NOT EXISTS "${winappsdk_generated_include_dir}")
|
||||
|
||||
if(CPP_WIN_RT_PATH)
|
||||
set(cpp_win_rt_path "${CPP_WIN_RT_PATH}")
|
||||
elseif(DEFINED ENV{CPP_WIN_RT_PATH})
|
||||
@ -53,23 +52,26 @@ function(qt6_add_win_app_sdk target)
|
||||
message(FATAL_ERROR "cppwinrt.exe could not be found")
|
||||
endif()
|
||||
|
||||
find_path(WINAPPSDK_INCLUDE_DIR
|
||||
find_path(winappsdk_include_dir
|
||||
NAMES MddBootstrap.h
|
||||
HINTS ${win_app_sdk_root}/include)
|
||||
HINTS ${win_app_sdk_root}/include
|
||||
NO_CACHE)
|
||||
|
||||
find_library(WINAPPSDK_LIBRARY
|
||||
find_library(winappsdk_library
|
||||
NAMES Microsoft.WindowsAppRuntime
|
||||
HINTS ${WINAPPSDK_LIBRARY_DIR} "${win_app_sdk_root}"
|
||||
"${win_app_sdk_root}/lib"
|
||||
"${win_app_sdk_root}/lib/win10-${win_app_sdk_arch}")
|
||||
"${win_app_sdk_root}/lib/win10-${win_app_sdk_arch}"
|
||||
NO_CACHE)
|
||||
|
||||
find_library(WINAPPSDK_BOOTSTRAP_LIBRARY
|
||||
find_library(winappsdk_bootstrap_library
|
||||
NAMES Microsoft.WindowsAppRuntime.Bootstrap
|
||||
HINTS ${WINAPPSDK_LIBRARY_DIR} "${win_app_sdk_root}"
|
||||
"${win_app_sdk_root}/lib"
|
||||
"${win_app_sdk_root}/lib/win10-${win_app_sdk_arch}")
|
||||
"${win_app_sdk_root}/lib/win10-${win_app_sdk_arch}"
|
||||
NO_CACHE)
|
||||
|
||||
if(WINAPPSDK_INCLUDE_DIR AND WINAPPSDK_LIBRARY AND WINAPPSDK_BOOTSTRAP_LIBRARY)
|
||||
if(winappsdk_include_dir AND winappsdk_library AND winappsdk_bootstrap_library)
|
||||
execute_process(COMMAND
|
||||
${cpp_win_rt_path} -out "${generated_headers_path}" -ref sdk
|
||||
-in "${win_app_sdk_root}/lib/uap10.0"
|
||||
@ -77,12 +79,8 @@ function(qt6_add_win_app_sdk target)
|
||||
-in "${win_app_sdk_root}/lib/uap10.0.18362"
|
||||
-in "${web_view_root}/lib")
|
||||
|
||||
find_path(WINAPPSDK_GENERATED_INCLUDE_DIR
|
||||
NAMES winrt/Microsoft.UI.h
|
||||
HINTS "${generated_headers_path}")
|
||||
|
||||
if(NOT WINAPPSDK_GENERATED_INCLUDE_DIR)
|
||||
message(FATAL_ERROR "Windows App SDK library headers generation failed")
|
||||
if(NOT EXISTS "${winappsdk_generated_include_dir}")
|
||||
message(FATAL_ERROR "Windows App SDK library headers generation failed.")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Windows App SDK library not found")
|
||||
|
@ -1,10 +1,15 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# For now these are simple internal forwarding wrappers for the public counterparts, which are
|
||||
# meant to be used in qt repo CMakeLists.txt files.
|
||||
function(qt_internal_add_sbom)
|
||||
_qt_internal_add_sbom(${ARGN})
|
||||
# These internal sbom functions are meant to be used in qt repo CMakeLists.txt files.
|
||||
|
||||
function(qt_internal_add_sbom target)
|
||||
if(NOT QT_GENERATE_SBOM)
|
||||
return()
|
||||
endif()
|
||||
|
||||
qt_internal_sbom_get_default_sbom_args("${target}" sbom_extra_args ${ARGN})
|
||||
_qt_internal_add_sbom(${target} ${ARGN} ${sbom_extra_args})
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_extend_sbom)
|
||||
@ -31,3 +36,161 @@ function(qt_internal_sbom_end_qt_repo_project)
|
||||
_qt_internal_sbom_end_qt_repo_project(${ARGN})
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_add_files)
|
||||
_qt_internal_sbom_add_files(${ARGN})
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_add_cmake_include_step)
|
||||
_qt_internal_sbom_add_cmake_include_step(${ARGN})
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_add_external_reference)
|
||||
_qt_internal_sbom_generate_add_external_reference(${ARGN})
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_add_project_relationship)
|
||||
_qt_internal_sbom_generate_add_project_relationship(${ARGN})
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_generate_tag_value_spdx_document)
|
||||
_qt_internal_sbom_generate_tag_value_spdx_document(${ARGN})
|
||||
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
OUT_VAR_OUTPUT_FILE_NAME
|
||||
OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH
|
||||
OUT_VAR_DEPS_FOUND
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
|
||||
if(arg_OUT_VAR_OUTPUT_FILE_NAME)
|
||||
set(${arg_OUT_VAR_OUTPUT_FILE_NAME} "${${arg_OUT_VAR_OUTPUT_FILE_NAME}}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if(arg_OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH)
|
||||
set(${arg_OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH} "${${arg_OUT_VAR_OUTPUT_ABSOLUTE_FILE_PATH}}"
|
||||
PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if(arg_OUT_VAR_DEPS_FOUND)
|
||||
set(${arg_OUT_VAR_DEPS_FOUND} "${${arg_OUT_VAR_DEPS_FOUND}}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_verify_deps_for_generate_tag_value_spdx_document)
|
||||
_qt_internal_sbom_verify_deps_for_generate_tag_value_spdx_document(${ARGN})
|
||||
|
||||
set(opt_args "")
|
||||
set(single_args
|
||||
OUT_VAR_DEPS_FOUND
|
||||
OUT_VAR_REASON_FAILURE_MESSAGE
|
||||
)
|
||||
set(multi_args "")
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
|
||||
if(arg_OUT_VAR_DEPS_FOUND)
|
||||
set(${arg_OUT_VAR_DEPS_FOUND} "${${arg_OUT_VAR_DEPS_FOUND}}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if(arg_OUT_VAR_REASON_FAILURE_MESSAGE)
|
||||
set(${arg_OUT_VAR_REASON_FAILURE_MESSAGE}
|
||||
"${${arg_OUT_VAR_REASON_FAILURE_MESSAGE}}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_get_project_spdx_id out_var)
|
||||
set(result "")
|
||||
|
||||
if(QT_GENERATE_SBOM)
|
||||
get_cmake_property(project_spdx_id _qt_internal_sbom_project_spdx_id)
|
||||
if(project_spdx_id)
|
||||
set(result "${project_spdx_id}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(${out_var} "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_get_target_spdx_id target out_var)
|
||||
set(result "")
|
||||
|
||||
if(QT_GENERATE_SBOM)
|
||||
_qt_internal_sbom_get_spdx_id_for_target(${target} result)
|
||||
endif()
|
||||
|
||||
set(${out_var} "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_get_external_document_ref_spdx_id project_name out_var)
|
||||
set(result "")
|
||||
|
||||
if(QT_GENERATE_SBOM)
|
||||
string(TOLOWER "${project_name}" project_name_lowercase)
|
||||
_qt_internal_sbom_get_external_document_ref_spdx_id("${project_name_lowercase}" result)
|
||||
endif()
|
||||
|
||||
set(${out_var} "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
macro(qt_internal_sbom_get_git_version_vars)
|
||||
_qt_internal_sbom_get_git_version_vars()
|
||||
endmacro()
|
||||
|
||||
function(qt_internal_sbom_get_project_supplier out_var)
|
||||
get_property(result GLOBAL PROPERTY _qt_sbom_project_supplier)
|
||||
set(${out_var} "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_get_project_supplier_url out_var)
|
||||
get_property(result GLOBAL PROPERTY _qt_sbom_project_supplier_url)
|
||||
set(${out_var} "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_get_project_namespace out_var)
|
||||
get_property(result GLOBAL PROPERTY _qt_sbom_project_namespace)
|
||||
set(${out_var} "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_compute_project_namespace out_var)
|
||||
_qt_internal_sbom_compute_project_namespace(result ${ARGN})
|
||||
set(${out_var} "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_compute_project_file_name out_var)
|
||||
_qt_internal_sbom_compute_project_file_name(result ${ARGN})
|
||||
set(${out_var} "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_sbom_get_sanitized_spdx_id out_var hint)
|
||||
_qt_internal_sbom_get_sanitized_spdx_id(result "${hint}")
|
||||
set(${out_var} "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Gets a list of default sbom args to use when processing qt entity types.
|
||||
function(qt_internal_sbom_get_default_sbom_args target out_var)
|
||||
_qt_internal_get_sbom_add_target_options(opt_args single_args multi_args)
|
||||
list(APPEND opt_args IMMEDIATE_FINALIZATION)
|
||||
cmake_parse_arguments(PARSE_ARGV 2 arg "${opt_args}" "${single_args}" "${multi_args}")
|
||||
|
||||
_qt_internal_validate_all_args_are_parsed(arg)
|
||||
|
||||
set(sbom_args "")
|
||||
|
||||
list(APPEND sbom_args USE_ATTRIBUTION_FILES)
|
||||
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PACKAGE_VERSION)
|
||||
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_SUPPLIER)
|
||||
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_DOWNLOAD_LOCATION)
|
||||
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_LICENSE)
|
||||
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_COPYRIGHTS)
|
||||
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_CPE)
|
||||
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL)
|
||||
list(APPEND sbom_args __QT_INTERNAL_HANDLE_QT_ENTITY_ATTRIBUTION_FILES)
|
||||
|
||||
set(${out_var} "${sbom_args}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(qt_internal_extend_qt_entity_sbom target)
|
||||
qt_internal_sbom_get_default_sbom_args("${target}" sbom_extra_args ${ARGN})
|
||||
_qt_internal_extend_sbom(${target} ${ARGN} ${sbom_extra_args})
|
||||
endfunction()
|
||||
|
@ -270,7 +270,7 @@ function(qt_enable_separate_debug_info target installDestination)
|
||||
if(QNX)
|
||||
set(debug_info_suffix sym)
|
||||
set(debug_info_keep --keep-file-symbols)
|
||||
set(strip_args "--strip-debug -R.ident")
|
||||
set(strip_args --strip-debug -R.ident)
|
||||
else()
|
||||
set(debug_info_suffix debug)
|
||||
set(debug_info_keep --only-keep-debug)
|
||||
|
@ -6,7 +6,11 @@
|
||||
# QT_REPO_PUBLIC_NAMESPACE_REGEX cache variable, that can be set by repository in .cmake.conf file.
|
||||
# The variable tells the syncqt program, what namespaces are treated as public. Symbols in public
|
||||
# namespaces are considered when generating CaMeL case header files.
|
||||
function(qt_internal_target_sync_headers target module_headers module_headers_generated)
|
||||
function(qt_internal_target_sync_headers target
|
||||
module_headers
|
||||
module_headers_generated
|
||||
module_headers_exclude_from_docs
|
||||
)
|
||||
if(NOT TARGET ${QT_CMAKE_EXPORT_NAMESPACE}::syncqt)
|
||||
message(FATAL_ERROR "${QT_CMAKE_EXPORT_NAMESPACE}::syncqt is not a target.")
|
||||
endif()
|
||||
@ -80,6 +84,13 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
|
||||
# std::filesystem API
|
||||
get_filename_component(source_dir_real "${sync_source_directory}" REALPATH)
|
||||
get_filename_component(binary_dir_real "${CMAKE_CURRENT_BINARY_DIR}" REALPATH)
|
||||
if(QT6_INSTALL_PREFIX)
|
||||
get_filename_component(install_dir_real "${QT6_INSTALL_PREFIX}" REALPATH)
|
||||
set(install_include_dir_argument
|
||||
-installIncludeDir "${install_dir_real}/${QT6_INSTALL_HEADERS}")
|
||||
else()
|
||||
set(install_include_dir_argument "")
|
||||
endif()
|
||||
|
||||
if(QT_REPO_PUBLIC_NAMESPACE_REGEX)
|
||||
set(public_namespaces_filter -publicNamespaceFilter "${QT_REPO_PUBLIC_NAMESPACE_REGEX}")
|
||||
@ -109,6 +120,7 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
|
||||
-binaryDir "${binary_dir_real}"
|
||||
-privateHeadersFilter "${private_filter_regex}"
|
||||
-includeDir "${module_build_interface_include_dir}"
|
||||
${install_include_dir_argument}
|
||||
-privateIncludeDir "${module_build_interface_private_include_dir}"
|
||||
-qpaIncludeDir "${module_build_interface_qpa_include_dir}"
|
||||
-rhiIncludeDir "${module_build_interface_rhi_include_dir}"
|
||||
@ -146,6 +158,13 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
|
||||
list(FILTER module_headers EXCLUDE REGEX
|
||||
"(.+/(ui_)[^/]+\\.h|${CMAKE_CURRENT_SOURCE_DIR}(/.+)?/doc/+\\.h)")
|
||||
|
||||
# Filter out all headers that should be excluded from documentation generation.
|
||||
# Documentation generation shouldn't depend on headers like the dbus-generated ones.
|
||||
set(module_headers_for_docs "${module_headers}")
|
||||
if(module_headers_exclude_from_docs)
|
||||
list(REMOVE_ITEM module_headers_for_docs ${module_headers_exclude_from_docs})
|
||||
endif()
|
||||
|
||||
set(syncqt_staging_dir "${module_build_interface_include_dir}/.syncqt_staging")
|
||||
|
||||
set(syncqt_args "${common_syncqt_arguments}")
|
||||
@ -225,10 +244,16 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
|
||||
"@${syncqt_all_args_rsp}"
|
||||
${external_headers_dir_copy_cmd}
|
||||
DEPENDS
|
||||
${module_headers}
|
||||
# Note, we don't depend anymore on ${target}_sync_headers so that we don't bring
|
||||
# in the headers that are usually excluded from docs.
|
||||
# This means if someone manually calls
|
||||
# `ninja sync_all_public_headers Gui_sync_headers` it will cause havoc due to two
|
||||
# syncqt calls accessing the same files concurrently. This is an edge case that should
|
||||
# not happen, but it ends up happening, we will have to implement some kind of lock
|
||||
# file mechanism.
|
||||
${module_headers_for_docs}
|
||||
${syncqt_all_args_rsp}
|
||||
${QT_CMAKE_EXPORT_NAMESPACE}::syncqt
|
||||
${target}_sync_headers
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
|
@ -148,6 +148,7 @@ function(qt_internal_extend_target target)
|
||||
|
||||
list(TRANSFORM arg_PUBLIC_LIBRARIES REPLACE "^Qt::" "${QT_CMAKE_EXPORT_NAMESPACE}::")
|
||||
list(TRANSFORM arg_LIBRARIES REPLACE "^Qt::" "${QT_CMAKE_EXPORT_NAMESPACE}::")
|
||||
qt_internal_wrap_private_modules(arg_LIBRARIES ${arg_LIBRARIES})
|
||||
|
||||
# Set-up the target
|
||||
|
||||
@ -231,6 +232,9 @@ function(qt_internal_extend_target target)
|
||||
)
|
||||
endif()
|
||||
|
||||
set(all_libraries ${arg_LIBRARIES} ${arg_PUBLIC_LIBRARIES})
|
||||
qt_internal_work_around_autogen_discarded_dependencies(${target} ${all_libraries})
|
||||
|
||||
if(QT_GENERATE_SBOM)
|
||||
set(sbom_args "")
|
||||
_qt_internal_forward_function_args(
|
||||
@ -257,6 +261,9 @@ function(qt_internal_extend_target target)
|
||||
if(TARGET "${target_private}")
|
||||
target_link_libraries("${target_private}"
|
||||
INTERFACE ${arg_PRIVATE_MODULE_INTERFACE})
|
||||
qt_internal_register_target_dependencies("${target_private}"
|
||||
PUBLIC ${arg_PRIVATE_MODULE_INTERFACE}
|
||||
)
|
||||
elseif(arg_PRIVATE_MODULE_INTERFACE)
|
||||
set(warning_message "")
|
||||
string(APPEND warning_message
|
||||
@ -266,10 +273,18 @@ function(qt_internal_extend_target target)
|
||||
"Ensure the target exists or remove the option.")
|
||||
message(AUTHOR_WARNING "${warning_message}")
|
||||
endif()
|
||||
qt_register_target_dependencies("${target}"
|
||||
"${arg_PUBLIC_LIBRARIES};${arg_PRIVATE_MODULE_INTERFACE}"
|
||||
"${qt_libs_private};${arg_LIBRARIES}")
|
||||
|
||||
set(qt_register_target_dependencies_args "")
|
||||
if(arg_PUBLIC_LIBRARIES)
|
||||
list(APPEND qt_register_target_dependencies_args
|
||||
PUBLIC ${arg_PUBLIC_LIBRARIES})
|
||||
endif()
|
||||
if(qt_libs_private OR arg_LIBRARIES)
|
||||
list(APPEND qt_register_target_dependencies_args
|
||||
PRIVATE ${qt_libs_private} ${arg_LIBRARIES})
|
||||
endif()
|
||||
qt_internal_register_target_dependencies("${target}"
|
||||
${qt_register_target_dependencies_args})
|
||||
|
||||
qt_autogen_tools(${target}
|
||||
ENABLE_AUTOGEN_TOOLS ${arg_ENABLE_AUTOGEN_TOOLS}
|
||||
@ -329,6 +344,43 @@ function(qt_internal_extend_target target)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Takes an output variable and a list of libraries.
|
||||
#
|
||||
# Every library that is a private module is wrapped in $<BUILD_INTERFACE> or
|
||||
# $<BUILD_LOCAL_INTERFACE> if CMake is new enough.
|
||||
#
|
||||
# This is necessary for static builds, because if Qt6Foo links to Qt6BarPrivate, this link
|
||||
# dependency is purely internal. If we don't do this, CMake adds a target check for Qt6BarPrivate
|
||||
# in Qt6FooTargets.cmake. This breaks if Qt6BarPrivate is not find_package'ed before.
|
||||
function(qt_internal_wrap_private_modules out_var)
|
||||
set(result "")
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS "3.26")
|
||||
set(wrapper_genex "BUILD_INTERFACE")
|
||||
else()
|
||||
set(wrapper_genex "BUILD_LOCAL_INTERFACE")
|
||||
endif()
|
||||
|
||||
foreach(lib IN LISTS ARGN)
|
||||
if(TARGET "${lib}")
|
||||
get_target_property(lib_is_private_module ${lib} _qt_is_private_module)
|
||||
if(lib_is_private_module)
|
||||
# Add the public module as non-wrapped link dependency. This is necessary for
|
||||
# targets that link only to the private module. Consumers of this target would then
|
||||
# get a linker error about missing symbols from that Qt module.
|
||||
get_target_property(lib_public_module_target ${lib} _qt_public_module_target_name)
|
||||
list(APPEND result "${INSTALL_CMAKE_NAMESPACE}::${lib_public_module_target}")
|
||||
|
||||
# Wrap the private module in BUILD_LOCAL_INTERFACE.
|
||||
set(lib "$<${wrapper_genex}:${lib}>")
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND result "${lib}")
|
||||
endforeach()
|
||||
|
||||
set("${out_var}" "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Given CMAKE_CONFIG and ALL_CMAKE_CONFIGS, determines if a directory suffix needs to be appended
|
||||
# to each destination, and sets the computed install target destination arguments in OUT_VAR.
|
||||
# Defaults used for each of the destination types, and can be configured per destination type.
|
||||
|
@ -232,6 +232,7 @@ function(qt_internal_get_test_arg_definitions optional_args single_value_args mu
|
||||
QML_IMPORTPATH
|
||||
TESTDATA
|
||||
QT_TEST_SERVER_LIST
|
||||
ANDROID_TESTRUNNER_PRE_TEST_ADB_COMMANDS
|
||||
${__default_private_args}
|
||||
${__default_public_args}
|
||||
PARENT_SCOPE
|
||||
@ -456,6 +457,8 @@ endfunction()
|
||||
# The option forces adding the provided TESTDATA to resources.
|
||||
# MANUAL
|
||||
# The option indicates that the test is a manual test.
|
||||
# ANDROID_TESTRUNNER_PRE_TEST_ADB_COMMANDS
|
||||
# Passes --pre-test-adb-command <command> to androidTestRunner. Android specific argument.
|
||||
function(qt_internal_add_test name)
|
||||
qt_internal_get_test_arg_definitions(optional_args single_value_args multi_value_args)
|
||||
|
||||
@ -684,6 +687,13 @@ function(qt_internal_add_test name)
|
||||
if(QT_ENABLE_VERBOSE_DEPLOYMENT OR build_environment STREQUAL "ci")
|
||||
list(APPEND extra_test_args "--verbose")
|
||||
endif()
|
||||
|
||||
if(arg_ANDROID_TESTRUNNER_PRE_TEST_ADB_COMMANDS)
|
||||
foreach(command IN LISTS arg_ANDROID_TESTRUNNER_PRE_TEST_ADB_COMMANDS)
|
||||
list(APPEND extra_test_args "--pre-test-adb-command" "${command}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(test_working_dir "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
elseif(QNX)
|
||||
set(test_working_dir "")
|
||||
@ -708,7 +718,11 @@ function(qt_internal_add_test name)
|
||||
set(browser "chrome")
|
||||
endif()
|
||||
list(APPEND extra_test_args "--browser=${browser}")
|
||||
list(APPEND extra_test_args "--browser_args=\"--password-store=basic\"")
|
||||
if(DEFINED ENV{HEADLESS_CHROME_FOR_TESTING})
|
||||
list(APPEND extra_test_args "--browser_args=\"--password-store=basic --headless\"")
|
||||
else()
|
||||
list(APPEND extra_test_args "--browser_args=\"--password-store=basic\"")
|
||||
endif()
|
||||
list(APPEND extra_test_args "--kill_exit")
|
||||
|
||||
# Tests may require asyncify if they use exec(). Enable asyncify for
|
||||
@ -794,18 +808,10 @@ function(qt_internal_add_test name)
|
||||
)
|
||||
endif()
|
||||
|
||||
# Add a ${target}/check makefile target, to more easily test one test.
|
||||
|
||||
set(test_config_options "")
|
||||
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
|
||||
if(is_multi_config)
|
||||
set(test_config_options -C $<CONFIG>)
|
||||
endif()
|
||||
add_custom_target("${testname}_check"
|
||||
VERBATIM
|
||||
COMMENT "Running ${CMAKE_CTEST_COMMAND} -V -R \"^${name}$\" ${test_config_options}"
|
||||
COMMAND "${CMAKE_CTEST_COMMAND}" -V -R "^${name}$" ${test_config_options}
|
||||
)
|
||||
# Add a ${target}_check makefile target, to more easily test one test.
|
||||
# TODO: Note in batch mode testname tests would execute all batched tests defined in name
|
||||
_qt_internal_make_check_target(${testname} CTEST_TEST_NAME ${name})
|
||||
# Add appropriate dependencies to the targets as needed
|
||||
if(TARGET "${name}")
|
||||
add_dependencies("${testname}_check" "${name}")
|
||||
if(ANDROID)
|
||||
@ -902,6 +908,20 @@ function(qt_internal_add_test name)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MACOS AND NOT CMAKE_GENERATOR STREQUAL "Xcode")
|
||||
# Add com.apple.security.get-task-allow entitlement to each
|
||||
# test binary, so we can hook into the Swift crash handling.
|
||||
if(NOT arg_QMLTEST AND arg_SOURCES)
|
||||
set(entitlements_file
|
||||
"${__qt_internal_cmake_apple_support_files_path}/test.entitlements.plist")
|
||||
add_custom_command(TARGET "${name}"
|
||||
POST_BUILD COMMAND codesign --sign -
|
||||
--entitlements "${entitlements_file}"
|
||||
"$<TARGET_FILE:${name}>"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
qt_internal_add_test_finalizers("${name}")
|
||||
endfunction()
|
||||
|
||||
|
@ -168,7 +168,10 @@ function(qt_internal_add_tool target_name)
|
||||
APPEND PROPERTY
|
||||
EXPORT_PROPERTIES "_qt_package_version")
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.19.0" AND QT_FEATURE_debug_and_release)
|
||||
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.19.0"
|
||||
AND QT_FEATURE_debug_and_release
|
||||
AND is_multi_config)
|
||||
set_property(TARGET "${target_name}"
|
||||
PROPERTY EXCLUDE_FROM_ALL "$<NOT:$<CONFIG:${QT_MULTI_CONFIG_FIRST_CONFIG}>>")
|
||||
endif()
|
||||
@ -303,7 +306,7 @@ function(qt_internal_add_tool target_name)
|
||||
${__qt_internal_sbom_multi_args}
|
||||
)
|
||||
|
||||
_qt_internal_extend_sbom(${target_name} ${sbom_args})
|
||||
qt_internal_extend_qt_entity_sbom(${target_name} ${sbom_args})
|
||||
endif()
|
||||
|
||||
qt_add_list_file_finalizer(qt_internal_finalize_tool ${target_name})
|
||||
@ -385,6 +388,7 @@ function(qt_export_tools module_name)
|
||||
|
||||
# List of package dependencies that need be find_package'd when using the Tools package.
|
||||
set(package_deps "")
|
||||
set(third_party_deps "")
|
||||
|
||||
# Additional cmake files to install
|
||||
set(extra_cmake_files "")
|
||||
@ -397,7 +401,15 @@ function(qt_export_tools module_name)
|
||||
# e.g. qtwaylandscanner depends on WaylandScanner (non-qt package).
|
||||
get_target_property(extra_packages "${tool_name}" QT_EXTRA_PACKAGE_DEPENDENCIES)
|
||||
if(extra_packages)
|
||||
list(APPEND package_deps "${extra_packages}")
|
||||
foreach(third_party_dep IN LISTS extra_packages)
|
||||
list(GET third_party_dep 0 third_party_dep_name)
|
||||
list(GET third_party_dep 1 third_party_dep_version)
|
||||
|
||||
# Assume that all tool thirdparty deps are mandatory.
|
||||
# TODO: Components are not supported
|
||||
list(APPEND third_party_deps
|
||||
"${third_party_dep_name}\\\;FALSE\\\;${third_party_dep_version}\\\;\\\;")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
get_target_property(_extra_cmake_files "${tool_name}" EXTRA_CMAKE_FILES)
|
||||
@ -700,14 +712,14 @@ function(qt_internal_find_tool out_var target_name tools_target)
|
||||
set(${tools_package_name}_BACKUP_CMAKE_FIND_ROOT_PATH "${CMAKE_FIND_ROOT_PATH}")
|
||||
if(QT_HOST_PATH_CMAKE_DIR)
|
||||
set(qt_host_path_cmake_dir_absolute "${QT_HOST_PATH_CMAKE_DIR}")
|
||||
elseif(Qt${PROJECT_VERSION_MAJOR}HostInfo_DIR)
|
||||
elseif(${INSTALL_CMAKE_NAMESPACE}HostInfo_DIR)
|
||||
get_filename_component(qt_host_path_cmake_dir_absolute
|
||||
"${Qt${PROJECT_VERSION_MAJOR}HostInfo_DIR}/.." ABSOLUTE)
|
||||
"${${INSTALL_CMAKE_NAMESPACE}HostInfo_DIR}/.." ABSOLUTE)
|
||||
else()
|
||||
# This should never happen, serves as an assert.
|
||||
message(FATAL_ERROR
|
||||
"Neither QT_HOST_PATH_CMAKE_DIR nor "
|
||||
"Qt${PROJECT_VERSION_MAJOR}HostInfo_DIR available.")
|
||||
"${INSTALL_CMAKE_NAMESPACE}HostInfo_DIR available.")
|
||||
endif()
|
||||
set(CMAKE_PREFIX_PATH "${qt_host_path_cmake_dir_absolute}")
|
||||
|
||||
|
@ -7,10 +7,10 @@ function (qt_internal_setup_wasm_target_properties wasmTarget)
|
||||
|
||||
target_link_options("${wasmTarget}" INTERFACE
|
||||
"SHELL:-s MAX_WEBGL_VERSION=2"
|
||||
"SHELL:-s FETCH=1"
|
||||
"SHELL:-s WASM_BIGINT=1"
|
||||
"SHELL:-s STACK_SIZE=5MB")
|
||||
|
||||
set(executable_link_flags "-sFETCH")
|
||||
## wasm64
|
||||
if (WASM64)
|
||||
target_compile_options("${wasmTarget}" INTERFACE "SHELL:-s MEMORY64=1" )
|
||||
@ -99,7 +99,7 @@ function (qt_internal_setup_wasm_target_properties wasmTarget)
|
||||
set(enable_side_module_if_needed
|
||||
"$<$<IN_LIST:$<TARGET_PROPERTY:TYPE>,${side_modules}>:SHELL:-s SIDE_MODULE=1>")
|
||||
set(enable_main_module_if_needed
|
||||
"$<$<IN_LIST:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:SHELL:-s MAIN_MODULE=1>")
|
||||
"$<$<IN_LIST:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:SHELL:-sMAIN_MODULE=1 ${executable_link_flags}>")
|
||||
set(set_shared_module_type_if_needed
|
||||
"${enable_side_module_if_needed}"
|
||||
"${enable_main_module_if_needed}"
|
||||
@ -115,7 +115,7 @@ function (qt_internal_setup_wasm_target_properties wasmTarget)
|
||||
target_link_options("${wasmTarget}" INTERFACE "${set_shared_module_type_if_needed}")
|
||||
|
||||
else()
|
||||
target_link_options("${wasmTarget}" INTERFACE "SHELL:-s ERROR_ON_UNDEFINED_SYMBOLS=1")
|
||||
target_link_options("${wasmTarget}" INTERFACE "SHELL:-sERROR_ON_UNDEFINED_SYMBOLS=1 ${executable_link_flags}")
|
||||
endif()
|
||||
|
||||
# Suppress warnings for known issues for developer builds
|
||||
|
@ -8,7 +8,7 @@ function(qt_internal_check_msvc_versions)
|
||||
set(min_msvc_version "1930")
|
||||
if(MSVC_VERSION VERSION_LESS min_msvc_version)
|
||||
message(FATAL_ERROR
|
||||
"Qt requires at least Visual Studio 2019 (MSVC ${min_msvc_version} or newer), "
|
||||
"Qt requires at least Visual Studio 2022 (MSVC ${min_msvc_version} or newer), "
|
||||
"you're building against version ${MSVC_VERSION}. "
|
||||
"You can turn off this version check by setting QT_NO_MSVC_MIN_VERSION_CHECK to ON."
|
||||
)
|
||||
|
@ -50,6 +50,7 @@ The following table describes the mapping of configure options to CMake argument
|
||||
| -sbom-json-required | -DQT_SBOM_REQUIRE_GENERATE_JSON=ON | Fails the build if Python deps are not found |
|
||||
| -sbom-verify | -DQT_SBOM_VERIFY=ON | Enables verification of generated SBOMs |
|
||||
| -sbom-verify-required | -DQT_SBOM_REQUIRE_VERIFY=ON | Fails the build if Python deps are not found |
|
||||
| -sbomdir <dir> | -DINSTALL_SBOMDIR=<dir> | Installation location of SBOM files. |
|
||||
| -qtinlinenamespace | -DQT_INLINE_NAMESPACE=ON | Make the namespace specified by -qtnamespace an inline one. |
|
||||
| -qtnamespace <name> | -DQT_NAMESPACE=<name> | |
|
||||
| -qtlibinfix <infix> | -DQT_LIBINFIX=<infix> | |
|
||||
@ -57,8 +58,10 @@ The following table describes the mapping of configure options to CMake argument
|
||||
| -gcov | -DINPUT_coverage=gcov | Enables code coverage using the gcov tool. |
|
||||
| -trace [backend] | -DINPUT_trace=yes or -DINPUT_trace=<backend> | |
|
||||
| | or -DFEATURE_<backend> | |
|
||||
| -sanitize address -sanitize undefined | -DFEATURE_sanitize_address=ON | Directly setting -DECM_ENABLE_SANITIZERS=foo is not supported |
|
||||
| | -DFEATURE_sanitize_undefined=ON | |
|
||||
| -sanitize address | -DFEATURE_sanitize_address=ON | Directly setting -DECM_ENABLE_SANITIZERS=foo is not supported |
|
||||
| -sanitize undefined | -DFEATURE_sanitize_undefined=ON | See above. |
|
||||
| -sanitize thread | -DFEATURE_sanitize_thread=ON | See above. |
|
||||
| -sanitize memory | -DFEATURE_sanitize_memory=ON | See above. |
|
||||
| -c++std c++20 | -DFEATURE_cxx20=ON | |
|
||||
| -sse2/-sse3/-ssse3/-sse4.1 | -DFEATURE_sse4=ON | |
|
||||
| -mips_dsp/-mips_dspr2 | -DFEATURE_mips_dsp=ON | |
|
||||
|
9
cmake/macos/test.entitlements.plist
Normal file
9
cmake/macos/test.entitlements.plist
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
||||
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.get-task-allow</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
@ -52,8 +52,8 @@ if(QT_USE_VCPKG OR (NOT DEFINED QT_USE_VCPKG AND __qt_initially_configured_use_v
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT VCPKG_CHAINLOAD_TOOLCHAIN_FILE AND QT_CHAINLOAD_TOOLCHAIN_FILE)
|
||||
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE "${QT_CHAINLOAD_TOOLCHAIN_FILE}" CACHE STRING "")
|
||||
if(NOT VCPKG_CHAINLOAD_TOOLCHAIN_FILE AND __qt_chainload_toolchain_file)
|
||||
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE "${__qt_chainload_toolchain_file}" CACHE STRING "")
|
||||
endif()
|
||||
|
||||
set(__qt_chainload_toolchain_file "${__qt_vcpkg_toolchain_file}")
|
||||
|
@ -21,8 +21,8 @@ instructions:
|
||||
variableValue: " {{.SourceDir}}/coin_qnx_qemu_runner.sh"
|
||||
enable_if:
|
||||
condition: property
|
||||
property: target.osVersion
|
||||
in_values: [QNX_710]
|
||||
property: target.os
|
||||
equals_value: QNX
|
||||
- type: AppendToEnvironmentVariable
|
||||
variableName: TESTRUNNER
|
||||
variableValue: " {{.AgentWorkingDir}}/coin_vxworks_qemu_runner.sh"
|
||||
@ -141,6 +141,16 @@ instructions:
|
||||
maxTimeBetweenOutput: 14400
|
||||
userMessageOnFailure: >
|
||||
Failed to run tests.
|
||||
- type: ExecuteCommand
|
||||
command: >
|
||||
cmake -E copy
|
||||
Testing{{.Env.CI_PATH_SEP}}Temporary{{.Env.CI_PATH_SEP}}LastTest.log
|
||||
{{.Env.COIN_CTEST_RESULTSDIR}}{{.Env.CI_PATH_SEP}}CTest.log
|
||||
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
|
||||
ignoreExitCode: false
|
||||
userMessageOnFailure: >
|
||||
Failed to copy LastTest.log to testresults directory.
|
||||
executeOn: always
|
||||
- type: Group
|
||||
enable_if:
|
||||
condition: runtime
|
||||
@ -155,16 +165,13 @@ instructions:
|
||||
maxTimeBetweenOutput: 14400
|
||||
userMessageOnFailure: >
|
||||
Failed to run tests.
|
||||
|
||||
- type: Group
|
||||
instructions:
|
||||
- type: ExecuteCommand
|
||||
command: >
|
||||
cmake -E copy
|
||||
Testing{{.Env.CI_PATH_SEP}}Temporary{{.Env.CI_PATH_SEP}}LastTest.log
|
||||
{{.Env.COIN_CTEST_RESULTSDIR}}{{.Env.CI_PATH_SEP}}CTest.log
|
||||
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
|
||||
ignoreExitCode: false
|
||||
ignoreExitCode: true
|
||||
userMessageOnFailure: >
|
||||
Failed to copy LastTest.log to testresults directory.
|
||||
executeOn: always
|
||||
|
@ -18,7 +18,7 @@ instructions:
|
||||
equals_property: target.os
|
||||
- condition: property
|
||||
property: target.osVersion
|
||||
not_in_values: [QEMU, QNX_710, VxWorks]
|
||||
not_in_values: [QEMU, QNX_710, QNX_800, VxWorks]
|
||||
- type: Group
|
||||
instructions:
|
||||
- type: EnvironmentVariable
|
||||
@ -32,7 +32,7 @@ instructions:
|
||||
equals_property: target.os
|
||||
- condition: property
|
||||
property: target.osVersion
|
||||
not_in_values: [QEMU, QNX_710, VxWorks]
|
||||
not_in_values: [QEMU, QNX_710, QNX_800, VxWorks]
|
||||
- type: Group
|
||||
instructions:
|
||||
- !include "{{qt/qtbase}}/cmake_setup_running_qnxqemu_tests_env_vars.yaml"
|
||||
@ -40,8 +40,8 @@ instructions:
|
||||
condition: and
|
||||
conditions:
|
||||
- condition: property
|
||||
property: target.osVersion
|
||||
equals_value: QNX_710
|
||||
property: target.os
|
||||
equals_value: QNX
|
||||
- condition: property
|
||||
property: features
|
||||
not_contains_value: DisableTests
|
||||
|
@ -1,6 +1,7 @@
|
||||
type: Group
|
||||
instructions:
|
||||
- !include "{{qt/qtbase}}/prepare_building_env.yaml"
|
||||
- !include "{{qt/qtbase}}/prepare_source_sbom_check.yaml"
|
||||
- type: Group
|
||||
instructions:
|
||||
- type: Group
|
||||
@ -54,19 +55,13 @@ instructions:
|
||||
- type: Group
|
||||
instructions:
|
||||
- !include "{{qt/qtbase}}/cmake_cross_compilation_module_build_instructions.yaml"
|
||||
- type: Group
|
||||
instructions:
|
||||
- !include "{{qt/qtbase}}/cmake_build_and_upload_test_artifacts_target.yaml"
|
||||
enable_if:
|
||||
condition: property
|
||||
property: target.osVersion
|
||||
in_values: [Android_ANY, QEMU, IOS_ANY, QNX_710, WebAssembly, INTEGRITY, VxWorks]
|
||||
- !include "{{qt/qtbase}}/cmake_build_and_upload_test_artifacts_target.yaml"
|
||||
enable_if:
|
||||
condition: or
|
||||
conditions:
|
||||
- condition: property
|
||||
property: target.osVersion
|
||||
in_values: [Android_ANY, QEMU, IOS_ANY, QNX_710, WebAssembly, INTEGRITY, VxWorks]
|
||||
in_values: [Android_ANY, QEMU, IOS_ANY, QNX_710, QNX_800, WebAssembly, INTEGRITY, VxWorks]
|
||||
- condition: and
|
||||
conditions:
|
||||
- condition: property
|
||||
|
@ -73,8 +73,8 @@ instructions:
|
||||
condition: and
|
||||
conditions:
|
||||
- condition: property
|
||||
property: target.osVersion
|
||||
equals_value: QNX_710
|
||||
property: target.os
|
||||
equals_value: QNX
|
||||
- condition: property
|
||||
property: features
|
||||
not_contains_value: DisableTests
|
||||
|
@ -24,7 +24,7 @@ instructions:
|
||||
equals_property: target.os
|
||||
- condition: property
|
||||
property: target.osVersion
|
||||
in_values: [QEMU, QNX_710]
|
||||
in_values: [QEMU, QNX_710, QNX_800]
|
||||
disable_if:
|
||||
condition: or
|
||||
conditions:
|
||||
|
@ -22,7 +22,7 @@ instructions:
|
||||
equals_property: target.os
|
||||
- condition: property
|
||||
property: target.osVersion
|
||||
in_values: [QEMU, QNX_710, IOS_ANY]
|
||||
in_values: [QEMU, QNX_710, QNX_800, IOS_ANY]
|
||||
- condition: property
|
||||
property: features
|
||||
contains_value: AndroidTestRun
|
||||
|
@ -1,6 +1,7 @@
|
||||
type: Group
|
||||
instructions:
|
||||
- !include "{{qt/qtbase}}/prepare_building_env.yaml"
|
||||
- !include "{{qt/qtbase}}/prepare_source_sbom_check.yaml"
|
||||
- type: Group
|
||||
instructions:
|
||||
- !include "{{qt/qtbase}}/cmake_qtbase_build_instructions.yaml"
|
||||
@ -45,19 +46,13 @@ instructions:
|
||||
property: target.arch
|
||||
equals_value: Multi
|
||||
- !include "{{qt/qtbase}}/prepare_android_multi_abi_env.yaml"
|
||||
- type: Group
|
||||
instructions:
|
||||
- !include "{{qt/qtbase}}/cmake_build_and_upload_test_artifacts_target.yaml"
|
||||
enable_if:
|
||||
condition: property
|
||||
property: target.osVersion
|
||||
in_values: [Android_ANY, QEMU, IOS_ANY, QNX_710, WebAssembly, INTEGRITY, VxWorks]
|
||||
- !include "{{qt/qtbase}}/cmake_build_and_upload_test_artifacts_target.yaml"
|
||||
enable_if:
|
||||
condition: or
|
||||
conditions:
|
||||
- condition: property
|
||||
property: target.osVersion
|
||||
in_values: [Android_ANY, QEMU, IOS_ANY, QNX_710, WebAssembly, INTEGRITY, VxWorks]
|
||||
in_values: [Android_ANY, QEMU, IOS_ANY, QNX_710, QNX_800, WebAssembly, INTEGRITY, VxWorks]
|
||||
- condition: and
|
||||
conditions:
|
||||
- condition: property
|
||||
|
@ -369,6 +369,22 @@ instructions:
|
||||
variableValue: "{{.Env.VXWORKS_HOME}}/wrenv.linux"
|
||||
|
||||
# QNX variables
|
||||
- type: EnvironmentVariable
|
||||
variableName: QNX_ACTIVE
|
||||
variableValue: "{{.Env.QNX_710}}"
|
||||
enable_if:
|
||||
condition: property
|
||||
property: target.osVersion
|
||||
equals_value: QNX_710
|
||||
|
||||
- type: EnvironmentVariable
|
||||
variableName: QNX_ACTIVE
|
||||
variableValue: "{{.Env.QNX_800}}"
|
||||
enable_if:
|
||||
condition: property
|
||||
property: target.osVersion
|
||||
equals_value: QNX_800
|
||||
|
||||
- type: Group
|
||||
enable_if:
|
||||
condition: and
|
||||
@ -380,63 +396,45 @@ instructions:
|
||||
property: target.os
|
||||
equals_value: QNX
|
||||
instructions:
|
||||
- type: EnvironmentVariable
|
||||
variableName: QNX_TARGET
|
||||
variableValue: "{{.Env.QNX_710}}/target/qnx7"
|
||||
- type: EnvironmentVariable
|
||||
variableName: QNX_CONFIGURATION_EXCLUSIVE
|
||||
variableValue: "{{.Env.HOME}}/.qnx"
|
||||
- type: EnvironmentVariable
|
||||
variableName: QNX_CONFIGURATION
|
||||
variableValue: "{{.Env.HOME}}/.qnx"
|
||||
- type: PrependToEnvironmentVariable
|
||||
variableName: PATH
|
||||
variableValue: "{{.Env.QNX_710}}/host/linux/x86_64/usr/bin:"
|
||||
- type: PrependToEnvironmentVariable
|
||||
variableName: PATH
|
||||
variableValue: "{{.Env.QNX_710}}/host/common/bin:"
|
||||
- type: PrependToEnvironmentVariable
|
||||
variableName: PATH
|
||||
variableValue: "{{.Env.HOME}}/.qnx:"
|
||||
- type: EnvironmentVariable
|
||||
variableName: QNX_HOST
|
||||
variableValue: "{{.Env.QNX_710}}/host/linux/x86_64"
|
||||
- type: AppendToEnvironmentVariable
|
||||
variableName: PATH
|
||||
variableValue: ":{{.Env.QEMUARMV7_TOOLCHAIN_SYSROOT}}/../x86_64-pokysdk-linux/usr/bin:"
|
||||
- type: EnvironmentVariable
|
||||
variableName: QNX_TARGET
|
||||
variableValue: "{{.Env.QNX_ACTIVE}}/target/qnx7"
|
||||
- type: PrependToEnvironmentVariable
|
||||
variableName: PATH
|
||||
variableValue: "{{.Env.QNX_ACTIVE}}/host/linux/x86_64/usr/bin:"
|
||||
- type: PrependToEnvironmentVariable
|
||||
variableName: PATH
|
||||
variableValue: "{{.Env.QNX_ACTIVE}}/host/common/bin:"
|
||||
- type: EnvironmentVariable
|
||||
variableName: QNX_HOST
|
||||
variableValue: "{{.Env.QNX_ACTIVE}}/host/linux/x86_64"
|
||||
|
||||
- type: Group
|
||||
- type: SetEnvironmentFromScript
|
||||
command: "{{.Env.QNX_ACTIVE}}\\qnxsdp-env.bat"
|
||||
userMessageOnFailure: "Failed to set QNX environment"
|
||||
maxTimeInSeconds: 60
|
||||
maxTimeBetweenOutput: 60
|
||||
enable_if:
|
||||
condition: and
|
||||
conditions:
|
||||
- condition: property
|
||||
property: host.os
|
||||
equals_value: Windows
|
||||
property: target.osVersion
|
||||
contains_value: QNX
|
||||
- condition: property
|
||||
property: target.os
|
||||
equals_value: QNX
|
||||
instructions:
|
||||
- type: EnvironmentVariable
|
||||
variableName: QNX_TARGET
|
||||
variableValue: "{{.Env.QNX_710_CMAKE}}/target/qnx7"
|
||||
- type: EnvironmentVariable
|
||||
variableName: QNX_CONFIGURATION_EXCLUSIVE
|
||||
variableValue: "{{.Env.HOMEPATH}}\\.qnx"
|
||||
- type: EnvironmentVariable
|
||||
variableName: QNX_CONFIGURATION
|
||||
variableValue: "{{.Env.HOMEPATH}}\\.qnx"
|
||||
- type: PrependToEnvironmentVariable
|
||||
variableName: PATH
|
||||
variableValue: "{{.Env.QNX_710}}\\host\\win64\\x86_64\\usr\\bin;"
|
||||
- type: PrependToEnvironmentVariable
|
||||
variableName: PATH
|
||||
variableValue: "{{.Env.QNX_710}}\\host\\common\\bin;"
|
||||
- type: PrependToEnvironmentVariable
|
||||
variableName: PATH
|
||||
variableValue: "{{.Env.HOMEPATH}}\\.qnx;"
|
||||
- type: EnvironmentVariable
|
||||
variableName: QNX_HOST
|
||||
variableValue: "{{.Env.QNX_710}}\\host\\win64\\x86_64"
|
||||
property: host.os
|
||||
contains_value: Windows
|
||||
|
||||
# Enable warnings are errors
|
||||
- type: Group
|
||||
|
47
coin/instructions/prepare_license_test.yaml
Normal file
47
coin/instructions/prepare_license_test.yaml
Normal file
@ -0,0 +1,47 @@
|
||||
type: Group
|
||||
instructions:
|
||||
- type: ChangeDirectory
|
||||
directory: "{{.AgentWorkingDir}}"
|
||||
- type: EnvironmentVariable
|
||||
variableName: QTQA_LICHECK_BRANCH
|
||||
variableValue: "{{ slice .Env.TESTED_MODULE_BRANCH_COIN 5 }}"
|
||||
enable_if:
|
||||
condition: runtime
|
||||
env_var: TESTED_MODULE_BRANCH_COIN
|
||||
contains_value: "tqtc/"
|
||||
- type: EnvironmentVariable
|
||||
variableName: QTQA_LICHECK_BRANCH
|
||||
variableValue: "{{ .Env.TESTED_MODULE_BRANCH_COIN }}"
|
||||
disable_if:
|
||||
condition: runtime
|
||||
env_var: TESTED_MODULE_BRANCH_COIN
|
||||
contains_value: "tqtc/"
|
||||
|
||||
# The command must not have whitespace directly after any piping,
|
||||
# as whitespace directly after pipes will be interpreted as part of the command.
|
||||
- type: ExecuteCommand
|
||||
command: ["bash", "-c", "git clone --depth=1 -b {{ .Env.QTQA_LICHECK_BRANCH }} git://{{.Env.QT_COIN_GIT_DAEMON}}/qt-project/qt/qtqa qt/qtqa-latest ||git clone --depth=1 -b dev git://{{.Env.QT_COIN_GIT_DAEMON}}/qt-project/qt/qtqa qt/qtqa-latest"]
|
||||
maxTimeInSeconds: 600
|
||||
maxTimeBetweenOutput: 600
|
||||
userMessageOnFailure: >
|
||||
Failed to clone qtqa sources. Please investigate why.
|
||||
disable_if:
|
||||
condition: property
|
||||
property: host.os
|
||||
equals_value: Windows
|
||||
- type: ExecuteCommand
|
||||
command: ["cmd.exe", "/C", "git clone --depth=1 -b {{ .Env.QTQA_LICHECK_BRANCH }} git://{{.Env.QT_COIN_GIT_DAEMON}}/qt-project/qt/qtqa qt/qtqa-latest ||git clone --depth=1 -b dev git://{{.Env.QT_COIN_GIT_DAEMON}}/qt-project/qt/qtqa qt/qtqa-latest"]
|
||||
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
|
||||
maxTimeInSeconds: 600
|
||||
maxTimeBetweenOutput: 600
|
||||
userMessageOnFailure: >
|
||||
Failed to clone qtqa sources. Please investigate why.
|
||||
enable_if:
|
||||
condition: property
|
||||
property: host.os
|
||||
equals_value: Windows
|
||||
- type: EnvironmentVariable
|
||||
variableName: QT_MODULE_TO_TEST
|
||||
variableValue: "{{.SourceDir}}"
|
||||
userMessageOnFailure: >
|
||||
Failed to set QT_MODULE_TO_TEST environment variable. This should not happen.
|
52
coin/instructions/prepare_source_sbom_check.yaml
Normal file
52
coin/instructions/prepare_source_sbom_check.yaml
Normal file
@ -0,0 +1,52 @@
|
||||
type: Group
|
||||
instructions:
|
||||
# need qemu toolchains update to have perl script verifying source SBOM
|
||||
- type: Group
|
||||
instructions:
|
||||
- type: EnvironmentVariable
|
||||
variableName: VERIFY_SOURCE_SBOM
|
||||
variableValue: "OFF"
|
||||
enable_if:
|
||||
condition: and
|
||||
conditions:
|
||||
- condition: property
|
||||
property: host.os
|
||||
equals_value: Linux
|
||||
- condition: property
|
||||
property: target.arch
|
||||
equals_value: MIPS64
|
||||
- type: Group
|
||||
instructions:
|
||||
- type: EnvironmentVariable
|
||||
variableName: VERIFY_SOURCE_SBOM
|
||||
variableValue: "OFF"
|
||||
enable_if:
|
||||
condition: and
|
||||
conditions:
|
||||
- condition: property
|
||||
property: host.os
|
||||
equals_value: Windows
|
||||
- condition: property
|
||||
property: target.arch
|
||||
equals_value: AARCH64
|
||||
- type: Group
|
||||
instructions:
|
||||
- !include "{{qt/qtbase}}/prepare_license_test.yaml"
|
||||
- type: Group
|
||||
instructions:
|
||||
- type: EnvironmentVariable
|
||||
variableName: QT_QA_LICENSE_TEST_DIR
|
||||
variableValue: "{{.AgentWorkingDir}}"
|
||||
- type: EnvironmentVariable
|
||||
variableName: QT_SOURCE_SBOM_TEST_SCRIPT
|
||||
variableValue: "qt{{.Env.CI_PATH_SEP}}qtqa-latest{{.Env.CI_PATH_SEP}}tests{{.Env.CI_PATH_SEP}}prebuild{{.Env.CI_PATH_SEP}}license{{.Env.CI_PATH_SEP}}tst_licenses.pl"
|
||||
userMessageOnFailure: >
|
||||
Failed to set QT_SOURCE_SBOM_TEST_SCRIPT environment variable. This should not happen.
|
||||
enable_if:
|
||||
condition: property
|
||||
property: features
|
||||
contains_value: GenerateSBOM
|
||||
|
||||
|
||||
|
||||
|
@ -1,35 +1,6 @@
|
||||
type: Group
|
||||
instructions:
|
||||
- type: ChangeDirectory
|
||||
directory: "{{.AgentWorkingDir}}"
|
||||
- type: EnvironmentVariable
|
||||
variableName: QTQA_LICHECK_BRANCH
|
||||
variableValue: "{{ slice .Env.TESTED_MODULE_BRANCH_COIN 5 }}"
|
||||
enable_if:
|
||||
condition: runtime
|
||||
env_var: TESTED_MODULE_BRANCH_COIN
|
||||
contains_value: "tqtc/"
|
||||
- type: EnvironmentVariable
|
||||
variableName: QTQA_LICHECK_BRANCH
|
||||
variableValue: "{{ .Env.TESTED_MODULE_BRANCH_COIN }}"
|
||||
disable_if:
|
||||
condition: runtime
|
||||
env_var: TESTED_MODULE_BRANCH_COIN
|
||||
contains_value: "tqtc/"
|
||||
|
||||
# The command must not have whitespace directly after any piping,
|
||||
# as whitespace directly after pipes will be interpreted as part of the command.
|
||||
- type: ExecuteCommand
|
||||
command: ["bash", "-c", "git clone --depth=1 -b {{ .Env.QTQA_LICHECK_BRANCH }} git://{{.Env.QT_COIN_GIT_DAEMON}}/qt-project/qt/qtqa qt/qtqa-latest ||git clone --depth=1 -b dev git://{{.Env.QT_COIN_GIT_DAEMON}}/qt-project/qt/qtqa qt/qtqa-latest"]
|
||||
maxTimeInSeconds: 600
|
||||
maxTimeBetweenOutput: 600
|
||||
userMessageOnFailure: >
|
||||
Failed to clone qtqa sources. Please investigate why.
|
||||
- type: EnvironmentVariable
|
||||
variableName: QT_MODULE_TO_TEST
|
||||
variableValue: "{{.SourceDir}}"
|
||||
userMessageOnFailure: >
|
||||
Failed to set QT_MODULE_TO_TEST environment variable. This should not happen.
|
||||
- !include "{{qt/qtbase}}/prepare_license_test.yaml"
|
||||
- type: ExecuteCommand
|
||||
command: perl qt/qtqa-latest/tests/prebuild/license/tst_licenses.pl
|
||||
maxTimeInSeconds: 7200
|
||||
|
@ -10,7 +10,7 @@ instructions:
|
||||
testdir="$(dirname $1)"
|
||||
testexecutable="$1"
|
||||
echo RUNNING via serial: "$quoted_args"
|
||||
echo "cmd rtp exec -p 200 -t 0x01000000 -u 1000000 $testexecutable -- $quoted_args" > /home/qt/work/vx.sh
|
||||
echo "cmd rtp exec -p 200 -t 0x01000000 -u 0x1000000 $testexecutable -- $quoted_args" > /home/qt/work/vx.sh
|
||||
echo "cmd echo \"qtest_in_vxworks_complete: $?\"" >> /home/qt/work/vx.sh
|
||||
#rtp exec Execute a process.
|
||||
# -p : specify the initial task priority
|
||||
@ -22,11 +22,17 @@ instructions:
|
||||
|
||||
# qtest_in_vxworks_complete echo is used to detect test process completion as it will
|
||||
# be echoed after test process ends normally or crashes when normal log lines are not present.
|
||||
|
||||
# Check that emulator is functioning
|
||||
echo "cmd echo \"health check\"" > /tmp/guest.in
|
||||
sleep 0.5
|
||||
read -t 5 echoline</tmp/guest.out
|
||||
read -t 1 testline</tmp/guest.out
|
||||
( echo "cmd echo \"health check\"" > /tmp/guest.in ) & pid=$!
|
||||
( sleep 5 && kill -HUP $pid ) 2>/dev/null & watcher=$!
|
||||
wait $pid 2>/dev/null && pkill -HUP -P $watcher
|
||||
|
||||
if [[ "$?" -eq "0" ]]; then
|
||||
read -t 5 echoline</tmp/guest.out
|
||||
read -t 1 testline</tmp/guest.out
|
||||
fi
|
||||
|
||||
if [[ -z "$testline" ]]; then
|
||||
echo "Restarting stuck emulator"
|
||||
pkill qemu-system
|
||||
@ -58,4 +64,16 @@ instructions:
|
||||
exitcode=$(echo "$line" | sed -nr 's/qtest_in_vxworks_complete: (-?[0-9]+)/\1/gp' | tr -d '\r')
|
||||
exit $exitcode
|
||||
fi
|
||||
|
||||
# Handle crashes
|
||||
if echo "$line" | /usr/bin/grep -qE "(SIGSEGV)|(SIGABRT)|(S_rtpLib_[A-Z_]+)"
|
||||
then
|
||||
# Empty output pipe
|
||||
while read -t 1 line; do
|
||||
echo $line
|
||||
done < /tmp/guest.out
|
||||
echo "Test crashed"
|
||||
pkill qemu-system # Kill emulator to force restart on next test start
|
||||
exit 1
|
||||
fi
|
||||
done < /tmp/guest.out
|
||||
|
@ -1,4 +1,5 @@
|
||||
version: 2
|
||||
tags: [git]
|
||||
accept_configuration:
|
||||
condition: property
|
||||
property: features
|
||||
@ -11,7 +12,11 @@ machine_type:
|
||||
cores: 4
|
||||
|
||||
instructions:
|
||||
|
||||
Build:
|
||||
- type: EnvironmentVariable
|
||||
variableName: VERIFY_SOURCE_SBOM
|
||||
variableValue: "ON"
|
||||
- !include "{{qt/qtbase}}/coin_qtbase_build_template_v2.yaml"
|
||||
|
||||
Test:
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user