mirror of
https://github.com/citra-emu/citra-nightly.git
synced 2025-09-27 21:17:25 +00:00
Compare commits
468 commits
nightly-19
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
0ff3440232 | ||
|
69e758d738 | ||
|
f4768cd26c | ||
|
e0d2c1308e | ||
|
4f9fc88bb3 | ||
|
d857743075 | ||
|
b5042a5257 | ||
|
e524542a40 | ||
|
3a4ebb1413 | ||
|
cbe8987036 | ||
|
da5aa70fc9 | ||
|
749a721aa2 | ||
|
bb003c2bd4 | ||
|
7638f87f74 | ||
|
aa6809e2a8 | ||
|
5e02be75a3 | ||
|
b9c9beeee5 | ||
|
de993dcfbd | ||
|
3c9157b1ec | ||
|
0c40c10022 | ||
|
2766118e33 | ||
|
06b26691ba | ||
|
d41ce64f7b | ||
|
1165a708d5 | ||
|
19784355f9 | ||
|
aa6a29d7e1 | ||
|
106364e01e | ||
|
d5a1bd07f3 | ||
|
8afa27718c | ||
|
8e2415f455 | ||
|
c978c074db | ||
|
cb92ec278e | ||
|
9f5d5c6ddd | ||
|
480604ec72 | ||
|
63feac6bb3 | ||
|
469f76b075 | ||
|
7a4854c519 | ||
|
d1e3dddf6a | ||
|
265e8193b9 | ||
|
e8c20fa782 | ||
|
95ae46f6a8 | ||
|
41fe75acb7 | ||
|
1744537d85 | ||
|
bea863efff | ||
|
89e13a85a7 | ||
|
549fdd0736 | ||
|
eddc4a029c | ||
|
82294425e3 | ||
|
77fce3cf82 | ||
|
8d82adb3d3 | ||
|
228f26d1e4 | ||
|
789654d7da | ||
|
ca3b2306d5 | ||
|
8e87bd606c | ||
|
f26044bb88 | ||
|
c59ef7d793 | ||
|
6a7841d4b0 | ||
|
a2d1c4a94c | ||
|
9c84721d84 | ||
|
cca8c08a9a | ||
|
72c1075402 | ||
|
30c53c9509 | ||
|
da9f382d2c | ||
|
a177769c3b | ||
|
f346949989 | ||
|
37f0a7484f | ||
|
19d5695aa3 | ||
|
6cbdc73f53 | ||
|
81ee7ad893 | ||
|
2ce0a9e899 | ||
|
015e42be05 | ||
|
57696b2c11 | ||
|
c8c2beaeff | ||
|
6069fac76d | ||
|
7bacb78ce3 | ||
|
0165012ba4 | ||
|
96aa1b3a08 | ||
|
b2c740ee0e | ||
|
bc352e8168 | ||
|
4f00eb20db | ||
|
8b6a9b0dd8 | ||
|
62409f8139 | ||
|
0df72f3873 | ||
|
f2ee9baec7 | ||
|
8e2037b3ff | ||
|
c6bcbc02de | ||
|
36db566428 | ||
|
9b147d3f9c | ||
|
7dd9174d31 | ||
|
5a7f615da1 | ||
|
811303ea54 | ||
|
5bcdcffd96 | ||
|
2bb7f89c30 | ||
|
602f4f60d8 | ||
|
3113ae6616 | ||
|
bd4ec251cd | ||
|
b6b98af105 | ||
|
60a280af24 | ||
|
178e602589 | ||
|
dccb8f6b17 | ||
|
f177433d41 | ||
|
71b88c4c1f | ||
|
c7e9f8449e | ||
|
2e369c03b8 | ||
|
a47d8a7b4d | ||
|
02ba5c652b | ||
|
762ddfd07b | ||
|
d680b79725 | ||
|
2b20082581 | ||
|
15ea0c6336 | ||
|
9a6d15ab74 | ||
|
60584e861d | ||
|
070853b465 | ||
|
24b5ffbfca | ||
|
4d9eedd0d8 | ||
|
59df319f48 | ||
|
875f5eaad5 | ||
|
ea9f522c0c | ||
|
55e0b02863 | ||
|
59beeac4c7 | ||
|
0ed909e782 | ||
|
9da78f6126 | ||
|
0842ee6d7b | ||
|
6ec079ede8 | ||
|
83b329f6e1 | ||
|
db7b929e47 | ||
|
dc8425a986 | ||
|
670e9936a4 | ||
|
c0ecdb689d | ||
|
68e6a2185d | ||
|
09b36c589b | ||
|
1dc0fa7bb5 | ||
|
85bd1be852 | ||
|
c17ec1d1aa | ||
|
33a1f27a99 | ||
|
5733c8681e | ||
|
f8ae41dfe3 | ||
|
52254537b7 | ||
|
98f17f8f04 | ||
|
ca6dae1744 | ||
|
b6acebcb11 | ||
|
ba702043f0 | ||
|
2a4c60c1dd | ||
|
a1532f813b | ||
|
26d5727b19 | ||
|
680e132318 | ||
|
90a5d989e7 | ||
|
de40153fa4 | ||
|
e9936e01c2 | ||
|
e28c2a390c | ||
|
63d1830429 | ||
|
88cc6acb4d | ||
|
3b31720c4d | ||
|
f9bbae81aa | ||
|
1c793deece | ||
|
d5b50a9fc0 | ||
|
168f168c33 | ||
|
312068eebf | ||
|
5118798c30 | ||
|
831c9c4a38 | ||
|
23ca10472a | ||
|
6f05dd9d1d | ||
|
19cc8e626b | ||
|
ceeda05798 | ||
|
222b1cc0d7 | ||
|
b74c91457e | ||
|
1c75d895fc | ||
|
271218b733 | ||
|
80213bf88f | ||
|
fa08df21a5 | ||
|
80ac6c03b5 | ||
|
d4f31bc617 | ||
|
13d02c14e0 | ||
|
84f9e9a10f | ||
|
fcc0fd671a | ||
|
ee372572a6 | ||
|
7930e1ea86 | ||
|
4dd6e12e46 | ||
|
1d4d421097 | ||
|
3f4b57635e | ||
|
86566f1c14 | ||
|
3f1f0aa7c2 | ||
|
8fe147b8f9 | ||
|
5193a5d222 | ||
|
1f6393e7d5 | ||
|
9b2a5926a6 | ||
|
e13735b624 | ||
|
3218af38d0 | ||
|
1cf64ffaef | ||
|
998b9a9525 | ||
|
27bad3a699 | ||
|
1570aeffcb | ||
|
09ee80f590 | ||
|
b10f3d96f5 | ||
|
b5d744bcae | ||
|
89d5d4a2b6 | ||
|
4284893044 | ||
|
79ea06b226 | ||
|
8d811913a5 | ||
|
ac9d72a95c | ||
|
d3ce43782d | ||
|
597a2e8ead | ||
|
b231a22ea5 | ||
|
1110c01657 | ||
|
45ef11654a | ||
|
259dbf17dc | ||
|
ec55807669 | ||
|
36146459f8 | ||
|
597297ffb4 | ||
|
4ac10c4a9d | ||
|
2416258117 | ||
|
6d4e462e42 | ||
|
ef43776c7b | ||
|
1caf569f16 | ||
|
2d83fff581 | ||
|
e49b3c75bd | ||
|
956b0868fd | ||
|
4c59443ed2 | ||
|
07839fb3ce | ||
|
3d55270de6 | ||
|
40ba5226c6 | ||
|
775a25b492 | ||
|
897d1fa957 | ||
|
1acb03b579 | ||
|
4220f69c06 | ||
|
6264b6d43c | ||
|
6cfd00e42d | ||
|
6244f9e3fd | ||
|
f5b8888686 | ||
|
2961dcf0fd | ||
|
492aa3cb10 | ||
|
7931aac3b7 | ||
|
053b3618dc | ||
|
483e877001 | ||
|
72ff0c5337 | ||
|
0ce956ba00 | ||
|
b28ade1ee8 | ||
|
9ec4954380 | ||
|
38a0a85777 | ||
|
376d33cff4 | ||
|
50f22d1f59 | ||
|
1492d73ccb | ||
|
60d815fada | ||
|
38f310f716 | ||
|
a35f8cbb78 | ||
|
6cfb8e02a8 | ||
|
5ced2c7af9 | ||
|
327a00b4d5 | ||
|
d0b8974845 | ||
|
d19fe9aa4c | ||
|
270d3eb7eb | ||
|
003a4ec09b | ||
|
279208347e | ||
|
af5202f6cb | ||
|
28c542c2c2 | ||
|
d1c16bad78 | ||
|
542209c993 | ||
|
8aee625a14 | ||
|
d2d37411bc | ||
|
43cedf59af | ||
|
30fcdc5474 | ||
|
ee3eab5054 | ||
|
dfa2fd0e0d | ||
|
8f8c54201d | ||
|
9be4fd8b91 | ||
|
bbb47cd753 | ||
|
0b0d3a4ac3 | ||
|
6aa31d6ec2 | ||
|
3e254d01ee | ||
|
928f352c94 | ||
|
e2d8eef5fa | ||
|
9e898bca06 | ||
|
cab0ad50f0 | ||
|
5ad58e0605 | ||
|
1159e4d928 | ||
|
93c7c6a995 | ||
|
81a5e2355a | ||
|
d2260bafef | ||
|
d1f600601d | ||
|
8b218e1b7d | ||
|
04aeecabcf | ||
|
df57012c50 | ||
|
61cf550d0c | ||
|
f2e0748a22 | ||
|
edf157200d | ||
|
a94297922b | ||
|
894c1c85a5 | ||
|
e129f07047 | ||
|
cf54210f42 | ||
|
b2092de871 | ||
|
6ddf4b241f | ||
|
f3d92dd3b8 | ||
|
1a6860f35c | ||
|
bc0bf4d3d2 | ||
|
1d3bf64f13 | ||
|
c3609785ff | ||
|
66404a669f | ||
|
6a1fd38063 | ||
|
a27971e723 | ||
|
eb8d2941c9 | ||
|
af78268dd5 | ||
|
baca2bfc6b | ||
|
33a2113b71 | ||
|
1f07ab8643 | ||
|
b739bd2632 | ||
|
f76165d848 | ||
|
ac78b74c45 | ||
|
a478bedb12 | ||
|
6d0cd5b00e | ||
|
5b52849f90 | ||
|
20f4677f80 | ||
|
0048e61fc7 | ||
|
aaeba6759e | ||
|
ebac2e4978 | ||
|
5b9f4d4129 | ||
|
b1b6f08926 | ||
|
7e6a761f07 | ||
|
6f7612f73d | ||
|
88ea66053e | ||
|
970f2284d8 | ||
|
baf3ea4beb | ||
|
35e208b447 | ||
|
f8b8b6e53c | ||
|
a955f02771 | ||
|
3fedc68230 | ||
|
335fb78c5c | ||
|
22c4eb86d7 | ||
|
964f9ee3cf | ||
|
bb364d9bc0 | ||
|
51996c54f0 | ||
|
539a1a0b6e | ||
|
8b21b902f2 | ||
|
19107cec4b | ||
|
a537f56766 | ||
|
b5e1a27a7e | ||
|
a9e390b1b1 | ||
|
71582a72a4 | ||
|
e783b0d4a9 | ||
|
700c00f021 | ||
|
9cb14044ec | ||
|
8b6b58a364 | ||
|
e043caac27 | ||
|
0bedb28bdc | ||
|
c10ffda91f | ||
|
5e8ae4fa8a | ||
|
7a7f485640 | ||
|
bbf833bceb | ||
|
8eebb83c2c | ||
|
d702915624 | ||
|
943d5eeddf | ||
|
f3ac6f054f | ||
|
a94af8ea62 | ||
|
6da4853360 | ||
|
b738584832 | ||
|
1cb34ea0d3 | ||
|
662bb9ba77 | ||
|
26e3f96983 | ||
|
cd3244f139 | ||
|
e5310b25d4 | ||
|
80033b84cb | ||
|
cf9bb90ae3 | ||
|
4ccd9f24fb | ||
|
753b36c6ef | ||
|
c00768d6d0 | ||
|
4383f6d80a | ||
|
dc5ca96c0f | ||
|
9d4609e29a | ||
|
df9cc1b84c | ||
|
13a8969824 | ||
|
d7b4260389 | ||
|
2126c240cd | ||
|
0b37c1da57 | ||
|
9527bfffed | ||
|
ba98bf058a | ||
|
c88acf7405 | ||
|
71aea7e571 | ||
|
3d0a3c2c45 | ||
|
9c3e2d0f50 | ||
|
0ddb095273 | ||
|
52b9007fcf | ||
|
e112421db8 | ||
|
ae6fda8638 | ||
|
197c1adcba | ||
|
fe027a96fb | ||
|
637ade3b25 | ||
|
a1443356f1 | ||
|
aa39430e2c | ||
|
8f51dd9513 | ||
|
98e9f4c32e | ||
|
a8340395a3 | ||
|
3641b9891d | ||
|
8e8ca7d9d0 | ||
|
b57773b1cf | ||
|
b559c078bc | ||
|
5c86147ef4 | ||
|
399f3d4e32 | ||
|
173b84c8ff | ||
|
b4c38372d1 | ||
|
4fd0cbebdb | ||
|
ca2d87e5e3 | ||
|
d26dcc8e31 | ||
|
0d516f6da5 | ||
|
2d6aca4563 | ||
|
2e479fcec5 | ||
|
7edc86a9bc | ||
|
9b82de6b24 | ||
|
7198243319 | ||
|
6b8a06e7b4 | ||
|
eb118b2a4c | ||
|
7616496456 | ||
|
89663e0db8 | ||
|
d8db0af1b2 | ||
|
08970e7ba0 | ||
|
d735f5c458 | ||
|
70225e92f7 | ||
|
bfb6a5b5de | ||
|
03dbdfc12f | ||
|
3faddd5e03 | ||
|
7c11b9b689 | ||
|
35d1b67fd4 | ||
|
4c8a98a321 | ||
|
982c60c67c | ||
|
7e134421d5 | ||
|
946a32d793 | ||
|
8eb89c260d | ||
|
796e8a9f24 | ||
|
c66594caf8 | ||
|
06db4ffb17 | ||
|
7f1ffa2a04 | ||
|
38435e9b3e | ||
|
d807cdfe62 | ||
|
318d55252f | ||
|
4d666b88b7 | ||
|
819d2a33c7 | ||
|
c074460f60 | ||
|
f5bb17c82e | ||
|
ccb2a7cbea | ||
|
238a574645 | ||
|
d9bf4fd8a2 | ||
|
54c499ed5b | ||
|
5b7cc76ba3 | ||
|
52f88f8fb4 | ||
|
abd949fea1 | ||
|
f1ece7c56f | ||
|
c67c648c1a | ||
|
723b662604 | ||
|
0f5ff64ae6 | ||
|
e33a8a9b26 | ||
|
b91fbf3f8e | ||
|
4ddb2116bf | ||
|
691e09473e | ||
|
b45c7188c7 | ||
|
a1d265325a | ||
|
1ede2f5b5a | ||
|
b452b61e58 | ||
|
848116b5be | ||
|
5311c939a2 | ||
|
8cada619b3 | ||
|
72b82ef6ed | ||
|
2281bf5b0b | ||
|
5c45c97ff9 | ||
|
975ee15635 | ||
|
fa8c530e10 | ||
|
7d6c14e584 | ||
|
40962c4479 | ||
|
110063aa56 | ||
|
a12058ea37 | ||
|
b89f5278ac |
22
.ci/android.sh
Executable file
22
.ci/android.sh
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/bin/bash -ex
|
||||||
|
|
||||||
|
export NDK_CCACHE=$(which ccache)
|
||||||
|
[ "$GITHUB_REPOSITORY" = "citra-emu/citra-canary" ] &&
|
||||||
|
BUILD_FLAVOR=canary ||
|
||||||
|
BUILD_FLAVOR=nightly
|
||||||
|
|
||||||
|
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
|
||||||
|
export ANDROID_KEYSTORE_FILE="${GITHUB_WORKSPACE}/ks.jks"
|
||||||
|
base64 --decode <<< "${ANDROID_KEYSTORE_B64}" > "${ANDROID_KEYSTORE_FILE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd src/android
|
||||||
|
chmod +x ./gradlew
|
||||||
|
./gradlew assemble${BUILD_FLAVOR}Release
|
||||||
|
./gradlew bundle${BUILD_FLAVOR}Release
|
||||||
|
|
||||||
|
ccache -s -v
|
||||||
|
|
||||||
|
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
|
||||||
|
rm "${ANDROID_KEYSTORE_FILE}"
|
||||||
|
fi
|
|
@ -1,15 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
export NDK_CCACHE=$(which ccache)
|
|
||||||
[ "$GITHUB_REPOSITORY" = "citra-emu/citra-canary" ] &&
|
|
||||||
BUILD_FLAVOR=canary ||
|
|
||||||
BUILD_FLAVOR=nightly
|
|
||||||
|
|
||||||
ccache -s
|
|
||||||
|
|
||||||
cd src/android
|
|
||||||
chmod +x ./gradlew
|
|
||||||
./gradlew assemble${BUILD_FLAVOR}Release
|
|
||||||
./gradlew bundle${BUILD_FLAVOR}Release
|
|
||||||
|
|
||||||
ccache -s
|
|
|
@ -1,23 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
. ./.ci/common/pre-upload.sh
|
|
||||||
|
|
||||||
REV_NAME="citra-android-${GITDATE}-${GITREV}"
|
|
||||||
[ "${GITHUB_REPOSITORY}" = "citra-emu/citra-canary" ] &&
|
|
||||||
BUILD_FLAVOR=canary ||
|
|
||||||
BUILD_FLAVOR=nightly
|
|
||||||
|
|
||||||
cp src/android/app/build/outputs/apk/${BUILD_FLAVOR}/release/app-${BUILD_FLAVOR}-release.apk \
|
|
||||||
"artifacts/${REV_NAME}.apk"
|
|
||||||
cp src/android/app/build/outputs/bundle/${BUILD_FLAVOR}Release/app-${BUILD_FLAVOR}-release.aab \
|
|
||||||
"artifacts/${REV_NAME}.aab"
|
|
||||||
|
|
||||||
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]
|
|
||||||
then
|
|
||||||
echo "Signing apk..."
|
|
||||||
base64 --decode <<< "${ANDROID_KEYSTORE_B64}" > ks.jks
|
|
||||||
|
|
||||||
apksigner sign --ks ks.jks \
|
|
||||||
--ks-key-alias "${ANDROID_KEY_ALIAS}" \
|
|
||||||
--ks-pass env:ANDROID_KEYSTORE_PASS "artifacts/${REV_NAME}.apk"
|
|
||||||
fi
|
|
|
@ -7,7 +7,7 @@ if grep -nrI '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .ci* dis
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Default clang-format points to default 3.5 version one
|
# Default clang-format points to default 3.5 version one
|
||||||
CLANG_FORMAT=clang-format-12
|
CLANG_FORMAT=clang-format-15
|
||||||
$CLANG_FORMAT --version
|
$CLANG_FORMAT --version
|
||||||
|
|
||||||
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
|
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
|
|
@ -1,28 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
# Copy documentation
|
|
||||||
cp license.txt "$REV_NAME"
|
|
||||||
cp README.md "$REV_NAME"
|
|
||||||
|
|
||||||
# Copy cross-platform scripting support
|
|
||||||
cp -r dist/scripting "$REV_NAME"
|
|
||||||
|
|
||||||
tar $COMPRESSION_FLAGS "$ARCHIVE_NAME" "$REV_NAME"
|
|
||||||
|
|
||||||
# Find out what release we are building
|
|
||||||
if [[ "$GITHUB_REF_NAME" =~ ^canary- ]] || [[ "$GITHUB_REF_NAME" =~ ^nightly- ]]; then
|
|
||||||
RELEASE_NAME=$(echo $GITHUB_REF_NAME | cut -d- -f1)
|
|
||||||
if [ "$NAME" = "linux-mingw" ]; then
|
|
||||||
RELEASE_NAME="${RELEASE_NAME}-mingw"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
RELEASE_NAME=head
|
|
||||||
fi
|
|
||||||
|
|
||||||
mv "$REV_NAME" $RELEASE_NAME
|
|
||||||
|
|
||||||
7z a "$REV_NAME.7z" $RELEASE_NAME
|
|
||||||
|
|
||||||
# move the compiled archive into the artifacts directory to be uploaded by travis releases
|
|
||||||
mv "$ARCHIVE_NAME" artifacts/
|
|
||||||
mv "$REV_NAME.7z" artifacts/
|
|
|
@ -1,6 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
|
|
||||||
GITREV="`git show -s --format='%h'`"
|
|
||||||
|
|
||||||
mkdir -p artifacts
|
|
15
.ci/ios.sh
Executable file
15
.ci/ios.sh
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/bash -ex
|
||||||
|
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -GNinja \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_SYSTEM_NAME=iOS \
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=arm64 \
|
||||||
|
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||||
|
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||||
|
-DENABLE_QT_TRANSLATION=ON \
|
||||||
|
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=ON \
|
||||||
|
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON
|
||||||
|
ninja
|
||||||
|
|
||||||
|
ccache -s -v
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
mkdir -p "$HOME/.ccache"
|
|
||||||
docker run -v $(pwd):/citra -v "$HOME/.ccache":/root/.ccache citraemu/build-environments:linux-appimage /bin/bash -ex /citra/.ci/linux/docker.sh
|
|
|
@ -1,21 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
#Building Citra
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_FFMPEG_VIDEO_DUMPER=ON
|
|
||||||
ninja
|
|
||||||
|
|
||||||
ctest -VV -C Release
|
|
||||||
|
|
||||||
#Building AppDir
|
|
||||||
DESTDIR="./AppDir" ninja install
|
|
||||||
mv ./AppDir/usr/local/bin ./AppDir/usr
|
|
||||||
mv ./AppDir/usr/local/share ./AppDir/usr
|
|
||||||
rm -rf ./AppDir/usr/local
|
|
||||||
|
|
||||||
#Circumvent missing LibFuse in Docker, by extracting the AppImage
|
|
||||||
export APPIMAGE_EXTRACT_AND_RUN=1
|
|
||||||
|
|
||||||
#Build AppImage
|
|
||||||
QMAKE=/usr/lib/qt6/bin/qmake DEPLOY_PLATFORM_THEMES=1 /linuxdeploy-x86_64.AppImage --appdir AppDir --plugin qt --output appimage
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
. .ci/common/pre-upload.sh
|
|
||||||
REV_NAME="citra-linux-${GITDATE}-${GITREV}"
|
|
||||||
mv build/Citra*.AppImage "${GITHUB_WORKSPACE}"/artifacts/${REV_NAME}.AppImage
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
mkdir -p "$HOME/.ccache"
|
|
||||||
docker run -v $(pwd):/citra -v "$HOME/.ccache":/root/.ccache citraemu/build-environments:linux-clang-format /bin/bash -ex /citra/.ci/clang-format/docker.sh
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
# Run clang-format
|
|
||||||
./.ci/linux-clang-format/script.sh
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
mkdir -p "$HOME/.ccache"
|
|
||||||
docker run -v $(pwd):/citra -v "$HOME/.ccache":/root/.ccache citraemu/build-environments:linux-fresh /bin/bash -ex /citra/.ci/linux/docker.sh
|
|
|
@ -1,7 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
mkdir build && cd build
|
|
||||||
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_FFMPEG_VIDEO_DUMPER=ON
|
|
||||||
ninja
|
|
||||||
|
|
||||||
ctest -VV -C Release
|
|
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
. .ci/common/pre-upload.sh
|
|
||||||
|
|
||||||
REV_NAME="citra-linux-${GITDATE}-${GITREV}"
|
|
||||||
ARCHIVE_NAME="${REV_NAME}.tar.xz"
|
|
||||||
COMPRESSION_FLAGS="-cJvf"
|
|
||||||
|
|
||||||
mkdir "$REV_NAME"
|
|
||||||
|
|
||||||
cp build/bin/Release/citra "$REV_NAME"
|
|
||||||
cp build/bin/Release/citra-room "$REV_NAME"
|
|
||||||
cp build/bin/Release/citra-qt "$REV_NAME"
|
|
||||||
|
|
||||||
# We need icons on Linux for .desktop entries
|
|
||||||
mkdir "$REV_NAME/dist"
|
|
||||||
cp dist/icon.png "$REV_NAME/dist/citra.png"
|
|
||||||
|
|
||||||
. .ci/common/post-upload.sh
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
mkdir -p "$HOME/.ccache"
|
|
||||||
docker run -v $(pwd):/citra -v "$HOME/.ccache":/root/.ccache citraemu/build-environments:linux-frozen /bin/bash -ex /citra/.ci/linux-frozen/docker.sh
|
|
|
@ -1,15 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
mkdir -p ~/bin/gold
|
|
||||||
echo '#!/bin/bash' > ~/bin/gold/ld
|
|
||||||
echo 'gold "$@"' >> ~/bin/gold/ld
|
|
||||||
chmod a+x ~/bin/gold/ld
|
|
||||||
export CFLAGS="-B$HOME/bin/gold $CFLAGS"
|
|
||||||
export CXXFLAGS="-B$HOME/bin/gold $CXXFLAGS"
|
|
||||||
|
|
||||||
|
|
||||||
mkdir build && cd build
|
|
||||||
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++
|
|
||||||
ninja
|
|
||||||
|
|
||||||
ctest -VV -C Release
|
|
|
@ -1,52 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
import subprocess
|
|
||||||
from launchpadlib.launchpad import Launchpad
|
|
||||||
|
|
||||||
if sys.version_info[0] > 2:
|
|
||||||
xrange = range
|
|
||||||
|
|
||||||
cachedir = '/.launchpadlib/cache/'
|
|
||||||
launchpad = Launchpad.login_anonymously(
|
|
||||||
'grab build info', 'production', cachedir, version='devel')
|
|
||||||
|
|
||||||
processed_packages = []
|
|
||||||
deb_file_list = []
|
|
||||||
|
|
||||||
|
|
||||||
def get_url(pkg, distro):
|
|
||||||
build_ref = launchpad.archives.getByReference(reference='ubuntu').getPublishedBinaries(
|
|
||||||
binary_name=pkg[0], distro_arch_series='https://api.launchpad.net/devel/ubuntu/' + distro + '/amd64', version=pkg[1], exact_match=True, order_by_date=True).entries[0]
|
|
||||||
build_link = build_ref['build_link']
|
|
||||||
deb_name = '{}_{}_{}.deb'.format(pkg[0], pkg[1], 'amd64' if build_ref['architecture_specific'] else 'all')
|
|
||||||
deb_link = build_link + '/+files/' + deb_name
|
|
||||||
return [deb_link, deb_name]
|
|
||||||
|
|
||||||
|
|
||||||
def list_dependencies(deb_file):
|
|
||||||
t = subprocess.check_output(
|
|
||||||
['bash', '-c', '(dpkg -I {} | grep -oP "^ Depends\: \K.*$") || true'.format(deb_file)])
|
|
||||||
deps = [i.strip() for i in t.split(',')]
|
|
||||||
equals_re = re.compile(r'^(.*) \(= (.*)\)$')
|
|
||||||
return [equals_re.sub(r'\1=\2', i).split('=') for i in filter(equals_re.match, deps)]
|
|
||||||
|
|
||||||
|
|
||||||
def get_package(pkg, distro):
|
|
||||||
if pkg in processed_packages:
|
|
||||||
return
|
|
||||||
print('Getting {}...'.format(pkg[0]))
|
|
||||||
url = get_url(pkg, distro)
|
|
||||||
subprocess.check_call(['wget', '--quiet', url[0], '-O', url[1]])
|
|
||||||
for dep in list_dependencies(url[1]):
|
|
||||||
get_package(dep, distro)
|
|
||||||
processed_packages.append(pkg)
|
|
||||||
deb_file_list.append('./' + url[1])
|
|
||||||
|
|
||||||
|
|
||||||
for i in xrange(1, len(sys.argv), 3):
|
|
||||||
get_package([sys.argv[i], sys.argv[i + 1]], sys.argv[i + 2])
|
|
||||||
|
|
||||||
subprocess.check_call(
|
|
||||||
['apt-get', 'install', '-y', '--force-yes'] + deb_file_list)
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
mkdir "$HOME/.ccache" || true
|
|
||||||
docker run -v $(pwd):/citra -v "$HOME/.ccache":/root/.ccache citraemu/build-environments:linux-mingw /bin/bash -ex /citra/.ci/linux-mingw/docker.sh
|
|
|
@ -1,30 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
# override CI ccache size
|
|
||||||
mkdir -p "$HOME/.ccache/"
|
|
||||||
echo 'max_size = 3.0G' > "$HOME/.ccache/ccache.conf"
|
|
||||||
|
|
||||||
mkdir build && cd build
|
|
||||||
cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MinGWCross.cmake" -DCITRA_USE_CCACHE=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_MF=ON -DENABLE_FFMPEG_VIDEO_DUMPER=ON -DCMAKE_NO_SYSTEM_FROM_IMPORTED=TRUE -DCOMPILE_WITH_DWARF=OFF
|
|
||||||
ninja
|
|
||||||
|
|
||||||
echo "Tests skipped"
|
|
||||||
#ctest -VV -C Release
|
|
||||||
|
|
||||||
ccache -s
|
|
||||||
|
|
||||||
echo 'Prepare binaries...'
|
|
||||||
cd ..
|
|
||||||
mkdir package
|
|
||||||
|
|
||||||
QT_PLATFORM_DLL_PATH='/usr/x86_64-w64-mingw32/lib/qt6/plugins/platforms/'
|
|
||||||
find build/ -name "citra*.exe" -exec cp {} 'package' \;
|
|
||||||
|
|
||||||
# copy Qt plugins
|
|
||||||
mkdir package/platforms
|
|
||||||
cp "${QT_PLATFORM_DLL_PATH}/qwindows.dll" package/platforms/
|
|
||||||
cp -rv "${QT_PLATFORM_DLL_PATH}/../multimedia/" package/
|
|
||||||
cp -rv "${QT_PLATFORM_DLL_PATH}/../imageformats/" package/
|
|
||||||
cp -rv "${QT_PLATFORM_DLL_PATH}/../styles/" package/
|
|
||||||
|
|
||||||
python3 .ci/linux-mingw/scan_dll.py package/*.exe package/imageformats/*.dll "package/"
|
|
|
@ -1,122 +0,0 @@
|
||||||
try:
|
|
||||||
import lief
|
|
||||||
except ImportError:
|
|
||||||
import pefile
|
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
import os
|
|
||||||
import queue
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
# constant definitions
|
|
||||||
KNOWN_SYS_DLLS = ['WINMM.DLL', 'MSVCRT.DLL', 'VERSION.DLL', 'MPR.DLL',
|
|
||||||
'DWMAPI.DLL', 'UXTHEME.DLL', 'DNSAPI.DLL', 'IPHLPAPI.DLL']
|
|
||||||
# below is for Ubuntu 18.04 with specified PPA enabled, if you are using
|
|
||||||
# other distro or different repositories, change the following accordingly
|
|
||||||
DLL_PATH = [
|
|
||||||
'/usr/x86_64-w64-mingw32/bin/',
|
|
||||||
'/usr/x86_64-w64-mingw32/lib/',
|
|
||||||
'/usr/lib/gcc/x86_64-w64-mingw32/9.3-posix/'
|
|
||||||
]
|
|
||||||
|
|
||||||
missing = []
|
|
||||||
|
|
||||||
|
|
||||||
def parse_imports_lief(filename):
|
|
||||||
results = []
|
|
||||||
pe = lief.parse(filename)
|
|
||||||
for entry in pe.imports:
|
|
||||||
name = entry.name
|
|
||||||
if name.upper() not in KNOWN_SYS_DLLS and not re.match(string=name, pattern=r'.*32\.DLL'):
|
|
||||||
results.append(name)
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
def parse_imports(file_name):
|
|
||||||
if globals().get('lief'):
|
|
||||||
return parse_imports_lief(file_name)
|
|
||||||
|
|
||||||
results = []
|
|
||||||
pe = pefile.PE(file_name, fast_load=True)
|
|
||||||
pe.parse_data_directories()
|
|
||||||
|
|
||||||
for entry in pe.DIRECTORY_ENTRY_IMPORT:
|
|
||||||
current = entry.dll.decode()
|
|
||||||
current_u = current.upper() # b/c Windows is often case insensitive
|
|
||||||
# here we filter out system dlls
|
|
||||||
# dll w/ names like *32.dll are likely to be system dlls
|
|
||||||
if current_u.upper() not in KNOWN_SYS_DLLS and not re.match(string=current_u, pattern=r'.*32\.DLL'):
|
|
||||||
results.append(current)
|
|
||||||
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
def parse_imports_recursive(file_name, path_list=[]):
|
|
||||||
q = queue.Queue() # create a FIFO queue
|
|
||||||
# file_name can be a string or a list for the convience
|
|
||||||
if isinstance(file_name, str):
|
|
||||||
q.put(file_name)
|
|
||||||
elif isinstance(file_name, list):
|
|
||||||
for i in file_name:
|
|
||||||
q.put(i)
|
|
||||||
full_list = []
|
|
||||||
while q.qsize():
|
|
||||||
current = q.get_nowait()
|
|
||||||
print('> %s' % current)
|
|
||||||
deps = parse_imports(current)
|
|
||||||
# if this dll does not have any import, ignore it
|
|
||||||
if not deps:
|
|
||||||
continue
|
|
||||||
for dep in deps:
|
|
||||||
# the dependency already included in the list, skip
|
|
||||||
if dep in full_list:
|
|
||||||
continue
|
|
||||||
# find the requested dll in the provided paths
|
|
||||||
full_path = find_dll(dep)
|
|
||||||
if not full_path:
|
|
||||||
missing.append(dep)
|
|
||||||
continue
|
|
||||||
full_list.append(dep)
|
|
||||||
q.put(full_path)
|
|
||||||
path_list.append(full_path)
|
|
||||||
return full_list
|
|
||||||
|
|
||||||
|
|
||||||
def find_dll(name):
|
|
||||||
for path in DLL_PATH:
|
|
||||||
for root, _, files in os.walk(path):
|
|
||||||
for f in files:
|
|
||||||
if name.lower() == f.lower():
|
|
||||||
return os.path.join(root, f)
|
|
||||||
|
|
||||||
|
|
||||||
def deploy(name, dst, dry_run=False):
|
|
||||||
dlls_path = []
|
|
||||||
parse_imports_recursive(name, dlls_path)
|
|
||||||
for dll_entry in dlls_path:
|
|
||||||
if not dry_run:
|
|
||||||
shutil.copy(dll_entry, dst)
|
|
||||||
else:
|
|
||||||
print('[Dry-Run] Copy %s to %s' % (dll_entry, dst))
|
|
||||||
print('Deploy completed.')
|
|
||||||
return dlls_path
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
if len(sys.argv) < 3:
|
|
||||||
print('Usage: %s [files to examine ...] [target deploy directory]')
|
|
||||||
return 1
|
|
||||||
to_deploy = sys.argv[1:-1]
|
|
||||||
tgt_dir = sys.argv[-1]
|
|
||||||
if not os.path.isdir(tgt_dir):
|
|
||||||
print('%s is not a directory.' % tgt_dir)
|
|
||||||
return 1
|
|
||||||
print('Scanning dependencies...')
|
|
||||||
deploy(to_deploy, tgt_dir)
|
|
||||||
if missing:
|
|
||||||
print('Following DLLs are not found: %s' % ('\n'.join(missing)))
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
. .ci/common/pre-upload.sh
|
|
||||||
|
|
||||||
REV_NAME="citra-windows-mingw-${GITDATE}-${GITREV}"
|
|
||||||
ARCHIVE_NAME="${REV_NAME}.tar.gz"
|
|
||||||
COMPRESSION_FLAGS="-czvf"
|
|
||||||
|
|
||||||
mkdir "$REV_NAME"
|
|
||||||
# get around the permission issues
|
|
||||||
cp -r package/* "$REV_NAME"
|
|
||||||
|
|
||||||
. .ci/common/post-upload.sh
|
|
31
.ci/linux.sh
Executable file
31
.ci/linux.sh
Executable file
|
@ -0,0 +1,31 @@
|
||||||
|
#!/bin/bash -ex
|
||||||
|
|
||||||
|
if [ "$TARGET" = "appimage" ]; then
|
||||||
|
# Compile the AppImage we distribute with Clang.
|
||||||
|
export EXTRA_CMAKE_FLAGS=(-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_LINKER=/etc/bin/ld.lld)
|
||||||
|
else
|
||||||
|
# For the linux-fresh verification target, verify compilation without PCH as well.
|
||||||
|
export EXTRA_CMAKE_FLAGS=(-DCITRA_USE_PRECOMPILED_HEADERS=OFF)
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -G Ninja \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||||
|
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||||
|
"${EXTRA_CMAKE_FLAGS[@]}" \
|
||||||
|
-DENABLE_QT_TRANSLATION=ON \
|
||||||
|
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=ON \
|
||||||
|
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
||||||
|
-DUSE_DISCORD_PRESENCE=ON
|
||||||
|
ninja
|
||||||
|
|
||||||
|
if [ "$TARGET" = "appimage" ]; then
|
||||||
|
ninja bundle
|
||||||
|
# TODO: Our AppImage environment currently uses an older ccache version without the verbose flag.
|
||||||
|
ccache -s
|
||||||
|
else
|
||||||
|
ccache -s -v
|
||||||
|
fi
|
||||||
|
|
||||||
|
ctest -VV -C Release
|
|
@ -1,45 +1,43 @@
|
||||||
#!/bin/bash -ex
|
#!/bin/bash -ex
|
||||||
|
|
||||||
. .ci/common/pre-upload.sh
|
|
||||||
|
|
||||||
REV_NAME="citra-osx-${GITDATE}-${GITREV}"
|
|
||||||
ARCHIVE_NAME="${REV_NAME}.tar.gz"
|
|
||||||
COMPRESSION_FLAGS="-czvf"
|
|
||||||
|
|
||||||
ARTIFACTS_LIST=($ARTIFACTS)
|
ARTIFACTS_LIST=($ARTIFACTS)
|
||||||
|
|
||||||
|
BUNDLE_DIR=build/bundle
|
||||||
|
mkdir build
|
||||||
|
|
||||||
# Set up the base artifact to combine into.
|
# Set up the base artifact to combine into.
|
||||||
BASE_ARTIFACT=${ARTIFACTS_LIST[0]}
|
BASE_ARTIFACT=${ARTIFACTS_LIST[0]}
|
||||||
BASE_ARTIFACT_ARCH="${BASE_ARTIFACT##*-}"
|
BASE_ARTIFACT_ARCH="${BASE_ARTIFACT##*-}"
|
||||||
tar xf $BASE_ARTIFACT/$REV_NAME.tar.gz -C $BASE_ARTIFACT
|
mv $BASE_ARTIFACT $BUNDLE_DIR
|
||||||
mv $BASE_ARTIFACT/$REV_NAME $REV_NAME
|
|
||||||
|
|
||||||
# Executable binary paths that need to be combined.
|
# Executable binary paths that need to be combined.
|
||||||
BIN_PATHS=(citra citra-room citra-qt.app/Contents/MacOS/citra-qt)
|
BIN_PATHS=(citra citra-room citra-qt.app/Contents/MacOS/citra-qt)
|
||||||
|
|
||||||
# Dylib paths that need to be combined.
|
# Dylib paths that need to be combined.
|
||||||
IFS=$'\n'
|
IFS=$'\n'
|
||||||
DYLIB_PATHS=($(cd $REV_NAME && find . -name '*.dylib'))
|
DYLIB_PATHS=($(cd $BUNDLE_DIR && find . -name '*.dylib'))
|
||||||
unset IFS
|
unset IFS
|
||||||
|
|
||||||
# Combine all of the executable binaries and dylibs.
|
# Combine all of the executable binaries and dylibs.
|
||||||
for OTHER_ARTIFACT in "${ARTIFACTS_LIST[@]:1}"; do
|
for OTHER_ARTIFACT in "${ARTIFACTS_LIST[@]:1}"; do
|
||||||
OTHER_ARTIFACT_ARCH="${OTHER_ARTIFACT##*-}"
|
OTHER_ARTIFACT_ARCH="${OTHER_ARTIFACT##*-}"
|
||||||
|
|
||||||
tar xf $OTHER_ARTIFACT/$REV_NAME.tar.gz -C $OTHER_ARTIFACT
|
|
||||||
|
|
||||||
for BIN_PATH in "${BIN_PATHS[@]}"; do
|
for BIN_PATH in "${BIN_PATHS[@]}"; do
|
||||||
lipo -create -output $REV_NAME/$BIN_PATH $REV_NAME/$BIN_PATH $OTHER_ARTIFACT/$REV_NAME/$BIN_PATH
|
lipo -create -output $BUNDLE_DIR/$BIN_PATH $BUNDLE_DIR/$BIN_PATH $OTHER_ARTIFACT/$BIN_PATH
|
||||||
done
|
done
|
||||||
|
|
||||||
for DYLIB_PATH in "${DYLIB_PATHS[@]}"; do
|
for DYLIB_PATH in "${DYLIB_PATHS[@]}"; do
|
||||||
# Only merge if the libraries do not have conflicting arches, otherwise it will fail.
|
# Only merge if the libraries do not have conflicting arches, otherwise it will fail.
|
||||||
DYLIB_INFO=`file $REV_NAME/$DYLIB_PATH`
|
DYLIB_INFO=`file $BUNDLE_DIR/$DYLIB_PATH`
|
||||||
OTHER_DYLIB_INFO=`file $OTHER_ARTIFACT/$REV_NAME/$DYLIB_PATH`
|
OTHER_DYLIB_INFO=`file $OTHER_ARTIFACT/$DYLIB_PATH`
|
||||||
if ! [[ "$DYLIB_INFO" =~ "$OTHER_ARTIFACT_ARCH" ]] && ! [[ "$OTHER_DYLIB_INFO" =~ "$BASE_ARTIFACT_ARCH" ]]; then
|
if ! [[ "$DYLIB_INFO" =~ "$OTHER_ARTIFACT_ARCH" ]] && ! [[ "$OTHER_DYLIB_INFO" =~ "$BASE_ARTIFACT_ARCH" ]]; then
|
||||||
lipo -create -output $REV_NAME/$DYLIB_PATH $REV_NAME/$DYLIB_PATH $OTHER_ARTIFACT/$REV_NAME/$DYLIB_PATH
|
lipo -create -output $BUNDLE_DIR/$DYLIB_PATH $BUNDLE_DIR/$DYLIB_PATH $OTHER_ARTIFACT/$DYLIB_PATH
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
. .ci/common/post-upload.sh
|
# Re-sign executables and bundles after combining.
|
||||||
|
APP_PATHS=(citra citra-room citra-qt.app)
|
||||||
|
for APP_PATH in "${APP_PATHS[@]}"; do
|
||||||
|
codesign --deep -fs - $BUNDLE_DIR/$APP_PATH
|
||||||
|
done
|
21
.ci/macos.sh
Executable file
21
.ci/macos.sh
Executable file
|
@ -0,0 +1,21 @@
|
||||||
|
#!/bin/bash -ex
|
||||||
|
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -GNinja \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES="$TARGET" \
|
||||||
|
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||||
|
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||||
|
-DENABLE_QT_TRANSLATION=ON \
|
||||||
|
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=ON \
|
||||||
|
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
||||||
|
-DUSE_DISCORD_PRESENCE=ON
|
||||||
|
ninja
|
||||||
|
ninja bundle
|
||||||
|
|
||||||
|
ccache -s -v
|
||||||
|
|
||||||
|
CURRENT_ARCH=`arch`
|
||||||
|
if [ "$TARGET" = "$CURRENT_ARCH" ]; then
|
||||||
|
ctest -VV -C Release
|
||||||
|
fi
|
|
@ -1,35 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
export PATH="/usr/local/opt/ccache/libexec:$PATH"
|
|
||||||
# ccache configurations
|
|
||||||
export CCACHE_CPP2=yes
|
|
||||||
export CCACHE_SLOPPINESS=time_macros
|
|
||||||
|
|
||||||
export CC="ccache clang"
|
|
||||||
export CXX="ccache clang++"
|
|
||||||
export OBJC="clang"
|
|
||||||
export ASM="clang"
|
|
||||||
|
|
||||||
ccache -s
|
|
||||||
|
|
||||||
mkdir build && cd build
|
|
||||||
# TODO: LibreSSL ASM disabled due to platform detection issues in build.
|
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release \
|
|
||||||
-DCMAKE_OSX_ARCHITECTURES="$TARGET_ARCH" \
|
|
||||||
-DENABLE_QT_TRANSLATION=ON \
|
|
||||||
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} \
|
|
||||||
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
|
||||||
-DUSE_DISCORD_PRESENCE=ON \
|
|
||||||
-DENABLE_FFMPEG_VIDEO_DUMPER=ON \
|
|
||||||
-DENABLE_ASM=OFF \
|
|
||||||
-GNinja
|
|
||||||
ninja
|
|
||||||
|
|
||||||
ccache -s
|
|
||||||
|
|
||||||
CURRENT_ARCH=`arch`
|
|
||||||
if [ "$TARGET_ARCH" = "$CURRENT_ARCH" ]; then
|
|
||||||
ctest -VV -C Release
|
|
||||||
fi
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/sh -ex
|
|
||||||
|
|
||||||
brew install ccache ninja || true
|
|
|
@ -1,16 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
. .ci/common/pre-upload.sh
|
|
||||||
|
|
||||||
REV_NAME="citra-osx-${GITDATE}-${GITREV}"
|
|
||||||
ARCHIVE_NAME="${REV_NAME}.tar.gz"
|
|
||||||
COMPRESSION_FLAGS="-czvf"
|
|
||||||
|
|
||||||
mkdir "$REV_NAME"
|
|
||||||
|
|
||||||
cp build/bin/Release/citra "$REV_NAME"
|
|
||||||
cp -r build/bin/Release/libs "$REV_NAME"
|
|
||||||
cp -r build/bin/Release/citra-qt.app "$REV_NAME"
|
|
||||||
cp build/bin/Release/citra-room "$REV_NAME"
|
|
||||||
|
|
||||||
. .ci/common/post-upload.sh
|
|
80
.ci/pack.sh
Executable file
80
.ci/pack.sh
Executable file
|
@ -0,0 +1,80 @@
|
||||||
|
#!/bin/bash -ex
|
||||||
|
|
||||||
|
# Determine the full revision name.
|
||||||
|
GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
|
||||||
|
GITREV="`git show -s --format='%h'`"
|
||||||
|
REV_NAME="citra-$OS-$TARGET-$GITDATE-$GITREV"
|
||||||
|
|
||||||
|
# Determine the name of the release being built.
|
||||||
|
if [[ "$GITHUB_REF_NAME" =~ ^canary- ]] || [[ "$GITHUB_REF_NAME" =~ ^nightly- ]]; then
|
||||||
|
RELEASE_NAME=$(echo $GITHUB_REF_NAME | cut -d- -f1)
|
||||||
|
else
|
||||||
|
RELEASE_NAME=head
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Archive and upload the artifacts.
|
||||||
|
mkdir artifacts
|
||||||
|
|
||||||
|
function pack_artifacts() {
|
||||||
|
ARTIFACTS_PATH="$1"
|
||||||
|
|
||||||
|
# Set up root directory for archive.
|
||||||
|
mkdir "$REV_NAME"
|
||||||
|
if [ -f "$ARTIFACTS_PATH" ]; then
|
||||||
|
mv "$ARTIFACTS_PATH" "$REV_NAME"
|
||||||
|
|
||||||
|
# Use file extension to differentiate archives.
|
||||||
|
FILENAME=$(basename "$ARTIFACT")
|
||||||
|
EXTENSION="${FILENAME##*.}"
|
||||||
|
ARCHIVE_NAME="$REV_NAME.$EXTENSION"
|
||||||
|
else
|
||||||
|
mv "$ARTIFACTS_PATH"/* "$REV_NAME"
|
||||||
|
|
||||||
|
ARCHIVE_NAME="$REV_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create .zip/.tar.gz
|
||||||
|
if [ "$OS" = "windows" ]; then
|
||||||
|
ARCHIVE_FULL_NAME="$ARCHIVE_NAME.zip"
|
||||||
|
powershell Compress-Archive "$REV_NAME" "$ARCHIVE_FULL_NAME"
|
||||||
|
elif [ "$OS" = "android" ]; then
|
||||||
|
ARCHIVE_FULL_NAME="$ARCHIVE_NAME.zip"
|
||||||
|
zip -r "$ARCHIVE_FULL_NAME" "$REV_NAME"
|
||||||
|
else
|
||||||
|
ARCHIVE_FULL_NAME="$ARCHIVE_NAME.tar.gz"
|
||||||
|
tar czvf "$ARCHIVE_FULL_NAME" "$REV_NAME"
|
||||||
|
fi
|
||||||
|
mv "$ARCHIVE_FULL_NAME" artifacts/
|
||||||
|
|
||||||
|
if [ -z "$SKIP_7Z" ]; then
|
||||||
|
# Create .7z
|
||||||
|
ARCHIVE_FULL_NAME="$ARCHIVE_NAME.7z"
|
||||||
|
mv "$REV_NAME" "$RELEASE_NAME"
|
||||||
|
7z a "$ARCHIVE_FULL_NAME" "$RELEASE_NAME"
|
||||||
|
mv "$ARCHIVE_FULL_NAME" artifacts/
|
||||||
|
|
||||||
|
# Clean up created release artifacts directory.
|
||||||
|
rm -rf "$RELEASE_NAME"
|
||||||
|
else
|
||||||
|
# Clean up created rev artifacts directory.
|
||||||
|
rm -rf "$REV_NAME"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -n "$UNPACKED" ]; then
|
||||||
|
# Copy the artifacts to be uploaded unpacked.
|
||||||
|
for ARTIFACT in build/bundle/*; do
|
||||||
|
FILENAME=$(basename "$ARTIFACT")
|
||||||
|
EXTENSION="${FILENAME##*.}"
|
||||||
|
|
||||||
|
mv "$ARTIFACT" "artifacts/$REV_NAME.$EXTENSION"
|
||||||
|
done
|
||||||
|
elif [ -n "$PACK_INDIVIDUALLY" ]; then
|
||||||
|
# Pack and upload the artifacts one-by-one.
|
||||||
|
for ARTIFACT in build/bundle/*; do
|
||||||
|
pack_artifacts "$ARTIFACT"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
# Pack all of the artifacts into a single archive.
|
||||||
|
pack_artifacts build/bundle
|
||||||
|
fi
|
|
@ -1,9 +1,13 @@
|
||||||
#!/bin/bash -ex
|
#!/bin/bash -ex
|
||||||
|
|
||||||
. .ci/common/pre-upload.sh
|
GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
|
||||||
|
GITREV="`git show -s --format='%h'`"
|
||||||
REV_NAME="citra-unified-source-${GITDATE}-${GITREV}"
|
REV_NAME="citra-unified-source-${GITDATE}-${GITREV}"
|
||||||
|
|
||||||
COMPAT_LIST='dist/compatibility_list/compatibility_list.json'
|
COMPAT_LIST='dist/compatibility_list/compatibility_list.json'
|
||||||
|
|
||||||
|
mkdir artifacts
|
||||||
|
|
||||||
pip3 install git-archive-all
|
pip3 install git-archive-all
|
||||||
wget -q https://api.citra-emu.org/gamedb -O "${COMPAT_LIST}"
|
wget -q https://api.citra-emu.org/gamedb -O "${COMPAT_LIST}"
|
||||||
git describe --abbrev=0 --always HEAD > GIT-COMMIT
|
git describe --abbrev=0 --always HEAD > GIT-COMMIT
|
|
@ -1,6 +1,4 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -ex
|
||||||
|
|
||||||
set -x
|
|
||||||
|
|
||||||
echo -e "\e[1m\e[33mBuild tools information:\e[0m"
|
echo -e "\e[1m\e[33mBuild tools information:\e[0m"
|
||||||
cmake --version
|
cmake --version
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash -e
|
|
||||||
|
|
||||||
docker run -e TRANSIFEX_API_TOKEN="${TRANSIFEX_API_TOKEN}" -v "$(pwd)":/citra citraemu/build-environments:linux-transifex /bin/sh -e /citra/.travis/transifex/docker.sh
|
|
|
@ -1,21 +0,0 @@
|
||||||
#!/bin/sh -ex
|
|
||||||
|
|
||||||
mkdir build && cd build
|
|
||||||
cmake .. \
|
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
|
||||||
-G Ninja \
|
|
||||||
-DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MSVCCache.cmake" \
|
|
||||||
-DCITRA_USE_CCACHE=ON \
|
|
||||||
-DENABLE_QT_TRANSLATION=ON \
|
|
||||||
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} \
|
|
||||||
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
|
||||||
-DUSE_DISCORD_PRESENCE=ON \
|
|
||||||
-DENABLE_MF=ON \
|
|
||||||
-DENABLE_FFMPEG_VIDEO_DUMPER=ON \
|
|
||||||
-DOPENSSL_DLL_DIR="C:\Program Files\OpenSSL\bin"
|
|
||||||
|
|
||||||
ninja
|
|
||||||
# show the caching efficiency
|
|
||||||
buildcache -s
|
|
||||||
|
|
||||||
ctest -VV -C Release || echo "::error ::Test error occurred on Windows MSVC build"
|
|
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/sh -ex
|
|
||||||
|
|
||||||
BUILDCACHE_VERSION="0.22.3"
|
|
||||||
|
|
||||||
choco install wget ninja
|
|
||||||
# Install buildcache
|
|
||||||
wget "https://github.com/mbitsnbites/buildcache/releases/download/v${BUILDCACHE_VERSION}/buildcache-win-mingw.zip"
|
|
||||||
7z x 'buildcache-win-mingw.zip'
|
|
||||||
mv ./buildcache/bin/buildcache.exe "/c/ProgramData/chocolatey/bin"
|
|
||||||
rm -rf ./buildcache/
|
|
|
@ -1,41 +0,0 @@
|
||||||
|
|
||||||
$GITDATE = $(git show -s --date=short --format='%ad') -replace "-", ""
|
|
||||||
$GITREV = $(git show -s --format='%h')
|
|
||||||
|
|
||||||
# Find out what release we are building
|
|
||||||
if ( $env:GITHUB_REF_NAME -like "*canary-*" -or $env:GITHUB_REF_NAME -like "*nightly-*" ) {
|
|
||||||
$RELEASE_NAME = ${env:GITHUB_REF_NAME}.split("-")[0]
|
|
||||||
$RELEASE_NAME = "${RELEASE_NAME}-msvc"
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$RELEASE_NAME = "head"
|
|
||||||
}
|
|
||||||
|
|
||||||
$MSVC_BUILD_ZIP = "citra-windows-msvc-$GITDATE-$GITREV.zip" -replace " ", ""
|
|
||||||
$MSVC_SEVENZIP = "citra-windows-msvc-$GITDATE-$GITREV.7z" -replace " ", ""
|
|
||||||
|
|
||||||
$BUILD_DIR = ".\build\bin\Release"
|
|
||||||
|
|
||||||
# Create artifact directories
|
|
||||||
mkdir $RELEASE_NAME
|
|
||||||
mkdir "artifacts"
|
|
||||||
|
|
||||||
echo "Starting to pack ${RELEASE_NAME}"
|
|
||||||
|
|
||||||
Copy-Item $BUILD_DIR\* -Destination $RELEASE_NAME -Recurse
|
|
||||||
Remove-Item $RELEASE_NAME\tests.* -ErrorAction ignore
|
|
||||||
Remove-Item $RELEASE_NAME\*.pdb -ErrorAction ignore
|
|
||||||
|
|
||||||
# Copy documentation
|
|
||||||
Copy-Item license.txt -Destination $RELEASE_NAME
|
|
||||||
Copy-Item README.md -Destination $RELEASE_NAME
|
|
||||||
|
|
||||||
# Copy cross-platform scripting support
|
|
||||||
Copy-Item dist\scripting -Destination $RELEASE_NAME -Recurse
|
|
||||||
|
|
||||||
# Build the final release artifacts
|
|
||||||
7z a -tzip $MSVC_BUILD_ZIP $RELEASE_NAME\*
|
|
||||||
7z a $MSVC_SEVENZIP $RELEASE_NAME
|
|
||||||
|
|
||||||
Copy-Item $MSVC_BUILD_ZIP -Destination "artifacts"
|
|
||||||
Copy-Item $MSVC_SEVENZIP -Destination "artifacts"
|
|
17
.ci/windows.sh
Normal file
17
.ci/windows.sh
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/sh -ex
|
||||||
|
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -G Ninja \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||||
|
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||||
|
-DENABLE_QT_TRANSLATION=ON \
|
||||||
|
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=ON \
|
||||||
|
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
||||||
|
-DUSE_DISCORD_PRESENCE=ON
|
||||||
|
ninja
|
||||||
|
ninja bundle
|
||||||
|
|
||||||
|
ccache -s -v
|
||||||
|
|
||||||
|
ctest -VV -C Release || echo "::error ::Test error occurred on Windows build"
|
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
@ -43,7 +43,7 @@ body:
|
||||||
id: log
|
id: log
|
||||||
attributes:
|
attributes:
|
||||||
label: Log File
|
label: Log File
|
||||||
description: A log file will help our developers to better diagnose and fix the issue.
|
description: A log file will help our developers to better diagnose and fix the issue. Instructions can be found [here](https://community.citra-emu.org/t/how-to-upload-the-log-file/296).
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
|
270
.github/workflows/build.yml
vendored
Normal file
270
.github/workflows/build.yml
vendored
Normal file
|
@ -0,0 +1,270 @@
|
||||||
|
name: citra-build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "*" ]
|
||||||
|
tags: [ "*" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
source:
|
||||||
|
if: ${{ !github.head_ref }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Pack
|
||||||
|
run: ./.ci/source.sh
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: source
|
||||||
|
path: artifacts/
|
||||||
|
linux:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
target: ["appimage", "fresh"]
|
||||||
|
container:
|
||||||
|
image: citraemu/build-environments:linux-${{ matrix.target }}
|
||||||
|
options: -u 1001
|
||||||
|
env:
|
||||||
|
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||||
|
CCACHE_COMPILERCHECK: content
|
||||||
|
CCACHE_SLOPPINESS: time_macros
|
||||||
|
OS: linux
|
||||||
|
TARGET: ${{ matrix.target }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Set up cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{ env.CCACHE_DIR }}
|
||||||
|
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-${{ matrix.target }}-
|
||||||
|
- name: Build
|
||||||
|
run: ./.ci/linux.sh
|
||||||
|
- name: Pack
|
||||||
|
run: ./.ci/pack.sh
|
||||||
|
if: ${{ matrix.target == 'appimage' }}
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
if: ${{ matrix.target == 'appimage' }}
|
||||||
|
with:
|
||||||
|
name: ${{ env.OS }}-${{ env.TARGET }}
|
||||||
|
path: artifacts/
|
||||||
|
macos:
|
||||||
|
runs-on: ${{ (matrix.target == 'x86_64' && 'macos-13') || 'macos-14' }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
target: ["x86_64", "arm64"]
|
||||||
|
env:
|
||||||
|
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||||
|
CCACHE_COMPILERCHECK: content
|
||||||
|
CCACHE_SLOPPINESS: time_macros
|
||||||
|
OS: macos
|
||||||
|
TARGET: ${{ matrix.target }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Set up cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{ env.CCACHE_DIR }}
|
||||||
|
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-${{ matrix.target }}-
|
||||||
|
- name: Install tools
|
||||||
|
run: brew install ccache ninja
|
||||||
|
- name: Build
|
||||||
|
run: ./.ci/macos.sh
|
||||||
|
- name: Prepare outputs for caching
|
||||||
|
run: mv build/bundle $OS-$TARGET
|
||||||
|
- name: Cache outputs for universal build
|
||||||
|
uses: actions/cache/save@v4
|
||||||
|
with:
|
||||||
|
path: ${{ env.OS }}-${{ env.TARGET }}
|
||||||
|
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||||
|
macos-universal:
|
||||||
|
runs-on: macos-14
|
||||||
|
needs: macos
|
||||||
|
env:
|
||||||
|
OS: macos
|
||||||
|
TARGET: universal
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Download x86_64 build from cache
|
||||||
|
uses: actions/cache/restore@v4
|
||||||
|
with:
|
||||||
|
path: ${{ env.OS }}-x86_64
|
||||||
|
key: ${{ runner.os }}-x86_64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||||
|
fail-on-cache-miss: true
|
||||||
|
- name: Download ARM64 build from cache
|
||||||
|
uses: actions/cache/restore@v4
|
||||||
|
with:
|
||||||
|
path: ${{ env.OS }}-arm64
|
||||||
|
key: ${{ runner.os }}-arm64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||||
|
fail-on-cache-miss: true
|
||||||
|
- name: Create universal app
|
||||||
|
run: ./.ci/macos-universal.sh
|
||||||
|
env:
|
||||||
|
ARTIFACTS: ${{ env.OS }}-x86_64 ${{ env.OS }}-arm64
|
||||||
|
- name: Pack
|
||||||
|
run: ./.ci/pack.sh
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ env.OS }}-${{ env.TARGET }}
|
||||||
|
path: artifacts/
|
||||||
|
windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
target: ["msvc", "msys2"]
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: ${{ (matrix.target == 'msys2' && 'msys2') || 'bash' }} {0}
|
||||||
|
env:
|
||||||
|
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||||
|
CCACHE_COMPILERCHECK: content
|
||||||
|
CCACHE_SLOPPINESS: time_macros
|
||||||
|
OS: windows
|
||||||
|
TARGET: ${{ matrix.target }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Set up cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{ env.CCACHE_DIR }}
|
||||||
|
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-${{ matrix.target }}-
|
||||||
|
- name: Set up MSVC
|
||||||
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
if: ${{ matrix.target == 'msvc' }}
|
||||||
|
- name: Install extra tools (MSVC)
|
||||||
|
run: choco install ccache ninja wget
|
||||||
|
if: ${{ matrix.target == 'msvc' }}
|
||||||
|
- name: Set up MSYS2
|
||||||
|
uses: msys2/setup-msys2@v2
|
||||||
|
if: ${{ matrix.target == 'msys2' }}
|
||||||
|
with:
|
||||||
|
msystem: clang64
|
||||||
|
update: true
|
||||||
|
install: git make p7zip
|
||||||
|
pacboy: >-
|
||||||
|
toolchain:p ccache:p cmake:p ninja:p
|
||||||
|
qt6-base:p qt6-multimedia:p qt6-multimedia-wmf:p qt6-tools:p qt6-translations:p
|
||||||
|
- name: Disable line ending translation
|
||||||
|
run: git config --global core.autocrlf input
|
||||||
|
- name: Build
|
||||||
|
run: ./.ci/windows.sh
|
||||||
|
- name: Pack
|
||||||
|
run: ./.ci/pack.sh
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ env.OS }}-${{ env.TARGET }}
|
||||||
|
path: artifacts/
|
||||||
|
android:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||||
|
CCACHE_COMPILERCHECK: content
|
||||||
|
CCACHE_SLOPPINESS: time_macros
|
||||||
|
OS: android
|
||||||
|
TARGET: universal
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Set up cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.gradle/caches
|
||||||
|
~/.gradle/wrapper
|
||||||
|
${{ env.CCACHE_DIR }}
|
||||||
|
key: ${{ runner.os }}-android-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-android-
|
||||||
|
- name: Set tag name
|
||||||
|
run: |
|
||||||
|
if [[ "$GITHUB_REF_NAME" =~ ^canary- ]] || [[ "$GITHUB_REF_NAME" =~ ^nightly- ]]; then
|
||||||
|
echo "GIT_TAG_NAME=$GITHUB_REF_NAME" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
echo $GIT_TAG_NAME
|
||||||
|
- name: Deps
|
||||||
|
run: |
|
||||||
|
sudo add-apt-repository -y ppa:theofficialgman/gpu-tools
|
||||||
|
sudo apt-get update -y
|
||||||
|
sudo apt-get install ccache apksigner -y
|
||||||
|
- name: Build
|
||||||
|
run: JAVA_HOME=$JAVA_HOME_17_X64 ./.ci/android.sh
|
||||||
|
env:
|
||||||
|
ANDROID_KEYSTORE_B64: ${{ secrets.ANDROID_KEYSTORE_B64 }}
|
||||||
|
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
|
||||||
|
ANDROID_KEYSTORE_PASS: ${{ secrets.ANDROID_KEYSTORE_PASS }}
|
||||||
|
- name: Pack
|
||||||
|
run: ../../../.ci/pack.sh
|
||||||
|
working-directory: src/android/app
|
||||||
|
env:
|
||||||
|
UNPACKED: 1
|
||||||
|
- name: Upload
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ env.OS }}-${{ env.TARGET }}
|
||||||
|
path: src/android/app/artifacts/
|
||||||
|
ios:
|
||||||
|
runs-on: macos-14
|
||||||
|
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
||||||
|
env:
|
||||||
|
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||||
|
CCACHE_COMPILERCHECK: content
|
||||||
|
CCACHE_SLOPPINESS: time_macros
|
||||||
|
OS: ios
|
||||||
|
TARGET: arm64
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Set up cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{ env.CCACHE_DIR }}
|
||||||
|
key: ${{ runner.os }}-ios-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-ios-
|
||||||
|
- name: Install tools
|
||||||
|
run: brew install ccache ninja
|
||||||
|
- name: Build
|
||||||
|
run: ./.ci/ios.sh
|
||||||
|
release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [windows, linux, macos-universal, android, source]
|
||||||
|
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/download-artifact@v4
|
||||||
|
- name: Create release
|
||||||
|
uses: actions/create-release@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
tag_name: ${{ github.ref_name }}
|
||||||
|
release_name: ${{ github.ref_name }}
|
||||||
|
draft: false
|
||||||
|
prerelease: false
|
||||||
|
- name: Upload artifacts
|
||||||
|
uses: alexellis/upload-assets@0.4.0
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
asset_paths: '["./**/*.tar.*","./**/*.AppImage","./**/*.7z","./**/*.zip","./**/*.apk","./**/*.aab"]'
|
8
.github/workflows/ci-merge.js
vendored
8
.github/workflows/ci-merge.js
vendored
|
@ -11,7 +11,7 @@ async function checkBaseChanges(github, context) {
|
||||||
repository(name:$name, owner:$owner) {
|
repository(name:$name, owner:$owner) {
|
||||||
ref(qualifiedName:$ref) {
|
ref(qualifiedName:$ref) {
|
||||||
target {
|
target {
|
||||||
... on Commit { id pushedDate oid }
|
... on Commit { id committedDate oid }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,9 @@ async function checkBaseChanges(github, context) {
|
||||||
ref: 'refs/heads/master',
|
ref: 'refs/heads/master',
|
||||||
};
|
};
|
||||||
const result = await github.graphql(query, variables);
|
const result = await github.graphql(query, variables);
|
||||||
const pushedAt = result.repository.ref.target.pushedDate;
|
const committedAt = result.repository.ref.target.committedDate;
|
||||||
console.log(`Last commit pushed at ${pushedAt}.`);
|
console.log(`Last commit committed at ${committedAt}.`);
|
||||||
const delta = new Date() - new Date(pushedAt);
|
const delta = new Date() - new Date(committedAt);
|
||||||
if (delta <= DETECTION_TIME_FRAME) {
|
if (delta <= DETECTION_TIME_FRAME) {
|
||||||
console.info('New changes detected, triggering a new build.');
|
console.info('New changes detected, triggering a new build.');
|
||||||
return true;
|
return true;
|
||||||
|
|
237
.github/workflows/ci.yml
vendored
237
.github/workflows/ci.yml
vendored
|
@ -1,237 +0,0 @@
|
||||||
name: citra-ci
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "*" ]
|
|
||||||
tags: [ "*" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
clang-format:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container:
|
|
||||||
image: citraemu/build-environments:linux-clang-format
|
|
||||||
options: -u 1001
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Build
|
|
||||||
env:
|
|
||||||
COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}
|
|
||||||
run: ./.ci/linux-clang-format/docker.sh
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
image: ["linux-appimage", "linux-fresh", "linux-frozen", "linux-mingw"]
|
|
||||||
container:
|
|
||||||
image: citraemu/build-environments:${{ matrix.image }}
|
|
||||||
options: -u 1001
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
- name: Set up cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: ~/.ccache
|
|
||||||
key: ${{ runner.os }}-${{ matrix.image }}-${{ github.sha }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-${{ matrix.image }}-
|
|
||||||
- name: Build
|
|
||||||
run: ./.ci/${{ matrix.image }}/docker.sh
|
|
||||||
env:
|
|
||||||
ENABLE_COMPATIBILITY_REPORTING: "ON"
|
|
||||||
- name: Pack
|
|
||||||
run: ./.ci/${{ matrix.image }}/upload.sh
|
|
||||||
if: ${{ matrix.image != 'linux-frozen' }}
|
|
||||||
env:
|
|
||||||
NAME: ${{ matrix.image }}
|
|
||||||
- name: Upload
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
if: ${{ matrix.image != 'linux-frozen' }}
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.image }}
|
|
||||||
path: artifacts/
|
|
||||||
source:
|
|
||||||
if: ${{ !github.head_ref }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
- name: Pack
|
|
||||||
run: ./.ci/source/build.sh
|
|
||||||
- name: Upload
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: source
|
|
||||||
path: artifacts/
|
|
||||||
macos:
|
|
||||||
runs-on: macos-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
arch: ["x86_64", "arm64"]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
- name: Set up cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: ~/Library/Caches/ccache
|
|
||||||
key: ${{ runner.os }}-macos-${{ matrix.arch }}-${{ github.sha }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-macos-${{ matrix.arch }}-
|
|
||||||
- name: Install dependencies
|
|
||||||
run: ./.ci/macos/deps.sh
|
|
||||||
- name: Build
|
|
||||||
run: ./.ci/macos/build.sh
|
|
||||||
env:
|
|
||||||
MACOSX_DEPLOYMENT_TARGET: "11"
|
|
||||||
ENABLE_COMPATIBILITY_REPORTING: "ON"
|
|
||||||
TARGET_ARCH: ${{ matrix.arch }}
|
|
||||||
- name: Pack
|
|
||||||
run: ./.ci/macos/upload.sh
|
|
||||||
- name: Upload
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: macos-${{ matrix.arch }}
|
|
||||||
path: artifacts/
|
|
||||||
macos-universal:
|
|
||||||
runs-on: macos-latest
|
|
||||||
needs: macos
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
- name: Download x86 build
|
|
||||||
uses: actions/download-artifact@master
|
|
||||||
with:
|
|
||||||
name: macos-x86_64
|
|
||||||
path: macos-x86_64/
|
|
||||||
- name: Download ARM64 build
|
|
||||||
uses: actions/download-artifact@master
|
|
||||||
with:
|
|
||||||
name: macos-arm64
|
|
||||||
path: macos-arm64/
|
|
||||||
- name: Create universal app
|
|
||||||
run: ./.ci/macos/universal.sh
|
|
||||||
env:
|
|
||||||
ARTIFACTS: macos-x86_64 macos-arm64
|
|
||||||
# - name: Upload
|
|
||||||
# uses: actions/upload-artifact@v3
|
|
||||||
# with:
|
|
||||||
# name: macos
|
|
||||||
# path: artifacts/
|
|
||||||
- name: Delete intermediate artifacts
|
|
||||||
uses: geekyeggo/delete-artifact@v2
|
|
||||||
with:
|
|
||||||
name: |
|
|
||||||
macos-x86_64
|
|
||||||
macos-arm64
|
|
||||||
windows:
|
|
||||||
runs-on: windows-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
- name: Set up cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: ~/.buildcache
|
|
||||||
key: ${{ runner.os }}-win-${{ github.sha }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-win-
|
|
||||||
- name: Install dependencies
|
|
||||||
run: ./.ci/windows-msvc/deps.sh
|
|
||||||
shell: bash
|
|
||||||
- name: Set up MSVC
|
|
||||||
uses: ilammy/msvc-dev-cmd@v1
|
|
||||||
- name: Build
|
|
||||||
run: ./.ci/windows-msvc/build.sh
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
ENABLE_COMPATIBILITY_REPORTING: "ON"
|
|
||||||
- name: Pack
|
|
||||||
run: ./.ci/windows-msvc/upload.ps1
|
|
||||||
- name: Upload
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: msvc
|
|
||||||
path: artifacts/
|
|
||||||
android:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
- name: Set up cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
~/.gradle/caches
|
|
||||||
~/.gradle/wrapper
|
|
||||||
~/.ccache
|
|
||||||
key: ${{ runner.os }}-android-${{ github.sha }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-android-
|
|
||||||
- name: Set tag name
|
|
||||||
run: |
|
|
||||||
if [[ "$GITHUB_REF_NAME" =~ ^canary- ]] || [[ "$GITHUB_REF_NAME" =~ ^nightly- ]]; then
|
|
||||||
echo "GIT_TAG_NAME=$GITHUB_REF_NAME" >> $GITHUB_ENV
|
|
||||||
fi
|
|
||||||
echo $GIT_TAG_NAME
|
|
||||||
- name: Deps
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install ccache apksigner -y
|
|
||||||
- name: Build
|
|
||||||
run: ./.ci/android/build.sh
|
|
||||||
- name: Copy and sign artifacts
|
|
||||||
env:
|
|
||||||
ANDROID_KEYSTORE_B64: ${{ secrets.ANDROID_KEYSTORE_B64 }}
|
|
||||||
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
|
|
||||||
ANDROID_KEYSTORE_PASS: ${{ secrets.ANDROID_KEYSTORE_PASS }}
|
|
||||||
run: ./.ci/android/upload.sh
|
|
||||||
- name: Upload
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: android
|
|
||||||
path: artifacts/
|
|
||||||
transifex:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container: citraemu/build-environments:linux-transifex
|
|
||||||
if: ${{ github.repository == 'citra-emu/citra' && !github.head_ref }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Update Translation
|
|
||||||
run: ./.ci/transifex/docker.sh
|
|
||||||
env:
|
|
||||||
TX_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
|
|
||||||
release:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [build, android, macos-universal, source, windows]
|
|
||||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/download-artifact@v3
|
|
||||||
- name: Create release
|
|
||||||
uses: actions/create-release@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
tag_name: ${{ github.ref_name }}
|
|
||||||
release_name: ${{ github.ref_name }}
|
|
||||||
draft: false
|
|
||||||
prerelease: false
|
|
||||||
- name: Upload artifacts
|
|
||||||
uses: alexellis/upload-assets@0.4.0
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
asset_paths: '["./**/*.tar.*","./**/*.AppImage","./**/*.7z","./**/*.zip","./**/*.apk","./**/*.aab"]'
|
|
22
.github/workflows/format.yml
vendored
Normal file
22
.github/workflows/format.yml
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
name: citra-format
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "*" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
clang-format:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: citraemu/build-environments:linux-fresh
|
||||||
|
options: -u 1001
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Build
|
||||||
|
env:
|
||||||
|
COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}
|
||||||
|
run: ./.ci/clang-format.sh
|
16
.github/workflows/publish.yml
vendored
16
.github/workflows/publish.yml
vendored
|
@ -20,11 +20,11 @@ jobs:
|
||||||
if: ${{ github.event.inputs.nightly != 'false' && github.repository == 'citra-emu/citra' }}
|
if: ${{ github.event.inputs.nightly != 'false' && github.repository == 'citra-emu/citra' }}
|
||||||
steps:
|
steps:
|
||||||
# this checkout is required to make sure the GitHub Actions scripts are available
|
# this checkout is required to make sure the GitHub Actions scripts are available
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
name: Pre-checkout
|
name: Pre-checkout
|
||||||
with:
|
with:
|
||||||
submodules: false
|
submodules: false
|
||||||
- uses: actions/github-script@v6
|
- uses: actions/github-script@v7
|
||||||
id: check-changes
|
id: check-changes
|
||||||
name: 'Check for new changes'
|
name: 'Check for new changes'
|
||||||
env:
|
env:
|
||||||
|
@ -38,7 +38,7 @@ jobs:
|
||||||
return checkBaseChanges(github, context);
|
return checkBaseChanges(github, context);
|
||||||
- run: npm install execa@5
|
- run: npm install execa@5
|
||||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
name: Checkout
|
name: Checkout
|
||||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||||
with:
|
with:
|
||||||
|
@ -46,7 +46,7 @@ jobs:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: true
|
submodules: true
|
||||||
token: ${{ secrets.ALT_GITHUB_TOKEN }}
|
token: ${{ secrets.ALT_GITHUB_TOKEN }}
|
||||||
- uses: actions/github-script@v6
|
- uses: actions/github-script@v7
|
||||||
name: 'Update and tag new commits'
|
name: 'Update and tag new commits'
|
||||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||||
env:
|
env:
|
||||||
|
@ -62,11 +62,11 @@ jobs:
|
||||||
if: ${{ github.event.inputs.canary != 'false' && github.repository == 'citra-emu/citra' }}
|
if: ${{ github.event.inputs.canary != 'false' && github.repository == 'citra-emu/citra' }}
|
||||||
steps:
|
steps:
|
||||||
# this checkout is required to make sure the GitHub Actions scripts are available
|
# this checkout is required to make sure the GitHub Actions scripts are available
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
name: Pre-checkout
|
name: Pre-checkout
|
||||||
with:
|
with:
|
||||||
submodules: false
|
submodules: false
|
||||||
- uses: actions/github-script@v6
|
- uses: actions/github-script@v7
|
||||||
id: check-changes
|
id: check-changes
|
||||||
name: 'Check for new changes'
|
name: 'Check for new changes'
|
||||||
env:
|
env:
|
||||||
|
@ -79,7 +79,7 @@ jobs:
|
||||||
return checkCanaryChanges(github, context);
|
return checkCanaryChanges(github, context);
|
||||||
- run: npm install execa@5
|
- run: npm install execa@5
|
||||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
name: Checkout
|
name: Checkout
|
||||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||||
with:
|
with:
|
||||||
|
@ -87,7 +87,7 @@ jobs:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: true
|
submodules: true
|
||||||
token: ${{ secrets.ALT_GITHUB_TOKEN }}
|
token: ${{ secrets.ALT_GITHUB_TOKEN }}
|
||||||
- uses: actions/github-script@v6
|
- uses: actions/github-script@v7
|
||||||
name: 'Check and merge canary changes'
|
name: 'Check and merge canary changes'
|
||||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||||
env:
|
env:
|
||||||
|
|
20
.github/workflows/transifex.yml
vendored
Normal file
20
.github/workflows/transifex.yml
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
name: citra-transifex
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
transifex:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: citraemu/build-environments:linux-fresh
|
||||||
|
if: ${{ github.repository == 'citra-emu/citra' }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Update Translation
|
||||||
|
run: ./.ci/transifex.sh
|
||||||
|
env:
|
||||||
|
TX_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
|
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -9,10 +9,14 @@ src/common/scm_rev.cpp
|
||||||
|
|
||||||
# Project/editor files
|
# Project/editor files
|
||||||
*.swp
|
*.swp
|
||||||
|
*.kdev4
|
||||||
.idea/
|
.idea/
|
||||||
.vs/
|
.vs/
|
||||||
.vscode/
|
.vscode/
|
||||||
.cache/
|
.cache/
|
||||||
|
.kdev4/
|
||||||
|
cmake-build-debug/
|
||||||
|
cmake-build-release/
|
||||||
CMakeLists.txt.user*
|
CMakeLists.txt.user*
|
||||||
|
|
||||||
# *nix related
|
# *nix related
|
||||||
|
@ -41,4 +45,6 @@ Thumbs.db
|
||||||
repo/
|
repo/
|
||||||
|
|
||||||
# GitHub Actions generated files
|
# GitHub Actions generated files
|
||||||
|
.ccache/
|
||||||
node_modules/
|
node_modules/
|
||||||
|
VULKAN_SDK/
|
||||||
|
|
32
.gitmodules
vendored
32
.gitmodules
vendored
|
@ -36,7 +36,7 @@
|
||||||
url = https://github.com/mozilla/cubeb
|
url = https://github.com/mozilla/cubeb
|
||||||
[submodule "discord-rpc"]
|
[submodule "discord-rpc"]
|
||||||
path = externals/discord-rpc
|
path = externals/discord-rpc
|
||||||
url = https://github.com/discord/discord-rpc.git
|
url = https://github.com/yuzu-emu/discord-rpc.git
|
||||||
[submodule "cpp-jwt"]
|
[submodule "cpp-jwt"]
|
||||||
path = externals/cpp-jwt
|
path = externals/cpp-jwt
|
||||||
url = https://github.com/arun11299/cpp-jwt.git
|
url = https://github.com/arun11299/cpp-jwt.git
|
||||||
|
@ -64,6 +64,30 @@
|
||||||
[submodule "dds-ktx"]
|
[submodule "dds-ktx"]
|
||||||
path = externals/dds-ktx
|
path = externals/dds-ktx
|
||||||
url = https://github.com/septag/dds-ktx
|
url = https://github.com/septag/dds-ktx
|
||||||
[submodule "externals/openal-soft"]
|
[submodule "openal-soft"]
|
||||||
path = externals/openal-soft
|
path = externals/openal-soft
|
||||||
url = https://github.com/kcat/openal-soft
|
url = https://github.com/kcat/openal-soft
|
||||||
|
[submodule "glslang"]
|
||||||
|
path = externals/glslang
|
||||||
|
url = https://github.com/KhronosGroup/glslang
|
||||||
|
[submodule "vma"]
|
||||||
|
path = externals/vma
|
||||||
|
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
|
||||||
|
[submodule "vulkan-headers"]
|
||||||
|
path = externals/vulkan-headers
|
||||||
|
url = https://github.com/KhronosGroup/Vulkan-Headers
|
||||||
|
[submodule "sirit"]
|
||||||
|
path = externals/sirit
|
||||||
|
url = https://github.com/yuzu-emu/sirit
|
||||||
|
[submodule "faad2"]
|
||||||
|
path = externals/faad2/faad2
|
||||||
|
url = https://github.com/knik0/faad2
|
||||||
|
[submodule "library-headers"]
|
||||||
|
path = externals/library-headers
|
||||||
|
url = https://github.com/citra-emu/ext-library-headers.git
|
||||||
|
[submodule "libadrenotools"]
|
||||||
|
path = externals/libadrenotools
|
||||||
|
url = https://github.com/bylaws/libadrenotools
|
||||||
|
[submodule "oaknut"]
|
||||||
|
path = externals/oaknut
|
||||||
|
url = https://github.com/merryhime/oaknut.git
|
||||||
|
|
13
.lgtm.yml
13
.lgtm.yml
|
@ -1,13 +0,0 @@
|
||||||
path_classifiers:
|
|
||||||
library: "externals"
|
|
||||||
extraction:
|
|
||||||
cpp:
|
|
||||||
prepare:
|
|
||||||
packages:
|
|
||||||
- "libsdl2-dev"
|
|
||||||
- "qtmultimedia5-dev"
|
|
||||||
- "clang-format-6.0"
|
|
||||||
- "libtbb-dev"
|
|
||||||
- "libjack-jackd2-dev"
|
|
||||||
- "doxygen"
|
|
||||||
- "graphviz"
|
|
268
CMakeLists.txt
268
CMakeLists.txt
|
@ -5,6 +5,10 @@ cmake_minimum_required(VERSION 3.15)
|
||||||
cmake_policy(SET CMP0092 NEW)
|
cmake_policy(SET CMP0092 NEW)
|
||||||
# Enforce new LTO setting
|
# Enforce new LTO setting
|
||||||
cmake_policy(SET CMP0069 NEW)
|
cmake_policy(SET CMP0069 NEW)
|
||||||
|
# Honor visibility properties for all targets
|
||||||
|
# Set the default so subdirectory cmake_minimum_required calls won't unset the policy.
|
||||||
|
cmake_policy(SET CMP0063 NEW)
|
||||||
|
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
|
||||||
|
@ -13,71 +17,90 @@ include(CMakeDependentOption)
|
||||||
|
|
||||||
project(citra LANGUAGES C CXX ASM)
|
project(citra LANGUAGES C CXX ASM)
|
||||||
|
|
||||||
if (APPLE)
|
# Some submodules like to pick their own default build type if not specified.
|
||||||
enable_language(OBJC)
|
# Make sure we default to Release build type always, unless the generator has custom types.
|
||||||
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
|
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(ENABLE_LTO "Enable link time optimization" OFF)
|
if (APPLE)
|
||||||
|
# Silence warnings on empty objects, for example when platform-specific code is #ifdef'd out.
|
||||||
|
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||||
|
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||||
|
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||||
|
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||||
|
|
||||||
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
|
if (IOS)
|
||||||
|
# Minimum iOS 14
|
||||||
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "14.0")
|
||||||
|
|
||||||
|
# Enable searching CMAKE_PREFIX_PATH for bundled dependencies.
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
|
||||||
|
else()
|
||||||
|
# Minimum macOS 11
|
||||||
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||||
|
set(IS_DEBUG_BUILD ON)
|
||||||
|
set(IS_RELEASE_BUILD OFF)
|
||||||
|
else()
|
||||||
|
set(IS_DEBUG_BUILD OFF)
|
||||||
|
set(IS_RELEASE_BUILD ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# LTO takes too much memory and time using MSVC.
|
||||||
|
if (NOT MSVC AND IS_RELEASE_BUILD)
|
||||||
|
set(DEFAULT_ENABLE_LTO ON)
|
||||||
|
else()
|
||||||
|
set(DEFAULT_ENABLE_LTO OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(ENABLE_SDL2 "Enable using SDL2" ON)
|
||||||
|
CMAKE_DEPENDENT_OPTION(ENABLE_SDL2_FRONTEND "Enable the SDL2 frontend" ON "ENABLE_SDL2;NOT ANDROID AND NOT IOS" OFF)
|
||||||
option(USE_SYSTEM_SDL2 "Use the system SDL2 lib (instead of the bundled one)" OFF)
|
option(USE_SYSTEM_SDL2 "Use the system SDL2 lib (instead of the bundled one)" OFF)
|
||||||
|
|
||||||
# Set bundled qt as dependent options.
|
# Set bundled qt as dependent options.
|
||||||
option(ENABLE_QT "Enable the Qt frontend" ON)
|
option(ENABLE_QT "Enable the Qt frontend" ON)
|
||||||
option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
|
option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
|
||||||
CMAKE_DEPENDENT_OPTION(CITRA_USE_BUNDLED_QT "Download bundled Qt binaries" ON "ENABLE_QT;MSVC OR APPLE" OFF)
|
CMAKE_DEPENDENT_OPTION(ENABLE_QT_UPDATER "Enable built-in updater for the Qt frontend" ON "NOT IOS" OFF)
|
||||||
|
|
||||||
|
CMAKE_DEPENDENT_OPTION(ENABLE_TESTS "Enable generating tests executable" ON "NOT IOS" OFF)
|
||||||
|
CMAKE_DEPENDENT_OPTION(ENABLE_DEDICATED_ROOM "Enable generating dedicated room executable" ON "NOT ANDROID AND NOT IOS" OFF)
|
||||||
|
|
||||||
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
|
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
|
||||||
if (MSVC)
|
option(ENABLE_SCRIPTING "Enable RPC server for scripting" ON)
|
||||||
set(OPENSSL_DLL_DIR "" CACHE PATH "Location of the Openssl dlls")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
|
CMAKE_DEPENDENT_OPTION(ENABLE_CUBEB "Enables the cubeb audio backend" ON "NOT IOS" OFF)
|
||||||
option(ENABLE_OPENAL "Enables the OpenAL audio backend" ON)
|
option(ENABLE_OPENAL "Enables the OpenAL audio backend" ON)
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(ENABLE_LIBUSB "Enable libusb for GameCube Adapter support" ON "NOT IOS" OFF)
|
CMAKE_DEPENDENT_OPTION(ENABLE_LIBUSB "Enable libusb for GameCube Adapter support" ON "NOT IOS" OFF)
|
||||||
|
|
||||||
option(ENABLE_FFMPEG_AUDIO_DECODER "Enable FFmpeg audio (AAC) decoder" OFF)
|
CMAKE_DEPENDENT_OPTION(ENABLE_SOFTWARE_RENDERER "Enables the software renderer" ON "NOT ANDROID" OFF)
|
||||||
option(ENABLE_FFMPEG_VIDEO_DUMPER "Enable FFmpeg video dumper" OFF)
|
CMAKE_DEPENDENT_OPTION(ENABLE_OPENGL "Enables the OpenGL renderer" ON "NOT APPLE" OFF)
|
||||||
|
option(ENABLE_VULKAN "Enables the Vulkan renderer" ON)
|
||||||
if (ENABLE_FFMPEG_AUDIO_DECODER OR ENABLE_FFMPEG_VIDEO_DUMPER)
|
|
||||||
set(ENABLE_FFMPEG ON)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(CITRA_USE_BUNDLED_FFMPEG "Download bundled FFmpeg binaries" ON "ENABLE_FFMPEG;MSVC OR APPLE" OFF)
|
|
||||||
|
|
||||||
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
|
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
|
||||||
|
|
||||||
|
# Compile options
|
||||||
|
CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ${IS_DEBUG_BUILD} "MINGW" OFF)
|
||||||
|
option(ENABLE_LTO "Enable link time optimization" ${DEFAULT_ENABLE_LTO})
|
||||||
option(CITRA_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON)
|
option(CITRA_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON)
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(ENABLE_MF "Use Media Foundation decoder (preferred over FFmpeg)" ON "WIN32" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(ENABLE_AUDIOTOOLBOX "Use AudioToolbox decoder (preferred over FFmpeg)" ON "APPLE" OFF)
|
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ON "MINGW" OFF)
|
|
||||||
|
|
||||||
option(USE_SYSTEM_BOOST "Use the system Boost libs (instead of the bundled ones)" OFF)
|
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(ENABLE_FDK "Use FDK AAC decoder" OFF "NOT ENABLE_FFMPEG_AUDIO_DECODER;NOT ENABLE_MF" OFF)
|
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(CITRA_BUNDLE_LIBRARIES "Bundle dependent libraries with the output executables" ON "APPLE" OFF)
|
|
||||||
|
|
||||||
option(CITRA_WARNINGS_AS_ERRORS "Enable warnings as errors" ON)
|
option(CITRA_WARNINGS_AS_ERRORS "Enable warnings as errors" ON)
|
||||||
|
|
||||||
if (CITRA_USE_PRECOMPILED_HEADERS)
|
include(CitraHandleSystemLibs)
|
||||||
if (MSVC AND CCACHE)
|
|
||||||
# buildcache does not properly cache PCH files, leading to compilation errors.
|
|
||||||
# See https://github.com/mbitsnbites/buildcache/discussions/230
|
|
||||||
message(WARNING "Buildcache does not properly support Precompiled Headers. Disabling PCH")
|
|
||||||
set(CITRA_USE_PRECOMPILED_HEADERS OFF)
|
|
||||||
endif()
|
|
||||||
if(APPLE)
|
|
||||||
message(WARNING "Precompiled Headers currently do not work on Apple. Disabling PCH")
|
|
||||||
set(CITRA_USE_PRECOMPILED_HEADERS OFF)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
if (CITRA_USE_PRECOMPILED_HEADERS)
|
if (CITRA_USE_PRECOMPILED_HEADERS)
|
||||||
message(STATUS "Using Precompiled Headers.")
|
message(STATUS "Using Precompiled Headers.")
|
||||||
set(CMAKE_PCH_INSTANTIATE_TEMPLATES ON)
|
set(CMAKE_PCH_INSTANTIATE_TEMPLATES ON)
|
||||||
|
|
||||||
|
# This ensures that pre-compiled headers won't invalidate build caches for every fresh checkout.
|
||||||
|
if(NOT MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
list(APPEND CMAKE_CXX_COMPILE_OPTIONS_CREATE_PCH -Xclang -fno-pch-timestamp)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/hooks/pre-commit)
|
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/hooks/pre-commit)
|
||||||
|
@ -124,7 +147,10 @@ function(check_submodules_present)
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
endfunction()
|
endfunction()
|
||||||
check_submodules_present()
|
if (EXISTS "${PROJECT_SOURCE_DIR}/.git/objects")
|
||||||
|
# only check submodules when source is obtained via Git
|
||||||
|
check_submodules_present()
|
||||||
|
endif()
|
||||||
|
|
||||||
configure_file(${PROJECT_SOURCE_DIR}/dist/compatibility_list/compatibility_list.qrc
|
configure_file(${PROJECT_SOURCE_DIR}/dist/compatibility_list/compatibility_list.qrc
|
||||||
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
|
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
|
||||||
|
@ -187,9 +213,15 @@ message(STATUS "Target architecture: ${ARCHITECTURE}")
|
||||||
|
|
||||||
# boost asio's concept usage doesn't play nicely with some compilers yet.
|
# boost asio's concept usage doesn't play nicely with some compilers yet.
|
||||||
add_definitions(-DBOOST_ASIO_DISABLE_CONCEPTS)
|
add_definitions(-DBOOST_ASIO_DISABLE_CONCEPTS)
|
||||||
|
# boost can have issues compiling with C++17 and up on newer versions of Clang.
|
||||||
|
add_definitions(-DBOOST_NO_CXX98_FUNCTION_BASE)
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
# Apply consistent visibility settings.
|
||||||
|
set(CMAKE_CXX_VISIBILITY_PRESET default)
|
||||||
|
set(CMAKE_VISIBILITY_INLINES_HIDDEN NO)
|
||||||
|
|
||||||
# set up output paths for executable binaries
|
# set up output paths for executable binaries
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/$<CONFIG>)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/$<CONFIG>)
|
||||||
|
|
||||||
|
@ -202,9 +234,8 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
if (ENABLE_QT)
|
if (ENABLE_QT)
|
||||||
if (CITRA_USE_BUNDLED_QT)
|
if (NOT USE_SYSTEM_QT)
|
||||||
download_qt_external(6.5.0 QT_PREFIX)
|
download_qt(6.6.0)
|
||||||
list(APPEND CMAKE_PREFIX_PATH ${QT_PREFIX})
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia Concurrent)
|
find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia Concurrent)
|
||||||
|
@ -217,62 +248,25 @@ if (ENABLE_QT)
|
||||||
find_package(Qt6 REQUIRED COMPONENTS LinguistTools)
|
find_package(Qt6 REQUIRED COMPONENTS LinguistTools)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT CITRA_USE_BUNDLED_QT)
|
if (NOT DEFINED QT_TARGET_PATH)
|
||||||
# Make sure the Qt bin directory is in the prefix path for later use, such as in post-build scripts.
|
# Determine the location of the compile target's Qt.
|
||||||
get_target_property(qmake_executable Qt6::qmake IMPORTED_LOCATION)
|
get_target_property(qtcore_path Qt6::Core LOCATION_Release)
|
||||||
get_filename_component(qt_bin_dir "${qmake_executable}" DIRECTORY)
|
string(FIND "${qtcore_path}" "/bin/" qtcore_path_bin_pos REVERSE)
|
||||||
list(APPEND CMAKE_PREFIX_PATH ${qt_bin_dir})
|
string(FIND "${qtcore_path}" "/lib/" qtcore_path_lib_pos REVERSE)
|
||||||
endif()
|
if (qtcore_path_bin_pos GREATER qtcore_path_lib_pos)
|
||||||
endif()
|
string(SUBSTRING "${qtcore_path}" 0 ${qtcore_path_bin_pos} QT_TARGET_PATH)
|
||||||
|
|
||||||
# Ensure libusb is properly configured (based on dolphin libusb include)
|
|
||||||
if (ENABLE_LIBUSB)
|
|
||||||
if(NOT APPLE)
|
|
||||||
include(FindPkgConfig)
|
|
||||||
find_package(LibUSB)
|
|
||||||
endif()
|
|
||||||
if (NOT LIBUSB_FOUND)
|
|
||||||
add_subdirectory(externals/libusb)
|
|
||||||
set(LIBUSB_INCLUDE_DIR "")
|
|
||||||
set(LIBUSB_LIBRARIES usb)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (ENABLE_FFMPEG)
|
|
||||||
if (CITRA_USE_BUNDLED_FFMPEG)
|
|
||||||
if ((MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1940) AND "x86_64" IN_LIST ARCHITECTURE)
|
|
||||||
set(FFmpeg_VER "ffmpeg-4.1-win64")
|
|
||||||
elseif (APPLE)
|
|
||||||
set(FFmpeg_VER "ffmpeg-6.0")
|
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "No bundled FFmpeg binaries for your toolchain. Disable CITRA_USE_BUNDLED_FFMPEG and provide your own.")
|
string(SUBSTRING "${qtcore_path}" 0 ${qtcore_path_lib_pos} QT_TARGET_PATH)
|
||||||
endif()
|
|
||||||
|
|
||||||
if (DEFINED FFmpeg_VER)
|
|
||||||
download_bundled_external("ffmpeg/" ${FFmpeg_VER} FFmpeg_PREFIX)
|
|
||||||
set(FFMPEG_DIR "${FFmpeg_PREFIX}")
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ENABLE_FFMPEG_VIDEO_DUMPER)
|
if (NOT DEFINED QT_HOST_PATH)
|
||||||
find_package(FFmpeg REQUIRED COMPONENTS avcodec avformat avutil swscale swresample)
|
# Use the same for host Qt if none is defined.
|
||||||
else()
|
set(QT_HOST_PATH "${QT_TARGET_PATH}")
|
||||||
find_package(FFmpeg REQUIRED COMPONENTS avcodec)
|
|
||||||
endif()
|
endif()
|
||||||
if ("${FFmpeg_avcodec_VERSION}" VERSION_LESS "57.48.101")
|
|
||||||
message(FATAL_ERROR "Found version for libavcodec is too low. The required version is at least 57.48.101 (included in FFmpeg 3.1 and later).")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (ENABLE_FFMPEG_VIDEO_DUMPER)
|
message(STATUS "Using target Qt at ${QT_TARGET_PATH}")
|
||||||
add_definitions(-DENABLE_FFMPEG_VIDEO_DUMPER)
|
message(STATUS "Using host Qt at ${QT_HOST_PATH}")
|
||||||
endif()
|
|
||||||
|
|
||||||
if (ENABLE_FDK)
|
|
||||||
find_library(FDK_AAC fdk-aac DOC "The path to fdk_aac library")
|
|
||||||
if(FDK_AAC STREQUAL "FDK_AAC-NOTFOUND")
|
|
||||||
message(FATAL_ERROR "fdk_aac library not found.")
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Use system tsl::robin_map if available (otherwise we fallback to version bundled with dynarmic)
|
# Use system tsl::robin_map if available (otherwise we fallback to version bundled with dynarmic)
|
||||||
|
@ -282,10 +276,22 @@ find_package(tsl-robin-map QUIET)
|
||||||
# ======================================
|
# ======================================
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
# Umbrella framework for everything GUI-related
|
if (NOT IOS)
|
||||||
find_library(COCOA_LIBRARY Cocoa)
|
# Umbrella framework for everything GUI-related
|
||||||
find_library(AVFOUNDATION_LIBRARY AVFoundation)
|
find_library(COCOA_LIBRARY Cocoa REQUIRED)
|
||||||
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${AVFOUNDATION_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY})
|
endif()
|
||||||
|
find_library(AVFOUNDATION_LIBRARY AVFoundation REQUIRED)
|
||||||
|
find_library(IOSURFACE_LIBRARY IOSurface REQUIRED)
|
||||||
|
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${AVFOUNDATION_LIBRARY} ${IOSURFACE_LIBRARY} ${MOLTENVK_LIBRARY})
|
||||||
|
|
||||||
|
if (ENABLE_VULKAN)
|
||||||
|
if (NOT USE_SYSTEM_MOLTENVK)
|
||||||
|
download_moltenvk()
|
||||||
|
endif()
|
||||||
|
find_library(MOLTENVK_LIBRARY MoltenVK REQUIRED)
|
||||||
|
message(STATUS "Using MoltenVK at ${MOLTENVK_LIBRARY}.")
|
||||||
|
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} ${MOLTENVK_LIBRARY})
|
||||||
|
endif()
|
||||||
elseif (WIN32)
|
elseif (WIN32)
|
||||||
set(PLATFORM_LIBRARIES winmm ws2_32)
|
set(PLATFORM_LIBRARIES winmm ws2_32)
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
|
@ -300,7 +306,7 @@ endif()
|
||||||
# against all the src files. This should be used before making a pull request.
|
# against all the src files. This should be used before making a pull request.
|
||||||
# =======================================================================
|
# =======================================================================
|
||||||
|
|
||||||
set(CLANG_FORMAT_POSTFIX "-12")
|
set(CLANG_FORMAT_POSTFIX "-15")
|
||||||
find_program(CLANG_FORMAT
|
find_program(CLANG_FORMAT
|
||||||
NAMES clang-format${CLANG_FORMAT_POSTFIX}
|
NAMES clang-format${CLANG_FORMAT_POSTFIX}
|
||||||
clang-format
|
clang-format
|
||||||
|
@ -336,7 +342,7 @@ if (CLANG_FORMAT)
|
||||||
add_custom_target(clang-format
|
add_custom_target(clang-format
|
||||||
COMMAND powershell.exe -Command "Get-ChildItem '${SRCS}/*' -Include *.cpp,*.h,*.mm -Recurse | Foreach {&'${CLANG_FORMAT}' -i $_.fullname}"
|
COMMAND powershell.exe -Command "Get-ChildItem '${SRCS}/*' -Include *.cpp,*.h,*.mm -Recurse | Foreach {&'${CLANG_FORMAT}' -i $_.fullname}"
|
||||||
COMMENT ${CCOMMENT})
|
COMMENT ${CCOMMENT})
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
add_custom_target(clang-format
|
add_custom_target(clang-format
|
||||||
COMMAND find ${SRCS} -iname *.h -o -iname *.cpp -o -iname *.mm | xargs ${CLANG_FORMAT} -i
|
COMMAND find ${SRCS} -iname *.h -o -iname *.cpp -o -iname *.mm | xargs ${CLANG_FORMAT} -i
|
||||||
|
@ -373,13 +379,6 @@ function(get_timestamp _var)
|
||||||
set(${_var} "${timestamp}" PARENT_SCOPE)
|
set(${_var} "${timestamp}" PARENT_SCOPE)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# Prevent boost from linking against libs when building
|
|
||||||
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY
|
|
||||||
-DBOOST_SYSTEM_NO_LIB
|
|
||||||
-DBOOST_DATE_TIME_NO_LIB
|
|
||||||
-DBOOST_REGEX_NO_LIB
|
|
||||||
)
|
|
||||||
|
|
||||||
# generate git/build information
|
# generate git/build information
|
||||||
include(GetGitRevisionDescription)
|
include(GetGitRevisionDescription)
|
||||||
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
||||||
|
@ -387,22 +386,23 @@ git_describe(GIT_DESC --always --long --dirty)
|
||||||
git_branch_name(GIT_BRANCH)
|
git_branch_name(GIT_BRANCH)
|
||||||
get_timestamp(BUILD_DATE)
|
get_timestamp(BUILD_DATE)
|
||||||
|
|
||||||
if (NOT USE_SYSTEM_BOOST)
|
# Boost
|
||||||
add_definitions( -DBOOST_ALL_NO_LIB )
|
# Prevent boost from linking against libs when building
|
||||||
|
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY
|
||||||
|
-DBOOST_SYSTEM_NO_LIB
|
||||||
|
-DBOOST_DATE_TIME_NO_LIB
|
||||||
|
-DBOOST_REGEX_NO_LIB
|
||||||
|
)
|
||||||
|
if (USE_SYSTEM_BOOST)
|
||||||
|
find_package(Boost 1.70.0 COMPONENTS container locale serialization iostreams REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
add_subdirectory(externals)
|
add_subdirectory(externals)
|
||||||
|
|
||||||
# See externals/CMakeLists.txt
|
# Boost (bundled)
|
||||||
foreach(def ${CRYPTOPP_COMPILE_DEFINITIONS})
|
if (NOT USE_SYSTEM_BOOST)
|
||||||
add_definitions(-D${def})
|
add_definitions( -DBOOST_ALL_NO_LIB )
|
||||||
endforeach()
|
|
||||||
|
|
||||||
# Boost
|
|
||||||
if (USE_SYSTEM_BOOST)
|
|
||||||
find_package(Boost 1.70.0 COMPONENTS serialization iostreams REQUIRED)
|
|
||||||
else()
|
|
||||||
add_library(Boost::boost ALIAS boost)
|
add_library(Boost::boost ALIAS boost)
|
||||||
add_library(Boost::serialization ALIAS boost_serialization)
|
add_library(Boost::serialization ALIAS boost_serialization)
|
||||||
add_library(Boost::iostreams ALIAS boost_iostreams)
|
add_library(Boost::iostreams ALIAS boost_iostreams)
|
||||||
|
@ -417,6 +417,19 @@ if (ENABLE_SDL2 AND USE_SYSTEM_SDL2)
|
||||||
add_library(SDL2::SDL2 ALIAS SDL2)
|
add_library(SDL2::SDL2 ALIAS SDL2)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (ENABLE_LIBUSB AND USE_SYSTEM_LIBUSB)
|
||||||
|
include(FindPkgConfig)
|
||||||
|
find_package(LibUSB)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (USE_SYSTEM_SOUNDTOUCH)
|
||||||
|
include(FindPkgConfig)
|
||||||
|
find_package(SoundTouch REQUIRED)
|
||||||
|
add_library(SoundTouch INTERFACE)
|
||||||
|
target_link_libraries(SoundTouch INTERFACE "${SOUNDTOUCH_LIBRARIES}")
|
||||||
|
target_include_directories(SoundTouch INTERFACE "${SOUNDTOUCH_INCLUDE_DIRS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(dist/installer)
|
add_subdirectory(dist/installer)
|
||||||
|
|
||||||
|
@ -428,6 +441,21 @@ else()
|
||||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT citra)
|
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT citra)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Create target for outputting distributable bundles.
|
||||||
|
# Not supported for mobile platforms as distributables are built differently.
|
||||||
|
if (NOT ANDROID AND NOT IOS)
|
||||||
|
include(BundleTarget)
|
||||||
|
if (ENABLE_SDL2_FRONTEND)
|
||||||
|
bundle_target(citra)
|
||||||
|
endif()
|
||||||
|
if (ENABLE_QT)
|
||||||
|
bundle_target(citra-qt)
|
||||||
|
endif()
|
||||||
|
if (ENABLE_DEDICATED_ROOM)
|
||||||
|
bundle_target(citra-room)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# Installation instructions
|
# Installation instructions
|
||||||
# =========================
|
# =========================
|
||||||
|
|
||||||
|
@ -436,7 +464,7 @@ endif()
|
||||||
# http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
|
# http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
|
||||||
# http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html
|
# http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html
|
||||||
if(ENABLE_QT AND UNIX AND NOT APPLE)
|
if(ENABLE_QT AND UNIX AND NOT APPLE)
|
||||||
install(FILES "${PROJECT_SOURCE_DIR}/dist/citra.desktop"
|
install(FILES "${PROJECT_SOURCE_DIR}/dist/citra-qt.desktop"
|
||||||
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/applications")
|
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/applications")
|
||||||
install(FILES "${PROJECT_SOURCE_DIR}/dist/citra.svg"
|
install(FILES "${PROJECT_SOURCE_DIR}/dist/citra.svg"
|
||||||
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps")
|
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps")
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# To use this as a script, make sure you pass in the variables BASE_DIR, SRC_DIR, BUILD_DIR, and TARGET_FILE
|
# To use this as a script, make sure you pass in the variables BASE_DIR, SRC_DIR, BUILD_DIR, and TARGET_FILE
|
||||||
|
cmake_minimum_required(VERSION 3.15)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(PLATFORM "windows")
|
set(PLATFORM "windows")
|
||||||
|
@ -12,7 +13,8 @@ endif()
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${BASE_DIR}/CMakeModules")
|
list(APPEND CMAKE_MODULE_PATH "${BASE_DIR}/CMakeModules")
|
||||||
include(DownloadExternals)
|
include(DownloadExternals)
|
||||||
download_qt_external(tools_ifw QT_PREFIX)
|
download_qt(tools_ifw)
|
||||||
|
get_external_prefix(qt QT_PREFIX)
|
||||||
|
|
||||||
file(GLOB_RECURSE INSTALLER_BASE "${QT_PREFIX}/**/installerbase*")
|
file(GLOB_RECURSE INSTALLER_BASE "${QT_PREFIX}/**/installerbase*")
|
||||||
file(GLOB_RECURSE BINARY_CREATOR "${QT_PREFIX}/**/binarycreator*")
|
file(GLOB_RECURSE BINARY_CREATOR "${QT_PREFIX}/**/binarycreator*")
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
# Bundles libraries with an output executable.
|
|
||||||
# Parameters:
|
|
||||||
# - TYPE: "qt" or "standalone". The type of app to bundle.
|
|
||||||
# - "qt" uses windeployqt/macdeployqt to bundle Qt and other libraries.
|
|
||||||
# - "standalone" copies dependent libraries to a "libs" folder alongside the executable file.
|
|
||||||
# - EXECUTABLE_PATH: Path to the executable binary.
|
|
||||||
|
|
||||||
# TODO: This does not really work fully for Windows yet, some libraries are missing from the output.
|
|
||||||
# TODO: Leaving a basic framework of Windows support here to be iterated on in the future.
|
|
||||||
if (WIN32)
|
|
||||||
message(FATAL_ERROR "Advanced library bundling is not yet supported for Windows.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if ("${TYPE}" STREQUAL "qt")
|
|
||||||
get_filename_component(executable_dir ${EXECUTABLE_PATH} DIRECTORY)
|
|
||||||
|
|
||||||
# Bundle dependencies using appropriate Qt tool.
|
|
||||||
if (WIN32)
|
|
||||||
find_program(WINDEPLOYQT_EXECUTABLE windeployqt)
|
|
||||||
execute_process(COMMAND ${WINDEPLOYQT_EXECUTABLE} ${EXECUTABLE_PATH}
|
|
||||||
--no-compiler-runtime --no-system-d3d-compiler --no-opengl-sw --no-translations
|
|
||||||
--plugindir "${executable_dir}/plugins")
|
|
||||||
elseif (APPLE)
|
|
||||||
get_filename_component(contents_dir ${executable_dir} DIRECTORY)
|
|
||||||
get_filename_component(bundle_dir ${contents_dir} DIRECTORY)
|
|
||||||
|
|
||||||
find_program(MACDEPLOYQT_EXECUTABLE macdeployqt)
|
|
||||||
execute_process(COMMAND ${MACDEPLOYQT_EXECUTABLE} ${bundle_dir} -executable=${EXECUTABLE_PATH} -always-overwrite)
|
|
||||||
|
|
||||||
# Bundling libraries can rewrite path information and break code signatures of system libraries.
|
|
||||||
# Perform an ad-hoc re-signing on the whole app bundle to fix this.
|
|
||||||
execute_process(COMMAND codesign --deep -fs - ${bundle_dir})
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "Unsupported OS for Qt-based library bundling.")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
# Resolve dependent library files.
|
|
||||||
file(GET_RUNTIME_DEPENDENCIES
|
|
||||||
EXECUTABLES ${EXECUTABLE_PATH}
|
|
||||||
RESOLVED_DEPENDENCIES_VAR resolved_deps
|
|
||||||
UNRESOLVED_DEPENDENCIES_VAR unresolved_deps
|
|
||||||
POST_EXCLUDE_REGEXES ".*system32/.*\\.dll")
|
|
||||||
|
|
||||||
# Determine libraries directory.
|
|
||||||
get_filename_component(executable_dir ${EXECUTABLE_PATH} DIRECTORY)
|
|
||||||
if (WIN32)
|
|
||||||
# Same directory since we don't have rpath.
|
|
||||||
set(lib_dir ${executable_dir})
|
|
||||||
else()
|
|
||||||
set(lib_dir ${executable_dir}/libs)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Copy library files to bundled output.
|
|
||||||
file(MAKE_DIRECTORY ${lib_dir})
|
|
||||||
foreach (lib_file ${resolved_deps})
|
|
||||||
# Use native copy to turn symlinks into normal files.
|
|
||||||
execute_process(COMMAND cp -L ${lib_file} ${lib_dir})
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
# Add libs directory to executable rpath where applicable.
|
|
||||||
if (APPLE)
|
|
||||||
execute_process(COMMAND install_name_tool -add_rpath "@loader_path/libs" ${EXECUTABLE_PATH})
|
|
||||||
elseif (UNIX)
|
|
||||||
execute_process(COMMAND patchelf --set-rpath '$ORIGIN/../libs' ${EXECUTABLE_PATH})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
374
CMakeModules/BundleTarget.cmake
Normal file
374
CMakeModules/BundleTarget.cmake
Normal file
|
@ -0,0 +1,374 @@
|
||||||
|
|
||||||
|
if (BUNDLE_TARGET_EXECUTE)
|
||||||
|
# --- Bundling method logic ---
|
||||||
|
|
||||||
|
function(symlink_safe_copy from to)
|
||||||
|
if (WIN32)
|
||||||
|
# Use cmake copy for maximum compatibility.
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${from}" "${to}"
|
||||||
|
RESULT_VARIABLE cp_result)
|
||||||
|
else()
|
||||||
|
# Use native copy to turn symlinks into normal files.
|
||||||
|
execute_process(COMMAND cp -L "${from}" "${to}"
|
||||||
|
RESULT_VARIABLE cp_result)
|
||||||
|
endif()
|
||||||
|
if (NOT cp_result EQUAL "0")
|
||||||
|
message(FATAL_ERROR "cp \"${from}\" \"${to}\" failed: ${cp_result}")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(bundle_qt executable_path)
|
||||||
|
if (WIN32)
|
||||||
|
# Perform standalone bundling first to copy over all used libraries, as windeployqt does not do this.
|
||||||
|
bundle_standalone("${executable_path}" "${EXECUTABLE_PATH}" "${BUNDLE_LIBRARY_PATHS}")
|
||||||
|
|
||||||
|
get_filename_component(executable_parent_dir "${executable_path}" DIRECTORY)
|
||||||
|
|
||||||
|
# Create a qt.conf file pointing to the app directory.
|
||||||
|
# This ensures Qt can find its plugins.
|
||||||
|
file(WRITE "${executable_parent_dir}/qt.conf" "[Paths]\nPrefix = .")
|
||||||
|
|
||||||
|
find_program(windeployqt_executable windeployqt6 PATHS "${QT_HOST_PATH}/bin")
|
||||||
|
find_program(qtpaths_executable qtpaths6 PATHS "${QT_HOST_PATH}/bin")
|
||||||
|
|
||||||
|
# TODO: Hack around windeployqt's poor cross-compilation support by
|
||||||
|
# TODO: making a local copy with a prefix pointing to the target Qt.
|
||||||
|
if (NOT "${QT_HOST_PATH}" STREQUAL "${QT_TARGET_PATH}")
|
||||||
|
set(windeployqt_dir "${BINARY_PATH}/windeployqt_copy")
|
||||||
|
file(MAKE_DIRECTORY "${windeployqt_dir}")
|
||||||
|
symlink_safe_copy("${windeployqt_executable}" "${windeployqt_dir}/windeployqt.exe")
|
||||||
|
symlink_safe_copy("${qtpaths_executable}" "${windeployqt_dir}/qtpaths.exe")
|
||||||
|
symlink_safe_copy("${QT_HOST_PATH}/bin/Qt6Core.dll" "${windeployqt_dir}")
|
||||||
|
|
||||||
|
if (EXISTS "${QT_TARGET_PATH}/share")
|
||||||
|
# Unix-style Qt; we need to wire up the paths manually.
|
||||||
|
file(WRITE "${windeployqt_dir}/qt.conf" "\
|
||||||
|
[Paths]\n
|
||||||
|
Prefix = ${QT_TARGET_PATH}\n \
|
||||||
|
ArchData = ${QT_TARGET_PATH}/share/qt6\n \
|
||||||
|
Binaries = ${QT_TARGET_PATH}/bin\n \
|
||||||
|
Data = ${QT_TARGET_PATH}/share/qt6\n \
|
||||||
|
Documentation = ${QT_TARGET_PATH}/share/qt6/doc\n \
|
||||||
|
Headers = ${QT_TARGET_PATH}/include/qt6\n \
|
||||||
|
Libraries = ${QT_TARGET_PATH}/lib\n \
|
||||||
|
LibraryExecutables = ${QT_TARGET_PATH}/share/qt6/bin\n \
|
||||||
|
Plugins = ${QT_TARGET_PATH}/share/qt6/plugins\n \
|
||||||
|
QmlImports = ${QT_TARGET_PATH}/share/qt6/qml\n \
|
||||||
|
Translations = ${QT_TARGET_PATH}/share/qt6/translations\n \
|
||||||
|
")
|
||||||
|
else()
|
||||||
|
# Windows-style Qt; the defaults should suffice.
|
||||||
|
file(WRITE "${windeployqt_dir}/qt.conf" "[Paths]\nPrefix = ${QT_TARGET_PATH}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(windeployqt_executable "${windeployqt_dir}/windeployqt.exe")
|
||||||
|
set(qtpaths_executable "${windeployqt_dir}/qtpaths.exe")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Executing windeployqt for executable ${executable_path}")
|
||||||
|
execute_process(COMMAND "${windeployqt_executable}" "${executable_path}"
|
||||||
|
--qtpaths "${qtpaths_executable}"
|
||||||
|
--no-compiler-runtime --no-system-d3d-compiler --no-opengl-sw --no-translations
|
||||||
|
--plugindir "${executable_parent_dir}/plugins"
|
||||||
|
RESULT_VARIABLE windeployqt_result)
|
||||||
|
if (NOT windeployqt_result EQUAL "0")
|
||||||
|
message(FATAL_ERROR "windeployqt failed: ${windeployqt_result}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Remove the FFmpeg multimedia plugin as we don't include FFmpeg.
|
||||||
|
# We want to use the Windows media plugin instead, which is also included.
|
||||||
|
file(REMOVE "${executable_parent_dir}/plugins/multimedia/ffmpegmediaplugin.dll")
|
||||||
|
elseif (APPLE)
|
||||||
|
get_filename_component(executable_name "${executable_path}" NAME_WE)
|
||||||
|
find_program(macdeployqt_executable macdeployqt6 PATHS "${QT_HOST_PATH}/bin")
|
||||||
|
|
||||||
|
message(STATUS "Executing macdeployqt at \"${macdeployqt_executable}\" for executable \"${executable_path}\"")
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${macdeployqt_executable}"
|
||||||
|
"${executable_path}"
|
||||||
|
"-executable=${executable_path}/Contents/MacOS/${executable_name}"
|
||||||
|
-always-overwrite
|
||||||
|
RESULT_VARIABLE macdeployqt_result)
|
||||||
|
if (NOT macdeployqt_result EQUAL "0")
|
||||||
|
message(FATAL_ERROR "macdeployqt failed: ${macdeployqt_result}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Bundling libraries can rewrite path information and break code signatures of system libraries.
|
||||||
|
# Perform an ad-hoc re-signing on the whole app bundle to fix this.
|
||||||
|
execute_process(COMMAND codesign --deep -fs - "${executable_path}"
|
||||||
|
RESULT_VARIABLE codesign_result)
|
||||||
|
if (NOT codesign_result EQUAL "0")
|
||||||
|
message(FATAL_ERROR "codesign failed: ${codesign_result}")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unsupported OS for Qt bundling.")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(bundle_appimage bundle_dir executable_path source_path binary_path linuxdeploy_executable enable_qt)
|
||||||
|
get_filename_component(executable_name "${executable_path}" NAME_WE)
|
||||||
|
set(appdir_path "${binary_path}/AppDir-${executable_name}")
|
||||||
|
|
||||||
|
if (enable_qt)
|
||||||
|
# Find qmake to make sure the plugin uses the right version of Qt.
|
||||||
|
find_program(qmake_executable qmake6 PATHS "${QT_HOST_PATH}/bin")
|
||||||
|
|
||||||
|
set(extra_linuxdeploy_env "QMAKE=${qmake_executable}")
|
||||||
|
set(extra_linuxdeploy_args --plugin qt)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Creating AppDir for executable ${executable_path}")
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E env
|
||||||
|
${extra_linuxdeploy_env}
|
||||||
|
"${linuxdeploy_executable}"
|
||||||
|
${extra_linuxdeploy_args}
|
||||||
|
--plugin checkrt
|
||||||
|
--executable "${executable_path}"
|
||||||
|
--icon-file "${source_path}/dist/citra.svg"
|
||||||
|
--desktop-file "${source_path}/dist/${executable_name}.desktop"
|
||||||
|
--appdir "${appdir_path}"
|
||||||
|
RESULT_VARIABLE linuxdeploy_appdir_result)
|
||||||
|
if (NOT linuxdeploy_appdir_result EQUAL "0")
|
||||||
|
message(FATAL_ERROR "linuxdeploy failed to create AppDir: ${linuxdeploy_appdir_result}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (enable_qt)
|
||||||
|
set(qt_hook_file "${appdir_path}/apprun-hooks/linuxdeploy-plugin-qt-hook.sh")
|
||||||
|
file(READ "${qt_hook_file}" qt_hook_contents)
|
||||||
|
# Add Cinnamon to list of DEs for GTK3 theming.
|
||||||
|
string(REPLACE
|
||||||
|
"*XFCE*"
|
||||||
|
"*X-Cinnamon*|*XFCE*"
|
||||||
|
qt_hook_contents "${qt_hook_contents}")
|
||||||
|
# Wayland backend crashes due to changed schemas in Gnome 40.
|
||||||
|
string(REPLACE
|
||||||
|
"export QT_QPA_PLATFORMTHEME=gtk3"
|
||||||
|
"export QT_QPA_PLATFORMTHEME=gtk3; export GDK_BACKEND=x11"
|
||||||
|
qt_hook_contents "${qt_hook_contents}")
|
||||||
|
file(WRITE "${qt_hook_file}" "${qt_hook_contents}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Creating AppImage for executable ${executable_path}")
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E env
|
||||||
|
"OUTPUT=${bundle_dir}/${executable_name}.AppImage"
|
||||||
|
"${linuxdeploy_executable}"
|
||||||
|
--output appimage
|
||||||
|
--appdir "${appdir_path}"
|
||||||
|
RESULT_VARIABLE linuxdeploy_appimage_result)
|
||||||
|
if (NOT linuxdeploy_appimage_result EQUAL "0")
|
||||||
|
message(FATAL_ERROR "linuxdeploy failed to create AppImage: ${linuxdeploy_appimage_result}")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(bundle_standalone executable_path original_executable_path bundle_library_paths)
|
||||||
|
get_filename_component(executable_parent_dir "${executable_path}" DIRECTORY)
|
||||||
|
|
||||||
|
# Resolve dependent library files if they were not passed in.
|
||||||
|
message(STATUS "Determining runtime dependencies of ${executable_path} using library paths ${bundle_library_paths}")
|
||||||
|
file(GET_RUNTIME_DEPENDENCIES
|
||||||
|
EXECUTABLES ${original_executable_path}
|
||||||
|
RESOLVED_DEPENDENCIES_VAR resolved_deps
|
||||||
|
UNRESOLVED_DEPENDENCIES_VAR unresolved_deps
|
||||||
|
DIRECTORIES ${bundle_library_paths}
|
||||||
|
POST_EXCLUDE_REGEXES ".*system32.*")
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
# Same directory since we don't have rpath.
|
||||||
|
set(lib_dir "${executable_parent_dir}")
|
||||||
|
else()
|
||||||
|
set(lib_dir "${executable_parent_dir}/libs")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Copy files to bundled output.
|
||||||
|
if (resolved_deps)
|
||||||
|
file(MAKE_DIRECTORY ${lib_dir})
|
||||||
|
foreach (lib_file IN LISTS resolved_deps)
|
||||||
|
message(STATUS "Bundling library ${lib_file}")
|
||||||
|
symlink_safe_copy("${lib_file}" "${lib_dir}")
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Add libs directory to executable rpath where applicable.
|
||||||
|
if (APPLE)
|
||||||
|
execute_process(COMMAND install_name_tool -add_rpath "@loader_path/libs" "${executable_path}"
|
||||||
|
RESULT_VARIABLE install_name_tool_result)
|
||||||
|
if (NOT install_name_tool_result EQUAL "0")
|
||||||
|
message(FATAL_ERROR "install_name_tool failed: ${install_name_tool_result}")
|
||||||
|
endif()
|
||||||
|
elseif (UNIX)
|
||||||
|
execute_process(COMMAND patchelf --set-rpath '$ORIGIN/../libs' "${executable_path}"
|
||||||
|
RESULT_VARIABLE patchelf_result)
|
||||||
|
if (NOT patchelf_result EQUAL "0")
|
||||||
|
message(FATAL_ERROR "patchelf failed: ${patchelf_result}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# --- Root bundling logic ---
|
||||||
|
|
||||||
|
set(bundle_dir ${BINARY_PATH}/bundle)
|
||||||
|
|
||||||
|
# On Linux, always bundle an AppImage.
|
||||||
|
if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
|
||||||
|
if (IN_PLACE)
|
||||||
|
message(FATAL_ERROR "Cannot bundle for Linux in-place.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
bundle_appimage("${bundle_dir}" "${EXECUTABLE_PATH}" "${SOURCE_PATH}" "${BINARY_PATH}" "${LINUXDEPLOY}" ${BUNDLE_QT})
|
||||||
|
else()
|
||||||
|
if (IN_PLACE)
|
||||||
|
message(STATUS "Bundling dependencies in-place")
|
||||||
|
set(bundled_executable_path "${EXECUTABLE_PATH}")
|
||||||
|
else()
|
||||||
|
message(STATUS "Copying base executable ${EXECUTABLE_PATH} to output directory ${bundle_dir}")
|
||||||
|
file(COPY ${EXECUTABLE_PATH} DESTINATION ${bundle_dir})
|
||||||
|
get_filename_component(bundled_executable_name "${EXECUTABLE_PATH}" NAME)
|
||||||
|
set(bundled_executable_path "${bundle_dir}/${bundled_executable_name}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (BUNDLE_QT)
|
||||||
|
bundle_qt("${bundled_executable_path}")
|
||||||
|
else()
|
||||||
|
bundle_standalone("${bundled_executable_path}" "${EXECUTABLE_PATH}" "${BUNDLE_LIBRARY_PATHS}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
elseif (BUNDLE_TARGET_DOWNLOAD_LINUXDEPLOY)
|
||||||
|
# --- linuxdeploy download logic ---
|
||||||
|
|
||||||
|
# Downloads and extracts a linuxdeploy component.
|
||||||
|
function(download_linuxdeploy_component base_dir name executable_name)
|
||||||
|
set(executable_file "${base_dir}/${executable_name}")
|
||||||
|
if (NOT EXISTS "${executable_file}")
|
||||||
|
message(STATUS "Downloading ${executable_name}")
|
||||||
|
file(DOWNLOAD
|
||||||
|
"https://github.com/${name}/releases/download/continuous/${executable_name}"
|
||||||
|
"${executable_file}" SHOW_PROGRESS)
|
||||||
|
file(CHMOD "${executable_file}" PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
|
||||||
|
|
||||||
|
get_filename_component(executable_ext "${executable_file}" LAST_EXT)
|
||||||
|
if (executable_ext STREQUAL ".AppImage")
|
||||||
|
message(STATUS "Extracting ${executable_name}")
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${executable_file}" --appimage-extract
|
||||||
|
WORKING_DIRECTORY "${base_dir}"
|
||||||
|
RESULT_VARIABLE extract_result)
|
||||||
|
if (NOT extract_result EQUAL "0")
|
||||||
|
message(FATAL_ERROR "AppImage extract failed: ${extract_result}")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(STATUS "Copying ${executable_name}")
|
||||||
|
file(COPY "${executable_file}" DESTINATION "${base_dir}/squashfs-root/usr/bin/")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Download plugins first so they don't overwrite linuxdeploy's AppRun file.
|
||||||
|
download_linuxdeploy_component("${LINUXDEPLOY_PATH}" "linuxdeploy/linuxdeploy-plugin-qt" "linuxdeploy-plugin-qt-${LINUXDEPLOY_ARCH}.AppImage")
|
||||||
|
download_linuxdeploy_component("${LINUXDEPLOY_PATH}" "darealshinji/linuxdeploy-plugin-checkrt" "linuxdeploy-plugin-checkrt.sh")
|
||||||
|
download_linuxdeploy_component("${LINUXDEPLOY_PATH}" "linuxdeploy/linuxdeploy" "linuxdeploy-${LINUXDEPLOY_ARCH}.AppImage")
|
||||||
|
else()
|
||||||
|
# --- Bundling target creation logic ---
|
||||||
|
|
||||||
|
# Creates the base bundle target with common files and pre-bundle steps.
|
||||||
|
function(create_base_bundle_target)
|
||||||
|
message(STATUS "Creating base bundle target")
|
||||||
|
|
||||||
|
add_custom_target(bundle)
|
||||||
|
add_custom_command(
|
||||||
|
TARGET bundle
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bundle/")
|
||||||
|
add_custom_command(
|
||||||
|
TARGET bundle
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bundle/dist/")
|
||||||
|
add_custom_command(
|
||||||
|
TARGET bundle
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/dist/icon.png" "${CMAKE_BINARY_DIR}/bundle/dist/citra.png")
|
||||||
|
add_custom_command(
|
||||||
|
TARGET bundle
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/license.txt" "${CMAKE_BINARY_DIR}/bundle/")
|
||||||
|
add_custom_command(
|
||||||
|
TARGET bundle
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/README.md" "${CMAKE_BINARY_DIR}/bundle/")
|
||||||
|
add_custom_command(
|
||||||
|
TARGET bundle
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/dist/scripting" "${CMAKE_BINARY_DIR}/bundle/scripting")
|
||||||
|
|
||||||
|
# On Linux, add a command to prepare linuxdeploy and any required plugins before any bundling occurs.
|
||||||
|
if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
|
||||||
|
add_custom_command(
|
||||||
|
TARGET bundle
|
||||||
|
COMMAND ${CMAKE_COMMAND}
|
||||||
|
"-DBUNDLE_TARGET_DOWNLOAD_LINUXDEPLOY=1"
|
||||||
|
"-DLINUXDEPLOY_PATH=${CMAKE_BINARY_DIR}/externals/linuxdeploy"
|
||||||
|
"-DLINUXDEPLOY_ARCH=${CMAKE_HOST_SYSTEM_PROCESSOR}"
|
||||||
|
-P "${CMAKE_SOURCE_DIR}/CMakeModules/BundleTarget.cmake"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Adds a target to the bundle target, packing in required libraries.
|
||||||
|
# If in_place is true, the bundling will be done in-place as part of the specified target.
|
||||||
|
function(bundle_target_internal target_name in_place)
|
||||||
|
# Create base bundle target if it does not exist.
|
||||||
|
if (NOT in_place AND NOT TARGET bundle)
|
||||||
|
create_base_bundle_target()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(bundle_executable_path "$<TARGET_FILE:${target_name}>")
|
||||||
|
if (target_name MATCHES ".*qt")
|
||||||
|
set(bundle_qt ON)
|
||||||
|
if (APPLE)
|
||||||
|
# For Qt targets on Apple, expect an app bundle.
|
||||||
|
set(bundle_executable_path "$<TARGET_BUNDLE_DIR:${target_name}>")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(bundle_qt OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Build a list of library search paths from prefix paths.
|
||||||
|
foreach(prefix_path IN LISTS CMAKE_FIND_ROOT_PATH CMAKE_PREFIX_PATH CMAKE_SYSTEM_PREFIX_PATH)
|
||||||
|
if (WIN32)
|
||||||
|
list(APPEND bundle_library_paths "${prefix_path}/bin")
|
||||||
|
endif()
|
||||||
|
list(APPEND bundle_library_paths "${prefix_path}/lib")
|
||||||
|
endforeach()
|
||||||
|
foreach(library_path IN LISTS CMAKE_SYSTEM_LIBRARY_PATH)
|
||||||
|
list(APPEND bundle_library_paths "${library_path}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if (in_place)
|
||||||
|
message(STATUS "Adding in-place bundling to ${target_name}")
|
||||||
|
set(dest_target ${target_name})
|
||||||
|
else()
|
||||||
|
message(STATUS "Adding ${target_name} to bundle target")
|
||||||
|
set(dest_target bundle)
|
||||||
|
add_dependencies(bundle ${target_name})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_custom_command(TARGET ${dest_target} POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND}
|
||||||
|
"-DQT_HOST_PATH=\"${QT_HOST_PATH}\""
|
||||||
|
"-DQT_TARGET_PATH=\"${QT_TARGET_PATH}\""
|
||||||
|
"-DBUNDLE_TARGET_EXECUTE=1"
|
||||||
|
"-DTARGET=${target_name}"
|
||||||
|
"-DSOURCE_PATH=${CMAKE_SOURCE_DIR}"
|
||||||
|
"-DBINARY_PATH=${CMAKE_BINARY_DIR}"
|
||||||
|
"-DEXECUTABLE_PATH=${bundle_executable_path}"
|
||||||
|
"-DBUNDLE_LIBRARY_PATHS=\"${bundle_library_paths}\""
|
||||||
|
"-DBUNDLE_QT=${bundle_qt}"
|
||||||
|
"-DIN_PLACE=${in_place}"
|
||||||
|
"-DLINUXDEPLOY=${CMAKE_BINARY_DIR}/externals/linuxdeploy/squashfs-root/AppRun"
|
||||||
|
-P "${CMAKE_SOURCE_DIR}/CMakeModules/BundleTarget.cmake"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Adds a target to the bundle target, packing in required libraries.
|
||||||
|
function(bundle_target target_name)
|
||||||
|
bundle_target_internal("${target_name}" OFF)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Bundles the target in-place, packing in required libraries.
|
||||||
|
function(bundle_target_in_place target_name)
|
||||||
|
bundle_target_internal("${target_name}" ON)
|
||||||
|
endfunction()
|
||||||
|
endif()
|
|
@ -1,11 +0,0 @@
|
||||||
function(copy_citra_FFmpeg_deps target_dir)
|
|
||||||
include(WindowsCopyFiles)
|
|
||||||
set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
|
|
||||||
windows_copy_files(${target_dir} ${FFMPEG_DIR}/bin ${DLL_DEST}
|
|
||||||
avcodec*.dll
|
|
||||||
avformat*.dll
|
|
||||||
avutil*.dll
|
|
||||||
swresample*.dll
|
|
||||||
swscale*.dll
|
|
||||||
)
|
|
||||||
endfunction(copy_citra_FFmpeg_deps)
|
|
|
@ -1,6 +0,0 @@
|
||||||
function(copy_citra_openssl_deps target_dir)
|
|
||||||
include(WindowsCopyFiles)
|
|
||||||
set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
|
|
||||||
windows_copy_files(${target_dir} ${OPENSSL_DLL_DIR} ${DLL_DEST} libcrypto-1_1-x64.dll)
|
|
||||||
windows_copy_files(${target_dir} ${OPENSSL_DLL_DIR} ${DLL_DEST} libssl-1_1-x64.dll)
|
|
||||||
endfunction(copy_citra_openssl_deps)
|
|
|
@ -1,46 +0,0 @@
|
||||||
function(copy_citra_Qt6_deps target_dir)
|
|
||||||
include(WindowsCopyFiles)
|
|
||||||
set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
|
|
||||||
set(Qt6_DLL_DIR "${Qt6_DIR}/../../../bin")
|
|
||||||
set(Qt6_PLATFORMS_DIR "${Qt6_DIR}/../../../plugins/platforms/")
|
|
||||||
set(Qt6_MULTIMEDIA_DIR "${Qt6_DIR}/../../../plugins/multimedia/")
|
|
||||||
set(Qt6_STYLES_DIR "${Qt6_DIR}/../../../plugins/styles/")
|
|
||||||
set(Qt6_IMAGEFORMATS_DIR "${Qt6_DIR}/../../../plugins/imageformats/")
|
|
||||||
set(PLATFORMS ${DLL_DEST}plugins/platforms/)
|
|
||||||
set(MULTIMEDIA ${DLL_DEST}plugins/multimedia/)
|
|
||||||
set(STYLES ${DLL_DEST}plugins/styles/)
|
|
||||||
set(IMAGEFORMATS ${DLL_DEST}plugins/imageformats/)
|
|
||||||
windows_copy_files(${target_dir} ${Qt6_DLL_DIR} ${DLL_DEST}
|
|
||||||
icudt*.dll
|
|
||||||
icuin*.dll
|
|
||||||
icuuc*.dll
|
|
||||||
Qt6Core$<$<CONFIG:Debug>:d>.*
|
|
||||||
Qt6Gui$<$<CONFIG:Debug>:d>.*
|
|
||||||
Qt6Widgets$<$<CONFIG:Debug>:d>.*
|
|
||||||
Qt6Concurrent$<$<CONFIG:Debug>:d>.*
|
|
||||||
Qt6Multimedia$<$<CONFIG:Debug>:d>.*
|
|
||||||
Qt6Network$<$<CONFIG:Debug>:d>.*
|
|
||||||
)
|
|
||||||
windows_copy_files(citra-qt ${Qt6_PLATFORMS_DIR} ${PLATFORMS} qwindows$<$<CONFIG:Debug>:d>.*)
|
|
||||||
windows_copy_files(citra-qt ${Qt6_MULTIMEDIA_DIR} ${MULTIMEDIA}
|
|
||||||
windowsmediaplugin$<$<CONFIG:Debug>:d>.*
|
|
||||||
)
|
|
||||||
windows_copy_files(citra-qt ${Qt6_STYLES_DIR} ${STYLES} qwindowsvistastyle$<$<CONFIG:Debug>:d>.*)
|
|
||||||
windows_copy_files(${target_dir} ${Qt6_IMAGEFORMATS_DIR} ${IMAGEFORMATS}
|
|
||||||
qgif$<$<CONFIG:Debug>:d>.dll
|
|
||||||
qicns$<$<CONFIG:Debug>:d>.dll
|
|
||||||
qico$<$<CONFIG:Debug>:d>.dll
|
|
||||||
qjpeg$<$<CONFIG:Debug>:d>.dll
|
|
||||||
qsvg$<$<CONFIG:Debug>:d>.dll
|
|
||||||
qtga$<$<CONFIG:Debug>:d>.dll
|
|
||||||
qtiff$<$<CONFIG:Debug>:d>.dll
|
|
||||||
qwbmp$<$<CONFIG:Debug>:d>.dll
|
|
||||||
qwebp$<$<CONFIG:Debug>:d>.dll
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create an empty qt.conf file. Qt will detect that this file exists, and use the folder that its in as the root folder.
|
|
||||||
# This way it'll look for plugins in the root/plugins/ folder
|
|
||||||
add_custom_command(TARGET citra-qt POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E touch ${DLL_DEST}qt.conf
|
|
||||||
)
|
|
||||||
endfunction(copy_citra_Qt6_deps)
|
|
|
@ -1,96 +1,196 @@
|
||||||
|
|
||||||
# This function downloads a binary library package from our external repo.
|
set(CURRENT_MODULE_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||||
# Params:
|
|
||||||
# remote_path: path to the file to download, relative to the remote repository root
|
|
||||||
# prefix_var: name of a variable which will be set with the path to the extracted contents
|
|
||||||
function(download_bundled_external remote_path lib_name prefix_var)
|
|
||||||
get_external_prefix(${lib_name} prefix)
|
|
||||||
if (NOT EXISTS "${prefix}")
|
|
||||||
message(STATUS "Downloading binaries for ${lib_name}...")
|
|
||||||
|
|
||||||
if (WIN32)
|
# Determines parameters based on the host and target for downloading the right Qt binaries.
|
||||||
set(repo_base "ext-windows-bin/raw/master")
|
function(determine_qt_parameters target host_out type_out arch_out arch_path_out host_type_out host_arch_out host_arch_path_out)
|
||||||
elseif (APPLE)
|
if (target MATCHES "tools_.*")
|
||||||
set(repo_base "ext-macos-bin/raw/main")
|
set(tool ON)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Bundled libraries are unsupported for this OS.")
|
set(tool OFF)
|
||||||
endif()
|
|
||||||
|
|
||||||
file(DOWNLOAD
|
|
||||||
https://github.com/citra-emu/${repo_base}/${remote_path}${lib_name}.7z
|
|
||||||
"${CMAKE_BINARY_DIR}/externals/${lib_name}.7z" SHOW_PROGRESS)
|
|
||||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${CMAKE_BINARY_DIR}/externals/${lib_name}.7z"
|
|
||||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# For packages that include the /usr/local prefix, include it in the prefix path.
|
|
||||||
if (EXISTS "${prefix}/usr/local")
|
|
||||||
set(prefix "${prefix}/usr/local")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message(STATUS "Using bundled binaries at ${prefix}")
|
|
||||||
set(${prefix_var} "${prefix}" PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# This function downloads Qt using aqt.
|
|
||||||
# Params:
|
|
||||||
# target: Qt dependency to install. Specify a version number to download Qt, or "tools_(name)" for a specific build tool.
|
|
||||||
# prefix_var: Name of a variable which will be set with the path to the extracted contents.
|
|
||||||
function(download_qt_external target prefix_var)
|
|
||||||
# Determine installation parameters for OS, architecture, and compiler
|
# Determine installation parameters for OS, architecture, and compiler
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
set(host "windows")
|
set(host "windows")
|
||||||
if (MINGW)
|
set(type "desktop")
|
||||||
set(arch_path "mingw81")
|
|
||||||
elseif ((MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1940) AND "x86_64" IN_LIST ARCHITECTURE)
|
if (NOT tool)
|
||||||
if ("arm64" IN_LIST ARCHITECTURE)
|
if (MINGW)
|
||||||
set(arch_path "msvc2019_arm64")
|
set(arch "win64_mingw")
|
||||||
elseif ("x86_64" IN_LIST ARCHITECTURE)
|
set(arch_path "mingw_64")
|
||||||
set(arch_path "msvc2019_64")
|
elseif (MSVC)
|
||||||
|
if ("arm64" IN_LIST ARCHITECTURE)
|
||||||
|
set(arch_path "msvc2019_arm64")
|
||||||
|
elseif ("x86_64" IN_LIST ARCHITECTURE)
|
||||||
|
set(arch_path "msvc2019_64")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unsupported bundled Qt architecture. Enable USE_SYSTEM_QT and provide your own.")
|
||||||
|
endif()
|
||||||
|
set(arch "win64_${arch_path}")
|
||||||
|
|
||||||
|
# In case we're cross-compiling, prepare to also fetch the correct host Qt tools.
|
||||||
|
if (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "AMD64")
|
||||||
|
set(host_arch_path "msvc2019_64")
|
||||||
|
elseif (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "ARM64")
|
||||||
|
# TODO: msvc2019_arm64 doesn't include some of the required tools for some reason,
|
||||||
|
# TODO: so until it does, just use msvc2019_64 under x86_64 emulation.
|
||||||
|
# set(host_arch_path "msvc2019_arm64")
|
||||||
|
set(host_arch_path "msvc2019_64")
|
||||||
|
endif()
|
||||||
|
set(host_arch "win64_${host_arch_path}")
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Unsupported bundled Qt architecture. Disable CITRA_USE_BUNDLED_QT and provide your own.")
|
message(FATAL_ERROR "Unsupported bundled Qt toolchain. Enable USE_SYSTEM_QT and provide your own.")
|
||||||
endif()
|
endif()
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "Unsupported bundled Qt toolchain. Disable CITRA_USE_BUNDLED_QT and provide your own.")
|
|
||||||
endif()
|
endif()
|
||||||
set(arch "win64_${arch_path}")
|
|
||||||
elseif (APPLE)
|
elseif (APPLE)
|
||||||
set(host "mac")
|
set(host "mac")
|
||||||
|
set(type "desktop")
|
||||||
set(arch "clang_64")
|
set(arch "clang_64")
|
||||||
set(arch_path "macos")
|
set(arch_path "macos")
|
||||||
|
|
||||||
|
if (IOS AND NOT tool)
|
||||||
|
set(host_type "${type}")
|
||||||
|
set(host_arch "${arch}")
|
||||||
|
set(host_arch_path "${arch_path}")
|
||||||
|
|
||||||
|
set(type "ios")
|
||||||
|
set(arch "ios")
|
||||||
|
set(arch_path "ios")
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
set(host "linux")
|
set(host "linux")
|
||||||
|
set(type "desktop")
|
||||||
set(arch "gcc_64")
|
set(arch "gcc_64")
|
||||||
set(arch_path "linux")
|
set(arch_path "linux")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
get_external_prefix(qt base_path)
|
set(${host_out} "${host}" PARENT_SCOPE)
|
||||||
|
set(${type_out} "${type}" PARENT_SCOPE)
|
||||||
|
set(${arch_out} "${arch}" PARENT_SCOPE)
|
||||||
|
set(${arch_path_out} "${arch_path}" PARENT_SCOPE)
|
||||||
|
if (DEFINED host_type)
|
||||||
|
set(${host_type_out} "${host_type}" PARENT_SCOPE)
|
||||||
|
else()
|
||||||
|
set(${host_type_out} "${type}" PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
if (DEFINED host_arch)
|
||||||
|
set(${host_arch_out} "${host_arch}" PARENT_SCOPE)
|
||||||
|
else()
|
||||||
|
set(${host_arch_out} "${arch}" PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
if (DEFINED host_arch_path)
|
||||||
|
set(${host_arch_path_out} "${host_arch_path}" PARENT_SCOPE)
|
||||||
|
else()
|
||||||
|
set(${host_arch_path_out} "${arch_path}" PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Download Qt binaries for a specifc configuration.
|
||||||
|
function(download_qt_configuration prefix_out target host type arch arch_path base_path)
|
||||||
if (target MATCHES "tools_.*")
|
if (target MATCHES "tools_.*")
|
||||||
set(prefix "${base_path}")
|
set(tool ON)
|
||||||
set(install_args install-tool --outputdir ${base_path} ${host} desktop ${target})
|
else()
|
||||||
|
set(tool OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(install_args -c "${CURRENT_MODULE_DIR}/aqt_config.ini")
|
||||||
|
if (tool)
|
||||||
|
set(prefix "${base_path}/Tools")
|
||||||
|
set(install_args ${install_args} install-tool --outputdir ${base_path} ${host} desktop ${target})
|
||||||
else()
|
else()
|
||||||
set(prefix "${base_path}/${target}/${arch_path}")
|
set(prefix "${base_path}/${target}/${arch_path}")
|
||||||
set(install_args install-qt --outputdir ${base_path} ${host} desktop ${target} ${arch} -m qtmultimedia)
|
set(install_args ${install_args} install-qt --outputdir ${base_path} ${host} ${type} ${target} ${arch}
|
||||||
|
-m qtmultimedia --archives qttranslations qttools qtsvg qtbase)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT EXISTS "${prefix}")
|
if (NOT EXISTS "${prefix}")
|
||||||
message(STATUS "Downloading binaries for Qt...")
|
message(STATUS "Downloading Qt binaries for ${target}:${host}:${type}:${arch}:${arch_path}")
|
||||||
|
set(AQT_PREBUILD_BASE_URL "https://github.com/miurahr/aqtinstall/releases/download/v3.1.9")
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
set(aqt_path "${CMAKE_BINARY_DIR}/externals/aqt.exe")
|
set(aqt_path "${base_path}/aqt.exe")
|
||||||
file(DOWNLOAD
|
if (NOT EXISTS "${aqt_path}")
|
||||||
https://github.com/miurahr/aqtinstall/releases/download/v3.1.4/aqt.exe
|
file(DOWNLOAD
|
||||||
${aqt_path} SHOW_PROGRESS)
|
${AQT_PREBUILD_BASE_URL}/aqt.exe
|
||||||
execute_process(COMMAND ${aqt_path} ${install_args})
|
${aqt_path} SHOW_PROGRESS)
|
||||||
|
endif()
|
||||||
|
execute_process(COMMAND ${aqt_path} ${install_args}
|
||||||
|
WORKING_DIRECTORY ${base_path})
|
||||||
|
elseif (APPLE)
|
||||||
|
set(aqt_path "${base_path}/aqt-macos")
|
||||||
|
if (NOT EXISTS "${aqt_path}")
|
||||||
|
file(DOWNLOAD
|
||||||
|
${AQT_PREBUILD_BASE_URL}/aqt-macos
|
||||||
|
${aqt_path} SHOW_PROGRESS)
|
||||||
|
endif()
|
||||||
|
execute_process(COMMAND chmod +x ${aqt_path})
|
||||||
|
execute_process(COMMAND ${aqt_path} ${install_args}
|
||||||
|
WORKING_DIRECTORY ${base_path})
|
||||||
else()
|
else()
|
||||||
# aqt does not offer binary releases for other platforms, so download and run from pip.
|
# aqt does not offer binary releases for other platforms, so download and run from pip.
|
||||||
set(aqt_install_path "${CMAKE_BINARY_DIR}/externals/aqt")
|
set(aqt_install_path "${base_path}/aqt")
|
||||||
execute_process(COMMAND python3 -m pip install --target=${aqt_install_path} aqtinstall)
|
file(MAKE_DIRECTORY "${aqt_install_path}")
|
||||||
execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${aqt_install_path} python3 -m aqt ${install_args})
|
|
||||||
|
execute_process(COMMAND python3 -m pip install --target=${aqt_install_path} aqtinstall
|
||||||
|
WORKING_DIRECTORY ${base_path})
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${aqt_install_path} python3 -m aqt ${install_args}
|
||||||
|
WORKING_DIRECTORY ${base_path})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Downloaded Qt binaries for ${target}:${host}:${type}:${arch}:${arch_path} to ${prefix}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
message(STATUS "Using downloaded Qt binaries at ${prefix}")
|
set(${prefix_out} "${prefix}" PARENT_SCOPE)
|
||||||
set(${prefix_var} "${prefix}" PARENT_SCOPE)
|
endfunction()
|
||||||
|
|
||||||
|
# This function downloads Qt using aqt.
|
||||||
|
# The path of the downloaded content will be added to the CMAKE_PREFIX_PATH.
|
||||||
|
# QT_TARGET_PATH is set to the Qt for the compile target platform.
|
||||||
|
# QT_HOST_PATH is set to a host-compatible Qt, for running tools.
|
||||||
|
# Params:
|
||||||
|
# target: Qt dependency to install. Specify a version number to download Qt, or "tools_(name)" for a specific build tool.
|
||||||
|
function(download_qt target)
|
||||||
|
determine_qt_parameters("${target}" host type arch arch_path host_type host_arch host_arch_path)
|
||||||
|
|
||||||
|
get_external_prefix(qt base_path)
|
||||||
|
file(MAKE_DIRECTORY "${base_path}")
|
||||||
|
|
||||||
|
download_qt_configuration(prefix "${target}" "${host}" "${type}" "${arch}" "${arch_path}" "${base_path}")
|
||||||
|
if (DEFINED host_arch_path AND NOT "${host_arch_path}" STREQUAL "${arch_path}")
|
||||||
|
download_qt_configuration(host_prefix "${target}" "${host}" "${host_type}" "${host_arch}" "${host_arch_path}" "${base_path}")
|
||||||
|
else()
|
||||||
|
set(host_prefix "${prefix}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(QT_TARGET_PATH "${prefix}" CACHE STRING "")
|
||||||
|
set(QT_HOST_PATH "${host_prefix}" CACHE STRING "")
|
||||||
|
|
||||||
|
# Add the target Qt prefix path so CMake can locate it.
|
||||||
|
list(APPEND CMAKE_PREFIX_PATH "${prefix}")
|
||||||
|
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(download_moltenvk)
|
||||||
|
if (IOS)
|
||||||
|
set(MOLTENVK_PLATFORM "iOS")
|
||||||
|
else()
|
||||||
|
set(MOLTENVK_PLATFORM "macOS")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(MOLTENVK_DIR "${CMAKE_BINARY_DIR}/externals/MoltenVK")
|
||||||
|
set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar")
|
||||||
|
if (NOT EXISTS ${MOLTENVK_DIR})
|
||||||
|
if (NOT EXISTS ${MOLTENVK_TAR})
|
||||||
|
file(DOWNLOAD https://github.com/KhronosGroup/MoltenVK/releases/download/v1.2.7-rc2/MoltenVK-all.tar
|
||||||
|
${MOLTENVK_TAR} SHOW_PROGRESS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${MOLTENVK_TAR}"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Add the MoltenVK library path to the prefix so find_library can locate it.
|
||||||
|
list(APPEND CMAKE_PREFIX_PATH "${MOLTENVK_DIR}/MoltenVK/dylib/${MOLTENVK_PLATFORM}")
|
||||||
|
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(get_external_prefix lib_name prefix_var)
|
function(get_external_prefix lib_name prefix_var)
|
||||||
|
|
65
CMakeModules/GenerateBuildInfo.cmake
Normal file
65
CMakeModules/GenerateBuildInfo.cmake
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
# Gets a UTC timstamp and sets the provided variable to it
|
||||||
|
function(get_timestamp _var)
|
||||||
|
string(TIMESTAMP timestamp UTC)
|
||||||
|
set(${_var} "${timestamp}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
get_timestamp(BUILD_DATE)
|
||||||
|
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${SRC_DIR}/externals/cmake-modules")
|
||||||
|
|
||||||
|
if (EXISTS "${SRC_DIR}/.git/objects")
|
||||||
|
# Find the package here with the known path so that the GetGit commands can find it as well
|
||||||
|
find_package(Git QUIET PATHS "${GIT_EXECUTABLE}")
|
||||||
|
|
||||||
|
# only use Git to check revision info when source is obtained via Git
|
||||||
|
include(GetGitRevisionDescription)
|
||||||
|
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
||||||
|
git_describe(GIT_DESC --always --long --dirty)
|
||||||
|
git_branch_name(GIT_BRANCH)
|
||||||
|
elseif (EXISTS "${SRC_DIR}/GIT-COMMIT" AND EXISTS "${SRC_DIR}/GIT-TAG")
|
||||||
|
# unified source archive
|
||||||
|
file(READ "${SRC_DIR}/GIT-COMMIT" GIT_REV_RAW LIMIT 64)
|
||||||
|
string(STRIP "${GIT_REV_RAW}" GIT_REV)
|
||||||
|
string(SUBSTRING "${GIT_REV_RAW}" 0 9 GIT_DESC)
|
||||||
|
set(GIT_BRANCH "HEAD")
|
||||||
|
else()
|
||||||
|
# self-packed archive?
|
||||||
|
set(GIT_REV "UNKNOWN")
|
||||||
|
set(GIT_DESC "UNKNOWN")
|
||||||
|
set(GIT_BRANCH "UNKNOWN")
|
||||||
|
endif()
|
||||||
|
string(SUBSTRING "${GIT_REV}" 0 7 GIT_SHORT_REV)
|
||||||
|
|
||||||
|
# Generate cpp with Git revision from template
|
||||||
|
# Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well
|
||||||
|
set(REPO_NAME "")
|
||||||
|
set(BUILD_VERSION "0")
|
||||||
|
set(BUILD_FULLNAME "${GIT_SHORT_REV}")
|
||||||
|
if (DEFINED ENV{CI})
|
||||||
|
if (DEFINED ENV{GITHUB_ACTIONS})
|
||||||
|
set(BUILD_REPOSITORY $ENV{GITHUB_REPOSITORY})
|
||||||
|
set(BUILD_TAG $ENV{GITHUB_REF_NAME})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# regex capture the string nightly or canary into CMAKE_MATCH_1
|
||||||
|
string(REGEX MATCH "citra-emu/citra-?(.*)" OUTVAR ${BUILD_REPOSITORY})
|
||||||
|
if ("${CMAKE_MATCH_COUNT}" GREATER 0)
|
||||||
|
# capitalize the first letter of each word in the repo name.
|
||||||
|
string(REPLACE "-" ";" REPO_NAME_LIST ${CMAKE_MATCH_1})
|
||||||
|
foreach(WORD ${REPO_NAME_LIST})
|
||||||
|
string(SUBSTRING ${WORD} 0 1 FIRST_LETTER)
|
||||||
|
string(SUBSTRING ${WORD} 1 -1 REMAINDER)
|
||||||
|
string(TOUPPER ${FIRST_LETTER} FIRST_LETTER)
|
||||||
|
set(REPO_NAME "${REPO_NAME}${FIRST_LETTER}${REMAINDER}")
|
||||||
|
endforeach()
|
||||||
|
string(REGEX MATCH "${CMAKE_MATCH_1}-([0-9]+)" OUTVAR ${BUILD_TAG})
|
||||||
|
if (${CMAKE_MATCH_COUNT} GREATER 0)
|
||||||
|
set(BUILD_VERSION ${CMAKE_MATCH_1})
|
||||||
|
endif()
|
||||||
|
if (BUILD_VERSION)
|
||||||
|
set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION}")
|
||||||
|
else()
|
||||||
|
set(BUILD_FULLNAME "")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
|
@ -1,79 +1,39 @@
|
||||||
# Gets a UTC timstamp and sets the provided variable to it
|
list(APPEND CMAKE_MODULE_PATH "${SRC_DIR}/CMakeModules")
|
||||||
function(get_timestamp _var)
|
include(GenerateBuildInfo)
|
||||||
string(TIMESTAMP timestamp UTC)
|
|
||||||
set(${_var} "${timestamp}" PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${SRC_DIR}/externals/cmake-modules")
|
|
||||||
|
|
||||||
# Find the package here with the known path so that the GetGit commands can find it as well
|
|
||||||
find_package(Git QUIET PATHS "${GIT_EXECUTABLE}")
|
|
||||||
|
|
||||||
# generate git/build information
|
|
||||||
include(GetGitRevisionDescription)
|
|
||||||
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
|
||||||
git_describe(GIT_DESC --always --long --dirty)
|
|
||||||
git_branch_name(GIT_BRANCH)
|
|
||||||
get_timestamp(BUILD_DATE)
|
|
||||||
|
|
||||||
# Generate cpp with Git revision from template
|
|
||||||
# Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well
|
|
||||||
set(REPO_NAME "")
|
|
||||||
set(BUILD_VERSION "0")
|
|
||||||
if (DEFINED ENV{CI})
|
|
||||||
if (DEFINED ENV{GITHUB_ACTIONS})
|
|
||||||
set(BUILD_REPOSITORY $ENV{GITHUB_REPOSITORY})
|
|
||||||
set(BUILD_TAG $ENV{GITHUB_REF_NAME})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# regex capture the string nightly or canary into CMAKE_MATCH_1
|
|
||||||
string(REGEX MATCH "citra-emu/citra-?(.*)" OUTVAR ${BUILD_REPOSITORY})
|
|
||||||
if ("${CMAKE_MATCH_COUNT}" GREATER 0)
|
|
||||||
# capitalize the first letter of each word in the repo name.
|
|
||||||
string(REPLACE "-" ";" REPO_NAME_LIST ${CMAKE_MATCH_1})
|
|
||||||
foreach(WORD ${REPO_NAME_LIST})
|
|
||||||
string(SUBSTRING ${WORD} 0 1 FIRST_LETTER)
|
|
||||||
string(SUBSTRING ${WORD} 1 -1 REMAINDER)
|
|
||||||
string(TOUPPER ${FIRST_LETTER} FIRST_LETTER)
|
|
||||||
set(REPO_NAME "${REPO_NAME}${FIRST_LETTER}${REMAINDER}")
|
|
||||||
endforeach()
|
|
||||||
string(REGEX MATCH "${CMAKE_MATCH_1}-([0-9]+)" OUTVAR ${BUILD_TAG})
|
|
||||||
if (${CMAKE_MATCH_COUNT} GREATER 0)
|
|
||||||
set(BUILD_VERSION ${CMAKE_MATCH_1})
|
|
||||||
endif()
|
|
||||||
if (BUILD_VERSION)
|
|
||||||
# This leaves a trailing space on the last word, but we actually want that
|
|
||||||
# because of how it's styled in the title bar.
|
|
||||||
set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION} ")
|
|
||||||
else()
|
|
||||||
set(BUILD_FULLNAME "")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# The variable SRC_DIR must be passed into the script (since it uses the current build directory for all values of CMAKE_*_DIR)
|
# The variable SRC_DIR must be passed into the script (since it uses the current build directory for all values of CMAKE_*_DIR)
|
||||||
set(VIDEO_CORE "${SRC_DIR}/src/video_core")
|
set(VIDEO_CORE "${SRC_DIR}/src/video_core")
|
||||||
set(HASH_FILES
|
set(HASH_FILES
|
||||||
"${VIDEO_CORE}/renderer_opengl/gl_shader_decompiler.cpp"
|
|
||||||
"${VIDEO_CORE}/renderer_opengl/gl_shader_decompiler.h"
|
|
||||||
"${VIDEO_CORE}/renderer_opengl/gl_shader_disk_cache.cpp"
|
"${VIDEO_CORE}/renderer_opengl/gl_shader_disk_cache.cpp"
|
||||||
"${VIDEO_CORE}/renderer_opengl/gl_shader_disk_cache.h"
|
"${VIDEO_CORE}/renderer_opengl/gl_shader_disk_cache.h"
|
||||||
"${VIDEO_CORE}/renderer_opengl/gl_shader_gen.cpp"
|
|
||||||
"${VIDEO_CORE}/renderer_opengl/gl_shader_gen.h"
|
|
||||||
"${VIDEO_CORE}/renderer_opengl/gl_shader_util.cpp"
|
"${VIDEO_CORE}/renderer_opengl/gl_shader_util.cpp"
|
||||||
"${VIDEO_CORE}/renderer_opengl/gl_shader_util.h"
|
"${VIDEO_CORE}/renderer_opengl/gl_shader_util.h"
|
||||||
|
"${VIDEO_CORE}/renderer_vulkan/vk_shader_util.cpp"
|
||||||
|
"${VIDEO_CORE}/renderer_vulkan/vk_shader_util.h"
|
||||||
|
"${VIDEO_CORE}/shader/generator/glsl_fs_shader_gen.cpp"
|
||||||
|
"${VIDEO_CORE}/shader/generator/glsl_fs_shader_gen.h"
|
||||||
|
"${VIDEO_CORE}/shader/generator/glsl_shader_decompiler.cpp"
|
||||||
|
"${VIDEO_CORE}/shader/generator/glsl_shader_decompiler.h"
|
||||||
|
"${VIDEO_CORE}/shader/generator/glsl_shader_gen.cpp"
|
||||||
|
"${VIDEO_CORE}/shader/generator/glsl_shader_gen.h"
|
||||||
|
"${VIDEO_CORE}/shader/generator/pica_fs_config.cpp"
|
||||||
|
"${VIDEO_CORE}/shader/generator/pica_fs_config.h"
|
||||||
|
"${VIDEO_CORE}/shader/generator/shader_gen.cpp"
|
||||||
|
"${VIDEO_CORE}/shader/generator/shader_gen.h"
|
||||||
|
"${VIDEO_CORE}/shader/generator/shader_uniforms.cpp"
|
||||||
|
"${VIDEO_CORE}/shader/generator/shader_uniforms.h"
|
||||||
|
"${VIDEO_CORE}/shader/generator/spv_fs_shader_gen.cpp"
|
||||||
|
"${VIDEO_CORE}/shader/generator/spv_fs_shader_gen.h"
|
||||||
"${VIDEO_CORE}/shader/shader.cpp"
|
"${VIDEO_CORE}/shader/shader.cpp"
|
||||||
"${VIDEO_CORE}/shader/shader.h"
|
"${VIDEO_CORE}/shader/shader.h"
|
||||||
"${VIDEO_CORE}/pica.cpp"
|
"${VIDEO_CORE}/pica/regs_framebuffer.h"
|
||||||
"${VIDEO_CORE}/pica.h"
|
"${VIDEO_CORE}/pica/regs_lighting.h"
|
||||||
"${VIDEO_CORE}/regs_framebuffer.h"
|
"${VIDEO_CORE}/pica/regs_pipeline.h"
|
||||||
"${VIDEO_CORE}/regs_lighting.h"
|
"${VIDEO_CORE}/pica/regs_rasterizer.h"
|
||||||
"${VIDEO_CORE}/regs_pipeline.h"
|
"${VIDEO_CORE}/pica/regs_shader.h"
|
||||||
"${VIDEO_CORE}/regs_rasterizer.h"
|
"${VIDEO_CORE}/pica/regs_texturing.h"
|
||||||
"${VIDEO_CORE}/regs_shader.h"
|
"${VIDEO_CORE}/pica/regs_internal.cpp"
|
||||||
"${VIDEO_CORE}/regs_texturing.h"
|
"${VIDEO_CORE}/pica/regs_internal.h"
|
||||||
"${VIDEO_CORE}/regs.cpp"
|
|
||||||
"${VIDEO_CORE}/regs.h"
|
|
||||||
)
|
)
|
||||||
set(COMBINED "")
|
set(COMBINED "")
|
||||||
foreach (F IN LISTS HASH_FILES)
|
foreach (F IN LISTS HASH_FILES)
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
# buildcache wrapper
|
|
||||||
OPTION(CITRA_USE_CCACHE "Use buildcache for compilation" OFF)
|
|
||||||
IF(CITRA_USE_CCACHE)
|
|
||||||
FIND_PROGRAM(CCACHE buildcache)
|
|
||||||
IF (CCACHE)
|
|
||||||
MESSAGE(STATUS "Using buildcache found in PATH")
|
|
||||||
SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE})
|
|
||||||
SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE})
|
|
||||||
ELSE(CCACHE)
|
|
||||||
MESSAGE(WARNING "CITRA_USE_CCACHE enabled, but no buildcache executable found")
|
|
||||||
ENDIF(CCACHE)
|
|
||||||
ENDIF(CITRA_USE_CCACHE)
|
|
|
@ -1,52 +0,0 @@
|
||||||
SET(MINGW_PREFIX /usr/x86_64-w64-mingw32/)
|
|
||||||
SET(CMAKE_SYSTEM_NAME Windows)
|
|
||||||
SET(CMAKE_SYSTEM_PROCESSOR x86_64)
|
|
||||||
|
|
||||||
|
|
||||||
SET(CMAKE_FIND_ROOT_PATH ${MINGW_PREFIX})
|
|
||||||
SET(SDL2_PATH ${MINGW_PREFIX})
|
|
||||||
SET(MINGW_TOOL_PREFIX ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32-)
|
|
||||||
|
|
||||||
# Specify the cross compiler
|
|
||||||
SET(CMAKE_C_COMPILER ${MINGW_TOOL_PREFIX}gcc)
|
|
||||||
SET(CMAKE_CXX_COMPILER ${MINGW_TOOL_PREFIX}g++)
|
|
||||||
SET(CMAKE_RC_COMPILER ${MINGW_TOOL_PREFIX}windres)
|
|
||||||
|
|
||||||
# Mingw tools
|
|
||||||
SET(STRIP ${MINGW_TOOL_PREFIX}strip)
|
|
||||||
SET(WINDRES ${MINGW_TOOL_PREFIX}windres)
|
|
||||||
SET(ENV{PKG_CONFIG} ${MINGW_TOOL_PREFIX}pkg-config)
|
|
||||||
|
|
||||||
# ccache wrapper
|
|
||||||
OPTION(CITRA_USE_CCACHE "Use ccache for compilation" OFF)
|
|
||||||
IF(CITRA_USE_CCACHE)
|
|
||||||
FIND_PROGRAM(CCACHE ccache)
|
|
||||||
IF (CCACHE)
|
|
||||||
MESSAGE(STATUS "Using ccache found in PATH")
|
|
||||||
SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE})
|
|
||||||
SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE})
|
|
||||||
ELSE(CCACHE)
|
|
||||||
MESSAGE(WARNING "CITRA_USE_CCACHE enabled, but no ccache found")
|
|
||||||
ENDIF(CCACHE)
|
|
||||||
ENDIF(CITRA_USE_CCACHE)
|
|
||||||
|
|
||||||
# Search for programs in the build host directories
|
|
||||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
|
||||||
|
|
||||||
|
|
||||||
# Echo modified cmake vars to screen for debugging purposes
|
|
||||||
IF(NOT DEFINED ENV{MINGW_DEBUG_INFO})
|
|
||||||
MESSAGE("")
|
|
||||||
MESSAGE("Custom cmake vars: (blank = system default)")
|
|
||||||
MESSAGE("-----------------------------------------")
|
|
||||||
MESSAGE("* CMAKE_C_COMPILER : ${CMAKE_C_COMPILER}")
|
|
||||||
MESSAGE("* CMAKE_CXX_COMPILER : ${CMAKE_CXX_COMPILER}")
|
|
||||||
MESSAGE("* CMAKE_RC_COMPILER : ${CMAKE_RC_COMPILER}")
|
|
||||||
MESSAGE("* WINDRES : ${WINDRES}")
|
|
||||||
MESSAGE("* ENV{PKG_CONFIG} : $ENV{PKG_CONFIG}")
|
|
||||||
MESSAGE("* STRIP : ${STRIP}")
|
|
||||||
MESSAGE("* CITRA_USE_CCACHE : ${CITRA_USE_CCACHE}")
|
|
||||||
MESSAGE("")
|
|
||||||
# So that the debug info only appears once
|
|
||||||
SET(ENV{MINGW_DEBUG_INFO} SHOWN)
|
|
||||||
ENDIF()
|
|
29
CMakeModules/aqt_config.ini
Normal file
29
CMakeModules/aqt_config.ini
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
[aqt]
|
||||||
|
concurrency: 2
|
||||||
|
|
||||||
|
[mirrors]
|
||||||
|
trusted_mirrors:
|
||||||
|
https://download.qt.io
|
||||||
|
blacklist:
|
||||||
|
https://qt.mirror.constant.com
|
||||||
|
https://mirrors.ocf.berkeley.edu
|
||||||
|
https://mirrors.ustc.edu.cn
|
||||||
|
https://mirrors.tuna.tsinghua.edu.cn
|
||||||
|
https://mirrors.geekpie.club
|
||||||
|
https://mirrors-wan.geekpie.club
|
||||||
|
https://mirrors.sjtug.sjtu.edu.cn
|
||||||
|
fallbacks:
|
||||||
|
https://qtproject.mirror.liquidtelecom.com/
|
||||||
|
https://mirrors.aliyun.com/qt/
|
||||||
|
https://ftp.jaist.ac.jp/pub/qtproject/
|
||||||
|
https://ftp.yz.yamagata-u.ac.jp/pub/qtproject/
|
||||||
|
https://qt-mirror.dannhauer.de/
|
||||||
|
https://ftp.fau.de/qtproject/
|
||||||
|
https://mirror.netcologne.de/qtproject/
|
||||||
|
https://mirrors.dotsrc.org/qtproject/
|
||||||
|
https://www.nic.funet.fi/pub/mirrors/download.qt-project.org/
|
||||||
|
https://master.qt.io/
|
||||||
|
https://mirrors.ukfast.co.uk/sites/qt.io/
|
||||||
|
https://ftp2.nluug.nl/languages/qt/
|
||||||
|
https://ftp1.nluug.nl/languages/qt/
|
||||||
|
|
84
dist/apple/Info.plist.in
vendored
Normal file
84
dist/apple/Info.plist.in
vendored
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
<?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>
|
||||||
|
<!-- Templated data -->
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||||
|
<key>CFBundleLongVersionString</key>
|
||||||
|
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||||
|
<key>CFBundleGetInfoString</key>
|
||||||
|
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
||||||
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
|
||||||
|
<!-- Fixed -->
|
||||||
|
<key>LSApplicationCategoryType</key>
|
||||||
|
<string>public.app-category.games</string>
|
||||||
|
<key>CFBundleDocumentTypes</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleTypeExtensions</key>
|
||||||
|
<array>
|
||||||
|
<string>3ds</string>
|
||||||
|
<string>3dsx</string>
|
||||||
|
<string>cci</string>
|
||||||
|
<string>cxi</string>
|
||||||
|
<string>cia</string>
|
||||||
|
</array>
|
||||||
|
<key>CFBundleTypeName</key>
|
||||||
|
<string>Nintendo 3DS File</string>
|
||||||
|
<key>CFBundleTypeRole</key>
|
||||||
|
<string>Viewer</string>
|
||||||
|
<key>LSHandlerRank</key>
|
||||||
|
<string>Default</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleTypeExtensions</key>
|
||||||
|
<array>
|
||||||
|
<string>elf</string>
|
||||||
|
<string>axf</string>
|
||||||
|
</array>
|
||||||
|
<key>CFBundleTypeName</key>
|
||||||
|
<string>Unix Executable and Linkable Format</string>
|
||||||
|
<key>CFBundleTypeRole</key>
|
||||||
|
<string>Viewer</string>
|
||||||
|
<key>LSHandlerRank</key>
|
||||||
|
<string>Alternate</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>NSCameraUsageDescription</key>
|
||||||
|
<string>This app requires camera access to emulate the 3DS's cameras.</string>
|
||||||
|
<key>NSMicrophoneUsageDescription</key>
|
||||||
|
<string>This app requires microphone access to emulate the 3DS's microphone.</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>English</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>????</string>
|
||||||
|
<key>CSResourcesFileMapped</key>
|
||||||
|
<true/>
|
||||||
|
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||||
|
<true/>
|
||||||
|
<key>NSHighResolutionCapable</key>
|
||||||
|
<string>True</string>
|
||||||
|
<key>UIFileSharingEnabled</key>
|
||||||
|
<true/>
|
||||||
|
<key>UILaunchStoryboardName</key>
|
||||||
|
<string>LaunchScreen</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
42
dist/apple/LaunchScreen.storyboard
vendored
Normal file
42
dist/apple/LaunchScreen.storyboard
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="Y6W-OH-hqX">
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--View Controller-->
|
||||||
|
<scene sceneID="s0d-6b-0kx">
|
||||||
|
<objects>
|
||||||
|
<viewController id="Y6W-OH-hqX" sceneMemberID="viewController">
|
||||||
|
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="launch_logo.png" translatesAutoresizingMaskIntoConstraints="NO" id="yrZ-hu-Uge">
|
||||||
|
<rect key="frame" x="-59.666666666666657" y="306" width="512.33333333333337" height="240"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="240" id="VhL-hA-Bwr"/>
|
||||||
|
</constraints>
|
||||||
|
</imageView>
|
||||||
|
</subviews>
|
||||||
|
<viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
|
||||||
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="yrZ-hu-Uge" firstAttribute="centerX" secondItem="5EZ-qb-Rvc" secondAttribute="centerX" id="1y3-Mx-a65"/>
|
||||||
|
<constraint firstItem="yrZ-hu-Uge" firstAttribute="centerY" secondItem="5EZ-qb-Rvc" secondAttribute="centerY" id="vNO-xV-EPD"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="219" y="18"/>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
<resources>
|
||||||
|
<image name="launch_logo.png" width="512" height="512"/>
|
||||||
|
<systemColor name="systemBackgroundColor">
|
||||||
|
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
</systemColor>
|
||||||
|
</resources>
|
||||||
|
</document>
|
0
dist/citra.icns → dist/apple/citra.icns
vendored
0
dist/citra.icns → dist/apple/citra.icns
vendored
BIN
dist/apple/launch_logo.png
vendored
Normal file
BIN
dist/apple/launch_logo.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 88 KiB |
15
dist/citra-qt.desktop
vendored
Normal file
15
dist/citra-qt.desktop
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Version=1.0
|
||||||
|
Type=Application
|
||||||
|
Name=Citra
|
||||||
|
GenericName=3DS Emulator
|
||||||
|
GenericName[fr]=Émulateur 3DS
|
||||||
|
Comment=Nintendo 3DS video game console emulator
|
||||||
|
Comment[fr]=Émulateur de console de jeu Nintendo 3DS
|
||||||
|
Icon=citra
|
||||||
|
TryExec=citra-qt
|
||||||
|
Exec=citra-qt %f
|
||||||
|
Categories=Game;Emulator;Qt;
|
||||||
|
MimeType=application/x-ctr-3dsx;application/x-ctr-cci;application/x-ctr-cia;application/x-ctr-cxi;
|
||||||
|
Keywords=3DS;Nintendo;
|
||||||
|
PrefersNonDefaultGPU=true
|
10
dist/citra-room.desktop
vendored
Normal file
10
dist/citra-room.desktop
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Version=1.0
|
||||||
|
Type=Application
|
||||||
|
Name=Citra Room
|
||||||
|
Comment=Multiplayer room host for Citra
|
||||||
|
Icon=citra
|
||||||
|
TryExec=citra-room
|
||||||
|
Exec=citra-room %f
|
||||||
|
Categories=Game;Emulator;
|
||||||
|
Keywords=3DS;Nintendo
|
6
dist/citra.desktop
vendored
6
dist/citra.desktop
vendored
|
@ -7,9 +7,9 @@ GenericName[fr]=Émulateur 3DS
|
||||||
Comment=Nintendo 3DS video game console emulator
|
Comment=Nintendo 3DS video game console emulator
|
||||||
Comment[fr]=Émulateur de console de jeu Nintendo 3DS
|
Comment[fr]=Émulateur de console de jeu Nintendo 3DS
|
||||||
Icon=citra
|
Icon=citra
|
||||||
TryExec=citra-qt
|
TryExec=citra
|
||||||
Exec=citra-qt %f
|
Exec=citra %f
|
||||||
Categories=Game;Emulator;Qt;
|
Categories=Game;Emulator;
|
||||||
MimeType=application/x-ctr-3dsx;application/x-ctr-cci;application/x-ctr-cia;application/x-ctr-cxi;
|
MimeType=application/x-ctr-3dsx;application/x-ctr-cci;application/x-ctr-cia;application/x-ctr-cxi;
|
||||||
Keywords=3DS;Nintendo;
|
Keywords=3DS;Nintendo;
|
||||||
PrefersNonDefaultGPU=true
|
PrefersNonDefaultGPU=true
|
||||||
|
|
8
dist/dumpkeys/DumpKeys.gm9
vendored
8
dist/dumpkeys/DumpKeys.gm9
vendored
|
@ -287,5 +287,13 @@ dumptxt -p $[OUT] "nfcSecret1Seed=$[NFC_SEED_1]"
|
||||||
dumptxt -p $[OUT] "nfcSecret1HmacKey=$[NFC_HMAC_KEY_1]"
|
dumptxt -p $[OUT] "nfcSecret1HmacKey=$[NFC_HMAC_KEY_1]"
|
||||||
dumptxt -p $[OUT] "nfcIv=$[NFC_IV]"
|
dumptxt -p $[OUT] "nfcIv=$[NFC_IV]"
|
||||||
|
|
||||||
|
# Dump seeddb.bin as well
|
||||||
|
|
||||||
|
set SEEDDB_IN "0:/gm9/out/seeddb.bin"
|
||||||
|
set SEEDDB_OUT "0:/gm9/seeddb.bin"
|
||||||
|
|
||||||
|
sdump -w seeddb.bin
|
||||||
|
cp -w $[SEEDDB_IN] $[SEEDDB_OUT]
|
||||||
|
|
||||||
@Exit
|
@Exit
|
||||||
|
|
||||||
|
|
2
dist/dumpkeys/README.md
vendored
2
dist/dumpkeys/README.md
vendored
|
@ -6,5 +6,5 @@ Usage:
|
||||||
1. Copy "DumpKeys.gm9" into the "gm9/scripts/" directory on your SD card.
|
1. Copy "DumpKeys.gm9" into the "gm9/scripts/" directory on your SD card.
|
||||||
2. Launch GodMode9, press the HOME button, select Scripts, and select "DumpKeys" from the list of scripts that appears.
|
2. Launch GodMode9, press the HOME button, select Scripts, and select "DumpKeys" from the list of scripts that appears.
|
||||||
3. Wait for the script to complete and return you to the GodMode9 main menu.
|
3. Wait for the script to complete and return you to the GodMode9 main menu.
|
||||||
4. Power off your system and copy the "gm9/aes_keys.txt" file off of your SD card into "(Citra directory)/sysdata/".
|
4. Power off your system and copy the "gm9/aes_keys.txt" and "gm9/seeddb.bin" files off of your SD card into "(Citra directory)/sysdata/".
|
||||||
|
|
||||||
|
|
2
dist/installer/CMakeLists.txt
vendored
2
dist/installer/CMakeLists.txt
vendored
|
@ -13,6 +13,8 @@ set(BUILD_DIR "${CMAKE_BINARY_DIR}/installer")
|
||||||
set(DIST_DIR "${BUILD_DIR}/dist")
|
set(DIST_DIR "${BUILD_DIR}/dist")
|
||||||
set(TARGET_FILE "${DIST_DIR}/citra-setup-${PLATFORM}")
|
set(TARGET_FILE "${DIST_DIR}/citra-setup-${PLATFORM}")
|
||||||
|
|
||||||
|
file(MAKE_DIRECTORY "${BUILD_DIR}" "${DIST_DIR}")
|
||||||
|
|
||||||
# Adds a custom target that will run the BuildInstaller.cmake file
|
# Adds a custom target that will run the BuildInstaller.cmake file
|
||||||
# CMake can't just run a cmake function as a custom command, so this is a way around it.
|
# CMake can't just run a cmake function as a custom command, so this is a way around it.
|
||||||
# Calls the cmake command and runs a cmake file in "scripting" mode passing in variables with -D
|
# Calls the cmake command and runs a cmake file in "scripting" mode passing in variables with -D
|
||||||
|
|
5
dist/languages/.tx/config
vendored
5
dist/languages/.tx/config
vendored
|
@ -7,3 +7,8 @@ source_file = en.ts
|
||||||
source_lang = en
|
source_lang = en
|
||||||
type = QT
|
type = QT
|
||||||
|
|
||||||
|
[o:citra:p:citra:r:android]
|
||||||
|
file_filter = ../../src/android/app/src/main/res/values-<lang>/strings.xml
|
||||||
|
source_file = ../../src/android/app/src/main/res/values/strings.xml
|
||||||
|
type = ANDROID
|
||||||
|
lang_map = es_ES:es, hu_HU:hu, ru_RU:ru, pt_BR:pt, zh_CN:zh
|
||||||
|
|
3519
dist/languages/da_DK.ts
vendored
3519
dist/languages/da_DK.ts
vendored
File diff suppressed because it is too large
Load diff
3911
dist/languages/de.ts
vendored
3911
dist/languages/de.ts
vendored
File diff suppressed because it is too large
Load diff
3603
dist/languages/el.ts
vendored
3603
dist/languages/el.ts
vendored
File diff suppressed because it is too large
Load diff
3488
dist/languages/es_ES.ts
vendored
3488
dist/languages/es_ES.ts
vendored
File diff suppressed because it is too large
Load diff
3566
dist/languages/fi.ts
vendored
3566
dist/languages/fi.ts
vendored
File diff suppressed because it is too large
Load diff
3764
dist/languages/fr.ts
vendored
3764
dist/languages/fr.ts
vendored
File diff suppressed because it is too large
Load diff
5229
dist/languages/fi_FI.ts → dist/languages/hu_HU.ts
vendored
5229
dist/languages/fi_FI.ts → dist/languages/hu_HU.ts
vendored
File diff suppressed because it is too large
Load diff
3517
dist/languages/id.ts
vendored
3517
dist/languages/id.ts
vendored
File diff suppressed because it is too large
Load diff
3658
dist/languages/it.ts
vendored
3658
dist/languages/it.ts
vendored
File diff suppressed because it is too large
Load diff
3580
dist/languages/ja_JP.ts
vendored
3580
dist/languages/ja_JP.ts
vendored
File diff suppressed because it is too large
Load diff
3718
dist/languages/ko_KR.ts
vendored
3718
dist/languages/ko_KR.ts
vendored
File diff suppressed because it is too large
Load diff
3603
dist/languages/lt_LT.ts
vendored
3603
dist/languages/lt_LT.ts
vendored
File diff suppressed because it is too large
Load diff
3525
dist/languages/nb.ts
vendored
3525
dist/languages/nb.ts
vendored
File diff suppressed because it is too large
Load diff
4371
dist/languages/nl.ts
vendored
4371
dist/languages/nl.ts
vendored
File diff suppressed because it is too large
Load diff
3610
dist/languages/pl_PL.ts
vendored
3610
dist/languages/pl_PL.ts
vendored
File diff suppressed because it is too large
Load diff
3710
dist/languages/pt_BR.ts
vendored
3710
dist/languages/pt_BR.ts
vendored
File diff suppressed because it is too large
Load diff
3546
dist/languages/ro_RO.ts
vendored
3546
dist/languages/ro_RO.ts
vendored
File diff suppressed because it is too large
Load diff
3527
dist/languages/ru_RU.ts
vendored
3527
dist/languages/ru_RU.ts
vendored
File diff suppressed because it is too large
Load diff
3536
dist/languages/tr_TR.ts
vendored
3536
dist/languages/tr_TR.ts
vendored
File diff suppressed because it is too large
Load diff
3691
dist/languages/vi_VN.ts
vendored
3691
dist/languages/vi_VN.ts
vendored
File diff suppressed because it is too large
Load diff
3508
dist/languages/zh_CN.ts
vendored
3508
dist/languages/zh_CN.ts
vendored
File diff suppressed because it is too large
Load diff
3739
dist/languages/zh_TW.ts
vendored
3739
dist/languages/zh_TW.ts
vendored
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,13 @@
|
||||||
Name=colorful_dark
|
Name=colorful_dark
|
||||||
Comment=Colorful theme (Dark style)
|
Comment=Colorful theme (Dark style)
|
||||||
Inherits=default
|
Inherits=default
|
||||||
Directories=16x16
|
Directories=16x16,48x48,256x256
|
||||||
|
|
||||||
[16x16]
|
[16x16]
|
||||||
Size=16
|
Size=16
|
||||||
|
|
||||||
|
[48x48]
|
||||||
|
Size=48
|
||||||
|
|
||||||
|
[256x256]
|
||||||
|
Size=256
|
||||||
|
|
|
@ -2,7 +2,13 @@
|
||||||
Name=colorful_midnight_blue
|
Name=colorful_midnight_blue
|
||||||
Comment=Colorful theme (Midnight Blue style)
|
Comment=Colorful theme (Midnight Blue style)
|
||||||
Inherits=default
|
Inherits=default
|
||||||
Directories=16x16
|
Directories=16x16,48x48,256x256
|
||||||
|
|
||||||
[16x16]
|
[16x16]
|
||||||
Size=16
|
Size=16
|
||||||
|
|
||||||
|
[48x48]
|
||||||
|
Size=48
|
||||||
|
|
||||||
|
[256x256]
|
||||||
|
Size=256
|
||||||
|
|
28
dist/qt_themes/default/style.qss
vendored
28
dist/qt_themes/default/style.qss
vendored
|
@ -1,6 +1,5 @@
|
||||||
QPushButton#3DOptionStatusBarButton {
|
QPushButton#GraphicsAPIStatusBarButton {
|
||||||
color: #A5A5A5;
|
color: #656565;
|
||||||
font-weight: bold;
|
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
padding: 0px 3px 0px 3px;
|
padding: 0px 3px 0px 3px;
|
||||||
|
@ -9,6 +8,27 @@ QPushButton#3DOptionStatusBarButton {
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#3DOptionStatusBarButton:hover {
|
QPushButton#GraphicsAPIStatusBarButton:hover {
|
||||||
border: 1px solid #76797C;
|
border: 1px solid #76797C;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPushButton#TogglableStatusBarButton {
|
||||||
|
color: #959595;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0px 3px 0px 3px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#TogglableStatusBarButton:checked {
|
||||||
|
color: #00FF00;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#TogglableStatusBarButton:hover {
|
||||||
|
border: 1px solid #76797C;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#button_reset_defaults {
|
||||||
|
min-width: 57px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
}
|
||||||
|
|
34
dist/qt_themes/qdarkstyle/style.qss
vendored
34
dist/qt_themes/qdarkstyle/style.qss
vendored
|
@ -1,3 +1,32 @@
|
||||||
|
QPushButton#GraphicsAPIStatusBarButton {
|
||||||
|
color: #656565;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0px 3px 0px 3px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#GraphicsAPIStatusBarButton:hover {
|
||||||
|
border: 1px solid #76797C;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#TogglableStatusBarButton {
|
||||||
|
min-width: 0px;
|
||||||
|
color: #656565;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0px 3px 0px 3px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#TogglableStatusBarButton:checked {
|
||||||
|
color: #00FF00;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#TogglableStatusBarButton:hover {
|
||||||
|
border: 1px solid #76797C;
|
||||||
|
}
|
||||||
|
|
||||||
QToolTip {
|
QToolTip {
|
||||||
border: 1px solid #76797C;
|
border: 1px solid #76797C;
|
||||||
background-color: #5A7566;
|
background-color: #5A7566;
|
||||||
|
@ -270,6 +299,11 @@ QAbstractItemView:read-only {
|
||||||
alternate-background-color: #232629;
|
alternate-background-color: #232629;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Workaround for https://bugreports.qt.io/browse/QTBUG-115529 */
|
||||||
|
QAbstractItemView:item {
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
QWidget:focus {
|
QWidget:focus {
|
||||||
border: 1px solid #3daee9;
|
border: 1px solid #3daee9;
|
||||||
}
|
}
|
||||||
|
|
|
@ -481,6 +481,11 @@ QAbstractItemView QLineEdit {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Workaround for https://bugreports.qt.io/browse/QTBUG-115529 */
|
||||||
|
QAbstractItemView:item {
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
/* QAbstractScrollArea ----------------------------------------------------
|
/* QAbstractScrollArea ----------------------------------------------------
|
||||||
|
|
||||||
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea
|
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea
|
||||||
|
@ -1067,6 +1072,10 @@ QPushButton:focus {
|
||||||
border: 1px solid #1464A0;
|
border: 1px solid #1464A0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPushButton#button_reset_defaults {
|
||||||
|
padding: 3px 6px;
|
||||||
|
}
|
||||||
|
|
||||||
/* QToolButton ------------------------------------------------------------
|
/* QToolButton ------------------------------------------------------------
|
||||||
|
|
||||||
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbutton
|
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbutton
|
||||||
|
|
433
externals/CMakeLists.txt
vendored
433
externals/CMakeLists.txt
vendored
|
@ -3,6 +3,8 @@
|
||||||
# Suppress warnings from external libraries
|
# Suppress warnings from external libraries
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||||
add_compile_options(/W0)
|
add_compile_options(/W0)
|
||||||
|
else()
|
||||||
|
add_compile_options(-w)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules)
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules)
|
||||||
|
@ -10,58 +12,62 @@ include(DownloadExternals)
|
||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
|
|
||||||
# Boost
|
# Boost
|
||||||
set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/boost")
|
if (NOT USE_SYSTEM_BOOST)
|
||||||
set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost")
|
message(STATUS "Including vendored Boost library")
|
||||||
set(Boost_NO_SYSTEM_PATHS ON)
|
set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/boost" CACHE STRING "")
|
||||||
add_library(boost INTERFACE)
|
set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost" CACHE STRING "")
|
||||||
target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR})
|
set(Boost_NO_SYSTEM_PATHS ON CACHE BOOL "")
|
||||||
|
add_library(boost INTERFACE)
|
||||||
|
target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR})
|
||||||
|
|
||||||
# Boost::serialization
|
# Boost::serialization
|
||||||
file(GLOB boost_serialization_SRC "${CMAKE_SOURCE_DIR}/externals/boost/libs/serialization/src/*.cpp")
|
file(GLOB boost_serialization_SRC "${CMAKE_SOURCE_DIR}/externals/boost/libs/serialization/src/*.cpp")
|
||||||
add_library(boost_serialization STATIC ${boost_serialization_SRC})
|
add_library(boost_serialization STATIC ${boost_serialization_SRC})
|
||||||
target_link_libraries(boost_serialization PUBLIC boost)
|
target_link_libraries(boost_serialization PUBLIC boost)
|
||||||
|
|
||||||
# Boost::iostreams
|
|
||||||
add_library(
|
|
||||||
boost_iostreams
|
|
||||||
STATIC
|
|
||||||
${CMAKE_SOURCE_DIR}/externals/boost/libs/iostreams/src/file_descriptor.cpp
|
|
||||||
${CMAKE_SOURCE_DIR}/externals/boost/libs/iostreams/src/mapped_file.cpp
|
|
||||||
)
|
|
||||||
target_link_libraries(boost_iostreams PUBLIC boost)
|
|
||||||
|
|
||||||
|
# Boost::iostreams
|
||||||
|
add_library(
|
||||||
|
boost_iostreams
|
||||||
|
STATIC
|
||||||
|
${CMAKE_SOURCE_DIR}/externals/boost/libs/iostreams/src/file_descriptor.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/externals/boost/libs/iostreams/src/mapped_file.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(boost_iostreams PUBLIC boost)
|
||||||
# Add additional boost libs here; remember to ALIAS them in the root CMakeLists!
|
# Add additional boost libs here; remember to ALIAS them in the root CMakeLists!
|
||||||
|
else()
|
||||||
|
unset(BOOST_ROOT CACHE)
|
||||||
|
unset(Boost_INCLUDE_DIR CACHE)
|
||||||
|
set(Boost_NO_SYSTEM_PATHS OFF CACHE BOOL "" FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Catch2
|
# Catch2
|
||||||
set(CATCH_INSTALL_DOCS OFF)
|
add_library(catch2 INTERFACE)
|
||||||
set(CATCH_INSTALL_EXTRAS OFF)
|
if(USE_SYSTEM_CATCH2)
|
||||||
add_subdirectory(catch2)
|
find_package(Catch2 3.0.0 REQUIRED)
|
||||||
|
else()
|
||||||
|
set(CATCH_INSTALL_DOCS OFF CACHE BOOL "")
|
||||||
|
set(CATCH_INSTALL_EXTRAS OFF CACHE BOOL "")
|
||||||
|
add_subdirectory(catch2)
|
||||||
|
endif()
|
||||||
|
target_link_libraries(catch2 INTERFACE Catch2::Catch2WithMain)
|
||||||
|
|
||||||
# Crypto++
|
# Crypto++
|
||||||
set(CRYPTOPP_BUILD_DOCUMENTATION OFF)
|
if(USE_SYSTEM_CRYPTOPP)
|
||||||
set(CRYPTOPP_BUILD_TESTING OFF)
|
find_package(cryptopp REQUIRED)
|
||||||
set(CRYPTOPP_INSTALL OFF)
|
add_library(cryptopp INTERFACE)
|
||||||
set(CRYPTOPP_SOURCES "${CMAKE_SOURCE_DIR}/externals/cryptopp")
|
target_link_libraries(cryptopp INTERFACE cryptopp::cryptopp)
|
||||||
add_subdirectory(cryptopp-cmake)
|
else()
|
||||||
|
if (WIN32 AND NOT MSVC AND "arm64" IN_LIST ARCHITECTURE)
|
||||||
|
# TODO: CryptoPP ARM64 ASM does not seem to support Windows unless compiled with MSVC.
|
||||||
|
# TODO: See https://github.com/weidai11/cryptopp/issues/1260
|
||||||
|
set(CRYPTOPP_DISABLE_ASM ON CACHE BOOL "")
|
||||||
|
endif()
|
||||||
|
|
||||||
# HACK: Mismatch between compilation of CryptoPP and headers used in Citra can cause runtime issues.
|
set(CRYPTOPP_BUILD_DOCUMENTATION OFF CACHE BOOL "")
|
||||||
# Pull out the compile definitions from CryptoPP and apply them to Citra as well to fix this.
|
set(CRYPTOPP_BUILD_TESTING OFF CACHE BOOL "")
|
||||||
# See: https://github.com/weidai11/cryptopp/issues/1191
|
set(CRYPTOPP_INSTALL OFF CACHE BOOL "")
|
||||||
get_source_file_property(CRYPTOPP_COMPILE_DEFINITIONS ${CRYPTOPP_SOURCES}/cryptlib.cpp TARGET_DIRECTORY cryptopp COMPILE_DEFINITIONS)
|
set(CRYPTOPP_SOURCES "${CMAKE_SOURCE_DIR}/externals/cryptopp" CACHE STRING "")
|
||||||
set(CRYPTOPP_COMPILE_DEFINITIONS ${CRYPTOPP_COMPILE_DEFINITIONS} PARENT_SCOPE)
|
add_subdirectory(cryptopp-cmake)
|
||||||
|
|
||||||
# HACK: The logic to set up the base include directory for CryptoPP does not work with Android SDK CMake 3.22.1.
|
|
||||||
# Until there is a fixed version available, this code will detect and add in the proper include if it does not exist.
|
|
||||||
if(ANDROID)
|
|
||||||
message(STATUS "Applying CryptoPP include fix.")
|
|
||||||
get_target_property(CRYPTOPP_INCLUDES cryptopp INTERFACE_INCLUDE_DIRECTORIES)
|
|
||||||
foreach(CRYPTOPP_INCLUDE ${CRYPTOPP_INCLUDES})
|
|
||||||
if("${CRYPTOPP_INCLUDE}" MATCHES "\\$<BUILD_INTERFACE:(.*)/cryptopp>")
|
|
||||||
message(STATUS "Fixed include path: ${CMAKE_MATCH_1}")
|
|
||||||
target_include_directories(cryptopp PUBLIC $<BUILD_INTERFACE:${CMAKE_MATCH_1}>)
|
|
||||||
break()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# dds-ktx
|
# dds-ktx
|
||||||
|
@ -70,19 +76,49 @@ target_include_directories(dds-ktx INTERFACE ./dds-ktx)
|
||||||
|
|
||||||
# fmt and Xbyak need to be added before dynarmic
|
# fmt and Xbyak need to be added before dynarmic
|
||||||
# libfmt
|
# libfmt
|
||||||
option(FMT_INSTALL "" ON)
|
if(USE_SYSTEM_FMT)
|
||||||
add_subdirectory(fmt EXCLUDE_FROM_ALL)
|
add_library(fmt INTERFACE)
|
||||||
|
find_package(fmt REQUIRED)
|
||||||
|
target_link_libraries(fmt INTERFACE fmt::fmt)
|
||||||
|
else()
|
||||||
|
option(FMT_INSTALL "" ON)
|
||||||
|
add_subdirectory(fmt EXCLUDE_FROM_ALL)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# Xbyak
|
# Xbyak
|
||||||
if ("x86_64" IN_LIST ARCHITECTURE)
|
if ("x86_64" IN_LIST ARCHITECTURE)
|
||||||
add_subdirectory(xbyak EXCLUDE_FROM_ALL)
|
if(USE_SYSTEM_XBYAK)
|
||||||
|
find_package(xbyak REQUIRED)
|
||||||
|
add_library(xbyak INTERFACE)
|
||||||
|
target_link_libraries(xbyak INTERFACE xbyak::xbyak)
|
||||||
|
else()
|
||||||
|
add_subdirectory(xbyak EXCLUDE_FROM_ALL)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Oaknut
|
||||||
|
if ("arm64" IN_LIST ARCHITECTURE)
|
||||||
|
add_subdirectory(oaknut EXCLUDE_FROM_ALL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Dynarmic
|
# Dynarmic
|
||||||
if ("x86_64" IN_LIST ARCHITECTURE OR "arm64" IN_LIST ARCHITECTURE)
|
if ("x86_64" IN_LIST ARCHITECTURE OR "arm64" IN_LIST ARCHITECTURE)
|
||||||
set(DYNARMIC_TESTS OFF)
|
if(USE_SYSTEM_DYNARMIC)
|
||||||
set(DYNARMIC_FRONTENDS "A32")
|
find_package(dynarmic REQUIRED)
|
||||||
add_subdirectory(dynarmic EXCLUDE_FROM_ALL)
|
add_library(dynarmic INTERFACE)
|
||||||
|
target_link_libraries(dynarmic INTERFACE dynarmic::dynarmic)
|
||||||
|
# The dynarmic package's cmake files are helpfully completely silent
|
||||||
|
# so we have to inform the user of its status ourselves
|
||||||
|
if(TARGET dynarmic::dynarmic)
|
||||||
|
message(STATUS "Found dynarmic")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(DYNARMIC_TESTS OFF CACHE BOOL "")
|
||||||
|
set(DYNARMIC_FRONTENDS "A32" CACHE STRING "")
|
||||||
|
set(DYNARMIC_USE_PRECOMPILED_HEADERS ${CITRA_USE_PRECOMPILED_HEADERS} CACHE BOOL "")
|
||||||
|
add_subdirectory(dynarmic EXCLUDE_FROM_ALL)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# getopt
|
# getopt
|
||||||
|
@ -90,31 +126,59 @@ if (MSVC)
|
||||||
add_subdirectory(getopt)
|
add_subdirectory(getopt)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Glad
|
|
||||||
add_subdirectory(glad)
|
|
||||||
|
|
||||||
# inih
|
# inih
|
||||||
add_subdirectory(inih)
|
if(USE_SYSTEM_INIH)
|
||||||
|
find_package(inih REQUIRED COMPONENTS inih inir)
|
||||||
|
add_library(inih INTERFACE)
|
||||||
|
target_link_libraries(inih INTERFACE inih::inih inih::inir)
|
||||||
|
else()
|
||||||
|
add_subdirectory(inih)
|
||||||
|
endif()
|
||||||
|
|
||||||
# MicroProfile
|
# MicroProfile
|
||||||
add_library(microprofile INTERFACE)
|
add_library(microprofile INTERFACE)
|
||||||
target_include_directories(microprofile INTERFACE ./microprofile)
|
target_include_directories(microprofile SYSTEM INTERFACE ./microprofile)
|
||||||
|
|
||||||
# Nihstro
|
# Nihstro
|
||||||
add_library(nihstro-headers INTERFACE)
|
add_library(nihstro-headers INTERFACE)
|
||||||
target_include_directories(nihstro-headers INTERFACE ./nihstro/include)
|
target_include_directories(nihstro-headers SYSTEM INTERFACE ./nihstro/include)
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
target_compile_options(nihstro-headers INTERFACE /W0)
|
# TODO: For some reason MSVC still applies this warning even with /W0 for externals.
|
||||||
|
target_compile_options(nihstro-headers INTERFACE /wd4715)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Open Source Archives
|
# Open Source Archives
|
||||||
add_subdirectory(open_source_archives)
|
add_subdirectory(open_source_archives)
|
||||||
|
|
||||||
# SoundTouch
|
# faad2
|
||||||
|
add_subdirectory(faad2 EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
set(INTEGER_SAMPLES ON CACHE BOOL "")
|
# Dynamic library headers
|
||||||
set(SOUNDSTRETCH OFF CACHE BOOL "")
|
add_library(library-headers INTERFACE)
|
||||||
set(SOUNDTOUCH_DLL OFF CACHE BOOL "")
|
|
||||||
add_subdirectory(soundtouch)
|
if (USE_SYSTEM_FFMPEG_HEADERS)
|
||||||
|
find_path(SYSTEM_FFMPEG_INCLUDES NAMES libavutil/avutil.h)
|
||||||
|
if (SYSTEM_FFMPEG_INCLUDES STREQUAL "SYSTEM_FFMPEG_INCLUDES-NOTFOUND")
|
||||||
|
message(WARNING "System FFmpeg headers not found. Falling back on bundled headers.")
|
||||||
|
else()
|
||||||
|
message(STATUS "Using system FFmpeg headers.")
|
||||||
|
target_include_directories(library-headers SYSTEM INTERFACE ${SYSTEM_FFMPEG_INCLUDES})
|
||||||
|
set(FOUND_FFMPEG_HEADERS ON)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if (NOT FOUND_FFMPEG_HEADERS)
|
||||||
|
message(STATUS "Using bundled ffmpeg headers.")
|
||||||
|
target_include_directories(library-headers SYSTEM INTERFACE ./library-headers/ffmpeg/include)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# SoundTouch
|
||||||
|
if(NOT USE_SYSTEM_SOUNDTOUCH)
|
||||||
|
set(INTEGER_SAMPLES ON CACHE BOOL "")
|
||||||
|
set(SOUNDSTRETCH OFF CACHE BOOL "")
|
||||||
|
set(SOUNDTOUCH_DLL OFF CACHE BOOL "")
|
||||||
|
add_subdirectory(soundtouch EXCLUDE_FROM_ALL)
|
||||||
|
target_compile_definitions(SoundTouch PUBLIC SOUNDTOUCH_INTEGER_SAMPLES)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Teakra
|
# Teakra
|
||||||
add_subdirectory(teakra EXCLUDE_FROM_ALL)
|
add_subdirectory(teakra EXCLUDE_FROM_ALL)
|
||||||
|
@ -124,67 +188,158 @@ if (ENABLE_SDL2 AND NOT USE_SYSTEM_SDL2)
|
||||||
add_subdirectory(sdl2)
|
add_subdirectory(sdl2)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# libusb
|
||||||
|
if (ENABLE_LIBUSB AND NOT USE_SYSTEM_LIBUSB)
|
||||||
|
add_subdirectory(libusb)
|
||||||
|
set(LIBUSB_INCLUDE_DIR "" PARENT_SCOPE)
|
||||||
|
set(LIBUSB_LIBRARIES usb PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Zstandard
|
# Zstandard
|
||||||
set(ZSTD_LEGACY_SUPPORT OFF)
|
if(USE_SYSTEM_ZSTD)
|
||||||
set(ZSTD_BUILD_PROGRAMS OFF)
|
find_package(zstd REQUIRED)
|
||||||
set(ZSTD_BUILD_SHARED OFF)
|
add_library(zstd INTERFACE)
|
||||||
add_subdirectory(zstd/build/cmake EXCLUDE_FROM_ALL)
|
if(TARGET zstd::libzstd_shared)
|
||||||
target_include_directories(libzstd_static INTERFACE $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/externals/zstd/lib>)
|
message(STATUS "Found system Zstandard")
|
||||||
|
endif()
|
||||||
|
target_link_libraries(zstd INTERFACE zstd::libzstd_shared)
|
||||||
|
else()
|
||||||
|
set(ZSTD_LEGACY_SUPPORT OFF)
|
||||||
|
set(ZSTD_BUILD_PROGRAMS OFF)
|
||||||
|
set(ZSTD_BUILD_SHARED OFF)
|
||||||
|
add_subdirectory(zstd/build/cmake EXCLUDE_FROM_ALL)
|
||||||
|
target_include_directories(libzstd_static INTERFACE $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/externals/zstd/lib>)
|
||||||
|
add_library(zstd ALIAS libzstd_static)
|
||||||
|
endif()
|
||||||
|
|
||||||
# ENet
|
# ENet
|
||||||
add_subdirectory(enet)
|
if(USE_SYSTEM_ENET)
|
||||||
target_include_directories(enet INTERFACE ./enet/include)
|
find_package(libenet REQUIRED)
|
||||||
|
add_library(enet INTERFACE)
|
||||||
|
target_link_libraries(enet INTERFACE libenet::libenet)
|
||||||
|
else()
|
||||||
|
add_subdirectory(enet)
|
||||||
|
target_include_directories(enet INTERFACE ./enet/include)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Cubeb
|
# Cubeb
|
||||||
if (ENABLE_CUBEB)
|
if (ENABLE_CUBEB)
|
||||||
set(BUILD_TESTS OFF CACHE BOOL "")
|
if(USE_SYSTEM_CUBEB)
|
||||||
add_subdirectory(cubeb EXCLUDE_FROM_ALL)
|
find_package(cubeb REQUIRED)
|
||||||
|
add_library(cubeb INTERFACE)
|
||||||
|
target_link_libraries(cubeb INTERFACE cubeb::cubeb)
|
||||||
|
if(TARGET cubeb::cubeb)
|
||||||
|
message(STATUS "Found system cubeb")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(BUILD_TESTS OFF CACHE BOOL "")
|
||||||
|
set(BUILD_TOOLS OFF CACHE BOOL "")
|
||||||
|
set(BUNDLE_SPEEX ON CACHE BOOL "")
|
||||||
|
add_subdirectory(cubeb EXCLUDE_FROM_ALL)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# DiscordRPC
|
# DiscordRPC
|
||||||
if (USE_DISCORD_PRESENCE)
|
if (USE_DISCORD_PRESENCE)
|
||||||
|
# rapidjson used by discord-rpc is old and doesn't correctly detect endianness for some platforms.
|
||||||
|
include(TestBigEndian)
|
||||||
|
test_big_endian(RAPIDJSON_BIG_ENDIAN)
|
||||||
|
if(RAPIDJSON_BIG_ENDIAN)
|
||||||
|
add_compile_definitions(RAPIDJSON_ENDIAN=1)
|
||||||
|
else()
|
||||||
|
add_compile_definitions(RAPIDJSON_ENDIAN=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Apply a dummy CLANG_FORMAT_SUFFIX to disable discord-rpc's unnecessary automatic clang-format.
|
||||||
|
set(CLANG_FORMAT_SUFFIX "dummy")
|
||||||
|
|
||||||
add_subdirectory(discord-rpc EXCLUDE_FROM_ALL)
|
add_subdirectory(discord-rpc EXCLUDE_FROM_ALL)
|
||||||
target_include_directories(discord-rpc INTERFACE ./discord-rpc/include)
|
target_include_directories(discord-rpc INTERFACE ./discord-rpc/include)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# JSON
|
# JSON
|
||||||
add_library(json-headers INTERFACE)
|
add_library(json-headers INTERFACE)
|
||||||
target_include_directories(json-headers INTERFACE ./json)
|
if (USE_SYSTEM_JSON)
|
||||||
|
find_package(nlohmann_json REQUIRED)
|
||||||
|
target_link_libraries(json-headers INTERFACE nlohmann_json::nlohmann_json)
|
||||||
|
get_target_property(NLOHMANN_PREFIX nlohmann_json::nlohmann_json INTERFACE_INCLUDE_DIRECTORIES)
|
||||||
|
# The nlohmann-json3 package expects "#include <nlohmann/json.hpp>"
|
||||||
|
# Citra uses "#include <json.hpp>" so we have to add this manually
|
||||||
|
target_include_directories(json-headers SYSTEM INTERFACE "${NLOHMANN_PREFIX}/nlohmann")
|
||||||
|
else()
|
||||||
|
target_include_directories(json-headers SYSTEM INTERFACE ./json)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (ENABLE_WEB_SERVICE)
|
# OpenSSL
|
||||||
|
if (USE_SYSTEM_OPENSSL)
|
||||||
find_package(OpenSSL 1.1)
|
find_package(OpenSSL 1.1)
|
||||||
if (OPENSSL_FOUND)
|
if (OPENSSL_FOUND)
|
||||||
set(OPENSSL_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
|
set(OPENSSL_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT OPENSSL_FOUND)
|
||||||
|
# LibreSSL
|
||||||
|
set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
|
||||||
|
set(OPENSSLDIR "/etc/ssl/")
|
||||||
|
add_subdirectory(libressl EXCLUDE_FROM_ALL)
|
||||||
|
target_include_directories(ssl SYSTEM INTERFACE ./libressl/include)
|
||||||
|
target_compile_definitions(ssl PRIVATE -DHAVE_INET_NTOP)
|
||||||
|
get_directory_property(OPENSSL_LIBRARIES
|
||||||
|
DIRECTORY libressl
|
||||||
|
DEFINITION OPENSSL_LIBS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# httplib
|
||||||
|
add_library(httplib INTERFACE)
|
||||||
|
if(USE_SYSTEM_CPP_HTTPLIB)
|
||||||
|
find_package(CppHttp 0.14.1)
|
||||||
|
# Detect if system cpphttplib is a shared library
|
||||||
|
# this breaks building as Citra relies on functions that are moved
|
||||||
|
# into the shared object.
|
||||||
|
get_target_property(HTTP_LIBS httplib::httplib INTERFACE_LINK_LIBRARIES)
|
||||||
|
if(HTTP_LIBS)
|
||||||
|
message(WARNING "Shared cpp-http (${HTTP_LIBS}) not supported. Falling back to bundled...")
|
||||||
|
target_include_directories(httplib SYSTEM INTERFACE ./httplib)
|
||||||
else()
|
else()
|
||||||
# LibreSSL
|
if(CppHttp_FOUND)
|
||||||
set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
|
target_link_libraries(httplib INTERFACE httplib::httplib)
|
||||||
set(OPENSSLDIR "/etc/ssl/")
|
else()
|
||||||
add_subdirectory(libressl EXCLUDE_FROM_ALL)
|
message(STATUS "Cpp-httplib not found or not suitable version! Falling back to bundled...")
|
||||||
target_include_directories(ssl INTERFACE ./libressl/include)
|
target_include_directories(httplib SYSTEM INTERFACE ./httplib)
|
||||||
target_compile_definitions(ssl PRIVATE -DHAVE_INET_NTOP)
|
endif()
|
||||||
get_directory_property(OPENSSL_LIBRARIES
|
|
||||||
DIRECTORY libressl
|
|
||||||
DEFINITION OPENSSL_LIBS)
|
|
||||||
endif()
|
endif()
|
||||||
|
else()
|
||||||
|
target_include_directories(httplib SYSTEM INTERFACE ./httplib)
|
||||||
|
endif()
|
||||||
|
target_compile_options(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
|
||||||
|
target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
|
||||||
|
|
||||||
if(ANDROID)
|
if (UNIX AND NOT APPLE)
|
||||||
add_subdirectory(android-ifaddrs)
|
add_subdirectory(gamemode)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# cpp-jwt
|
||||||
|
if (ENABLE_WEB_SERVICE)
|
||||||
|
if (USE_SYSTEM_CPP_JWT)
|
||||||
|
find_package(cpp-jwt REQUIRED)
|
||||||
|
add_library(cpp-jwt INTERFACE)
|
||||||
|
target_link_libraries(cpp-jwt INTERFACE cpp-jwt::cpp-jwt)
|
||||||
|
else()
|
||||||
|
add_library(cpp-jwt INTERFACE)
|
||||||
|
target_include_directories(cpp-jwt SYSTEM INTERFACE ./cpp-jwt/include)
|
||||||
|
target_compile_definitions(cpp-jwt INTERFACE CPP_JWT_USE_VENDORED_NLOHMANN_JSON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# httplib
|
|
||||||
add_library(httplib INTERFACE)
|
|
||||||
target_include_directories(httplib INTERFACE ./httplib)
|
|
||||||
target_compile_options(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
|
|
||||||
target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
|
|
||||||
|
|
||||||
# cpp-jwt
|
|
||||||
add_library(cpp-jwt INTERFACE)
|
|
||||||
target_include_directories(cpp-jwt INTERFACE ./cpp-jwt/include)
|
|
||||||
target_compile_definitions(cpp-jwt INTERFACE CPP_JWT_USE_VENDORED_NLOHMANN_JSON)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# lodepng
|
# lodepng
|
||||||
add_subdirectory(lodepng)
|
if(USE_SYSTEM_LODEPNG)
|
||||||
|
add_library(lodepng INTERFACE)
|
||||||
|
find_package(lodepng REQUIRED)
|
||||||
|
target_link_libraries(lodepng INTERFACE lodepng::lodepng)
|
||||||
|
else()
|
||||||
|
add_subdirectory(lodepng)
|
||||||
|
endif()
|
||||||
|
|
||||||
# (xperia64): Only use libyuv on Android b/c of build issues on Windows and mandatory JPEG
|
# (xperia64): Only use libyuv on Android b/c of build issues on Windows and mandatory JPEG
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
|
@ -195,13 +350,81 @@ endif()
|
||||||
|
|
||||||
# OpenAL Soft
|
# OpenAL Soft
|
||||||
if (ENABLE_OPENAL)
|
if (ENABLE_OPENAL)
|
||||||
set(ALSOFT_EMBED_HRTF_DATA OFF CACHE BOOL "")
|
if(USE_SYSTEM_OPENAL)
|
||||||
set(ALSOFT_EXAMPLES OFF CACHE BOOL "")
|
add_library(OpenAL INTERFACE)
|
||||||
set(ALSOFT_INSTALL OFF CACHE BOOL "")
|
find_package(OpenAL REQUIRED)
|
||||||
set(ALSOFT_INSTALL_CONFIG OFF CACHE BOOL "")
|
target_link_libraries(OpenAL INTERFACE OpenAL::OpenAL)
|
||||||
set(ALSOFT_INSTALL_HRTF_DATA OFF CACHE BOOL "")
|
else()
|
||||||
set(ALSOFT_INSTALL_AMBDEC_PRESETS OFF CACHE BOOL "")
|
set(ALSOFT_EMBED_HRTF_DATA OFF CACHE BOOL "")
|
||||||
set(ALSOFT_UTILS OFF CACHE BOOL "")
|
set(ALSOFT_EXAMPLES OFF CACHE BOOL "")
|
||||||
set(LIBTYPE "STATIC" CACHE STRING "")
|
set(ALSOFT_INSTALL OFF CACHE BOOL "")
|
||||||
add_subdirectory(openal-soft EXCLUDE_FROM_ALL)
|
set(ALSOFT_INSTALL_CONFIG OFF CACHE BOOL "")
|
||||||
|
set(ALSOFT_INSTALL_HRTF_DATA OFF CACHE BOOL "")
|
||||||
|
set(ALSOFT_INSTALL_AMBDEC_PRESETS OFF CACHE BOOL "")
|
||||||
|
set(ALSOFT_UTILS OFF CACHE BOOL "")
|
||||||
|
set(LIBTYPE "STATIC" CACHE STRING "")
|
||||||
|
add_subdirectory(openal-soft EXCLUDE_FROM_ALL)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# OpenGL dependencies
|
||||||
|
if (ENABLE_OPENGL)
|
||||||
|
# Glad
|
||||||
|
add_subdirectory(glad)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Vulkan dependencies
|
||||||
|
if (ENABLE_VULKAN)
|
||||||
|
# glslang
|
||||||
|
if(USE_SYSTEM_GLSLANG)
|
||||||
|
find_package(glslang REQUIRED)
|
||||||
|
add_library(glslang INTERFACE)
|
||||||
|
add_library(SPIRV INTERFACE)
|
||||||
|
target_link_libraries(glslang INTERFACE glslang::glslang)
|
||||||
|
target_link_libraries(SPIRV INTERFACE glslang::SPIRV)
|
||||||
|
# System include path is different from submodule include path
|
||||||
|
get_target_property(GLSLANG_PREFIX glslang::SPIRV INTERFACE_INCLUDE_DIRECTORIES)
|
||||||
|
target_include_directories(SPIRV SYSTEM INTERFACE "${GLSLANG_PREFIX}/glslang")
|
||||||
|
else()
|
||||||
|
set(SKIP_GLSLANG_INSTALL ON CACHE BOOL "")
|
||||||
|
set(ENABLE_GLSLANG_BINARIES OFF CACHE BOOL "")
|
||||||
|
set(ENABLE_SPVREMAPPER OFF CACHE BOOL "")
|
||||||
|
set(ENABLE_CTEST OFF CACHE BOOL "")
|
||||||
|
set(ENABLE_HLSL OFF CACHE BOOL "")
|
||||||
|
set(BUILD_EXTERNAL OFF CACHE BOOL "")
|
||||||
|
add_subdirectory(glslang)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# sirit
|
||||||
|
add_subdirectory(sirit EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
# VMA
|
||||||
|
if(USE_SYSTEM_VMA)
|
||||||
|
add_library(vma INTERFACE)
|
||||||
|
find_package(VulkanMemoryAllocator REQUIRED)
|
||||||
|
if(TARGET GPUOpen::VulkanMemoryAllocator)
|
||||||
|
message(STATUS "Found VulkanMemoryAllocator")
|
||||||
|
target_link_libraries(vma INTERFACE GPUOpen::VulkanMemoryAllocator)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
add_library(vma INTERFACE)
|
||||||
|
target_include_directories(vma SYSTEM INTERFACE ./vma/include)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# vulkan-headers
|
||||||
|
add_library(vulkan-headers INTERFACE)
|
||||||
|
if(USE_SYSTEM_VULKAN_HEADERS)
|
||||||
|
find_package(Vulkan REQUIRED)
|
||||||
|
if(TARGET Vulkan::Headers)
|
||||||
|
message(STATUS "Found Vulkan headers")
|
||||||
|
target_link_libraries(vulkan-headers INTERFACE Vulkan::Headers)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
target_include_directories(vulkan-headers SYSTEM INTERFACE ./vulkan-headers/include)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# adrenotools
|
||||||
|
if (ANDROID AND "arm64" IN_LIST ARCHITECTURE)
|
||||||
|
add_subdirectory(libadrenotools)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
8
externals/android-ifaddrs/CMakeLists.txt
vendored
8
externals/android-ifaddrs/CMakeLists.txt
vendored
|
@ -1,8 +0,0 @@
|
||||||
add_library(ifaddrs
|
|
||||||
ifaddrs.c
|
|
||||||
ifaddrs.h
|
|
||||||
)
|
|
||||||
|
|
||||||
create_target_directory_groups(ifaddrs)
|
|
||||||
|
|
||||||
target_include_directories(ifaddrs INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
|
600
externals/android-ifaddrs/ifaddrs.c
vendored
600
externals/android-ifaddrs/ifaddrs.c
vendored
|
@ -1,600 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (c) 2013, Kenneth MacKay
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ifaddrs.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <net/if_arp.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <linux/netlink.h>
|
|
||||||
#include <linux/rtnetlink.h>
|
|
||||||
|
|
||||||
typedef struct NetlinkList
|
|
||||||
{
|
|
||||||
struct NetlinkList *m_next;
|
|
||||||
struct nlmsghdr *m_data;
|
|
||||||
unsigned int m_size;
|
|
||||||
} NetlinkList;
|
|
||||||
|
|
||||||
static int netlink_socket(void)
|
|
||||||
{
|
|
||||||
int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
|
||||||
if(l_socket < 0)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sockaddr_nl l_addr;
|
|
||||||
memset(&l_addr, 0, sizeof(l_addr));
|
|
||||||
l_addr.nl_family = AF_NETLINK;
|
|
||||||
if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0)
|
|
||||||
{
|
|
||||||
close(l_socket);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return l_socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int netlink_send(int p_socket, int p_request)
|
|
||||||
{
|
|
||||||
char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))];
|
|
||||||
memset(l_buffer, 0, sizeof(l_buffer));
|
|
||||||
struct nlmsghdr *l_hdr = (struct nlmsghdr *)l_buffer;
|
|
||||||
struct rtgenmsg *l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr);
|
|
||||||
|
|
||||||
l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg));
|
|
||||||
l_hdr->nlmsg_type = p_request;
|
|
||||||
l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
|
|
||||||
l_hdr->nlmsg_pid = 0;
|
|
||||||
l_hdr->nlmsg_seq = p_socket;
|
|
||||||
l_msg->rtgen_family = AF_UNSPEC;
|
|
||||||
|
|
||||||
struct sockaddr_nl l_addr;
|
|
||||||
memset(&l_addr, 0, sizeof(l_addr));
|
|
||||||
l_addr.nl_family = AF_NETLINK;
|
|
||||||
return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int netlink_recv(int p_socket, void *p_buffer, size_t p_len)
|
|
||||||
{
|
|
||||||
struct msghdr l_msg;
|
|
||||||
struct iovec l_iov = { p_buffer, p_len };
|
|
||||||
struct sockaddr_nl l_addr;
|
|
||||||
int l_result;
|
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
l_msg.msg_name = (void *)&l_addr;
|
|
||||||
l_msg.msg_namelen = sizeof(l_addr);
|
|
||||||
l_msg.msg_iov = &l_iov;
|
|
||||||
l_msg.msg_iovlen = 1;
|
|
||||||
l_msg.msg_control = NULL;
|
|
||||||
l_msg.msg_controllen = 0;
|
|
||||||
l_msg.msg_flags = 0;
|
|
||||||
int l_result = recvmsg(p_socket, &l_msg, 0);
|
|
||||||
|
|
||||||
if(l_result < 0)
|
|
||||||
{
|
|
||||||
if(errno == EINTR)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_msg.msg_flags & MSG_TRUNC)
|
|
||||||
{ // buffer was too small
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return l_result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_done)
|
|
||||||
{
|
|
||||||
size_t l_size = 4096;
|
|
||||||
void *l_buffer = NULL;
|
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
free(l_buffer);
|
|
||||||
l_buffer = malloc(l_size);
|
|
||||||
|
|
||||||
int l_read = netlink_recv(p_socket, l_buffer, l_size);
|
|
||||||
*p_size = l_read;
|
|
||||||
if(l_read == -2)
|
|
||||||
{
|
|
||||||
free(l_buffer);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if(l_read >= 0)
|
|
||||||
{
|
|
||||||
pid_t l_pid = getpid();
|
|
||||||
struct nlmsghdr *l_hdr;
|
|
||||||
for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read))
|
|
||||||
{
|
|
||||||
if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_hdr->nlmsg_type == NLMSG_DONE)
|
|
||||||
{
|
|
||||||
*p_done = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_hdr->nlmsg_type == NLMSG_ERROR)
|
|
||||||
{
|
|
||||||
free(l_buffer);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return l_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_size *= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size)
|
|
||||||
{
|
|
||||||
NetlinkList *l_item = malloc(sizeof(NetlinkList));
|
|
||||||
l_item->m_next = NULL;
|
|
||||||
l_item->m_data = p_data;
|
|
||||||
l_item->m_size = p_size;
|
|
||||||
return l_item;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void freeResultList(NetlinkList *p_list)
|
|
||||||
{
|
|
||||||
NetlinkList *l_cur;
|
|
||||||
while(p_list)
|
|
||||||
{
|
|
||||||
l_cur = p_list;
|
|
||||||
p_list = p_list->m_next;
|
|
||||||
free(l_cur->m_data);
|
|
||||||
free(l_cur);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static NetlinkList *getResultList(int p_socket, int p_request)
|
|
||||||
{
|
|
||||||
if(netlink_send(p_socket, p_request) < 0)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetlinkList *l_list = NULL;
|
|
||||||
NetlinkList *l_end = NULL;
|
|
||||||
int l_size;
|
|
||||||
int l_done = 0;
|
|
||||||
while(!l_done)
|
|
||||||
{
|
|
||||||
struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done);
|
|
||||||
if(!l_hdr)
|
|
||||||
{ // error
|
|
||||||
freeResultList(l_list);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetlinkList *l_item = newListItem(l_hdr, l_size);
|
|
||||||
if(!l_list)
|
|
||||||
{
|
|
||||||
l_list = l_item;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
l_end->m_next = l_item;
|
|
||||||
}
|
|
||||||
l_end = l_item;
|
|
||||||
}
|
|
||||||
return l_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t maxSize(size_t a, size_t b)
|
|
||||||
{
|
|
||||||
return (a > b ? a : b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t calcAddrLen(sa_family_t p_family, int p_dataSize)
|
|
||||||
{
|
|
||||||
switch(p_family)
|
|
||||||
{
|
|
||||||
case AF_INET:
|
|
||||||
return sizeof(struct sockaddr_in);
|
|
||||||
case AF_INET6:
|
|
||||||
return sizeof(struct sockaddr_in6);
|
|
||||||
case AF_PACKET:
|
|
||||||
return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize);
|
|
||||||
default:
|
|
||||||
return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size)
|
|
||||||
{
|
|
||||||
switch(p_family)
|
|
||||||
{
|
|
||||||
case AF_INET:
|
|
||||||
memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size);
|
|
||||||
break;
|
|
||||||
case AF_INET6:
|
|
||||||
memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size);
|
|
||||||
break;
|
|
||||||
case AF_PACKET:
|
|
||||||
memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size);
|
|
||||||
((struct sockaddr_ll*)p_dest)->sll_halen = p_size;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
memcpy(p_dest->sa_data, p_data, p_size);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p_dest->sa_family = p_family;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry)
|
|
||||||
{
|
|
||||||
if(!*p_resultList)
|
|
||||||
{
|
|
||||||
*p_resultList = p_entry;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct ifaddrs *l_cur = *p_resultList;
|
|
||||||
while(l_cur->ifa_next)
|
|
||||||
{
|
|
||||||
l_cur = l_cur->ifa_next;
|
|
||||||
}
|
|
||||||
l_cur->ifa_next = p_entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_links, struct ifaddrs **p_resultList)
|
|
||||||
{
|
|
||||||
struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr);
|
|
||||||
|
|
||||||
size_t l_nameSize = 0;
|
|
||||||
size_t l_addrSize = 0;
|
|
||||||
size_t l_dataSize = 0;
|
|
||||||
|
|
||||||
size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
|
|
||||||
struct rtattr *l_rta;
|
|
||||||
for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifinfomsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
|
|
||||||
{
|
|
||||||
void *l_rtaData = RTA_DATA(l_rta);
|
|
||||||
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
|
||||||
switch(l_rta->rta_type)
|
|
||||||
{
|
|
||||||
case IFLA_ADDRESS:
|
|
||||||
case IFLA_BROADCAST:
|
|
||||||
l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize));
|
|
||||||
break;
|
|
||||||
case IFLA_IFNAME:
|
|
||||||
l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
|
|
||||||
break;
|
|
||||||
case IFLA_STATS:
|
|
||||||
l_dataSize += NLMSG_ALIGN(l_rtaSize);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize + l_dataSize);
|
|
||||||
memset(l_entry, 0, sizeof(struct ifaddrs));
|
|
||||||
l_entry->ifa_name = "";
|
|
||||||
|
|
||||||
char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
|
|
||||||
char *l_addr = l_name + l_nameSize;
|
|
||||||
char *l_data = l_addr + l_addrSize;
|
|
||||||
|
|
||||||
l_entry->ifa_flags = l_info->ifi_flags;
|
|
||||||
|
|
||||||
l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
|
|
||||||
for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifinfomsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
|
|
||||||
{
|
|
||||||
void *l_rtaData = RTA_DATA(l_rta);
|
|
||||||
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
|
||||||
switch(l_rta->rta_type)
|
|
||||||
{
|
|
||||||
case IFLA_ADDRESS:
|
|
||||||
case IFLA_BROADCAST:
|
|
||||||
{
|
|
||||||
size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize);
|
|
||||||
makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
|
|
||||||
((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index;
|
|
||||||
((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type;
|
|
||||||
if(l_rta->rta_type == IFLA_ADDRESS)
|
|
||||||
{
|
|
||||||
l_entry->ifa_addr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
l_addr += NLMSG_ALIGN(l_addrLen);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IFLA_IFNAME:
|
|
||||||
strncpy(l_name, l_rtaData, l_rtaDataSize);
|
|
||||||
l_name[l_rtaDataSize] = '\0';
|
|
||||||
l_entry->ifa_name = l_name;
|
|
||||||
break;
|
|
||||||
case IFLA_STATS:
|
|
||||||
memcpy(l_data, l_rtaData, l_rtaDataSize);
|
|
||||||
l_entry->ifa_data = l_data;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addToEnd(p_resultList, l_entry);
|
|
||||||
p_links[l_info->ifi_index - 1] = l_entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_links, struct ifaddrs **p_resultList)
|
|
||||||
{
|
|
||||||
struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr);
|
|
||||||
|
|
||||||
size_t l_nameSize = 0;
|
|
||||||
size_t l_addrSize = 0;
|
|
||||||
|
|
||||||
int l_addedNetmask = 0;
|
|
||||||
|
|
||||||
size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
|
|
||||||
struct rtattr *l_rta;
|
|
||||||
for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
|
|
||||||
{
|
|
||||||
void *l_rtaData = RTA_DATA(l_rta);
|
|
||||||
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
|
||||||
if(l_info->ifa_family == AF_PACKET)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(l_rta->rta_type)
|
|
||||||
{
|
|
||||||
case IFA_ADDRESS:
|
|
||||||
case IFA_LOCAL:
|
|
||||||
if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask)
|
|
||||||
{ // make room for netmask
|
|
||||||
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
|
|
||||||
l_addedNetmask = 1;
|
|
||||||
}
|
|
||||||
case IFA_BROADCAST:
|
|
||||||
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
|
|
||||||
break;
|
|
||||||
case IFA_LABEL:
|
|
||||||
l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
|
|
||||||
memset(l_entry, 0, sizeof(struct ifaddrs));
|
|
||||||
l_entry->ifa_name = p_links[l_info->ifa_index - 1]->ifa_name;
|
|
||||||
|
|
||||||
char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
|
|
||||||
char *l_addr = l_name + l_nameSize;
|
|
||||||
|
|
||||||
l_entry->ifa_flags = l_info->ifa_flags | p_links[l_info->ifa_index - 1]->ifa_flags;
|
|
||||||
|
|
||||||
l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
|
|
||||||
for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
|
|
||||||
{
|
|
||||||
void *l_rtaData = RTA_DATA(l_rta);
|
|
||||||
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
|
||||||
switch(l_rta->rta_type)
|
|
||||||
{
|
|
||||||
case IFA_ADDRESS:
|
|
||||||
case IFA_BROADCAST:
|
|
||||||
case IFA_LOCAL:
|
|
||||||
{
|
|
||||||
size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize);
|
|
||||||
makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
|
|
||||||
if(l_info->ifa_family == AF_INET6)
|
|
||||||
{
|
|
||||||
if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData))
|
|
||||||
{
|
|
||||||
((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_rta->rta_type == IFA_ADDRESS)
|
|
||||||
{ // apparently in a point-to-point network IFA_ADDRESS contains the dest address and IFA_LOCAL contains the local address
|
|
||||||
if(l_entry->ifa_addr)
|
|
||||||
{
|
|
||||||
l_entry->ifa_dstaddr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
l_entry->ifa_addr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(l_rta->rta_type == IFA_LOCAL)
|
|
||||||
{
|
|
||||||
if(l_entry->ifa_addr)
|
|
||||||
{
|
|
||||||
l_entry->ifa_dstaddr = l_entry->ifa_addr;
|
|
||||||
}
|
|
||||||
l_entry->ifa_addr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
l_addr += NLMSG_ALIGN(l_addrLen);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IFA_LABEL:
|
|
||||||
strncpy(l_name, l_rtaData, l_rtaDataSize);
|
|
||||||
l_name[l_rtaDataSize] = '\0';
|
|
||||||
l_entry->ifa_name = l_name;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6))
|
|
||||||
{
|
|
||||||
unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128);
|
|
||||||
unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen);
|
|
||||||
char l_mask[16] = {0};
|
|
||||||
unsigned i;
|
|
||||||
for(i=0; i<(l_prefix/8); ++i)
|
|
||||||
{
|
|
||||||
l_mask[i] = 0xff;
|
|
||||||
}
|
|
||||||
l_mask[i] = 0xff << (8 - (l_prefix % 8));
|
|
||||||
|
|
||||||
makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8);
|
|
||||||
l_entry->ifa_netmask = (struct sockaddr *)l_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
addToEnd(p_resultList, l_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void interpret(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_links, struct ifaddrs **p_resultList)
|
|
||||||
{
|
|
||||||
pid_t l_pid = getpid();
|
|
||||||
for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
|
|
||||||
{
|
|
||||||
unsigned int l_nlsize = p_netlinkList->m_size;
|
|
||||||
struct nlmsghdr *l_hdr;
|
|
||||||
for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
|
|
||||||
{
|
|
||||||
if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_hdr->nlmsg_type == NLMSG_DONE)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_hdr->nlmsg_type == RTM_NEWLINK)
|
|
||||||
{
|
|
||||||
interpretLink(l_hdr, p_links, p_resultList);
|
|
||||||
}
|
|
||||||
else if(l_hdr->nlmsg_type == RTM_NEWADDR)
|
|
||||||
{
|
|
||||||
interpretAddr(l_hdr, p_links, p_resultList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned countLinks(int p_socket, NetlinkList *p_netlinkList)
|
|
||||||
{
|
|
||||||
unsigned l_links = 0;
|
|
||||||
pid_t l_pid = getpid();
|
|
||||||
for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
|
|
||||||
{
|
|
||||||
unsigned int l_nlsize = p_netlinkList->m_size;
|
|
||||||
struct nlmsghdr *l_hdr;
|
|
||||||
for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
|
|
||||||
{
|
|
||||||
if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_hdr->nlmsg_type == NLMSG_DONE)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_hdr->nlmsg_type == RTM_NEWLINK)
|
|
||||||
{
|
|
||||||
++l_links;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return l_links;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getifaddrs(struct ifaddrs **ifap)
|
|
||||||
{
|
|
||||||
if(!ifap)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*ifap = NULL;
|
|
||||||
|
|
||||||
int l_socket = netlink_socket();
|
|
||||||
if(l_socket < 0)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetlinkList *l_linkResults = getResultList(l_socket, RTM_GETLINK);
|
|
||||||
if(!l_linkResults)
|
|
||||||
{
|
|
||||||
close(l_socket);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetlinkList *l_addrResults = getResultList(l_socket, RTM_GETADDR);
|
|
||||||
if(!l_addrResults)
|
|
||||||
{
|
|
||||||
close(l_socket);
|
|
||||||
freeResultList(l_linkResults);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned l_numLinks = countLinks(l_socket, l_linkResults) + countLinks(l_socket, l_addrResults);
|
|
||||||
struct ifaddrs *l_links[l_numLinks];
|
|
||||||
memset(l_links, 0, l_numLinks * sizeof(struct ifaddrs *));
|
|
||||||
|
|
||||||
interpret(l_socket, l_linkResults, l_links, ifap);
|
|
||||||
interpret(l_socket, l_addrResults, l_links, ifap);
|
|
||||||
|
|
||||||
freeResultList(l_linkResults);
|
|
||||||
freeResultList(l_addrResults);
|
|
||||||
close(l_socket);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void freeifaddrs(struct ifaddrs *ifa)
|
|
||||||
{
|
|
||||||
struct ifaddrs *l_cur;
|
|
||||||
while(ifa)
|
|
||||||
{
|
|
||||||
l_cur = ifa;
|
|
||||||
ifa = ifa->ifa_next;
|
|
||||||
free(l_cur);
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue