Compare commits
182 Commits
nvapi
...
custom-tex
Author | SHA1 | Date | |
---|---|---|---|
87a86c90cd | |||
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 | |||
0768bd8ce0 | |||
dc39eac916 | |||
7677ace5ea | |||
71a9981430 | |||
d8e74a9ff4 | |||
3a27603e3d | |||
b9d644b777 | |||
f9ab0b3042 | |||
2035433159 | |||
ee025174fb | |||
2e47afd48e | |||
ebac6b17b0 | |||
b4db9aebf2 | |||
2e655f73b8 | |||
322d7a8287 | |||
62792b6b0e | |||
2b8610fcc4 | |||
2273df4d70 | |||
70335a7f4d | |||
53da17b925 | |||
7b4e2b3c9d |
@ -5,7 +5,10 @@ export NDK_CCACHE=$(which ccache)
|
||||
BUILD_FLAVOR=canary ||
|
||||
BUILD_FLAVOR=nightly
|
||||
|
||||
ccache -s
|
||||
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
|
||||
@ -13,3 +16,7 @@ chmod +x ./gradlew
|
||||
./gradlew bundle${BUILD_FLAVOR}Release
|
||||
|
||||
ccache -s
|
||||
|
||||
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
|
||||
rm "${ANDROID_KEYSTORE_FILE}"
|
||||
fi
|
@ -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
|
@ -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
|
@ -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,28 +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
|
||||
|
||||
#Copy External Libraries
|
||||
mkdir -p ./AppDir/usr/plugins/platformthemes
|
||||
mkdir -p ./AppDir/usr/plugins/styles
|
||||
cp /usr/lib/x86_64-linux-gnu/qt5/plugins/platformthemes/libqt5ct.so ./AppDir/usr/plugins/platformthemes
|
||||
cp /usr/lib/x86_64-linux-gnu/qt5/plugins/platformthemes/libqgtk3.so ./AppDir/usr/plugins/platformthemes
|
||||
cp /usr/lib/x86_64-linux-gnu/qt5/plugins/styles/libqt5ct-style.so ./AppDir/usr/plugins/styles
|
||||
|
||||
#Build AppImage
|
||||
/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,31 +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/qt/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}/../mediaservice/" package/
|
||||
cp -rv "${QT_PLATFORM_DLL_PATH}/../imageformats/" package/
|
||||
cp -rv "${QT_PLATFORM_DLL_PATH}/../styles/" package/
|
||||
rm -f package/mediaservice/*d.dll
|
||||
|
||||
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
|
20
.ci/linux.sh
Executable file
20
.ci/linux.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#!/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
|
||||
|
||||
if [ "$TARGET" = "appimage" ]; then
|
||||
ninja bundle
|
||||
fi
|
||||
|
||||
ccache -s
|
||||
|
||||
ctest -VV -C Release
|
@ -1,45 +1,43 @@
|
||||
#!/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)
|
||||
|
||||
BUNDLE_DIR=build/bundle
|
||||
mkdir build
|
||||
|
||||
# Set up the base artifact to combine into.
|
||||
BASE_ARTIFACT=${ARTIFACTS_LIST[0]}
|
||||
BASE_ARTIFACT_ARCH="${BASE_ARTIFACT##*-}"
|
||||
tar xf $BASE_ARTIFACT/$REV_NAME.tar.gz -C $BASE_ARTIFACT
|
||||
mv $BASE_ARTIFACT/$REV_NAME $REV_NAME
|
||||
mv $BASE_ARTIFACT $BUNDLE_DIR
|
||||
|
||||
# Executable binary paths that need to be combined.
|
||||
BIN_PATHS=(citra citra-room citra-qt.app/Contents/MacOS/citra-qt)
|
||||
|
||||
# Dylib paths that need to be combined.
|
||||
IFS=$'\n'
|
||||
DYLIB_PATHS=($(cd $REV_NAME && find . -name '*.dylib'))
|
||||
DYLIB_PATHS=($(cd $BUNDLE_DIR && find . -name '*.dylib'))
|
||||
unset IFS
|
||||
|
||||
# Combine all of the executable binaries and dylibs.
|
||||
for OTHER_ARTIFACT in "${ARTIFACTS_LIST[@]:1}"; do
|
||||
OTHER_ARTIFACT_ARCH="${OTHER_ARTIFACT##*-}"
|
||||
|
||||
tar xf $OTHER_ARTIFACT/$REV_NAME.tar.gz -C $OTHER_ARTIFACT
|
||||
|
||||
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
|
||||
|
||||
for DYLIB_PATH in "${DYLIB_PATHS[@]}"; do
|
||||
# Only merge if the libraries do not have conflicting arches, otherwise it will fail.
|
||||
DYLIB_INFO=`file $REV_NAME/$DYLIB_PATH`
|
||||
OTHER_DYLIB_INFO=`file $OTHER_ARTIFACT/$REV_NAME/$DYLIB_PATH`
|
||||
DYLIB_INFO=`file $BUNDLE_DIR/$DYLIB_PATH`
|
||||
OTHER_DYLIB_INFO=`file $OTHER_ARTIFACT/$DYLIB_PATH`
|
||||
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
|
||||
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
|
||||
|
||||
CURRENT_ARCH=`arch`
|
||||
if [ "$TARGET" = "$CURRENT_ARCH" ]; then
|
||||
ctest -VV -C Release
|
||||
fi
|
@ -1,36 +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_AUDIO_DECODER=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,13 +0,0 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
brew install ccache ninja || true
|
||||
|
||||
export QT_VER=5.15.8
|
||||
|
||||
mkdir tmp
|
||||
cd tmp/
|
||||
|
||||
# install Qt
|
||||
wget https://github.com/citra-emu/ext-macos-bin/raw/main/qt/qt-${QT_VER}.7z
|
||||
7z x qt-${QT_VER}.7z
|
||||
sudo cp -rv $(pwd)/qt-${QT_VER}/* /usr/local/
|
@ -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
|
48
.ci/pack.sh
Executable file
48
.ci/pack.sh
Executable file
@ -0,0 +1,48 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
|
||||
GITREV="`git show -s --format='%h'`"
|
||||
REV_NAME="citra-${OS}-${TARGET}-${GITDATE}-${GITREV}"
|
||||
|
||||
# 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)
|
||||
# For compatibility with existing installs, use mingw/osx in the archive and target names.
|
||||
if [ "$TARGET" = "msys2" ]; then
|
||||
REV_NAME="citra-${OS}-mingw-${GITDATE}-${GITREV}"
|
||||
RELEASE_NAME="${RELEASE_NAME}-mingw"
|
||||
elif [ "$OS" = "macos" ]; then
|
||||
REV_NAME="citra-osx-${TARGET}-${GITDATE}-${GITREV}"
|
||||
fi
|
||||
else
|
||||
RELEASE_NAME=head
|
||||
fi
|
||||
|
||||
mkdir -p artifacts
|
||||
|
||||
if [ -z "${UPLOAD_RAW}" ]; then
|
||||
# Archive and upload the artifacts.
|
||||
mkdir "$REV_NAME"
|
||||
mv build/bundle/* "$REV_NAME"
|
||||
|
||||
if [ "$OS" = "windows" ]; then
|
||||
ARCHIVE_NAME="${REV_NAME}.zip"
|
||||
powershell Compress-Archive "$REV_NAME" "$ARCHIVE_NAME"
|
||||
else
|
||||
ARCHIVE_NAME="${REV_NAME}.tar.gz"
|
||||
tar czvf "$ARCHIVE_NAME" "$REV_NAME"
|
||||
fi
|
||||
|
||||
mv "$REV_NAME" $RELEASE_NAME
|
||||
7z a "$REV_NAME.7z" $RELEASE_NAME
|
||||
|
||||
mv "$ARCHIVE_NAME" artifacts/
|
||||
mv "$REV_NAME.7z" artifacts/
|
||||
else
|
||||
# Directly upload the raw artifacts, renamed with the revision.
|
||||
for ARTIFACT in build/bundle/*; do
|
||||
FILENAME=$(basename "$ARTIFACT")
|
||||
EXTENSION="${FILENAME##*.}"
|
||||
mv "$ARTIFACT" "artifacts/$REV_NAME.$EXTENSION"
|
||||
done
|
||||
fi
|
@ -1,9 +1,13 @@
|
||||
#!/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}"
|
||||
|
||||
COMPAT_LIST='dist/compatibility_list/compatibility_list.json'
|
||||
|
||||
mkdir artifacts
|
||||
|
||||
pip3 install git-archive-all
|
||||
wget -q https://api.citra-emu.org/gamedb -O "${COMPAT_LIST}"
|
||||
git describe --abbrev=0 --always HEAD > GIT-COMMIT
|
@ -1,6 +1,4 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
set -x
|
||||
#!/bin/bash -ex
|
||||
|
||||
echo -e "\e[1m\e[33mBuild tools information:\e[0m"
|
||||
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=OFF \
|
||||
-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
|
||||
|
||||
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
|
||||
attributes:
|
||||
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:
|
||||
required: true
|
||||
- type: textarea
|
||||
|
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) {
|
||||
ref(qualifiedName:$ref) {
|
||||
target {
|
||||
... on Commit { id pushedDate oid }
|
||||
... on Commit { id committedDate oid }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22,9 +22,9 @@ async function checkBaseChanges(github, context) {
|
||||
ref: 'refs/heads/master',
|
||||
};
|
||||
const result = await github.graphql(query, variables);
|
||||
const pushedAt = result.repository.ref.target.pushedDate;
|
||||
console.log(`Last commit pushed at ${pushedAt}.`);
|
||||
const delta = new Date() - new Date(pushedAt);
|
||||
const committedAt = result.repository.ref.target.committedDate;
|
||||
console.log(`Last commit committed at ${committedAt}.`);
|
||||
const delta = new Date() - new Date(committedAt);
|
||||
if (delta <= DETECTION_TIME_FRAME) {
|
||||
console.info('New changes detected, triggering a new build.');
|
||||
return true;
|
||||
|
224
.github/workflows/ci.yml
vendored
224
.github/workflows/ci.yml
vendored
@ -11,7 +11,7 @@ jobs:
|
||||
clang-format:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: citraemu/build-environments:linux-clang-format
|
||||
image: citraemu/build-environments:linux-fresh
|
||||
options: -u 1001
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@ -20,41 +20,7 @@ jobs:
|
||||
- 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/
|
||||
run: ./.ci/clang-format.sh
|
||||
source:
|
||||
if: ${{ !github.head_ref }}
|
||||
runs-on: ubuntu-latest
|
||||
@ -63,17 +29,57 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Pack
|
||||
run: ./.ci/source/build.sh
|
||||
run: ./.ci/source.sh
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
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
|
||||
OS: linux
|
||||
TARGET: ${{ matrix.target }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Set up cache
|
||||
uses: actions/cache@v3
|
||||
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@v3
|
||||
if: ${{ matrix.target == 'appimage' }}
|
||||
with:
|
||||
name: ${{ env.OS }}-${{ env.TARGET }}
|
||||
path: artifacts/
|
||||
macos:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
arch: ["x86_64", "arm64"]
|
||||
target: ["x86_64", "arm64"]
|
||||
env:
|
||||
CCACHE_CPP2: yes
|
||||
CCACHE_SLOPPINESS: time_macros
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
OS: macos
|
||||
TARGET: ${{ matrix.target }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
@ -81,59 +87,66 @@ jobs:
|
||||
- name: Set up cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/Library/Caches/ccache
|
||||
key: ${{ runner.os }}-macos-${{ matrix.arch }}-${{ github.sha }}
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-macos-${{ matrix.arch }}-
|
||||
- name: Install dependencies
|
||||
run: ./.ci/macos/deps.sh
|
||||
${{ runner.os }}-${{ matrix.target }}-
|
||||
- name: Install tools
|
||||
run: brew install ccache glslang ninja
|
||||
- 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
|
||||
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@v3
|
||||
with:
|
||||
name: macos-${{ matrix.arch }}
|
||||
path: artifacts/
|
||||
path: ${{ env.OS }}-${{ env.TARGET }}
|
||||
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
macos-universal:
|
||||
runs-on: macos-latest
|
||||
needs: macos
|
||||
env:
|
||||
OS: macos
|
||||
TARGET: universal
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Download x86 build
|
||||
uses: actions/download-artifact@master
|
||||
- name: Download x86_64 build from cache
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
name: macos-x86_64
|
||||
path: macos-x86_64/
|
||||
- name: Download ARM64 build
|
||||
uses: actions/download-artifact@master
|
||||
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@v3
|
||||
with:
|
||||
name: macos-arm64
|
||||
path: macos-arm64/
|
||||
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
|
||||
run: ./.ci/macos-universal.sh
|
||||
env:
|
||||
ARTIFACTS: macos-x86_64 macos-arm64
|
||||
ARTIFACTS: ${{ env.OS }}-x86_64 ${{ env.OS }}-arm64
|
||||
- name: Pack
|
||||
run: ./.ci/pack.sh
|
||||
# - name: Upload
|
||||
# uses: actions/upload-artifact@v3
|
||||
# with:
|
||||
# name: macos
|
||||
# name: ${{ env.OS }}-${{ env.TARGET }}
|
||||
# path: artifacts/
|
||||
- name: Delete intermediate artifacts
|
||||
uses: geekyeggo/delete-artifact@v2
|
||||
with:
|
||||
name: |
|
||||
macos-x86_64
|
||||
macos-arm64
|
||||
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
|
||||
OS: windows
|
||||
TARGET: ${{ matrix.target }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
@ -141,29 +154,50 @@ jobs:
|
||||
- name: Set up cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.buildcache
|
||||
key: ${{ runner.os }}-win-${{ github.sha }}
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-win-
|
||||
- name: Install dependencies
|
||||
run: ./.ci/windows-msvc/deps.sh
|
||||
shell: bash
|
||||
${{ runner.os }}-${{ matrix.target }}-
|
||||
- name: Set up MSVC
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
if: ${{ matrix.target == 'msvc' }}
|
||||
- name: Install MSVC extra tools
|
||||
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: Setup Vulkan SDK
|
||||
uses: humbletim/setup-vulkan-sdk@v1.2.0
|
||||
with:
|
||||
vulkan-query-version: latest
|
||||
vulkan-components: Glslang
|
||||
vulkan-use-cache: true
|
||||
- name: Test glslangValidator
|
||||
run: glslangValidator --version
|
||||
- name: Disable line ending translation
|
||||
run: git config --global core.autocrlf input
|
||||
- name: Build
|
||||
run: ./.ci/windows-msvc/build.sh
|
||||
shell: bash
|
||||
env:
|
||||
ENABLE_COMPATIBILITY_REPORTING: "ON"
|
||||
run: ./.ci/windows.sh
|
||||
- name: Pack
|
||||
run: ./.ci/windows-msvc/upload.ps1
|
||||
run: ./.ci/pack.sh
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: msvc
|
||||
name: ${{ env.OS }}-${{ env.TARGET }}
|
||||
path: artifacts/
|
||||
android:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
OS: android
|
||||
TARGET: universal
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
@ -186,24 +220,28 @@ jobs:
|
||||
echo $GIT_TAG_NAME
|
||||
- name: Deps
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install ccache apksigner -y
|
||||
sudo add-apt-repository -y ppa:theofficialgman/gpu-tools
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install ccache glslang-dev glslang-tools apksigner -y
|
||||
- name: Build
|
||||
run: ./.ci/android/build.sh
|
||||
- name: Copy and sign artifacts
|
||||
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 }}
|
||||
run: ./.ci/android/upload.sh
|
||||
- name: Pack
|
||||
run: ../../../.ci/pack.sh
|
||||
working-directory: src/android/app
|
||||
env:
|
||||
UPLOAD_RAW: 1
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: android
|
||||
path: artifacts/
|
||||
name: ${{ env.OS }}-${{ env.TARGET }}
|
||||
path: src/android/app/artifacts/
|
||||
transifex:
|
||||
runs-on: ubuntu-latest
|
||||
container: citraemu/build-environments:linux-transifex
|
||||
container: citraemu/build-environments:linux-fresh
|
||||
if: ${{ github.repository == 'citra-emu/citra' && !github.head_ref }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@ -211,12 +249,12 @@ jobs:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
- name: Update Translation
|
||||
run: ./.ci/transifex/docker.sh
|
||||
run: ./.ci/transifex.sh
|
||||
env:
|
||||
TX_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build, android, macos-universal, source, windows]
|
||||
needs: [windows, linux, macos-universal, android, source]
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -13,6 +13,8 @@ src/common/scm_rev.cpp
|
||||
.vs/
|
||||
.vscode/
|
||||
.cache/
|
||||
cmake-build-debug/
|
||||
cmake-build-release/
|
||||
CMakeLists.txt.user*
|
||||
|
||||
# *nix related
|
||||
@ -41,4 +43,6 @@ Thumbs.db
|
||||
repo/
|
||||
|
||||
# GitHub Actions generated files
|
||||
.ccache/
|
||||
node_modules/
|
||||
VULKAN_SDK/
|
||||
|
23
.gitmodules
vendored
23
.gitmodules
vendored
@ -36,7 +36,7 @@
|
||||
url = https://github.com/mozilla/cubeb
|
||||
[submodule "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"]
|
||||
path = externals/cpp-jwt
|
||||
url = https://github.com/arun11299/cpp-jwt.git
|
||||
@ -64,6 +64,21 @@
|
||||
[submodule "dds-ktx"]
|
||||
path = externals/dds-ktx
|
||||
url = https://github.com/septag/dds-ktx
|
||||
[submodule "externals/openal-soft"]
|
||||
path = externals/openal-soft
|
||||
url = https://github.com/kcat/openal-soft
|
||||
[submodule "openal-soft"]
|
||||
path = externals/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 "library-headers"]
|
||||
path = externals/library-headers/library-headers
|
||||
url = https://github.com/citra-emu/ext-library-headers.git
|
||||
|
239
CMakeLists.txt
239
CMakeLists.txt
@ -5,6 +5,10 @@ cmake_minimum_required(VERSION 3.15)
|
||||
cmake_policy(SET CMP0092 NEW)
|
||||
# Enforce new LTO setting
|
||||
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}/externals/cmake-modules")
|
||||
@ -14,66 +18,71 @@ include(CMakeDependentOption)
|
||||
project(citra LANGUAGES C CXX ASM)
|
||||
|
||||
if (APPLE)
|
||||
enable_language(OBJC)
|
||||
# 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>")
|
||||
|
||||
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()
|
||||
|
||||
option(ENABLE_LTO "Enable link time optimization" OFF)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||
set(IS_DEBUG_BUILD ON)
|
||||
else()
|
||||
set(IS_DEBUG_BUILD OFF)
|
||||
endif()
|
||||
|
||||
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
|
||||
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)
|
||||
|
||||
# Set bundled qt as dependent options.
|
||||
option(ENABLE_QT "Enable the Qt frontend" ON)
|
||||
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" 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)
|
||||
if (MSVC)
|
||||
set(OPENSSL_DLL_DIR "" CACHE PATH "Location of the Openssl dlls")
|
||||
endif()
|
||||
option(ENABLE_SCRIPTING "Enable RPC server for scripting" ON)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
option(ENABLE_FFMPEG_VIDEO_DUMPER "Enable FFmpeg video dumper" OFF)
|
||||
|
||||
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(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)
|
||||
|
||||
# Compile options
|
||||
CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ${IS_DEBUG_BUILD} "MINGW" OFF)
|
||||
option(ENABLE_LTO "Enable link time optimization" OFF)
|
||||
option(CITRA_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON)
|
||||
option(CITRA_WARNINGS_AS_ERRORS "Enable warnings as errors" ON)
|
||||
|
||||
if (CITRA_USE_PRECOMPILED_HEADERS)
|
||||
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()
|
||||
# System library options
|
||||
CMAKE_DEPENDENT_OPTION(USE_SYSTEM_QT "Use the system Qt lib (instead of the bundled one)" OFF "ENABLE_QT;MSVC OR APPLE" ON)
|
||||
CMAKE_DEPENDENT_OPTION(USE_SYSTEM_MOLTENVK "Use the system MoltenVK lib (instead of the bundled one)" OFF "APPLE" OFF)
|
||||
option(USE_SYSTEM_SDL2 "Use the system SDL2 lib (instead of the bundled one)" OFF)
|
||||
option(USE_SYSTEM_BOOST "Use the system Boost libs (instead of the bundled ones)" OFF)
|
||||
option(USE_SYSTEM_OPENSSL "Use the system OpenSSL libs (instead of the bundled LibreSSL)" OFF)
|
||||
option(USE_SYSTEM_LIBUSB "Use the system libusb (instead of the bundled libusb)" OFF)
|
||||
|
||||
if (CITRA_USE_PRECOMPILED_HEADERS)
|
||||
message(STATUS "Using Precompiled Headers.")
|
||||
set(CMAKE_PCH_INSTANTIATE_TEMPLATES ON)
|
||||
@ -123,7 +132,10 @@ function(check_submodules_present)
|
||||
endif()
|
||||
endforeach()
|
||||
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
|
||||
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
|
||||
@ -186,9 +198,15 @@ message(STATUS "Target architecture: ${ARCHITECTURE}")
|
||||
|
||||
# boost asio's concept usage doesn't play nicely with some compilers yet.
|
||||
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_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(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/$<CONFIG>)
|
||||
|
||||
@ -201,89 +219,43 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
if (ENABLE_QT)
|
||||
if (CITRA_USE_BUNDLED_QT)
|
||||
download_qt_external(5.15.2 QT_PREFIX)
|
||||
list(APPEND CMAKE_PREFIX_PATH ${QT_PREFIX})
|
||||
if (NOT USE_SYSTEM_QT)
|
||||
download_qt(6.5.0)
|
||||
endif()
|
||||
|
||||
find_package(Qt5 REQUIRED COMPONENTS Widgets Multimedia Concurrent)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia Concurrent)
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
find_package(Qt5 REQUIRED COMPONENTS DBus)
|
||||
find_package(Qt6 REQUIRED COMPONENTS DBus)
|
||||
endif()
|
||||
|
||||
if (ENABLE_QT_TRANSLATION)
|
||||
find_package(Qt5 REQUIRED COMPONENTS LinguistTools)
|
||||
endif()
|
||||
|
||||
if (NOT CITRA_USE_BUNDLED_QT)
|
||||
# Make sure the Qt bin directory is in the prefix path for later consumers.
|
||||
get_target_property(qmake_executable Qt5::qmake IMPORTED_LOCATION)
|
||||
get_filename_component(qt_bin_dir "${qmake_executable}" DIRECTORY)
|
||||
list(APPEND CMAKE_PREFIX_PATH ${qt_bin_dir})
|
||||
find_package(Qt6 REQUIRED COMPONENTS LinguistTools)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# 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()
|
||||
# Use system tsl::robin_map if available (otherwise we fallback to version bundled with dynarmic)
|
||||
find_package(tsl-robin-map QUIET)
|
||||
|
||||
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()
|
||||
message(FATAL_ERROR "No bundled FFmpeg binaries for your toolchain. Disable CITRA_USE_BUNDLED_FFMPEG and provide your own.")
|
||||
endif()
|
||||
|
||||
if (DEFINED FFmpeg_VER)
|
||||
download_bundled_external("ffmpeg/" ${FFmpeg_VER} FFmpeg_PREFIX)
|
||||
set(FFMPEG_DIR "${FFmpeg_PREFIX}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (ENABLE_FFMPEG_VIDEO_DUMPER)
|
||||
find_package(FFmpeg REQUIRED COMPONENTS avcodec avformat avutil swscale swresample)
|
||||
else()
|
||||
find_package(FFmpeg REQUIRED COMPONENTS avcodec)
|
||||
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)
|
||||
add_definitions(-DENABLE_FFMPEG_VIDEO_DUMPER)
|
||||
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()
|
||||
# Platform-specific library requirements
|
||||
# ======================================
|
||||
|
||||
if (APPLE)
|
||||
# Umbrella framework for everything GUI-related
|
||||
find_library(COCOA_LIBRARY Cocoa)
|
||||
find_library(AVFOUNDATION_LIBRARY AVFoundation)
|
||||
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${AVFOUNDATION_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY})
|
||||
if (NOT USE_SYSTEM_MOLTENVK)
|
||||
download_moltenvk()
|
||||
endif()
|
||||
find_library(MOLTENVK_LIBRARY MoltenVK REQUIRED)
|
||||
message(STATUS "Using MoltenVK at ${MOLTENVK_LIBRARY}.")
|
||||
|
||||
if (NOT IOS)
|
||||
# Umbrella framework for everything GUI-related
|
||||
find_library(COCOA_LIBRARY Cocoa REQUIRED)
|
||||
endif()
|
||||
|
||||
find_library(AVFOUNDATION_LIBRARY AVFoundation REQUIRED)
|
||||
find_library(IOSURFACE_LIBRARY IOSurface REQUIRED)
|
||||
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${AVFOUNDATION_LIBRARY} ${IOSURFACE_LIBRARY} ${MOLTENVK_LIBRARY})
|
||||
elseif (WIN32)
|
||||
# WSAPoll and SHGetKnownFolderPath (AppData/Roaming) didn't exist before WinNT 6.x (Vista)
|
||||
add_definitions(-D_WIN32_WINNT=0x0601 -DWINVER=0x0601)
|
||||
set(PLATFORM_LIBRARIES winmm ws2_32)
|
||||
if (MINGW)
|
||||
# PSAPI is the Process Status API
|
||||
@ -333,7 +305,7 @@ if (CLANG_FORMAT)
|
||||
add_custom_target(clang-format
|
||||
COMMAND powershell.exe -Command "Get-ChildItem '${SRCS}/*' -Include *.cpp,*.h,*.mm -Recurse | Foreach {&'${CLANG_FORMAT}' -i $_.fullname}"
|
||||
COMMENT ${CCOMMENT})
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
add_custom_target(clang-format
|
||||
COMMAND find ${SRCS} -iname *.h -o -iname *.cpp -o -iname *.mm | xargs ${CLANG_FORMAT} -i
|
||||
@ -370,13 +342,6 @@ function(get_timestamp _var)
|
||||
set(${_var} "${timestamp}" PARENT_SCOPE)
|
||||
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
|
||||
include(GetGitRevisionDescription)
|
||||
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
||||
@ -384,22 +349,23 @@ git_describe(GIT_DESC --always --long --dirty)
|
||||
git_branch_name(GIT_BRANCH)
|
||||
get_timestamp(BUILD_DATE)
|
||||
|
||||
if (NOT USE_SYSTEM_BOOST)
|
||||
add_definitions( -DBOOST_ALL_NO_LIB )
|
||||
# Boost
|
||||
# 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()
|
||||
|
||||
enable_testing()
|
||||
add_subdirectory(externals)
|
||||
|
||||
# See externals/CMakeLists.txt
|
||||
foreach(def ${CRYPTOPP_COMPILE_DEFINITIONS})
|
||||
add_definitions(-D${def})
|
||||
endforeach()
|
||||
|
||||
# Boost
|
||||
if (USE_SYSTEM_BOOST)
|
||||
find_package(Boost 1.70.0 COMPONENTS serialization iostreams REQUIRED)
|
||||
else()
|
||||
# Boost (bundled)
|
||||
if (NOT USE_SYSTEM_BOOST)
|
||||
add_definitions( -DBOOST_ALL_NO_LIB )
|
||||
add_library(Boost::boost ALIAS boost)
|
||||
add_library(Boost::serialization ALIAS boost_serialization)
|
||||
add_library(Boost::iostreams ALIAS boost_iostreams)
|
||||
@ -414,6 +380,11 @@ if (ENABLE_SDL2 AND USE_SYSTEM_SDL2)
|
||||
add_library(SDL2::SDL2 ALIAS SDL2)
|
||||
endif()
|
||||
|
||||
if (ENABLE_LIBUSB AND USE_SYSTEM_LIBUSB)
|
||||
include(FindPkgConfig)
|
||||
find_package(LibUSB)
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(dist/installer)
|
||||
|
||||
@ -425,6 +396,20 @@ else()
|
||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT citra)
|
||||
endif()
|
||||
|
||||
# Create target for outputting distributable bundles.
|
||||
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
|
||||
# =========================
|
||||
|
||||
@ -433,7 +418,7 @@ endif()
|
||||
# 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
|
||||
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")
|
||||
install(FILES "${PROJECT_SOURCE_DIR}/dist/citra.svg"
|
||||
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps")
|
||||
|
@ -12,7 +12,7 @@ endif()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${BASE_DIR}/CMakeModules")
|
||||
include(DownloadExternals)
|
||||
download_qt_external(tools_ifw QT_PREFIX)
|
||||
download_qt(tools_ifw QT_PREFIX)
|
||||
|
||||
file(GLOB_RECURSE INSTALLER_BASE "${QT_PREFIX}/**/installerbase*")
|
||||
file(GLOB_RECURSE BINARY_CREATOR "${QT_PREFIX}/**/binarycreator*")
|
||||
|
@ -1,62 +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)
|
||||
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()
|
271
CMakeModules/BundleTarget.cmake
Normal file
271
CMakeModules/BundleTarget.cmake
Normal file
@ -0,0 +1,271 @@
|
||||
|
||||
if (BUNDLE_TARGET_EXECUTE)
|
||||
# --- Bundling method logic ---
|
||||
|
||||
function(bundle_qt executable_path)
|
||||
if (WIN32)
|
||||
get_filename_component(executable_parent_dir "${executable_path}" DIRECTORY)
|
||||
find_program(windeployqt_executable windeployqt6)
|
||||
|
||||
# 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 = .")
|
||||
|
||||
message(STATUS "Executing windeployqt for executable ${executable_path}")
|
||||
execute_process(COMMAND "${windeployqt_executable}" "${executable_path}"
|
||||
--no-compiler-runtime --no-system-d3d-compiler --no-opengl-sw --no-translations
|
||||
--plugindir "${executable_parent_dir}/plugins")
|
||||
|
||||
# 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)
|
||||
|
||||
message(STATUS "Executing macdeployqt for executable ${executable_path}")
|
||||
execute_process(
|
||||
COMMAND "${MACDEPLOYQT_EXECUTABLE}"
|
||||
"${executable_path}"
|
||||
"-executable=${executable_path}/Contents/MacOS/${executable_name}"
|
||||
-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 - "${executable_path}")
|
||||
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)
|
||||
|
||||
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}")
|
||||
|
||||
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}")
|
||||
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}")
|
||||
# Use native copy to turn symlinks into normal files.
|
||||
execute_process(COMMAND cp -L "${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}")
|
||||
elseif (UNIX)
|
||||
execute_process(COMMAND patchelf --set-rpath '$ORIGIN/../libs' "${executable_path}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# --- Root bundling logic ---
|
||||
|
||||
set(bundle_dir ${BINARY_PATH}/bundle)
|
||||
|
||||
# On Linux, always bundle an AppImage.
|
||||
if (DEFINED LINUXDEPLOY)
|
||||
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}")
|
||||
endif()
|
||||
|
||||
if (WIN32 OR NOT BUNDLE_QT)
|
||||
bundle_standalone("${bundled_executable_path}" "${EXECUTABLE_PATH}" "${BUNDLE_LIBRARY_PATHS}")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
# --- Bundling target creation 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/linuxdeploy/${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}")
|
||||
else()
|
||||
message(STATUS "Copying ${executable_name}")
|
||||
file(COPY "${executable_file}" DESTINATION "${base_dir}/squashfs-root/usr/bin/")
|
||||
endif()
|
||||
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)
|
||||
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 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")
|
||||
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_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()
|
||||
|
||||
# On Linux, prepare linuxdeploy and any required plugins.
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(LINUXDEPLOY_BASE "${CMAKE_BINARY_DIR}/externals/linuxdeploy")
|
||||
|
||||
# Download plugins first so they don't overwrite linuxdeploy's AppRun file.
|
||||
download_linuxdeploy_component("${LINUXDEPLOY_BASE}" "linuxdeploy-plugin-qt" "linuxdeploy-plugin-qt-x86_64.AppImage")
|
||||
download_linuxdeploy_component("${LINUXDEPLOY_BASE}" "linuxdeploy-plugin-checkrt" "linuxdeploy-plugin-checkrt-x86_64.sh")
|
||||
download_linuxdeploy_component("${LINUXDEPLOY_BASE}" "linuxdeploy" "linuxdeploy-x86_64.AppImage")
|
||||
|
||||
set(EXTRA_BUNDLE_ARGS "-DLINUXDEPLOY=${LINUXDEPLOY_BASE}/squashfs-root/AppRun")
|
||||
endif()
|
||||
|
||||
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}
|
||||
"-DCMAKE_PREFIX_PATH=\"${CMAKE_PREFIX_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}"
|
||||
${EXTRA_BUNDLE_ARGS}
|
||||
-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,47 +0,0 @@
|
||||
function(copy_citra_Qt5_deps target_dir)
|
||||
include(WindowsCopyFiles)
|
||||
set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
|
||||
set(Qt5_DLL_DIR "${Qt5_DIR}/../../../bin")
|
||||
set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/")
|
||||
set(Qt5_MEDIASERVICE_DIR "${Qt5_DIR}/../../../plugins/mediaservice/")
|
||||
set(Qt5_STYLES_DIR "${Qt5_DIR}/../../../plugins/styles/")
|
||||
set(Qt5_IMAGEFORMATS_DIR "${Qt5_DIR}/../../../plugins/imageformats/")
|
||||
set(PLATFORMS ${DLL_DEST}plugins/platforms/)
|
||||
set(MEDIASERVICE ${DLL_DEST}plugins/mediaservice/)
|
||||
set(STYLES ${DLL_DEST}plugins/styles/)
|
||||
set(IMAGEFORMATS ${DLL_DEST}plugins/imageformats/)
|
||||
windows_copy_files(${target_dir} ${Qt5_DLL_DIR} ${DLL_DEST}
|
||||
icudt*.dll
|
||||
icuin*.dll
|
||||
icuuc*.dll
|
||||
Qt5Core$<$<CONFIG:Debug>:d>.*
|
||||
Qt5Gui$<$<CONFIG:Debug>:d>.*
|
||||
Qt5Widgets$<$<CONFIG:Debug>:d>.*
|
||||
Qt5Concurrent$<$<CONFIG:Debug>:d>.*
|
||||
Qt5Multimedia$<$<CONFIG:Debug>:d>.*
|
||||
Qt5Network$<$<CONFIG:Debug>:d>.*
|
||||
)
|
||||
windows_copy_files(citra-qt ${Qt5_PLATFORMS_DIR} ${PLATFORMS} qwindows$<$<CONFIG:Debug>:d>.*)
|
||||
windows_copy_files(citra-qt ${Qt5_MEDIASERVICE_DIR} ${MEDIASERVICE}
|
||||
dsengine$<$<CONFIG:Debug>:d>.*
|
||||
wmfengine$<$<CONFIG:Debug>:d>.*
|
||||
)
|
||||
windows_copy_files(citra-qt ${Qt5_STYLES_DIR} ${STYLES} qwindowsvistastyle$<$<CONFIG:Debug>:d>.*)
|
||||
windows_copy_files(${target_dir} ${Qt5_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_Qt5_deps)
|
@ -1,5 +0,0 @@
|
||||
function(copy_citra_SDL_deps target_dir)
|
||||
include(WindowsCopyFiles)
|
||||
set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
|
||||
windows_copy_files(${target_dir} ${SDL2_DLL_DIR} ${DLL_DEST} SDL2.dll)
|
||||
endfunction(copy_citra_SDL_deps)
|
@ -1,96 +1,117 @@
|
||||
|
||||
# This function downloads a binary library package from our external repo.
|
||||
# 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)
|
||||
set(repo_base "ext-windows-bin/raw/master")
|
||||
elseif (APPLE)
|
||||
set(repo_base "ext-macos-bin/raw/main")
|
||||
else()
|
||||
message(FATAL_ERROR "Bundled libraries are unsupported for this OS.")
|
||||
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()
|
||||
|
||||
# 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)
|
||||
function(download_qt target)
|
||||
# Determine installation parameters for OS, architecture, and compiler
|
||||
if (WIN32)
|
||||
set(host "windows")
|
||||
set(type "desktop")
|
||||
if (MINGW)
|
||||
set(arch_path "mingw81")
|
||||
elseif ((MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1940) AND "x86_64" IN_LIST ARCHITECTURE)
|
||||
set(arch "win64_mingw")
|
||||
set(arch_path "mingw_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. Disable CITRA_USE_BUNDLED_QT and provide your own.")
|
||||
message(FATAL_ERROR "Unsupported bundled Qt architecture. Enable USE_SYSTEM_QT and provide your own.")
|
||||
endif()
|
||||
set(arch "win64_${arch_path}")
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported bundled Qt toolchain. 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()
|
||||
set(arch "win64_${arch_path}")
|
||||
elseif (APPLE)
|
||||
set(host "mac")
|
||||
set(arch "clang_64")
|
||||
set(arch_path "macos")
|
||||
if (IOS)
|
||||
set(type "ios")
|
||||
set(arch "ios")
|
||||
set(arch_path "ios")
|
||||
set(host_arch_path "macos")
|
||||
else()
|
||||
set(type "desktop")
|
||||
set(arch "clang_64")
|
||||
set(arch_path "macos")
|
||||
endif()
|
||||
else()
|
||||
set(host "linux")
|
||||
set(type "desktop")
|
||||
set(arch "gcc_64")
|
||||
set(arch_path "linux")
|
||||
endif()
|
||||
|
||||
get_external_prefix(qt base_path)
|
||||
file(MAKE_DIRECTORY "${base_path}")
|
||||
|
||||
if (target MATCHES "tools_.*")
|
||||
set(prefix "${base_path}")
|
||||
set(install_args install-tool --outputdir ${base_path} ${host} desktop ${target})
|
||||
else()
|
||||
set(prefix "${base_path}/${target}/${arch_path}")
|
||||
set(install_args install-qt --outputdir ${base_path} ${host} desktop ${target} ${arch})
|
||||
if (host_arch_path)
|
||||
set(host_flag "--autodesktop")
|
||||
set(host_prefix "${base_path}/${target}/${host_arch_path}")
|
||||
endif()
|
||||
set(install_args install-qt --outputdir ${base_path} ${host} ${type} ${target} ${arch} ${host_flag} -m qtmultimedia)
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS "${prefix}")
|
||||
message(STATUS "Downloading binaries for Qt...")
|
||||
if (WIN32)
|
||||
set(aqt_path "${CMAKE_BINARY_DIR}/externals/aqt.exe")
|
||||
set(aqt_path "${base_path}/aqt.exe")
|
||||
file(DOWNLOAD
|
||||
https://github.com/miurahr/aqtinstall/releases/download/v3.1.4/aqt.exe
|
||||
${aqt_path} SHOW_PROGRESS)
|
||||
execute_process(COMMAND ${aqt_path} ${install_args})
|
||||
execute_process(COMMAND ${aqt_path} ${install_args}
|
||||
WORKING_DIRECTORY ${base_path})
|
||||
else()
|
||||
# aqt does not offer binary releases for other platforms, so download and run from pip.
|
||||
set(aqt_install_path "${CMAKE_BINARY_DIR}/externals/aqt")
|
||||
execute_process(COMMAND python3 -m pip install --target=${aqt_install_path} aqtinstall)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${aqt_install_path} python3 -m aqt ${install_args})
|
||||
set(aqt_install_path "${base_path}/aqt")
|
||||
file(MAKE_DIRECTORY "${aqt_install_path}")
|
||||
|
||||
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 "Using downloaded Qt binaries at ${prefix}")
|
||||
set(${prefix_var} "${prefix}" PARENT_SCOPE)
|
||||
|
||||
# Add the Qt prefix path so CMake can locate it.
|
||||
list(APPEND CMAKE_PREFIX_PATH "${prefix}")
|
||||
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
|
||||
|
||||
if (DEFINED host_prefix)
|
||||
message(STATUS "Using downloaded host Qt binaries at ${host_prefix}")
|
||||
set(QT_HOST_PATH "${host_prefix}" CACHE STRING "")
|
||||
endif()
|
||||
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/latest/download/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()
|
||||
|
||||
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,55 +1,5 @@
|
||||
# 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()
|
||||
|
||||
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()
|
||||
list(APPEND CMAKE_MODULE_PATH "${SRC_DIR}/CMakeModules")
|
||||
include(GenerateBuildInfo)
|
||||
|
||||
# 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")
|
||||
|
@ -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,54 +0,0 @@
|
||||
SET(MINGW_PREFIX /usr/x86_64-w64-mingw32/)
|
||||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
SET(CMAKE_SYSTEM_PROCESSOR x86_64)
|
||||
# Actually a hack, w/o this will cause some strange errors
|
||||
SET(CMAKE_HOST_WIN32 TRUE)
|
||||
|
||||
|
||||
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()
|
@ -2,45 +2,49 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string></string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>citra.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.citra-emu.citra</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string></string>
|
||||
<!-- Templated data -->
|
||||
<key>CFBundleName</key>
|
||||
<string>Citra</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string></string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string></string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>LSRequiresCarbon</key>
|
||||
<true/>
|
||||
<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></string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<string>True</string>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<!-- Fixed -->
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.games</string>
|
||||
<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>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.games</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[fr]=Émulateur de console de jeu Nintendo 3DS
|
||||
Icon=citra
|
||||
TryExec=citra-qt
|
||||
Exec=citra-qt %f
|
||||
Categories=Game;Emulator;Qt;
|
||||
TryExec=citra
|
||||
Exec=citra %f
|
||||
Categories=Game;Emulator;
|
||||
MimeType=application/x-ctr-3dsx;application/x-ctr-cci;application/x-ctr-cia;application/x-ctr-cxi;
|
||||
Keywords=3DS;Nintendo;
|
||||
PrefersNonDefaultGPU=true
|
||||
|
14
dist/qt_themes/default/style.qss
vendored
14
dist/qt_themes/default/style.qss
vendored
@ -1,3 +1,17 @@
|
||||
QPushButton#GraphicsAPIStatusBarButton {
|
||||
color: #656565;
|
||||
border: 1px solid transparent;
|
||||
background-color: transparent;
|
||||
padding: 0px 3px 0px 3px;
|
||||
text-align: center;
|
||||
min-width: 60px;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
QPushButton#GraphicsAPIStatusBarButton:hover {
|
||||
border: 1px solid #76797C;
|
||||
}
|
||||
|
||||
QPushButton#3DOptionStatusBarButton {
|
||||
color: #A5A5A5;
|
||||
font-weight: bold;
|
||||
|
33
dist/qt_themes/qdarkstyle/style.qss
vendored
33
dist/qt_themes/qdarkstyle/style.qss
vendored
@ -1,3 +1,31 @@
|
||||
QPushButton#TogglableStatusBarButton {
|
||||
color: #959595;
|
||||
border: 1px solid transparent;
|
||||
background-color: transparent;
|
||||
padding: 0px 3px 0px 3px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
QPushButton#TogglableStatusBarButton:checked {
|
||||
color: palette(text);
|
||||
}
|
||||
|
||||
QPushButton#TogglableStatusBarButton:hover {
|
||||
border: 1px solid #76797C;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
QToolTip {
|
||||
border: 1px solid #76797C;
|
||||
background-color: #5A7566;
|
||||
@ -270,6 +298,11 @@ QAbstractItemView:read-only {
|
||||
alternate-background-color: #232629;
|
||||
}
|
||||
|
||||
/* Workaround for https://bugreports.qt.io/browse/QTBUG-115529 */
|
||||
QAbstractItemView:item {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
QWidget:focus {
|
||||
border: 1px solid #3daee9;
|
||||
}
|
||||
|
@ -481,6 +481,11 @@ QAbstractItemView QLineEdit {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
/* Workaround for https://bugreports.qt.io/browse/QTBUG-115529 */
|
||||
QAbstractItemView:item {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
/* QAbstractScrollArea ----------------------------------------------------
|
||||
|
||||
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea
|
||||
|
150
externals/CMakeLists.txt
vendored
150
externals/CMakeLists.txt
vendored
@ -3,6 +3,8 @@
|
||||
# Suppress warnings from external libraries
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
add_compile_options(/W0)
|
||||
else()
|
||||
add_compile_options(-w)
|
||||
endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules)
|
||||
@ -10,46 +12,42 @@ include(DownloadExternals)
|
||||
include(ExternalProject)
|
||||
|
||||
# Boost
|
||||
set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/boost")
|
||||
set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost")
|
||||
set(Boost_NO_SYSTEM_PATHS ON)
|
||||
add_library(boost INTERFACE)
|
||||
target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR})
|
||||
if (NOT USE_SYSTEM_BOOST)
|
||||
message(STATUS "Including vendored Boost library")
|
||||
set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/boost" CACHE STRING "")
|
||||
set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost" CACHE STRING "")
|
||||
set(Boost_NO_SYSTEM_PATHS ON CACHE BOOL "")
|
||||
add_library(boost INTERFACE)
|
||||
target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR})
|
||||
|
||||
# Boost::serialization
|
||||
file(GLOB boost_serialization_SRC "${CMAKE_SOURCE_DIR}/externals/boost/libs/serialization/src/*.cpp")
|
||||
add_library(boost_serialization STATIC ${boost_serialization_SRC})
|
||||
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::serialization
|
||||
file(GLOB boost_serialization_SRC "${CMAKE_SOURCE_DIR}/externals/boost/libs/serialization/src/*.cpp")
|
||||
add_library(boost_serialization STATIC ${boost_serialization_SRC})
|
||||
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)
|
||||
# Add additional boost libs here; remember to ALIAS them in the root CMakeLists!
|
||||
endif()
|
||||
|
||||
# Catch2
|
||||
set(CATCH_INSTALL_DOCS OFF)
|
||||
set(CATCH_INSTALL_EXTRAS OFF)
|
||||
set(CATCH_INSTALL_DOCS OFF CACHE BOOL "")
|
||||
set(CATCH_INSTALL_EXTRAS OFF CACHE BOOL "")
|
||||
add_subdirectory(catch2)
|
||||
|
||||
# Crypto++
|
||||
set(CRYPTOPP_BUILD_DOCUMENTATION OFF)
|
||||
set(CRYPTOPP_BUILD_TESTING OFF)
|
||||
set(CRYPTOPP_INSTALL OFF)
|
||||
set(CRYPTOPP_SOURCES "${CMAKE_SOURCE_DIR}/externals/cryptopp")
|
||||
set(CRYPTOPP_BUILD_DOCUMENTATION OFF CACHE BOOL "")
|
||||
set(CRYPTOPP_BUILD_TESTING OFF CACHE BOOL "")
|
||||
set(CRYPTOPP_INSTALL OFF CACHE BOOL "")
|
||||
set(CRYPTOPP_SOURCES "${CMAKE_SOURCE_DIR}/externals/cryptopp" CACHE STRING "")
|
||||
add_subdirectory(cryptopp-cmake)
|
||||
|
||||
# HACK: Mismatch between compilation of CryptoPP and headers used in Citra can cause runtime issues.
|
||||
# Pull out the compile definitions from CryptoPP and apply them to Citra as well to fix this.
|
||||
# See: https://github.com/weidai11/cryptopp/issues/1191
|
||||
get_source_file_property(CRYPTOPP_COMPILE_DEFINITIONS ${CRYPTOPP_SOURCES}/cryptlib.cpp TARGET_DIRECTORY cryptopp COMPILE_DEFINITIONS)
|
||||
set(CRYPTOPP_COMPILE_DEFINITIONS ${CRYPTOPP_COMPILE_DEFINITIONS} PARENT_SCOPE)
|
||||
|
||||
# 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)
|
||||
@ -80,8 +78,8 @@ endif()
|
||||
|
||||
# Dynarmic
|
||||
if ("x86_64" IN_LIST ARCHITECTURE OR "arm64" IN_LIST ARCHITECTURE)
|
||||
set(DYNARMIC_TESTS OFF)
|
||||
set(DYNARMIC_FRONTENDS "A32")
|
||||
set(DYNARMIC_TESTS OFF CACHE BOOL "")
|
||||
set(DYNARMIC_FRONTENDS "A32" CACHE STRING "")
|
||||
add_subdirectory(dynarmic EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
@ -93,28 +91,43 @@ endif()
|
||||
# Glad
|
||||
add_subdirectory(glad)
|
||||
|
||||
# glslang
|
||||
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 "")
|
||||
add_subdirectory(glslang)
|
||||
|
||||
# inih
|
||||
add_subdirectory(inih)
|
||||
|
||||
# MicroProfile
|
||||
add_library(microprofile INTERFACE)
|
||||
target_include_directories(microprofile INTERFACE ./microprofile)
|
||||
target_include_directories(microprofile SYSTEM INTERFACE ./microprofile)
|
||||
|
||||
# Nihstro
|
||||
add_library(nihstro-headers INTERFACE)
|
||||
target_include_directories(nihstro-headers INTERFACE ./nihstro/include)
|
||||
target_include_directories(nihstro-headers SYSTEM INTERFACE ./nihstro/include)
|
||||
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()
|
||||
|
||||
# Open Source Archives
|
||||
add_subdirectory(open_source_archives)
|
||||
|
||||
# SoundTouch
|
||||
# Dynamic library headers
|
||||
add_subdirectory(library-headers EXCLUDE_FROM_ALL)
|
||||
|
||||
# SoundTouch
|
||||
set(INTEGER_SAMPLES ON CACHE BOOL "")
|
||||
set(SOUNDSTRETCH OFF CACHE BOOL "")
|
||||
set(SOUNDTOUCH_DLL OFF CACHE BOOL "")
|
||||
add_subdirectory(soundtouch)
|
||||
add_subdirectory(soundtouch EXCLUDE_FROM_ALL)
|
||||
|
||||
# sirit
|
||||
add_subdirectory(sirit EXCLUDE_FROM_ALL)
|
||||
|
||||
# Teakra
|
||||
add_subdirectory(teakra EXCLUDE_FROM_ALL)
|
||||
@ -124,6 +137,13 @@ if (ENABLE_SDL2 AND NOT USE_SYSTEM_SDL2)
|
||||
add_subdirectory(sdl2)
|
||||
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
|
||||
set(ZSTD_LEGACY_SUPPORT OFF)
|
||||
set(ZSTD_BUILD_PROGRAMS OFF)
|
||||
@ -138,6 +158,8 @@ target_include_directories(enet INTERFACE ./enet/include)
|
||||
# Cubeb
|
||||
if (ENABLE_CUBEB)
|
||||
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()
|
||||
|
||||
@ -151,33 +173,39 @@ endif()
|
||||
add_library(json-headers INTERFACE)
|
||||
target_include_directories(json-headers INTERFACE ./json)
|
||||
|
||||
if (ENABLE_WEB_SERVICE)
|
||||
# OpenSSL
|
||||
if (USE_SYSTEM_OPENSSL)
|
||||
find_package(OpenSSL 1.1)
|
||||
if (OPENSSL_FOUND)
|
||||
set(OPENSSL_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
|
||||
else()
|
||||
# LibreSSL
|
||||
set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
|
||||
set(OPENSSLDIR "/etc/ssl/")
|
||||
add_subdirectory(libressl EXCLUDE_FROM_ALL)
|
||||
target_include_directories(ssl INTERFACE ./libressl/include)
|
||||
target_compile_definitions(ssl PRIVATE -DHAVE_INET_NTOP)
|
||||
get_directory_property(OPENSSL_LIBRARIES
|
||||
DIRECTORY libressl
|
||||
DEFINITION OPENSSL_LIBS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
add_subdirectory(android-ifaddrs)
|
||||
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 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)
|
||||
target_include_directories(httplib INTERFACE ./httplib)
|
||||
target_compile_options(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
|
||||
target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
|
||||
# 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
|
||||
if(ANDROID)
|
||||
add_subdirectory(android-ifaddrs)
|
||||
target_link_libraries(httplib INTERFACE ifaddrs)
|
||||
endif()
|
||||
|
||||
# cpp-jwt
|
||||
if (ENABLE_WEB_SERVICE)
|
||||
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)
|
||||
@ -205,3 +233,11 @@ if (ENABLE_OPENAL)
|
||||
set(LIBTYPE "STATIC" CACHE STRING "")
|
||||
add_subdirectory(openal-soft EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
# VMA
|
||||
add_library(vma INTERFACE)
|
||||
target_include_directories(vma SYSTEM INTERFACE ./vma/include)
|
||||
|
||||
# vulkan-headers
|
||||
add_library(vulkan-headers INTERFACE)
|
||||
target_include_directories(vulkan-headers SYSTEM INTERFACE ./vulkan-headers/include)
|
||||
|
2
externals/boost
vendored
2
externals/boost
vendored
Submodule externals/boost updated: 80a171a179...700ae2eff3
2
externals/catch2
vendored
2
externals/catch2
vendored
Submodule externals/catch2 updated: dc001fa935...3f0283de7a
192
externals/cmake-modules/FindFFmpeg.cmake
vendored
192
externals/cmake-modules/FindFFmpeg.cmake
vendored
@ -1,192 +0,0 @@
|
||||
# FindFFmpeg
|
||||
# ----------
|
||||
#
|
||||
# Find the native FFmpeg includes and libraries
|
||||
#
|
||||
# This module defines the following variables:
|
||||
#
|
||||
# FFmpeg_INCLUDE_<component>: where to find <component>.h
|
||||
# FFmpeg_LIBRARY_<component>: where to find the <component> library
|
||||
# FFmpeg_INCLUDES: aggregate all the include paths
|
||||
# FFmpeg_LIBRARIES: aggregate all the paths to the libraries
|
||||
# FFmpeg_FOUND: True if all components have been found
|
||||
#
|
||||
# This module defines the following targets, which are prefered over variables:
|
||||
#
|
||||
# FFmpeg::<component>: Target to use <component> directly, with include path,
|
||||
# library and dependencies set up. If you are using a static build, you are
|
||||
# responsible for adding any external dependencies (such as zlib, bzlib...).
|
||||
#
|
||||
# <component> can be one of:
|
||||
# avcodec
|
||||
# avdevice
|
||||
# avfilter
|
||||
# avformat
|
||||
# postproc
|
||||
# swresample
|
||||
# swscale
|
||||
#
|
||||
|
||||
set(_FFmpeg_ALL_COMPONENTS
|
||||
avcodec
|
||||
avdevice
|
||||
avfilter
|
||||
avformat
|
||||
avutil
|
||||
postproc
|
||||
swresample
|
||||
swscale
|
||||
)
|
||||
|
||||
set(_FFmpeg_DEPS_avcodec avutil)
|
||||
set(_FFmpeg_DEPS_avdevice avcodec avformat avutil)
|
||||
set(_FFmpeg_DEPS_avfilter avutil)
|
||||
set(_FFmpeg_DEPS_avformat avcodec avutil)
|
||||
set(_FFmpeg_DEPS_postproc avutil)
|
||||
set(_FFmpeg_DEPS_swresample avutil)
|
||||
set(_FFmpeg_DEPS_swscale avutil)
|
||||
|
||||
function(find_ffmpeg LIBNAME)
|
||||
if(DEFINED ENV{FFMPEG_DIR})
|
||||
set(FFMPEG_DIR $ENV{FFMPEG_DIR})
|
||||
endif()
|
||||
|
||||
if(FFMPEG_DIR)
|
||||
list(APPEND INCLUDE_PATHS
|
||||
${FFMPEG_DIR}
|
||||
${FFMPEG_DIR}/ffmpeg
|
||||
${FFMPEG_DIR}/lib${LIBNAME}
|
||||
${FFMPEG_DIR}/include/lib${LIBNAME}
|
||||
${FFMPEG_DIR}/include/ffmpeg
|
||||
${FFMPEG_DIR}/include
|
||||
NO_DEFAULT_PATH
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
list(APPEND LIB_PATHS
|
||||
${FFMPEG_DIR}
|
||||
${FFMPEG_DIR}/lib
|
||||
${FFMPEG_DIR}/lib${LIBNAME}
|
||||
NO_DEFAULT_PATH
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
)
|
||||
else()
|
||||
list(APPEND INCLUDE_PATHS
|
||||
/usr/local/include/ffmpeg
|
||||
/usr/local/include/lib${LIBNAME}
|
||||
/usr/include/ffmpeg
|
||||
/usr/include/lib${LIBNAME}
|
||||
/usr/include/ffmpeg/lib${LIBNAME}
|
||||
)
|
||||
|
||||
list(APPEND LIB_PATHS
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
)
|
||||
endif()
|
||||
|
||||
find_path(FFmpeg_INCLUDE_${LIBNAME} lib${LIBNAME}/${LIBNAME}.h
|
||||
HINTS ${INCLUDE_PATHS}
|
||||
)
|
||||
|
||||
find_library(FFmpeg_LIBRARY_${LIBNAME} ${LIBNAME}
|
||||
HINTS ${LIB_PATHS}
|
||||
)
|
||||
|
||||
if(NOT FFMPEG_DIR AND (NOT FFmpeg_LIBRARY_${LIBNAME} OR NOT FFmpeg_INCLUDE_${LIBNAME}))
|
||||
# Didn't find it in the usual paths, try pkg-config
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(FFmpeg_PKGCONFIG_${LIBNAME} QUIET lib${LIBNAME})
|
||||
|
||||
find_path(FFmpeg_INCLUDE_${LIBNAME} lib${LIBNAME}/${LIBNAME}.h
|
||||
${FFmpeg_PKGCONFIG_${LIBNAME}_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(FFmpeg_LIBRARY_${LIBNAME} ${LIBNAME}
|
||||
${FFmpeg_PKGCONFIG_${LIBNAME}_LIBRARY_DIRS}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(FFmpeg_INCLUDE_${LIBNAME} AND FFmpeg_LIBRARY_${LIBNAME})
|
||||
set(FFmpeg_INCLUDE_${LIBNAME} "${FFmpeg_INCLUDE_${LIBNAME}}" PARENT_SCOPE)
|
||||
set(FFmpeg_LIBRARY_${LIBNAME} "${FFmpeg_LIBRARY_${LIBNAME}}" PARENT_SCOPE)
|
||||
|
||||
# Extract FFmpeg version from version.h
|
||||
foreach(v MAJOR MINOR MICRO)
|
||||
set(FFmpeg_${LIBNAME}_VERSION_${v} 0)
|
||||
endforeach()
|
||||
string(TOUPPER ${LIBNAME} LIBNAME_UPPER)
|
||||
file(STRINGS "${FFmpeg_INCLUDE_${LIBNAME}}/lib${LIBNAME}/version.h" _FFmpeg_VERSION_H_CONTENTS REGEX "#define LIB${LIBNAME_UPPER}_VERSION_(MAJOR|MINOR|MICRO) ")
|
||||
if (EXISTS "${FFmpeg_INCLUDE_${LIBNAME}}/lib${LIBNAME}/version_major.h")
|
||||
file(STRINGS "${FFmpeg_INCLUDE_${LIBNAME}}/lib${LIBNAME}/version_major.h" _FFmpeg_MAJOR_VERSION_H_CONTENTS REGEX "#define LIB${LIBNAME_UPPER}_VERSION_MAJOR ")
|
||||
string(APPEND _FFmpeg_VERSION_H_CONTENTS "\n" ${_FFmpeg_MAJOR_VERSION_H_CONTENTS})
|
||||
endif()
|
||||
set(_FFmpeg_VERSION_REGEX "([0-9]+)")
|
||||
foreach(v MAJOR MINOR MICRO)
|
||||
if("${_FFmpeg_VERSION_H_CONTENTS}" MATCHES "#define LIB${LIBNAME_UPPER}_VERSION_${v}[\\t ]+${_FFmpeg_VERSION_REGEX}")
|
||||
set(FFmpeg_${LIBNAME}_VERSION_${v} "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(FFmpeg_${LIBNAME}_VERSION "${FFmpeg_${LIBNAME}_VERSION_MAJOR}.${FFmpeg_${LIBNAME}_VERSION_MINOR}.${FFmpeg_${LIBNAME}_VERSION_MICRO}")
|
||||
set(FFmpeg_${c}_VERSION "${FFmpeg_${LIBNAME}_VERSION}" PARENT_SCOPE)
|
||||
unset(_FFmpeg_VERSION_REGEX)
|
||||
unset(_FFmpeg_VERSION_H_CONTENTS)
|
||||
|
||||
set(FFmpeg_${c}_FOUND TRUE PARENT_SCOPE)
|
||||
if(NOT FFmpeg_FIND_QUIETLY)
|
||||
message("-- Found ${LIBNAME}: ${FFmpeg_INCLUDE_${LIBNAME}} ${FFmpeg_LIBRARY_${LIBNAME}} (version: ${FFmpeg_${LIBNAME}_VERSION})")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
foreach(c ${_FFmpeg_ALL_COMPONENTS})
|
||||
find_ffmpeg(${c})
|
||||
endforeach()
|
||||
|
||||
foreach(c ${_FFmpeg_ALL_COMPONENTS})
|
||||
if(FFmpeg_${c}_FOUND)
|
||||
list(APPEND FFmpeg_INCLUDES ${FFmpeg_INCLUDE_${c}})
|
||||
list(APPEND FFmpeg_LIBRARIES ${FFmpeg_LIBRARY_${c}})
|
||||
|
||||
add_library(FFmpeg::${c} IMPORTED UNKNOWN)
|
||||
set_target_properties(FFmpeg::${c} PROPERTIES
|
||||
IMPORTED_LOCATION ${FFmpeg_LIBRARY_${c}}
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${FFmpeg_INCLUDE_${c}}
|
||||
)
|
||||
if(APPLE)
|
||||
set_target_properties(FFmpeg::${c} PROPERTIES
|
||||
MACOSX_RPATH 1
|
||||
)
|
||||
endif()
|
||||
if(_FFmpeg_DEPS_${c})
|
||||
set(deps)
|
||||
foreach(dep ${_FFmpeg_DEPS_${c}})
|
||||
list(APPEND deps FFmpeg::${dep})
|
||||
endforeach()
|
||||
|
||||
set_target_properties(FFmpeg::${c} PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "${deps}"
|
||||
)
|
||||
unset(deps)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(FFmpeg_INCLUDES)
|
||||
list(REMOVE_DUPLICATES FFmpeg_INCLUDES)
|
||||
endif()
|
||||
|
||||
foreach(c ${FFmpeg_FIND_COMPONENTS})
|
||||
list(APPEND _FFmpeg_REQUIRED_VARS FFmpeg_INCLUDE_${c} FFmpeg_LIBRARY_${c})
|
||||
endforeach()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(FFmpeg
|
||||
REQUIRED_VARS ${_FFmpeg_REQUIRED_VARS}
|
||||
HANDLE_COMPONENTS
|
||||
)
|
||||
|
||||
foreach(c ${_FFmpeg_ALL_COMPONENTS})
|
||||
unset(_FFmpeg_DEPS_${c})
|
||||
endforeach()
|
||||
unset(_FFmpeg_ALL_COMPONENTS)
|
||||
unset(_FFmpeg_REQUIRED_VARS)
|
28
externals/cmake-modules/WindowsCopyFiles.cmake
vendored
28
externals/cmake-modules/WindowsCopyFiles.cmake
vendored
@ -1,28 +0,0 @@
|
||||
# Copyright 2016 Citra Emulator Project
|
||||
# Licensed under GPLv2 or any later version
|
||||
# Refer to the license.txt file included.
|
||||
|
||||
# This file provides the function windows_copy_files.
|
||||
# This is only valid on Windows.
|
||||
|
||||
# Include guard
|
||||
if(__windows_copy_files)
|
||||
return()
|
||||
endif()
|
||||
set(__windows_copy_files YES)
|
||||
|
||||
# Any number of files to copy from SOURCE_DIR to DEST_DIR can be specified after DEST_DIR.
|
||||
# This copying happens post-build.
|
||||
function(windows_copy_files TARGET SOURCE_DIR DEST_DIR)
|
||||
# windows commandline expects the / to be \ so switch them
|
||||
string(REPLACE "/" "\\\\" SOURCE_DIR ${SOURCE_DIR})
|
||||
string(REPLACE "/" "\\\\" DEST_DIR ${DEST_DIR})
|
||||
|
||||
# /NJH /NJS /NDL /NFL /NC /NS /NP - Silence any output
|
||||
# cmake adds an extra check for command success which doesn't work too well with robocopy
|
||||
# so trick it into thinking the command was successful with the || cmd /c "exit /b 0"
|
||||
add_custom_command(TARGET ${TARGET} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${DEST_DIR}
|
||||
COMMAND robocopy ${SOURCE_DIR} ${DEST_DIR} ${ARGN} /NJH /NJS /NDL /NFL /NC /NS /NP || cmd /c "exit /b 0"
|
||||
)
|
||||
endfunction()
|
2
externals/cubeb
vendored
2
externals/cubeb
vendored
Submodule externals/cubeb updated: dc511c6b35...48689ae7a7
2
externals/discord-rpc
vendored
2
externals/discord-rpc
vendored
Submodule externals/discord-rpc updated: 963aa9f3e5...20cc99aeff
2
externals/dynarmic
vendored
2
externals/dynarmic
vendored
Submodule externals/dynarmic updated: c08c5a9362...d333a09b3b
1
externals/glslang
vendored
Submodule
1
externals/glslang
vendored
Submodule
Submodule externals/glslang added at 1e4955adbc
6
externals/httplib/httplib.h
vendored
6
externals/httplib/httplib.h
vendored
@ -233,6 +233,12 @@ using socket_t = int;
|
||||
#undef X509_EXTENSIONS
|
||||
#undef PKCS7_SIGNER_INFO
|
||||
|
||||
// libressl will warn without this, which becomes an error.
|
||||
#undef OCSP_REQUEST
|
||||
#undef OCSP_RESPONSE
|
||||
#undef PKCS7_ISSUER_AND_SERIAL
|
||||
#undef __WINCRYPT_H__
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "crypt32.lib")
|
||||
#pragma comment(lib, "cryptui.lib")
|
||||
|
48
externals/library-headers/CMakeLists.txt
vendored
Normal file
48
externals/library-headers/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
add_library(library-headers INTERFACE)
|
||||
|
||||
# libfdk-aac headers
|
||||
find_path(FDK_AAC_INCLUDES NAMES fdk-aac/aacdecoder_lib.h)
|
||||
if (FDK_AAC_INCLUDES STREQUAL "FDK_AAC_INCLUDES-NOTFOUND")
|
||||
message(STATUS "fdk_aac headers not found, using bundled headers.")
|
||||
target_include_directories(library-headers INTERFACE ./library-headers/fdk-aac/include)
|
||||
else()
|
||||
message(STATUS "Using headers from system fdk_aac")
|
||||
target_include_directories(library-headers SYSTEM INTERFACE ${FDK_AAC_INCLUDES})
|
||||
endif()
|
||||
|
||||
# FFmpeg headers
|
||||
find_path(AVUTIL_INCLUDES NAMES libavutil/avutil.h)
|
||||
find_path(AVCODEC_INCLUDES NAMES libavcodec/avcodec.h)
|
||||
find_path(AVFORMAT_INCLUDES NAMES libavformat/avformat.h)
|
||||
find_path(AVFILTER_INCLUDES NAMES libavfilter/avfilter.h)
|
||||
find_path(SWRESAMPLE_INCLUDES NAMES libswresample/swresample.h)
|
||||
# Make sure all the headers are found and from the same place, so we don't
|
||||
# have missing or mismatched components.
|
||||
if (AVUTIL_INCLUDES STREQUAL "AVUTIL_INCLUDES-NOTFOUND"
|
||||
OR NOT AVCODEC_INCLUDES STREQUAL AVUTIL_INCLUDES
|
||||
OR NOT AVFORMAT_INCLUDES STREQUAL AVUTIL_INCLUDES
|
||||
OR NOT AVFILTER_INCLUDES STREQUAL AVUTIL_INCLUDES
|
||||
OR NOT SWRESAMPLE_INCLUDES STREQUAL AVUTIL_INCLUDES)
|
||||
message(STATUS "Complete FFmpeg headers not found, using bundled headers.")
|
||||
target_include_directories(library-headers INTERFACE ./library-headers/ffmpeg/include)
|
||||
else()
|
||||
# Extract libavutil version from header.
|
||||
file(STRINGS "${AVUTIL_INCLUDES}/libavutil/version.h" AVUTIL_VERSION_DATA
|
||||
REGEX "#define LIBAVUTIL_VERSION_(MAJOR|MINOR|MICRO) ")
|
||||
set(AVUTIL_VERSION_REGEX "([0-9]+)")
|
||||
foreach(v MAJOR MINOR MICRO)
|
||||
if("${AVUTIL_VERSION_DATA}" MATCHES "#define LIBAVUTIL_VERSION_${v}[\\t ]+${AVUTIL_VERSION_REGEX}")
|
||||
set(AVUTIL_VERSION_${v} "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(AVUTIL_VERSION "${AVUTIL_VERSION_MAJOR}.${AVUTIL_VERSION_MINOR}.${AVUTIL_VERSION_MICRO}")
|
||||
|
||||
message(STATUS "Detected FFmpeg libavutil version is ${AVUTIL_VERSION}")
|
||||
if ("${AVUTIL_VERSION}" VERSION_LESS "56.30.100")
|
||||
message(WARNING "System FFmpeg version is too low (< 4.2), using bundled headers.")
|
||||
target_include_directories(library-headers INTERFACE ./library-headers/ffmpeg/include)
|
||||
else()
|
||||
message(STATUS "Using headers from system FFmpeg")
|
||||
target_include_directories(library-headers SYSTEM INTERFACE ${AVUTIL_INCLUDES})
|
||||
endif()
|
||||
endif()
|
1
externals/library-headers/library-headers
vendored
Submodule
1
externals/library-headers/library-headers
vendored
Submodule
Submodule externals/library-headers/library-headers added at 3b3e28dbe6
2
externals/libressl
vendored
2
externals/libressl
vendored
Submodule externals/libressl updated: 8929f818fd...d4fc7348a3
29
externals/libusb/CMakeLists.txt
vendored
29
externals/libusb/CMakeLists.txt
vendored
@ -4,7 +4,6 @@ if(MSVC)
|
||||
endif()
|
||||
|
||||
add_library(usb STATIC EXCLUDE_FROM_ALL
|
||||
libusb/libusb/core.c
|
||||
libusb/libusb/core.c
|
||||
libusb/libusb/descriptor.c
|
||||
libusb/libusb/hotplug.c
|
||||
@ -42,10 +41,9 @@ endif()
|
||||
|
||||
if(WIN32 OR CYGWIN)
|
||||
target_sources(usb PRIVATE
|
||||
libusb/libusb/os/threads_windows.c
|
||||
libusb/libusb/os/windows_winusb.c
|
||||
libusb/libusb/os/windows_usbdk.c
|
||||
libusb/libusb/os/windows_nt_common.c
|
||||
libusb/libusb/os/windows_common.c
|
||||
)
|
||||
set(OS_WINDOWS TRUE)
|
||||
elseif(APPLE)
|
||||
@ -54,10 +52,12 @@ elseif(APPLE)
|
||||
)
|
||||
find_library(COREFOUNDATION_LIBRARY CoreFoundation)
|
||||
find_library(IOKIT_LIBRARY IOKit)
|
||||
find_library(SECURITY_LIBRARY Security)
|
||||
find_library(OBJC_LIBRARY objc)
|
||||
target_link_libraries(usb PRIVATE
|
||||
${COREFOUNDATION_LIBRARY}
|
||||
${IOKIT_LIBRARY}
|
||||
${SECURITY_LIBRARY}
|
||||
${OBJC_LIBRARY}
|
||||
)
|
||||
set(OS_DARWIN TRUE)
|
||||
@ -102,7 +102,7 @@ endif()
|
||||
|
||||
if(UNIX)
|
||||
target_sources(usb PRIVATE
|
||||
libusb/libusb/os/poll_posix.c
|
||||
libusb/libusb/os/events_posix.c
|
||||
libusb/libusb/os/threads_posix.c
|
||||
)
|
||||
find_package(Threads REQUIRED)
|
||||
@ -112,12 +112,13 @@ if(UNIX)
|
||||
if(CMAKE_THREAD_LIBS_INIT)
|
||||
target_link_libraries(usb PRIVATE "${CMAKE_THREAD_LIBS_INIT}")
|
||||
endif()
|
||||
set(THREADS_POSIX TRUE)
|
||||
set(PLATFORM_POSIX TRUE)
|
||||
elseif(WIN32)
|
||||
target_sources(usb PRIVATE
|
||||
libusb/libusb/os/poll_windows.c
|
||||
libusb/libusb/os/events_windows.c
|
||||
libusb/libusb/os/threads_windows.c
|
||||
)
|
||||
set(PLATFORM_WINDOWS TRUE)
|
||||
endif()
|
||||
|
||||
include(CheckFunctionExists)
|
||||
@ -127,7 +128,8 @@ check_include_files(asm/types.h HAVE_ASM_TYPES_H)
|
||||
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
|
||||
check_include_files(linux/filter.h HAVE_LINUX_FILTER_H)
|
||||
check_include_files(linux/netlink.h HAVE_LINUX_NETLINK_H)
|
||||
check_include_files(poll.h HAVE_POLL_H)
|
||||
check_function_exists(eventfd HAVE_EVENTFD)
|
||||
check_function_exists(timerfd_create HAVE_TIMERFD)
|
||||
check_include_files(signal.h HAVE_SIGNAL_H)
|
||||
check_include_files(strings.h HAVE_STRINGS_H)
|
||||
check_type_size("struct timespec" STRUCT_TIMESPEC)
|
||||
@ -136,17 +138,6 @@ check_include_files(syslog.h HAVE_SYSLOG_H)
|
||||
check_include_files(sys/socket.h HAVE_SYS_SOCKET_H)
|
||||
check_include_files(sys/time.h HAVE_SYS_TIME_H)
|
||||
check_include_files(sys/types.h HAVE_SYS_TYPES_H)
|
||||
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES poll.h)
|
||||
check_type_size("nfds_t" nfds_t)
|
||||
unset(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
if(HAVE_NFDS_T)
|
||||
set(POLL_NFDS_TYPE "nfds_t")
|
||||
else()
|
||||
set(POLL_NFDS_TYPE "unsigned int")
|
||||
endif()
|
||||
|
||||
check_include_files(sys/timerfd.h USBI_TIMERFD_AVAILABLE)
|
||||
|
||||
check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
|
||||
|
||||
configure_file(config.h.in config.h)
|
||||
|
21
externals/libusb/config.h.in
vendored
21
externals/libusb/config.h.in
vendored
@ -26,8 +26,11 @@
|
||||
/* Define to 1 if you have the <linux/netlink.h> header file. */
|
||||
#cmakedefine HAVE_LINUX_NETLINK_H 1
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#cmakedefine HAVE_POLL_H 1
|
||||
/* Define to 1 if you have eventfd support. */
|
||||
#cmakedefine HAVE_EVENTFD 1
|
||||
|
||||
/* Define to 1 if you have timerfd support. */
|
||||
#cmakedefine HAVE_TIMERFD 1
|
||||
|
||||
/* Define to 1 if you have the <signal.h> header file. */
|
||||
#cmakedefine HAVE_SIGNAL_H 1
|
||||
@ -53,6 +56,9 @@
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#cmakedefine HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the 'clock_gettime' function. */
|
||||
#cmakedefine HAVE_CLOCK_GETTIME 1
|
||||
|
||||
/* Darwin backend */
|
||||
#cmakedefine OS_DARWIN 1
|
||||
|
||||
@ -68,14 +74,11 @@
|
||||
/* Windows backend */
|
||||
#cmakedefine OS_WINDOWS 1
|
||||
|
||||
/* type of second poll() argument */
|
||||
#define POLL_NFDS_TYPE @POLL_NFDS_TYPE@
|
||||
/* Use POSIX Platform */
|
||||
#cmakedefine PLATFORM_POSIX
|
||||
|
||||
/* Use POSIX Threads */
|
||||
#cmakedefine THREADS_POSIX
|
||||
|
||||
/* timerfd headers available */
|
||||
#cmakedefine USBI_TIMERFD_AVAILABLE 1
|
||||
/* Use Windows Platform */
|
||||
#cmakedefine PLATFORM_WINDOWS
|
||||
|
||||
/* Enable output to system log */
|
||||
#define USE_SYSTEM_LOGGING_FACILITY 1
|
||||
|
2
externals/libusb/libusb
vendored
2
externals/libusb/libusb
vendored
Submodule externals/libusb/libusb updated: e782eeb251...54350bd83f
35
externals/sdl2/CMakeLists.txt
vendored
35
externals/sdl2/CMakeLists.txt
vendored
@ -1,33 +1,6 @@
|
||||
# Disable building the stuff we don't need.
|
||||
set(SDL_DISKAUDIO OFF CACHE BOOL "")
|
||||
set(SDL_OPENGL ON CACHE BOOL "")
|
||||
set(SDL_OPENGLES ON CACHE BOOL "")
|
||||
set(SDL_OSS OFF CACHE BOOL "")
|
||||
set(SDL_ALSA OFF CACHE BOOL "")
|
||||
set(SDL_JACK OFF CACHE BOOL "")
|
||||
set(SDL_ESD OFF CACHE BOOL "")
|
||||
set(SDL_PIPEWIRE OFF CACHE BOOL "")
|
||||
set(SDL_PULSEAUDIO OFF CACHE BOOL "")
|
||||
set(SDL_ARTS OFF CACHE BOOL "")
|
||||
set(SDL_NAS OFF CACHE BOOL "")
|
||||
set(SDL_SNDIO OFF CACHE BOOL "")
|
||||
set(SDL_FUSIONSOUND OFF CACHE BOOL "")
|
||||
set(SDL_LIBSAMPLERATE OFF CACHE BOOL "")
|
||||
set(SDL_X11 OFF CACHE BOOL "")
|
||||
set(SDL_WAYLAND OFF CACHE BOOL "")
|
||||
set(SDL_RPI OFF CACHE BOOL "")
|
||||
set(SDL_COCOA ON CACHE BOOL "")
|
||||
set(SDL_DIRECTX OFF CACHE BOOL "")
|
||||
set(SDL_WASAPI OFF CACHE BOOL "")
|
||||
set(SDL_RENDER_D3D OFF CACHE BOOL "")
|
||||
set(SDL_RENDER_METAL OFF CACHE BOOL "")
|
||||
set(SDL_VIVANTE OFF CACHE BOOL "")
|
||||
set(SDL_VULKAN OFF CACHE BOOL "")
|
||||
set(SDL_METAL OFF CACHE BOOL "")
|
||||
set(SDL_KMSDRM OFF CACHE BOOL "")
|
||||
set(SDL_OFFSCREEN OFF CACHE BOOL "")
|
||||
set(SDL_SHARED ON CACHE BOOL "")
|
||||
set(SDL_STATIC OFF CACHE BOOL "")
|
||||
# Configure static library build
|
||||
set(SDL_SHARED OFF CACHE BOOL "")
|
||||
set(SDL_STATIC ON CACHE BOOL "")
|
||||
|
||||
# Subsystems
|
||||
set(SDL_ATOMIC ON CACHE BOOL "")
|
||||
@ -43,7 +16,7 @@ set(SDL_THREADS ON CACHE BOOL "")
|
||||
set(SDL_TIMERS ON CACHE BOOL "")
|
||||
set(SDL_FILE ON CACHE BOOL "")
|
||||
set(SDL_LOADSO ON CACHE BOOL "")
|
||||
set(SDL_CPUINFO OFF CACHE BOOL "")
|
||||
set(SDL_CPUINFO ON CACHE BOOL "")
|
||||
set(SDL_FILESYSTEM OFF CACHE BOOL "")
|
||||
set(SDL_DLOPEN ON CACHE BOOL "")
|
||||
set(SDL_SENSOR OFF CACHE BOOL "")
|
||||
|
2
externals/sdl2/SDL
vendored
2
externals/sdl2/SDL
vendored
Submodule externals/sdl2/SDL updated: a1d1946dcb...ac13ca9ab6
1
externals/sirit
vendored
Submodule
1
externals/sirit
vendored
Submodule
Submodule externals/sirit added at 4ab79a8c02
1
externals/vma
vendored
Submodule
1
externals/vma
vendored
Submodule
Submodule externals/vma added at 0e89587db3
1
externals/vulkan-headers
vendored
Submodule
1
externals/vulkan-headers
vendored
Submodule
Submodule externals/vulkan-headers added at bae9700cd9
2
externals/zstd
vendored
2
externals/zstd
vendored
Submodule externals/zstd updated: e47e674cd0...63779c7982
@ -40,7 +40,6 @@ if (MSVC)
|
||||
/Zo
|
||||
/permissive-
|
||||
/EHsc
|
||||
/std:c++latest
|
||||
/utf-8
|
||||
/volatile:iso
|
||||
/Zc:externConstexpr
|
||||
@ -85,7 +84,7 @@ if (MSVC)
|
||||
# Since MSVC's debugging information is not very deterministic, so we have to disable it
|
||||
# when using ccache or other caching tools
|
||||
if (CITRA_USE_CCACHE OR CITRA_USE_PRECOMPILED_HEADERS)
|
||||
# Precompiled headers are deleted if not using /Z7. See https://github.com/nanoant/CMakePCHCompiler/issues/21
|
||||
# Precompiled headers are deleted if not using /Z7. See https://github.com/nanoant/CMakePCHCompiler/issues/21
|
||||
add_compile_options(/Z7)
|
||||
else()
|
||||
add_compile_options(/Zi)
|
||||
@ -102,17 +101,12 @@ else()
|
||||
-Wno-attributes
|
||||
)
|
||||
|
||||
if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||
add_compile_options("-stdlib=libc++")
|
||||
if (CITRA_WARNINGS_AS_ERRORS)
|
||||
add_compile_options(-Werror)
|
||||
endif()
|
||||
|
||||
# Set file offset size to 64 bits.
|
||||
#
|
||||
# On modern Unixes, this is typically already the case. The lone exception is
|
||||
# glibc, which may default to 32 bits. glibc allows this to be configured
|
||||
# by setting _FILE_OFFSET_BITS.
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR MINGW)
|
||||
add_definitions(-D_FILE_OFFSET_BITS=64)
|
||||
if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||
add_compile_options("-stdlib=libc++")
|
||||
endif()
|
||||
|
||||
if (MINGW)
|
||||
@ -120,14 +114,16 @@ else()
|
||||
if (COMPILE_WITH_DWARF)
|
||||
add_compile_options("-gdwarf")
|
||||
endif()
|
||||
|
||||
if (MINGW_STATIC_BUILD)
|
||||
add_definitions(-DQT_STATICPLUGIN)
|
||||
add_compile_options("-static")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR MINGW)
|
||||
# Set file offset size to 64 bits.
|
||||
#
|
||||
# On modern Unixes, this is typically already the case. The lone exception is
|
||||
# glibc, which may default to 32 bits. glibc allows this to be configured
|
||||
# by setting _FILE_OFFSET_BITS.
|
||||
add_definitions(-D_FILE_OFFSET_BITS=64)
|
||||
|
||||
# GNU ar: Create thin archive files.
|
||||
# Requires binutils-2.19 or later.
|
||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcTP <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
@ -143,9 +139,12 @@ add_subdirectory(video_core)
|
||||
add_subdirectory(audio_core)
|
||||
add_subdirectory(network)
|
||||
add_subdirectory(input_common)
|
||||
add_subdirectory(tests)
|
||||
|
||||
if (ENABLE_SDL2)
|
||||
if (ENABLE_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if (ENABLE_SDL2 AND ENABLE_SDL2_FRONTEND)
|
||||
add_subdirectory(citra)
|
||||
endif()
|
||||
|
||||
@ -153,11 +152,13 @@ if (ENABLE_QT)
|
||||
add_subdirectory(citra_qt)
|
||||
endif()
|
||||
|
||||
if (ENABLE_DEDICATED_ROOM)
|
||||
add_subdirectory(dedicated_room)
|
||||
endif()
|
||||
|
||||
if (ANDROID)
|
||||
add_subdirectory(android/app/src/main/jni)
|
||||
target_include_directories(citra-android PRIVATE android/app/src/main)
|
||||
else()
|
||||
add_subdirectory(dedicated_room)
|
||||
endif()
|
||||
|
||||
if (ENABLE_WEB_SERVICE)
|
||||
|
@ -1,169 +0,0 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
/**
|
||||
* Use the number of seconds/10 since Jan 1 2016 as the versionCode.
|
||||
* This lets us upload a new build at most every 10 seconds for the
|
||||
* next 680 years.
|
||||
*/
|
||||
def autoVersion = (int) (((new Date().getTime() / 1000) - 1451606400) / 10)
|
||||
def buildType
|
||||
def abiFilter = "arm64-v8a" //, "x86"
|
||||
|
||||
android {
|
||||
compileSdkVersion 32
|
||||
ndkVersion "25.1.8937393"
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
// This is important as it will run lint but not abort on error
|
||||
// Lint has some overly obnoxious "errors" that should really be warnings
|
||||
abortOnError false
|
||||
|
||||
//Uncomment disable lines for test builds...
|
||||
//disable 'MissingTranslation'bin
|
||||
//disable 'ExtraTranslation'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO If this is ever modified, change application_id in strings.xml
|
||||
applicationId "org.citra.citra_emu"
|
||||
minSdkVersion 28
|
||||
targetSdkVersion 31
|
||||
versionCode autoVersion
|
||||
versionName getVersion()
|
||||
ndk.abiFilters abiFilter
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
//release {
|
||||
// storeFile file('')
|
||||
// storePassword System.getenv('ANDROID_KEYPASS')
|
||||
// keyAlias = 'key0'
|
||||
// keyPassword System.getenv('ANDROID_KEYPASS')
|
||||
//}
|
||||
}
|
||||
|
||||
applicationVariants.all { variant ->
|
||||
buildType = variant.buildType.name // sets the current build type
|
||||
}
|
||||
|
||||
// Define build types, which are orthogonal to product flavors.
|
||||
buildTypes {
|
||||
|
||||
// Signed by release key, allowing for upload to Play Store.
|
||||
release {
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
|
||||
// builds a release build that doesn't need signing
|
||||
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
|
||||
relWithDebInfo {
|
||||
initWith release
|
||||
applicationIdSuffix ".debug"
|
||||
versionNameSuffix '-debug'
|
||||
signingConfig signingConfigs.debug
|
||||
minifyEnabled false
|
||||
testCoverageEnabled false
|
||||
debuggable true
|
||||
jniDebuggable true
|
||||
}
|
||||
|
||||
// Signed by debug key disallowing distribution on Play Store.
|
||||
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
|
||||
debug {
|
||||
// TODO If this is ever modified, change application_id in debug/strings.xml
|
||||
applicationIdSuffix ".debug"
|
||||
versionNameSuffix '-debug'
|
||||
debuggable true
|
||||
jniDebuggable true
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions "version"
|
||||
productFlavors {
|
||||
canary {
|
||||
dimension "version"
|
||||
applicationIdSuffix ".canary"
|
||||
}
|
||||
nightly {
|
||||
dimension "version"
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version "3.22.1"
|
||||
path "../../../CMakeLists.txt"
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DENABLE_QT=0", // Don't use QT
|
||||
"-DENABLE_SDL2=0", // Don't use SDL
|
||||
"-DENABLE_WEB_SERVICE=0", // Don't use telemetry
|
||||
"-DANDROID_ARM_NEON=true", // cryptopp requires Neon to work
|
||||
"-DBUNDLE_SPEEX=ON"
|
||||
|
||||
abiFilters abiFilter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "androidx.activity:activity:1.5.1"
|
||||
implementation "androidx.fragment:fragment:1.5.5"
|
||||
implementation 'androidx.appcompat:appcompat:1.5.1'
|
||||
implementation 'androidx.exifinterface:exifinterface:1.3.4'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||
implementation "androidx.documentfile:documentfile:1.0.1"
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.5.1'
|
||||
implementation 'androidx.fragment:fragment:1.5.3'
|
||||
implementation "androidx.slidingpanelayout:slidingpanelayout:1.2.0"
|
||||
implementation 'com.google.android.material:material:1.6.1'
|
||||
implementation 'androidx.core:core-splashscreen:1.0.0'
|
||||
|
||||
// For loading huge screenshots from the disk.
|
||||
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||
|
||||
// Allows FRP-style asynchronous operations in Android.
|
||||
implementation 'io.reactivex:rxandroid:1.2.1'
|
||||
implementation 'org.ini4j:ini4j:0.5.4'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
|
||||
// Please don't upgrade the billing library as the newer version is not GPL-compatible
|
||||
implementation 'com.android.billingclient:billing:2.0.3'
|
||||
|
||||
// To use the androidx.test.core APIs
|
||||
androidTestImplementation "androidx.test:core:1.5.0"
|
||||
androidTestImplementation "androidx.test.ext:junit:1.1.5"
|
||||
}
|
||||
|
||||
def getVersion() {
|
||||
def versionName = '0.0'
|
||||
|
||||
try {
|
||||
versionName = 'git describe --always --long'.execute([], project.rootDir).text
|
||||
.trim()
|
||||
.replaceAll(/(-0)?-[^-]+$/, "")
|
||||
} catch (Exception) {
|
||||
logger.error('Cannot find git, defaulting to dummy version number')
|
||||
}
|
||||
|
||||
if (System.getenv("GITHUB_ACTIONS") != null) {
|
||||
def gitTag = System.getenv("GIT_TAG_NAME")
|
||||
versionName = gitTag ?: versionName
|
||||
}
|
||||
|
||||
return versionName
|
||||
}
|
203
src/android/app/build.gradle.kts
Normal file
203
src/android/app/build.gradle.kts
Normal file
@ -0,0 +1,203 @@
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
import android.databinding.tool.ext.capitalizeUS
|
||||
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
id("org.jetbrains.kotlin.android")
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the number of seconds/10 since Jan 1 2016 as the versionCode.
|
||||
* This lets us upload a new build at most every 10 seconds for the
|
||||
* next 680 years.
|
||||
*/
|
||||
val autoVersion = (((System.currentTimeMillis() / 1000) - 1451606400) / 10).toInt()
|
||||
val abiFilter = listOf("arm64-v8a"/*, "x86", "x86_64"*/)
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
android {
|
||||
namespace = "org.citra.citra_emu"
|
||||
|
||||
compileSdkVersion = "android-33"
|
||||
ndkVersion = "25.2.9519653"
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = "17"
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
}
|
||||
|
||||
lint {
|
||||
// This is important as it will run lint but not abort on error
|
||||
// Lint has some overly obnoxious "errors" that should really be warnings
|
||||
abortOnError = false
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO If this is ever modified, change application_id in strings.xml
|
||||
applicationId = "org.citra.citra_emu"
|
||||
minSdk = 28
|
||||
targetSdk = 33
|
||||
versionCode = autoVersion
|
||||
versionName = getGitVersion()
|
||||
|
||||
ndk {
|
||||
//noinspection ChromeOsAbiSupport
|
||||
abiFilters += abiFilter
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments(
|
||||
"-DENABLE_QT=0", // Don't use QT
|
||||
"-DENABLE_SDL2=0", // Don't use SDL
|
||||
"-DANDROID_ARM_NEON=true" // cryptopp requires Neon to work
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val keystoreFile = System.getenv("ANDROID_KEYSTORE_FILE")
|
||||
if (keystoreFile != null) {
|
||||
signingConfigs {
|
||||
create("release") {
|
||||
storeFile = file(keystoreFile)
|
||||
storePassword = System.getenv("ANDROID_KEYSTORE_PASS")
|
||||
keyAlias = System.getenv("ANDROID_KEY_ALIAS")
|
||||
keyPassword = System.getenv("ANDROID_KEYSTORE_PASS")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Define build types, which are orthogonal to product flavors.
|
||||
buildTypes {
|
||||
// Signed by release key, allowing for upload to Play Store.
|
||||
release {
|
||||
signingConfig = if (keystoreFile != null) {
|
||||
signingConfigs.getByName("release")
|
||||
} else {
|
||||
signingConfigs.getByName("debug")
|
||||
}
|
||||
}
|
||||
|
||||
// builds a release build that doesn't need signing
|
||||
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
|
||||
register("relWithDebInfo") {
|
||||
initWith(getByName("release"))
|
||||
applicationIdSuffix = ".debug"
|
||||
versionNameSuffix = "-debug"
|
||||
signingConfig = signingConfigs.getByName("debug")
|
||||
isMinifyEnabled = false
|
||||
isDebuggable = true
|
||||
isJniDebuggable = true
|
||||
}
|
||||
|
||||
// Signed by debug key disallowing distribution on Play Store.
|
||||
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
|
||||
debug {
|
||||
// TODO If this is ever modified, change application_id in debug/strings.xml
|
||||
applicationIdSuffix = ".debug"
|
||||
versionNameSuffix = "-debug"
|
||||
isDebuggable = true
|
||||
isJniDebuggable = true
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions.add("version")
|
||||
productFlavors {
|
||||
create("canary") {
|
||||
dimension = "version"
|
||||
applicationIdSuffix = ".canary"
|
||||
}
|
||||
|
||||
create("nightly") {
|
||||
dimension = "version"
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version = "3.22.1"
|
||||
path = file("../../../CMakeLists.txt")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("androidx.activity:activity-ktx:1.7.2")
|
||||
implementation("androidx.fragment:fragment-ktx:1.6.0")
|
||||
implementation("androidx.appcompat:appcompat:1.6.1")
|
||||
implementation("androidx.documentfile:documentfile:1.0.1")
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1")
|
||||
implementation("androidx.slidingpanelayout:slidingpanelayout:1.2.0")
|
||||
implementation("com.google.android.material:material:1.9.0")
|
||||
implementation("androidx.core:core-splashscreen:1.0.1")
|
||||
implementation("androidx.work:work-runtime:2.8.1")
|
||||
|
||||
// For loading huge screenshots from the disk.
|
||||
implementation("com.squareup.picasso:picasso:2.71828")
|
||||
|
||||
// Allows FRP-style asynchronous operations in Android.
|
||||
implementation("io.reactivex:rxandroid:1.2.1")
|
||||
|
||||
implementation("org.ini4j:ini4j:0.5.4")
|
||||
implementation("androidx.localbroadcastmanager:localbroadcastmanager:1.1.0")
|
||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
||||
|
||||
// Please don't upgrade the billing library as the newer version is not GPL-compatible
|
||||
implementation("com.android.billingclient:billing:2.0.3")
|
||||
}
|
||||
|
||||
fun getGitVersion(): String {
|
||||
var versionName = "0.0"
|
||||
|
||||
try {
|
||||
versionName = ProcessBuilder("git", "describe", "--always", "--long")
|
||||
.directory(project.rootDir)
|
||||
.redirectOutput(ProcessBuilder.Redirect.PIPE)
|
||||
.redirectError(ProcessBuilder.Redirect.PIPE)
|
||||
.start().inputStream.bufferedReader().use { it.readText() }
|
||||
.trim()
|
||||
.replace(Regex("(-0)?-[^-]+$"), "")
|
||||
} catch (e: Exception) {
|
||||
logger.error("Cannot find git, defaulting to dummy version number")
|
||||
}
|
||||
|
||||
if (System.getenv("GITHUB_ACTIONS") != null) {
|
||||
val gitTag = System.getenv("GIT_TAG_NAME")
|
||||
versionName = gitTag ?: versionName
|
||||
}
|
||||
|
||||
return versionName
|
||||
}
|
||||
|
||||
android.applicationVariants.configureEach {
|
||||
val variant = this
|
||||
val capitalizedName = variant.name.capitalizeUS()
|
||||
|
||||
val copyTask = tasks.register("copyBundle${capitalizedName}") {
|
||||
doLast {
|
||||
project.copy {
|
||||
from(variant.outputs.first().outputFile.parentFile)
|
||||
include("*.apk")
|
||||
into(layout.buildDirectory.dir("bundle"))
|
||||
}
|
||||
project.copy {
|
||||
from(layout.buildDirectory.dir("outputs/bundle/${variant.name}"))
|
||||
include("*.aab")
|
||||
into(layout.buildDirectory.dir("bundle"))
|
||||
}
|
||||
}
|
||||
}
|
||||
tasks.named("bundle${capitalizedName}").configure { finalizedBy(copyTask) }
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package org.citra.citra_emu;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
assertEquals("org.citra.citra_emu", appContext.getPackageName());
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.citra.citra_emu">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-feature
|
||||
android:name="android.hardware.touchscreen"
|
||||
android:required="false"/>
|
||||
@ -30,6 +29,7 @@
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
|
||||
<application
|
||||
android:name="org.citra.citra_emu.CitraApplication"
|
||||
|
@ -23,16 +23,33 @@ public class CitraApplication extends Application {
|
||||
private void createNotificationChannel() {
|
||||
// Create the NotificationChannel, but only on API 26+ because
|
||||
// the NotificationChannel class is new and not in the support library
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
return;
|
||||
}
|
||||
NotificationManager notificationManager = getSystemService(NotificationManager.class);
|
||||
{
|
||||
// General notification
|
||||
CharSequence name = getString(R.string.app_notification_channel_name);
|
||||
String description = getString(R.string.app_notification_channel_description);
|
||||
NotificationChannel channel = new NotificationChannel(getString(R.string.app_notification_channel_id), name, NotificationManager.IMPORTANCE_LOW);
|
||||
NotificationChannel channel = new NotificationChannel(
|
||||
getString(R.string.app_notification_channel_id), name,
|
||||
NotificationManager.IMPORTANCE_LOW);
|
||||
channel.setDescription(description);
|
||||
channel.setSound(null, null);
|
||||
channel.setVibrationPattern(null);
|
||||
// Register the channel with the system; you can't change the importance
|
||||
// or other notification behaviors after this
|
||||
NotificationManager notificationManager = getSystemService(NotificationManager.class);
|
||||
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
{
|
||||
// CIA Install notifications
|
||||
NotificationChannel channel = new NotificationChannel(
|
||||
getString(R.string.cia_install_notification_channel_id),
|
||||
getString(R.string.cia_install_notification_channel_name),
|
||||
NotificationManager.IMPORTANCE_DEFAULT);
|
||||
channel.setDescription(getString(R.string.cia_install_notification_channel_description));
|
||||
channel.setSound(null, null);
|
||||
channel.setVibrationPattern(null);
|
||||
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
}
|
||||
|
@ -128,29 +128,7 @@ public final class NativeLibrary {
|
||||
|
||||
public static native void InitGameIni(String gameID);
|
||||
|
||||
/**
|
||||
* Gets the embedded icon within the given ROM.
|
||||
*
|
||||
* @param filename the file path to the ROM.
|
||||
* @return an integer array containing the color data for the icon.
|
||||
*/
|
||||
public static native int[] GetIcon(String filename);
|
||||
|
||||
/**
|
||||
* Gets the embedded title of the given ISO/ROM.
|
||||
*
|
||||
* @param filename The file path to the ISO/ROM.
|
||||
* @return the embedded title of the ISO/ROM.
|
||||
*/
|
||||
public static native String GetTitle(String filename);
|
||||
|
||||
public static native String GetDescription(String filename);
|
||||
|
||||
public static native String GetGameId(String filename);
|
||||
|
||||
public static native String GetRegions(String filename);
|
||||
|
||||
public static native String GetCompany(String filename);
|
||||
public static native long GetTitleId(String filename);
|
||||
|
||||
public static native String GetGitRevision();
|
||||
|
||||
@ -210,6 +188,11 @@ public final class NativeLibrary {
|
||||
*/
|
||||
public static native boolean IsRunning();
|
||||
|
||||
/**
|
||||
* Returns the title ID of the currently running title, or 0 on failure.
|
||||
*/
|
||||
public static native long GetRunningTitleId();
|
||||
|
||||
/**
|
||||
* Returns the performance stats for the current game
|
||||
**/
|
||||
@ -602,12 +585,10 @@ public final class NativeLibrary {
|
||||
/// Notifies that the activity is now in foreground and camera devices can now be reloaded
|
||||
public static native void ReloadCameraDevices();
|
||||
|
||||
public static native boolean LoadAmiibo(byte[] bytes);
|
||||
public static native boolean LoadAmiibo(String path);
|
||||
|
||||
public static native void RemoveAmiibo();
|
||||
|
||||
public static native void InstallCIAS(String[] path);
|
||||
|
||||
public static final int SAVESTATE_SLOT_COUNT = 10;
|
||||
|
||||
public static final class SavestateInfo {
|
||||
|
@ -491,7 +491,7 @@ public final class EmulationActivity extends AppCompatActivity {
|
||||
break;
|
||||
|
||||
case MENU_ACTION_OPEN_CHEATS:
|
||||
CheatsActivity.launch(this);
|
||||
CheatsActivity.launch(this, NativeLibrary.GetRunningTitleId());
|
||||
break;
|
||||
|
||||
case MENU_ACTION_CLOSE_GAME:
|
||||
@ -570,15 +570,7 @@ public final class EmulationActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void onAmiiboSelected(String selectedFile) {
|
||||
boolean success = false;
|
||||
try {
|
||||
Uri uri = Uri.parse(selectedFile);
|
||||
DocumentFile file = DocumentFile.fromSingleUri(this, uri);
|
||||
byte[] bytes = FileUtil.getBytesFromFile(this, file);
|
||||
success = NativeLibrary.LoadAmiibo(bytes);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
boolean success = NativeLibrary.LoadAmiibo(selectedFile);
|
||||
|
||||
if (!success) {
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.citra.citra_emu.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.DataSetObserver;
|
||||
import android.os.Build;
|
||||
@ -14,10 +15,13 @@ import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.color.MaterialColors;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.citra.citra_emu.CitraApplication;
|
||||
import org.citra.citra_emu.NativeLibrary;
|
||||
import org.citra.citra_emu.R;
|
||||
import org.citra.citra_emu.activities.EmulationActivity;
|
||||
import org.citra.citra_emu.features.cheats.ui.CheatsActivity;
|
||||
import org.citra.citra_emu.model.GameDatabase;
|
||||
import org.citra.citra_emu.utils.FileUtil;
|
||||
import org.citra.citra_emu.utils.Log;
|
||||
@ -31,8 +35,7 @@ import java.util.stream.Stream;
|
||||
* ContentProviders and Loaders, allows for efficient display of a limited view into a (possibly)
|
||||
* large dataset.
|
||||
*/
|
||||
public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> implements
|
||||
View.OnClickListener {
|
||||
public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> {
|
||||
private Cursor mCursor;
|
||||
private GameDataSetObserver mObserver;
|
||||
|
||||
@ -61,7 +64,8 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl
|
||||
View gameCard = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.card_game, parent, false);
|
||||
|
||||
gameCard.setOnClickListener(this);
|
||||
gameCard.setOnClickListener(this::onClick);
|
||||
gameCard.setOnLongClickListener(this::onLongClick);
|
||||
|
||||
// Use that view to create a ViewHolder.
|
||||
return new GameViewHolder(gameCard);
|
||||
@ -193,10 +197,9 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl
|
||||
/**
|
||||
* Launches the game that was clicked on.
|
||||
*
|
||||
* @param view The card representing the game the user wants to play.
|
||||
* @param view The view representing the game the user wants to play.
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
private void onClick(View view) {
|
||||
// Double-click prevention, using threshold of 1000 ms
|
||||
if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) {
|
||||
return;
|
||||
@ -208,6 +211,31 @@ public final class GameAdapter extends RecyclerView.Adapter<GameViewHolder> impl
|
||||
EmulationActivity.launch((FragmentActivity) view.getContext(), holder.path, holder.title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the cheats settings for the game that was clicked on.
|
||||
*
|
||||
* @param view The view representing the game the user wants to play.
|
||||
*/
|
||||
private boolean onLongClick(View view) {
|
||||
Context context = view.getContext();
|
||||
GameViewHolder holder = (GameViewHolder) view.getTag();
|
||||
|
||||
final long titleId = NativeLibrary.GetTitleId(holder.path);
|
||||
|
||||
if (titleId == 0) {
|
||||
new MaterialAlertDialogBuilder(context)
|
||||
.setIcon(R.mipmap.ic_launcher)
|
||||
.setTitle(R.string.properties)
|
||||
.setMessage(R.string.properties_not_loaded)
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.show();
|
||||
} else {
|
||||
CheatsActivity.launch(context, titleId);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isValidGame(String path) {
|
||||
return Stream.of(
|
||||
".rar", ".zip", ".7z", ".torrent", ".tar", ".gz").noneMatch(suffix -> path.toLowerCase().endsWith(suffix));
|
||||
|
@ -1,13 +1,28 @@
|
||||
package org.citra.citra_emu.features.cheats.model;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
public class CheatEngine {
|
||||
public static native Cheat[] getCheats();
|
||||
@Keep
|
||||
private final long mPointer;
|
||||
|
||||
public static native void addCheat(Cheat cheat);
|
||||
@Keep
|
||||
public CheatEngine(long titleId) {
|
||||
mPointer = initialize(titleId);
|
||||
}
|
||||
|
||||
public static native void removeCheat(int index);
|
||||
private static native long initialize(long titleId);
|
||||
|
||||
public static native void updateCheat(int index, Cheat newCheat);
|
||||
@Override
|
||||
protected native void finalize();
|
||||
|
||||
public static native void saveCheatFile();
|
||||
public native Cheat[] getCheats();
|
||||
|
||||
public native void addCheat(Cheat cheat);
|
||||
|
||||
public native void removeCheat(int index);
|
||||
|
||||
public native void updateCheat(int index, Cheat newCheat);
|
||||
|
||||
public native void saveCheatFile();
|
||||
}
|
||||
|
@ -19,11 +19,17 @@ public class CheatsViewModel extends ViewModel {
|
||||
private final MutableLiveData<Integer> mCheatDeletedEvent = new MutableLiveData<>(null);
|
||||
private final MutableLiveData<Boolean> mOpenDetailsViewEvent = new MutableLiveData<>(false);
|
||||
|
||||
private CheatEngine mCheatEngine;
|
||||
private Cheat[] mCheats;
|
||||
private boolean mCheatsNeedSaving = false;
|
||||
|
||||
public void load() {
|
||||
mCheats = CheatEngine.getCheats();
|
||||
public void initialize(long titleId) {
|
||||
mCheatEngine = new CheatEngine(titleId);
|
||||
load();
|
||||
}
|
||||
|
||||
private void load() {
|
||||
mCheats = mCheatEngine.getCheats();
|
||||
|
||||
for (int i = 0; i < mCheats.length; i++) {
|
||||
int position = i;
|
||||
@ -36,7 +42,7 @@ public class CheatsViewModel extends ViewModel {
|
||||
|
||||
public void saveIfNeeded() {
|
||||
if (mCheatsNeedSaving) {
|
||||
CheatEngine.saveCheatFile();
|
||||
mCheatEngine.saveCheatFile();
|
||||
mCheatsNeedSaving = false;
|
||||
}
|
||||
}
|
||||
@ -106,7 +112,7 @@ public class CheatsViewModel extends ViewModel {
|
||||
|
||||
int position = mCheats.length;
|
||||
|
||||
CheatEngine.addCheat(cheat);
|
||||
mCheatEngine.addCheat(cheat);
|
||||
|
||||
mCheatsNeedSaving = true;
|
||||
load();
|
||||
@ -132,7 +138,7 @@ public class CheatsViewModel extends ViewModel {
|
||||
}
|
||||
|
||||
public void updateSelectedCheat(Cheat newCheat) {
|
||||
CheatEngine.updateCheat(mSelectedCheatPosition, newCheat);
|
||||
mCheatEngine.updateCheat(mSelectedCheatPosition, newCheat);
|
||||
|
||||
mCheatsNeedSaving = true;
|
||||
load();
|
||||
@ -162,7 +168,7 @@ public class CheatsViewModel extends ViewModel {
|
||||
|
||||
setSelectedCheat(null, -1);
|
||||
|
||||
CheatEngine.removeCheat(position);
|
||||
mCheatEngine.removeCheat(position);
|
||||
|
||||
mCheatsNeedSaving = true;
|
||||
load();
|
||||
|
@ -32,6 +32,8 @@ import java.util.List;
|
||||
|
||||
public class CheatsActivity extends AppCompatActivity
|
||||
implements SlidingPaneLayout.PanelSlideListener {
|
||||
private static String ARG_TITLE_ID = "title_id";
|
||||
|
||||
private CheatsViewModel mViewModel;
|
||||
|
||||
private SlidingPaneLayout mSlidingPaneLayout;
|
||||
@ -41,8 +43,9 @@ public class CheatsActivity extends AppCompatActivity
|
||||
private View mCheatListLastFocus;
|
||||
private View mCheatDetailsLastFocus;
|
||||
|
||||
public static void launch(Context context) {
|
||||
public static void launch(Context context, long titleId) {
|
||||
Intent intent = new Intent(context, CheatsActivity.class);
|
||||
intent.putExtra(ARG_TITLE_ID, titleId);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
@ -54,8 +57,10 @@ public class CheatsActivity extends AppCompatActivity
|
||||
|
||||
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
|
||||
|
||||
long titleId = getIntent().getLongExtra(ARG_TITLE_ID, -1);
|
||||
|
||||
mViewModel = new ViewModelProvider(this).get(CheatsViewModel.class);
|
||||
mViewModel.load();
|
||||
mViewModel.initialize(titleId);
|
||||
|
||||
setContentView(R.layout.activity_cheats);
|
||||
|
||||
|
@ -196,8 +196,12 @@ public final class SettingsFragmentPresenter {
|
||||
|
||||
sl.add(new SingleChoiceSetting(SettingsFile.KEY_REGION_VALUE, Settings.SECTION_SYSTEM, R.string.emulated_region, 0, R.array.regionNames, R.array.regionValues, -1, region));
|
||||
sl.add(new SingleChoiceSetting(SettingsFile.KEY_LANGUAGE, Settings.SECTION_SYSTEM, R.string.emulated_language, 0, R.array.languageNames, R.array.languageValues, 1, language));
|
||||
|
||||
sl.add(new HeaderSetting(null, null, R.string.clock, 0));
|
||||
sl.add(new SingleChoiceSetting(SettingsFile.KEY_INIT_CLOCK, Settings.SECTION_SYSTEM, R.string.init_clock, R.string.init_clock_description, R.array.systemClockNames, R.array.systemClockValues, 0, systemClock));
|
||||
sl.add(new DateTimeSetting(SettingsFile.KEY_INIT_TIME, Settings.SECTION_SYSTEM, R.string.init_time, R.string.init_time_description, "2000-01-01 00:00:01", dateTime));
|
||||
|
||||
sl.add(new HeaderSetting(null, null, R.string.plugin_loader, 0));
|
||||
sl.add(new CheckBoxSetting(SettingsFile.KEY_PLUGIN_LOADER, Settings.SECTION_SYSTEM, R.string.plugin_loader, R.string.plugin_loader_description, false, pluginLoader));
|
||||
sl.add(new CheckBoxSetting(SettingsFile.KEY_ALLOW_PLUGIN_LOADER, Settings.SECTION_SYSTEM, R.string.allow_plugin_loader, R.string.allow_plugin_loader_description, true, allowPluginLoader));
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import org.citra.citra_emu.utils.FileUtil;
|
||||
import org.citra.citra_emu.utils.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
@ -206,27 +207,26 @@ public final class GameDatabase extends SQLiteOpenHelper {
|
||||
}
|
||||
|
||||
private static void attemptToAddGame(SQLiteDatabase database, String filePath) {
|
||||
String name = NativeLibrary.GetTitle(filePath);
|
||||
GameInfo gameInfo;
|
||||
try {
|
||||
gameInfo = new GameInfo(filePath);
|
||||
} catch (IOException e) {
|
||||
gameInfo = null;
|
||||
}
|
||||
|
||||
String name = gameInfo != null ? gameInfo.getTitle() : "";
|
||||
|
||||
// If the game's title field is empty, use the filename.
|
||||
if (name.isEmpty()) {
|
||||
name = filePath.substring(filePath.lastIndexOf("/") + 1);
|
||||
}
|
||||
|
||||
String gameId = NativeLibrary.GetGameId(filePath);
|
||||
|
||||
// If the game's ID field is empty, use the filename without extension.
|
||||
if (gameId.isEmpty()) {
|
||||
gameId = filePath.substring(filePath.lastIndexOf("/") + 1,
|
||||
filePath.lastIndexOf("."));
|
||||
}
|
||||
|
||||
ContentValues game = Game.asContentValues(name,
|
||||
NativeLibrary.GetDescription(filePath).replace("\n", " "),
|
||||
NativeLibrary.GetRegions(filePath),
|
||||
filePath.replace("\n", " "),
|
||||
gameInfo != null ? gameInfo.getRegions() : "Invalid region",
|
||||
filePath,
|
||||
gameId,
|
||||
NativeLibrary.GetCompany(filePath));
|
||||
filePath,
|
||||
gameInfo != null ? gameInfo.getCompany() : "");
|
||||
|
||||
// Try to update an existing game first.
|
||||
int rowsMatched = database.update(TABLE_NAME_GAMES, // Which table to update.
|
||||
|
@ -0,0 +1,37 @@
|
||||
package org.citra.citra_emu.model;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class GameInfo {
|
||||
@Keep
|
||||
private final long mPointer;
|
||||
|
||||
@Keep
|
||||
public GameInfo(String path) throws IOException {
|
||||
mPointer = initialize(path);
|
||||
if (mPointer == 0L) {
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
|
||||
private static native long initialize(String path);
|
||||
|
||||
@Override
|
||||
protected native void finalize();
|
||||
|
||||
@NonNull
|
||||
public native String getTitle();
|
||||
|
||||
@NonNull
|
||||
public native String getRegions();
|
||||
|
||||
@NonNull
|
||||
public native String getCompany();
|
||||
|
||||
@Nullable
|
||||
public native int[] getIcon();
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
package org.citra.citra_emu.ui.main;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
@ -13,6 +16,7 @@ import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.splashscreen.SplashScreen;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import java.util.Collections;
|
||||
@ -20,10 +24,15 @@ import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
import androidx.work.Data;
|
||||
import androidx.work.ExistingWorkPolicy;
|
||||
import androidx.work.OneTimeWorkRequest;
|
||||
import androidx.work.OutOfQuotaPolicy;
|
||||
import androidx.work.WorkManager;
|
||||
import androidx.work.WorkRequest;
|
||||
|
||||
import com.google.android.material.appbar.AppBarLayout;
|
||||
|
||||
import org.citra.citra_emu.NativeLibrary;
|
||||
import org.citra.citra_emu.R;
|
||||
import org.citra.citra_emu.activities.EmulationActivity;
|
||||
import org.citra.citra_emu.contracts.OpenFileResultContract;
|
||||
@ -32,6 +41,7 @@ import org.citra.citra_emu.model.GameProvider;
|
||||
import org.citra.citra_emu.ui.platform.PlatformGamesFragment;
|
||||
import org.citra.citra_emu.utils.AddDirectoryHelper;
|
||||
import org.citra.citra_emu.utils.BillingManager;
|
||||
import org.citra.citra_emu.utils.CiaInstallWorker;
|
||||
import org.citra.citra_emu.utils.CitraDirectoryHelper;
|
||||
import org.citra.citra_emu.utils.DirectoryInitialization;
|
||||
import org.citra.citra_emu.utils.FileBrowserHelper;
|
||||
@ -50,7 +60,9 @@ public final class MainActivity extends AppCompatActivity implements MainView {
|
||||
private int mFrameLayoutId;
|
||||
private PlatformGamesFragment mPlatformGamesFragment;
|
||||
|
||||
private MainPresenter mPresenter = new MainPresenter(this);
|
||||
private final MainPresenter mPresenter = new MainPresenter(this);
|
||||
|
||||
// private final CiaInstallWorker mCiaInstallWorker = new CiaInstallWorker();
|
||||
|
||||
// Singleton to manage user billing state
|
||||
private static BillingManager mBillingManager;
|
||||
@ -91,7 +103,7 @@ public final class MainActivity extends AppCompatActivity implements MainView {
|
||||
mPresenter.onDirectorySelected(result.toString());
|
||||
});
|
||||
|
||||
private final ActivityResultLauncher<Boolean> mOpenFileLauncher =
|
||||
private final ActivityResultLauncher<Boolean> mInstallCiaFileLauncher =
|
||||
registerForActivityResult(new OpenFileResultContract(), result -> {
|
||||
if (result == null)
|
||||
return;
|
||||
@ -104,10 +116,21 @@ public final class MainActivity extends AppCompatActivity implements MainView {
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
NativeLibrary.InstallCIAS(selectedFiles);
|
||||
mPresenter.refreshGameList();
|
||||
WorkManager workManager = WorkManager.getInstance(getApplicationContext());
|
||||
workManager.enqueueUniqueWork("installCiaWork", ExistingWorkPolicy.APPEND_OR_REPLACE,
|
||||
new OneTimeWorkRequest.Builder(CiaInstallWorker.class)
|
||||
.setInputData(
|
||||
new Data.Builder().putStringArray("CIA_FILES", selectedFiles)
|
||||
.build()
|
||||
)
|
||||
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
|
||||
.build()
|
||||
);
|
||||
});
|
||||
|
||||
private final ActivityResultLauncher<String> requestNotificationPermissionLauncher =
|
||||
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> { });
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
SplashScreen splashScreen = SplashScreen.installSplashScreen(this);
|
||||
@ -149,6 +172,12 @@ public final class MainActivity extends AppCompatActivity implements MainView {
|
||||
EmulationActivity.tryDismissRunningNotification(this);
|
||||
|
||||
setInsets();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
|
||||
requestNotificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -233,7 +262,7 @@ public final class MainActivity extends AppCompatActivity implements MainView {
|
||||
mOpenGameListLauncher.launch(null);
|
||||
break;
|
||||
case MainPresenter.REQUEST_INSTALL_CIA:
|
||||
mOpenFileLauncher.launch(true);
|
||||
mInstallCiaFileLauncher.launch(true);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user