macOS: Create App Store build (#17074)

This commit is contained in:
Eric Warmenhoven 2024-10-04 15:46:51 -04:00 committed by GitHub
parent e1e341d003
commit 7ae8597765
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 193 additions and 54 deletions

View File

@ -1569,7 +1569,7 @@ static bool core_info_get_file_id(const char *core_filename,
/* > Remove extension */
strlcpy(core_file_id, core_filename, len);
path_remove_extension(core_file_id);
#if IOS
#if defined(IOS) || defined(OSX)
/* iOS framework names, to quote Apple:
* "must contain only alphanumerics, dots, hyphens and must not end with a dot."
*

View File

@ -411,6 +411,8 @@ static void frontend_darwin_get_env(int *argc, char *argv[],
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_REMAP], g_defaults.dirs[DEFAULT_DIR_MENU_CONFIG], "remaps", sizeof(g_defaults.dirs[DEFAULT_DIR_REMAP]));
#if defined(HAVE_UPDATE_CORES) || defined(HAVE_STEAM)
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], application_data, "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
#elif defined(OSX) && defined(HAVE_APPLE_STORE)
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], bundle_path_buf, "Contents/Frameworks", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
#else
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], bundle_path_buf, "Frameworks", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
#endif

View File

@ -185,7 +185,7 @@ size_t frontend_driver_get_core_extension(char *s, size_t len)
s[2] = 'l';
s[3] = '\0';
return 3;
#elif defined(IOS)
#elif defined(IOS) || (defined(OSX) && defined(HAVE_APPLE_STORE))
s[0] = 'f';
s[1] = 'r';
s[2] = 'a';

View File

@ -130,7 +130,7 @@ dylib_t dylib_load(const char *path)
#elif defined(ORBIS)
int res;
dylib_t lib = (dylib_t)sceKernelLoadStartModule(path, 0, NULL, 0, NULL, &res);
#elif defined(IOS)
#elif defined(IOS) || defined(OSX)
dylib_t lib;
static const char fw_suffix[] = ".framework";
if (string_ends_with(path, fw_suffix))

View File

@ -189,7 +189,7 @@ static int dir_list_read(const char *dir,
if (!include_hidden && strcmp(name, "System Volume Information") == 0)
continue;
#endif
#ifdef IOS
#if defined(IOS) || defined(OSX)
if (string_ends_with(name, ".framework"))
{
attr.i = RARCH_PLAIN_FILE;

View File

@ -4,9 +4,11 @@
//
//
#include "Metal.xcconfig"
INFOPLIST_FILE = $(SRCROOT)/OSX/Info_AppStore.plist
DEVELOPMENT_TEAM=UK699V5ZS8
OTHER_CFLAGS = $(inherited) -DHAVE_APPLE_STORE
OTHER_CFLAGS = $(inherited) -DHAVE_ICLOUD
OTHER_CFLAGS = $(inherited) -DHAVE_MAIN
OTHER_CFLAGS = $(inherited) -DHAVE_ONLINE_UPDATER
INFOPLIST_FILE = $(SRCROOT)/OSX/Info_AppStore.plist
DEVELOPMENT_TEAM=UK699V5ZS8
CODE_SIGN_ENTITLEMENTS = RetroArchAppStore.entitlements

View File

@ -1653,7 +1653,6 @@
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>

4
pkg/apple/OSX/modules/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

View File

@ -76,11 +76,10 @@
0790F67B2BF282B400AA58C9 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0790F6782BF282B400AA58C9 /* Media.xcassets */; };
0790F67C2BF2925400AA58C9 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0790F6782BF282B400AA58C9 /* Media.xcassets */; };
0795A8C7299A095300D5035D /* CoreHaptics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0795A8C6299A095300D5035D /* CoreHaptics.framework */; };
07D851CD2CAF06E2005097EA /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 075650242C488918004C5E7E /* CloudKit.framework */; };
07EF0FFA2BEB117000EDCA9B /* MoltenVK.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 07EF0FF42BEB114000EDCA9B /* MoltenVK.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
07EF0FFC2BEB117400EDCA9B /* MoltenVK.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07EF0FF42BEB114000EDCA9B /* MoltenVK.xcframework */; };
07EF0FFD2BEB117400EDCA9B /* MoltenVK.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 07EF0FF42BEB114000EDCA9B /* MoltenVK.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
07EF0FFF2BEB117900EDCA9B /* MoltenVK.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 07EF0FF42BEB114000EDCA9B /* MoltenVK.xcframework */; };
07EF10002BEB117900EDCA9B /* MoltenVK.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 07EF0FF42BEB114000EDCA9B /* MoltenVK.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
07F2BBC62BE83A4700FD1295 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
07F2BBC82BE83A4700FD1295 /* assets.zip in Resources */ = {isa = PBXBuildFile; fileRef = 9254B33025FA0BA300A1E0DA /* assets.zip */; };
07F2BBC92BE83A4700FD1295 /* MainMenu_Metal.xib in Resources */ = {isa = PBXBuildFile; fileRef = A9020F323D5F3C8E120D04AC /* MainMenu_Metal.xib */; };
@ -166,17 +165,6 @@
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
07EF10012BEB117900EDCA9B /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
07EF10002BEB117900EDCA9B /* MoltenVK.xcframework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
@ -579,9 +567,9 @@
07F2BBDC2BE83A4700FD1295 /* MetalKit.framework in Frameworks */,
07F2BBDD2BE83A4700FD1295 /* libz.dylib in Frameworks */,
07F2BBDE2BE83A4700FD1295 /* OpenAL.framework in Frameworks */,
07EF0FFF2BEB117900EDCA9B /* MoltenVK.xcframework in Frameworks */,
07F2BBDF2BE83A4700FD1295 /* CoreAudio.framework in Frameworks */,
07F2BBE02BE83A4700FD1295 /* AudioUnit.framework in Frameworks */,
07D851CD2CAF06E2005097EA /* CloudKit.framework in Frameworks */,
07F2BBE12BE83A4700FD1295 /* AppKit.framework in Frameworks */,
07F2BBE22BE83A4700FD1295 /* IOKit.framework in Frameworks */,
);
@ -1372,11 +1360,10 @@
buildConfigurationList = 07F2BBE62BE83A4700FD1295 /* Build configuration list for PBXNativeTarget "RetroArch AppStore" */;
buildPhases = (
07F2BBC42BE83A4700FD1295 /* ShellScript */,
07F2BBC52BE83A4700FD1295 /* Resources */,
07F2BBCB2BE83A4700FD1295 /* Sources */,
07F2BBD22BE83A4700FD1295 /* Frameworks */,
070CCFA82BF248E600E560BA /* ShellScript */,
07EF10012BEB117900EDCA9B /* Embed Frameworks */,
07F2BBC52BE83A4700FD1295 /* Resources */,
);
buildRules = (
);
@ -1528,7 +1515,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "FILTERSDIR=\"$TARGET_BUILD_DIR\"/\"$UNLOCALIZED_RESOURCES_FOLDER_PATH\"/filters\nmkdir -p \"$FILTERSDIR\"/audio\ncp -Xf ${SRCBASE}/libretro-common/audio/dsp_filters/*.dsp \"$FILTERSDIR\"/audio/\nmkdir -p \"$FILTERSDIR\"/video\ncp -Xf ${SRCBASE}/gfx/video_filters/*.filt \"$FILTERSDIR\"/video/\n";
shellScript = "./rebuild-assets.sh -d -i -m -x\n\nrm -f ${SRCROOT}/OSX/modules/*.dylib\n./update-cores.sh macos appstore\n./make-frameworks.sh\n\nFILTERSDIR=\"$TARGET_BUILD_DIR\"/\"$UNLOCALIZED_RESOURCES_FOLDER_PATH\"/filters\nmkdir -p \"$FILTERSDIR\"/audio\ncp -Xf ${SRCBASE}/libretro-common/audio/dsp_filters/*.dsp \"$FILTERSDIR\"/audio/\nmkdir -p \"$FILTERSDIR\"/video\ncp -Xf ${SRCBASE}/gfx/video_filters/*.filt \"$FILTERSDIR\"/video/\n";
};
0720993C29B1258C001642BB /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
@ -1800,9 +1787,16 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
CODE_SIGN_ENTITLEMENTS = RetroArchAppStore.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 44;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=macosx*]" = UK699V5ZS8;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.entertainment";
PRODUCT_BUNDLE_IDENTIFIER = com.libretro.dist.RetroArch;
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "macOS App Store";
};
name = Debug;
};
@ -1813,9 +1807,16 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
CODE_SIGN_ENTITLEMENTS = RetroArchAppStore.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 44;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=macosx*]" = UK699V5ZS8;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.entertainment";
PRODUCT_BUNDLE_IDENTIFIER = com.libretro.dist.RetroArch;
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "macOS App Store";
};
name = Release;
};

View File

@ -15,6 +15,85 @@
default_platform(:ios)
platform :mac do
desc "Push a new beta build to TestFlight"
lane :beta do
# this needs these environment variables set:
# APP_STORE_CONNECT_API_KEY_KEY_ID,
# APP_STORE_CONNECT_API_KEY_ISSUER_ID,
# APP_STORE_CONNECT_API_KEY_KEY_FILEPATH
app_store_connect_api_key
reset_git_repo(
force: true,
files: [
"./OSX/assets.zip",
"./OSX/Info_AppStore.plist"
]
)
# ensure_git_status_clean
# git_pull
# sh("git log -1")
begin
app_store_build_number(
app_identifier: "com.libretro.dist.RetroArch",
platform: "osx",
username: "libretro@gmail.com",
team_id: "118576492",
live: true
)
current_version_number = lane_context[SharedValues::LATEST_VERSION]
rescue => ex
current_version_number = "1.19.1"
end
begin
latest_testflight_build_number(
app_identifier: "com.libretro.dist.RetroArch",
platform: "osx",
username: "libretro@gmail.com",
team_id: "118576492"
)
next_version_number = lane_context[SharedValues::LATEST_TESTFLIGHT_VERSION]
next_build_number = lane_context[SharedValues::LATEST_TESTFLIGHT_BUILD_NUMBER]
rescue => ex
next_version_number = "1.19.2"
next_build_number = 45
end
next_version_number = "1.19.2"
if current_version_number == next_version_number
version_array = next_version_number.split(".").map(&:to_i)
version_array[-1] = version_array[-1] + 1
next_version_number = version_array.join(".")
end
# can't use update_build_number/agvtool to update this as it
# doesn't deal with multiple projects in the same folder
update_info_plist(
plist_path: "OSX/Info_AppStore.plist",
block: proc do |plist|
plist["CFBundleVersion"] = (next_build_number + 1).to_s
plist["CFBundleShortVersionString"] = next_version_number
end
)
build_mac_app(
workspace: "RetroArch.xcworkspace",
scheme: "RetroArch AppStore",
xcodebuild_formatter: 'xcpretty',
buildlog_path: "buildlog",
export_method: "app-store",
export_options: {
provisioningProfiles: {
"com.libretro.dist.RetroArch" => "macOS App Store"
}
}
)
upload_to_testflight(
distribute_external: true,
groups: ['Invaders', 'Patreons'],
changelog: "Rebuild frontend from latest master branch and take latest build of all cores."
)
end
end
platform :ios do
desc "Push a new beta build to TestFlight"
lane :beta do

View File

@ -13,6 +13,19 @@ For _fastlane_ installation instructions, see [Installing _fastlane_](https://do
# Available Actions
## Mac
### mac beta
```sh
[bundle exec] fastlane mac beta
```
Push a new beta build to TestFlight
----
## iOS
### ios beta

View File

@ -13,7 +13,7 @@
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>MinimumOSVersion</key>
<string>12.0</string>
<string>%OSVER%</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleInfoDictionaryVersion</key>

View File

@ -24,7 +24,7 @@ elif [ "$PLATFORM_FAMILY_NAME" = "macOS" ] ; then
BASE_DIR="OSX"
SUFFIX=
PLATFORM=
DEPLOYMENT_TARGET=
DEPLOYMENT_TARGET="${MACOSX_DEPLOYMENT_TARGET}"
fi
if [ -n "$BUILT_PRODUCTS_DIR" -a -n "$FRAMEWORKS_FOLDER_PATH" ] ; then
@ -51,7 +51,15 @@ for dylib in $(find "$BASE_DIR"/modules -maxdepth 1 -type f -regex '.*libretro.*
vtool -set-build-version "${PLATFORM}" "${DEPLOYMENT_TARGET}" "${build_sdk}" -set-build-tool "$PLATFORM" ld 1115.7.3 -set-source-version 0.0 -replace -output "$dylib" "$dylib"
fi
lipo -create "$dylib" -output "$fwDir/$fwName"
sed -e "s,%CORE%,$fwName," -e "s,%BUNDLE%,$fwName," -e "s,%IDENTIFIER%,$fwName," iOS/fw.tmpl > "$fwDir/Info.plist"
sed -e "s,%CORE%,$fwName," -e "s,%BUNDLE%,$fwName," -e "s,%IDENTIFIER%,$fwName," -e "s,%OSVER%,$DEPLOYMENT_TARGET," iOS/fw.tmpl > "$fwDir/Info.plist"
if [ "$PLATFORM_FAMILY_NAME" = "macOS" ] ; then
mkdir -p "$fwDir"/Versions/A/Resources
mv "$fwDir/$fwName" "$fwDir"/Versions/A
mv "$fwDir"/Info.plist "$fwDir"/Versions/A/Resources
ln -sf A "$fwDir"/Versions/Current
ln -sf Versions/Current/Resources "$fwDir"/Resources
ln -sf "Versions/Current/$fwName" "$fwDir/$fwName"
fi
echo "signing $fwName"
codesign --force --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "$fwDir"
done
@ -67,7 +75,7 @@ fi
MVK_PLATFORM_SUBDIR="${SWIFT_PLATFORM_TARGET_PREFIX}-$(echo $ARCHS_STANDARD_64_BIT | sed -e 's/ /_/g')${LLVM_TARGET_TRIPLE_SUFFIX}"
if [ -d "${MOLTENVK_XCFRAMEWORK}/${MVK_PLATFORM_SUBDIR}/MoltenVK.framework" ] ; then
echo copying moltenvk from "${MOLTENVK_XCFRAMEWORK}/${MVK_PLATFORM_SUBDIR}/MoltenVK.framework"
cp -r "${MOLTENVK_XCFRAMEWORK}/${MVK_PLATFORM_SUBDIR}/MoltenVK.framework" "${OUTDIR}"
cp -R "${MOLTENVK_XCFRAMEWORK}/${MVK_PLATFORM_SUBDIR}/MoltenVK.framework" "${OUTDIR}"
codesign --force --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" "${OUTDIR}/MoltenVK.framework"
fi

View File

@ -5,12 +5,10 @@ DEBUG=
if [ -z "$DEBUG" ] ; then
CURL_DEBUG=-sf
UNZIP_DEBUG=-q
NO_RM=
else
printf "Turning on debug\n"
CURL_DEBUG=
UNZIP_DEBUG=
NO_RM=1
fi
function debug() {
@ -32,18 +30,33 @@ else
DRY_RUN=
fi
if [ "$1" = "tvos" -o "$1" = "--tvos" ] ; then
URL_BASE="https://buildbot.libretro.com/nightly/apple"
if [ "$PLATFORM_FAMILY_NAME" = "tvOS" -o "$1" = "tvos" -o "$1" = "--tvos" ] ; then
CORES_DIR="${APPLE_DIR}/tvOS/modules"
PLATFORM=tvos
shift
URL_PLATFORMS=( tvos-arm64 )
if [ "$1" = "tvos" -o "$1" = "--tvos" ] ; then
shift
fi
elif [ "$PLATFORM_FAMILY_NAME" = "macOS" -o "$1" = "macos" -o "$1" = "--macos" ] ; then
CORES_DIR="${APPLE_DIR}/OSX/modules"
PLATFORM=osx
URL_PLATFORMS=( osx/arm64 osx/x86_64 )
if [ "$1" = "macos" -o "$1" = "--macos" ] ; then
shift
fi
else
CORES_DIR="${APPLE_DIR}/iOS/modules"
PLATFORM=ios
URL_PLATFORMS=( ios-arm64 )
if [ "$1" = "ios" -o "$1" = "--ios" ] ; then
shift
fi
fi
debug CORES_DIR is $CORES_DIR
cd "$CORES_DIR"
URL_BASE="https://buildbot.libretro.com/nightly/apple/${PLATFORM}-arm64/latest"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
@ -55,35 +68,47 @@ function update_dylib() {
if [ -n "$DRY_RUN" ] ; then
return
fi
if [ -f "$dylib" ] ; then
mv "$dylib" "$dylib".bak
fi
debug curl $CURL_DEBUG -o "$dylib".zip "$URL_BASE"/"$dylib".zip
(
curl $CURL_DEBUG -o "$dylib".zip "$URL_BASE"/"$dylib".zip
if [ ! -f "$dylib".zip ] ; then
printf "${RED}Download ${dylib} failed${NC}\n"
if [ -f "$dylib".bak ] ; then
mv "$dylib".bak "$dylib"
mkdir "$dylib".tmp
pushd "$dylib".tmp >/dev/null
for urlp in "${URL_PLATFORMS[@]}" ; do
debug curl $CURL_DEBUG -o "$dylib".zip "$URL_BASE"/"$urlp"/latest/"$dylib".zip
curl $CURL_DEBUG -o "$dylib".zip "$URL_BASE"/"$urlp"/latest/"$dylib".zip
if [ ! -f "$dylib".zip ] ; then
printf "${RED}Download ${dylib} failed${NC}\n"
break
fi
debug unzip $UNZIP_DEBUG "$dylib".zip
unzip $UNZIP_DEBUG "$dylib".zip
if [ ! -f "$dylib" ] ; then
printf "${RED}Unzip ${dylib} failed${NC}\n"
break
fi
rm -f "$dylib".zip
# macos app store needs universal binaries
if [ "${#URL_PLATFORMS[@]}" != 1 ] ; then
mv "$dylib" "$dylib".$(basename "$urlp")
fi
done
if [ "${#URL_PLATFORMS[@]}" != 1 ] ; then
lipo -create -output "$dylib" "$dylib".*
fi
else
debug unzip $UNZIP_DEBUG "$dylib".zip
unzip $UNZIP_DEBUG "$dylib".zip
if [ ! -f "$dylib" ] ; then
printf "${RED}Unzip ${dylib} failed${NC}\n"
mv "$dylib".bak "$dylib"
else
popd >/dev/null
if [ -f "$dylib".tmp/"$dylib" ] ; then
printf "${GREEN}Download ${dylib} success!${NC}\n"
[ -n "$NO_RM" ] || rm -f "$dylib".zip "$dylib".bak
mv "$dylib".tmp/"$dylib" "$dylib"
fi
fi
rm -rf "$dylib".tmp
) &
}
allcores=
function get_all_cores() {
if [ -z "$allcores" ] ; then
allcores=($(curl $CURL_DEBUG $URL_BASE/ | sed -e 's/></\n/g' | grep '>[^<]\+\.dylib.zip<' | sed -e 's/.*>\(.*\)\.zip<.*/\1/'))
allcores=($(curl $CURL_DEBUG "$URL_BASE/${URL_PLATFORMS[0]}/latest/" | sed -e 's/></\n/g' | grep '>[^<]\+\.dylib.zip<' | sed -e 's/.*>\(.*\)\.zip<.*/\1/'))
fi
}
@ -217,6 +242,12 @@ else
wasm4
xrick
)
if [ "$PLATFORM" = "osx" ] ; then
exports+=(
flycast
play
)
fi
for dylib in "${exports[@]}" ; do
find_dylib $dylib
done

View File

@ -6453,7 +6453,7 @@ static void retroarch_parse_input_libretro_path(const char *path, size_t path_le
/* Check if path is a directory */
if (
((path_stats & RETRO_VFS_STAT_IS_DIRECTORY) != 0)
#if IOS
#if defined(IOS) || defined(OSX)
&& !string_ends_with(path, ".framework")
#endif
)