Skip to content

Commit c7fe1c1

Browse files
Alejandro PérezAlejandro Pérez
authored andcommitted
Add initial iOS port scaffolding
1 parent 5e8695a commit c7fe1c1

5 files changed

Lines changed: 186 additions & 7 deletions

File tree

CMakePresets.json

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,65 @@
165165
"CMAKE_BUILD_TYPE": "Release",
166166
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": true
167167
}
168+
},
169+
{
170+
"name": "ios-simulator-debug",
171+
"displayName": "iOS Simulator Debug",
172+
"generator": "Ninja",
173+
"binaryDir": "${sourceDir}/out/build/${presetName}",
174+
"installDir": "${sourceDir}/out/install/${presetName}",
175+
"cacheVariables": {
176+
"CMAKE_SYSTEM_NAME": "iOS",
177+
"CMAKE_OSX_SYSROOT": "iphonesimulator",
178+
"CMAKE_OSX_ARCHITECTURES": "arm64",
179+
"CMAKE_BUILD_TYPE": "Debug",
180+
"CMAKE_TOOLCHAIN_FILE": {
181+
"value": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
182+
"type": "FILEPATH"
183+
},
184+
"VCPKG_TARGET_TRIPLET": {
185+
"value": "arm64-ios-simulator",
186+
"type": "STRING"
187+
}
188+
},
189+
"environment": {
190+
"VCPKG_ROOT": "${sourceDir}/thirdparty/vcpkg"
191+
},
192+
"condition": {
193+
"type": "equals",
194+
"lhs": "${hostSystemName}",
195+
"rhs": "Darwin"
196+
}
197+
},
198+
{
199+
"name": "ios-device-release",
200+
"displayName": "iOS Device Release",
201+
"generator": "Ninja",
202+
"binaryDir": "${sourceDir}/out/build/${presetName}",
203+
"installDir": "${sourceDir}/out/install/${presetName}",
204+
"cacheVariables": {
205+
"CMAKE_SYSTEM_NAME": "iOS",
206+
"CMAKE_OSX_SYSROOT": "iphoneos",
207+
"CMAKE_OSX_ARCHITECTURES": "arm64",
208+
"CMAKE_BUILD_TYPE": "Release",
209+
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": true,
210+
"CMAKE_TOOLCHAIN_FILE": {
211+
"value": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
212+
"type": "FILEPATH"
213+
},
214+
"VCPKG_TARGET_TRIPLET": {
215+
"value": "arm64-ios",
216+
"type": "STRING"
217+
}
218+
},
219+
"environment": {
220+
"VCPKG_ROOT": "${sourceDir}/thirdparty/vcpkg"
221+
},
222+
"condition": {
223+
"type": "equals",
224+
"lhs": "${hostSystemName}",
225+
"rhs": "Darwin"
226+
}
168227
}
169228
]
170229
}

UnleashedRecomp/CMakeLists.txt

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")
9797
"os/linux/user_linux.cpp"
9898
"os/linux/version_linux.cpp"
9999
)
100-
elseif (APPLE)
101-
set(UNLEASHED_RECOMP_OS_CXX_SOURCES
102-
"os/macos/logger_macos.cpp"
100+
elseif (APPLE)
101+
set(UNLEASHED_RECOMP_OS_CXX_SOURCES
102+
"os/macos/logger_macos.cpp"
103103
"os/macos/media_macos.cpp"
104104
"os/macos/process_macos.cpp"
105105
"os/macos/user_macos.cpp"
@@ -292,7 +292,26 @@ if (WIN32)
292292
if (${CMAKE_BUILD_TYPE} MATCHES "Release")
293293
target_link_options(UnleashedRecomp PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup")
294294
endif()
295-
elseif (APPLE)
295+
elseif (CMAKE_SYSTEM_NAME STREQUAL "iOS")
296+
CreateVersionString(
297+
VERSION_TXT ${VERSION_TXT}
298+
OUTPUT_VAR IOS_BUNDLE_VERSION
299+
)
300+
301+
add_executable(UnleashedRecomp MACOSX_BUNDLE
302+
${UNLEASHED_RECOMP_CXX_SOURCES}
303+
)
304+
set_target_properties(UnleashedRecomp PROPERTIES
305+
OUTPUT_NAME "Unleashed Recompiled"
306+
MACOSX_BUNDLE_GUI_IDENTIFIER hedge-dev.UnleashedRecomp
307+
MACOSX_BUNDLE_BUNDLE_NAME "Unleashed Recompiled"
308+
MACOSX_BUNDLE_BUNDLE_VERSION ${IOS_BUNDLE_VERSION}
309+
MACOSX_BUNDLE_SHORT_VERSION_STRING ${IOS_BUNDLE_VERSION}
310+
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "hedge-dev.UnleashedRecomp"
311+
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
312+
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
313+
)
314+
elseif (APPLE)
296315
# Create version number for app bundle.
297316
CreateVersionString(
298317
VERSION_TXT ${VERSION_TXT}

thirdparty/CMakeLists.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ set(SDL2MIXER_OPUS OFF)
1515
set(SDL2MIXER_VORBIS "VORBISFILE")
1616
set(SDL2MIXER_WAVPACK OFF)
1717

18-
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
18+
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "iOS")
1919
set(SDL_VULKAN_ENABLED ON CACHE BOOL "")
2020
endif()
2121

@@ -24,12 +24,18 @@ if (WIN32)
2424
endif()
2525

2626
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/msdf-atlas-gen")
27-
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/nativefiledialog-extended")
27+
if (CMAKE_SYSTEM_NAME STREQUAL "iOS")
28+
add_library(nfd STATIC "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/nfd_ios_stub.c")
29+
add_library(nfd::nfd ALIAS nfd)
30+
target_include_directories(nfd PUBLIC "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/nativefiledialog-extended/src/include")
31+
else()
32+
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/nativefiledialog-extended")
33+
endif()
2834
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/o1heap")
2935
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL")
3036
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL_mixer")
3137
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/plume")
3238

33-
if (APPLE)
39+
if (APPLE AND NOT CMAKE_SYSTEM_NAME STREQUAL "iOS")
3440
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/MoltenVK")
3541
endif()

thirdparty/nfd_ios_stub.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include <nfd.h>
2+
#include <stdlib.h>
3+
4+
static const char* g_nfd_ios_error = "Native file dialogs are not implemented for iOS yet.";
5+
6+
nfdresult_t NFD_Init(void) { return NFD_OKAY; }
7+
void NFD_Quit(void) {}
8+
const char* NFD_GetError(void) { return g_nfd_ios_error; }
9+
10+
void NFD_FreePathN(nfdnchar_t* filePath) { free(filePath); }
11+
void NFD_FreePathU8(nfdu8char_t* filePath) { free(filePath); }
12+
13+
nfdresult_t NFD_OpenDialogN(nfdnchar_t** outPath, const nfdnfilteritem_t* filterList, nfdfiltersize_t filterCount, const nfdnchar_t* defaultPath) { (void)outPath; (void)filterList; (void)filterCount; (void)defaultPath; return NFD_ERROR; }
14+
nfdresult_t NFD_OpenDialogU8(nfdu8char_t** outPath, const nfdu8filteritem_t* filterList, nfdfiltersize_t filterCount, const nfdu8char_t* defaultPath) { (void)outPath; (void)filterList; (void)filterCount; (void)defaultPath; return NFD_ERROR; }
15+
nfdresult_t NFD_OpenDialogN_With_Impl(nfdversion_t version, nfdnchar_t** outPath, const nfdopendialognargs_t* args) { (void)version; (void)outPath; (void)args; return NFD_ERROR; }
16+
nfdresult_t NFD_OpenDialogU8_With_Impl(nfdversion_t version, nfdu8char_t** outPath, const nfdopendialogu8args_t* args) { (void)version; (void)outPath; (void)args; return NFD_ERROR; }
17+
nfdresult_t NFD_OpenDialogMultipleN(const nfdpathset_t** outPaths, const nfdnfilteritem_t* filterList, nfdfiltersize_t filterCount, const nfdnchar_t* defaultPath) { (void)outPaths; (void)filterList; (void)filterCount; (void)defaultPath; return NFD_ERROR; }
18+
nfdresult_t NFD_OpenDialogMultipleU8(const nfdpathset_t** outPaths, const nfdu8filteritem_t* filterList, nfdfiltersize_t filterCount, const nfdu8char_t* defaultPath) { (void)outPaths; (void)filterList; (void)filterCount; (void)defaultPath; return NFD_ERROR; }
19+
nfdresult_t NFD_OpenDialogMultipleN_With_Impl(nfdversion_t version, const nfdpathset_t** outPaths, const nfdopendialognargs_t* args) { (void)version; (void)outPaths; (void)args; return NFD_ERROR; }
20+
nfdresult_t NFD_OpenDialogMultipleU8_With_Impl(nfdversion_t version, const nfdpathset_t** outPaths, const nfdopendialogu8args_t* args) { (void)version; (void)outPaths; (void)args; return NFD_ERROR; }
21+
nfdresult_t NFD_SaveDialogN(nfdnchar_t** outPath, const nfdnfilteritem_t* filterList, nfdfiltersize_t filterCount, const nfdnchar_t* defaultPath, const nfdnchar_t* defaultName) { (void)outPath; (void)filterList; (void)filterCount; (void)defaultPath; (void)defaultName; return NFD_ERROR; }
22+
nfdresult_t NFD_SaveDialogU8(nfdu8char_t** outPath, const nfdu8filteritem_t* filterList, nfdfiltersize_t filterCount, const nfdu8char_t* defaultPath, const nfdu8char_t* defaultName) { (void)outPath; (void)filterList; (void)filterCount; (void)defaultPath; (void)defaultName; return NFD_ERROR; }
23+
nfdresult_t NFD_SaveDialogN_With_Impl(nfdversion_t version, nfdnchar_t** outPath, const nfdsavedialognargs_t* args) { (void)version; (void)outPath; (void)args; return NFD_ERROR; }
24+
nfdresult_t NFD_SaveDialogU8_With_Impl(nfdversion_t version, nfdu8char_t** outPath, const nfdsavedialogu8args_t* args) { (void)version; (void)outPath; (void)args; return NFD_ERROR; }
25+
nfdresult_t NFD_PickFolderN(nfdnchar_t** outPath, const nfdnchar_t* defaultPath) { (void)outPath; (void)defaultPath; return NFD_ERROR; }
26+
nfdresult_t NFD_PickFolderU8(nfdu8char_t** outPath, const nfdu8char_t* defaultPath) { (void)outPath; (void)defaultPath; return NFD_ERROR; }
27+
nfdresult_t NFD_PickFolderN_With_Impl(nfdversion_t version, nfdnchar_t** outPath, const nfdpickfoldernargs_t* args) { (void)version; (void)outPath; (void)args; return NFD_ERROR; }
28+
nfdresult_t NFD_PickFolderU8_With_Impl(nfdversion_t version, nfdu8char_t** outPath, const nfdpickfolderu8args_t* args) { (void)version; (void)outPath; (void)args; return NFD_ERROR; }
29+
nfdresult_t NFD_PickFolderMultipleN(const nfdpathset_t** outPaths, const nfdnchar_t* defaultPath) { (void)outPaths; (void)defaultPath; return NFD_ERROR; }
30+
nfdresult_t NFD_PickFolderMultipleU8(const nfdpathset_t** outPaths, const nfdu8char_t* defaultPath) { (void)outPaths; (void)defaultPath; return NFD_ERROR; }
31+
nfdresult_t NFD_PickFolderMultipleN_With_Impl(nfdversion_t version, const nfdpathset_t** outPaths, const nfdpickfoldernargs_t* args) { (void)version; (void)outPaths; (void)args; return NFD_ERROR; }
32+
nfdresult_t NFD_PickFolderMultipleU8_With_Impl(nfdversion_t version, const nfdpathset_t** outPaths, const nfdpickfolderu8args_t* args) { (void)version; (void)outPaths; (void)args; return NFD_ERROR; }
33+
nfdresult_t NFD_PathSet_GetCount(const nfdpathset_t* pathSet, nfdpathsetsize_t* count) { (void)pathSet; if (count) *count = 0; return NFD_OKAY; }
34+
nfdresult_t NFD_PathSet_GetPathN(const nfdpathset_t* pathSet, nfdpathsetsize_t index, nfdnchar_t** outPath) { (void)pathSet; (void)index; (void)outPath; return NFD_ERROR; }
35+
nfdresult_t NFD_PathSet_GetPathU8(const nfdpathset_t* pathSet, nfdpathsetsize_t index, nfdu8char_t** outPath) { (void)pathSet; (void)index; (void)outPath; return NFD_ERROR; }
36+
void NFD_PathSet_FreePathN(const nfdnchar_t* filePath) { free((void*)filePath); }
37+
void NFD_PathSet_FreePathU8(const nfdu8char_t* filePath) { free((void*)filePath); }
38+
void NFD_PathSet_Free(const nfdpathset_t* pathSet) { (void)pathSet; }
39+
void NFD_PathSet_FreeEnum(nfdpathsetenum_t* enumerator) { (void)enumerator; }
40+
nfdresult_t NFD_PathSet_GetEnum(const nfdpathset_t* pathSet, nfdpathsetenum_t** outEnumerator) { (void)pathSet; (void)outEnumerator; return NFD_ERROR; }
41+
nfdresult_t NFD_PathSet_EnumNextN(nfdpathsetenum_t* enumerator, nfdnchar_t** outPath) { (void)enumerator; (void)outPath; return NFD_ERROR; }
42+
nfdresult_t NFD_PathSet_EnumNextU8(nfdpathsetenum_t* enumerator, nfdu8char_t** outPath) { (void)enumerator; (void)outPath; return NFD_ERROR; }

tools/package_ios_ipa.sh

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5+
BUILD_DIR="$ROOT/out/build/ios-device-release"
6+
IPA_DIR="$ROOT/out/ipa"
7+
PAYLOAD_DIR="$IPA_DIR/Payload"
8+
APP_PATH="$BUILD_DIR/Unleashed Recompiled.app"
9+
IPA_PATH="$IPA_DIR/UnleashedRecompiled.ipa"
10+
11+
missing=0
12+
for file in \
13+
"$ROOT/UnleashedRecompLib/private/default.xex" \
14+
"$ROOT/UnleashedRecompLib/private/default.xexp" \
15+
"$ROOT/UnleashedRecompLib/private/shader.ar"; do
16+
if [[ ! -f "$file" ]]; then
17+
printf 'Missing required file: %s\n' "$file" >&2
18+
missing=1
19+
fi
20+
done
21+
22+
if [[ "$missing" -ne 0 ]]; then
23+
exit 1
24+
fi
25+
26+
cmake --preset ios-device-release
27+
cmake --build "$BUILD_DIR" --target UnleashedRecomp -j "${JOBS:-8}"
28+
29+
if [[ ! -d "$APP_PATH" ]]; then
30+
printf 'Expected app bundle was not produced: %s\n' "$APP_PATH" >&2
31+
exit 1
32+
fi
33+
34+
rm -rf "$IPA_DIR"
35+
mkdir -p "$PAYLOAD_DIR"
36+
cp -R "$APP_PATH" "$PAYLOAD_DIR/"
37+
38+
if [[ -n "${MOBILEPROVISION:-}" ]]; then
39+
cp "$MOBILEPROVISION" "$PAYLOAD_DIR/Unleashed Recompiled.app/embedded.mobileprovision"
40+
fi
41+
42+
if [[ -n "${CODESIGN_IDENTITY:-}" ]]; then
43+
codesign --force --sign "$CODESIGN_IDENTITY" \
44+
${ENTITLEMENTS:+--entitlements "$ENTITLEMENTS"} \
45+
"$PAYLOAD_DIR/Unleashed Recompiled.app"
46+
fi
47+
48+
(
49+
cd "$IPA_DIR"
50+
zip -qry "$IPA_PATH" Payload
51+
)
52+
53+
printf '%s\n' "$IPA_PATH"

0 commit comments

Comments
 (0)