Script to Compile the latest github for retroarch+cores for iOS

Introduction

I made a script that is fairly portable that can automate building, signing, etc. all cores from the latest github versions of retroarch on the latest iOS versions. It generates a nice little IPA for you to just pop on into your cydia impactor or whatever else.

Script Advantages

The script is below, but to describe the advantages of running my script rather than libretro-build-ios-arm64.sh directly with no arguments…

  1. It attempts to compile all available cores with various versions of iOS. This means that some cores that are not included in the default libretro-build-ios-arm64.sh, but which nonetheless compile properly and work great, will be included. Cores like quasi88, for example.
  2. It also builds the IPA for you - no need to mess around with xcode beyond installation.
  3. It keeps an archive of the latest compiled versions of each core. This is important since some cores lose their compilability through updates to their code (temporary breaking, etc). With this, you will keep access to the core regardless.
  4. This will copy in other cores in the order of iOS10 > iOS9 > iOS Generic > iOS-theos in case they don’t compile in arm64. The cores won’t work, mind you, but hey they’ll be there if you want 'em? There may be a way to get them to work, so please tell me if you happen to know.
  5. Fetches are done only immediately before building, which I guess makes it slightly more likely that you get the most bleeding edge core possible compiled compared to running libretro-fetch.sh and then libretro-build-ios-arm64.sh. Hurrah?
  6. Fetches and compiles actually work for weird cores that are not pulled in normally by running libretro-fetch.sh without options. For some reason, for example, Play is not fetched by that script unless you explicitly run libretro-fetch.sh play. Not that Play compiles currently, mind you. But it might some day!

Script Setup

  1. Install the latest OSX (I am using an install of an OSX guest on VMWare via a Windows host, so it does compile fine on that)
  2. Install xcode (ideally the latest developer version, as that’s what I’m testing against). Make sure the right xcode is set properly by running xcode-select -p
  3. Use git to check out libretrosuper and retroarch
  4. Figure out your provisioning profile name and developer certificate name (check https://developer.apple.com/account/resources/certificates/list and https://developer.apple.com/account/resources/profiles/list).
  5. Install xcprovisioner by running sudo gem install xcprovisioner
  6. Create a directory to store the output
  7. Edit the variables at the start of the script to reflect the directories you created and information you obtained.
  8. Download http://buildbot.libretro.com/assets/frontend/assets.zip and put it in pkg/apple in your retroarch directory.
  9. Make all the other .sh files referenced executable (chmod a+x)
  10. Run sudo easy_install pip; sudo pip install tinydb; sudo pip install gitpython

There may be a better way to handle signing via CLI.

You may also need to run open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg and follow the installation.

I am going to assume that you know how to do all those steps above. If you don’t, I probably won’t be providing support.


Cores that do not compile currently, but which do compile with some tweaks

3dengine

basilisk2

bnes

bsnes2014

Run the command CMAKE=cmake VERBOSE=1 SINGLE_CORE=bsnes2014 FORCE=YES EXIT_ON_ERROR=1 ./libretro-buildbot-recipe.sh recipes/apple/cores-ios-arm64-generic

bsnes_cplusplus98

craft

chailove

EasyRPG

Install brew and then use that to install cmake and pkg-config. Then cd into libretro-easyrpg and run git submodule update --init. Each time you re-build, you will need to run the following before doing so:

git clean -xfd
git submodule foreach --recursive git clean -xfd
git reset --hard
git submodule foreach --recursive git reset --hard
git submodule update --init --recursive

emux

Add the following line to recipes/apple/cores-ios-arm64-generic

emux libretro-emux https://github.com/libretro/emux.git master YES GENERIC Makefile.ios-arm64 libretro | emux_nes:MACHINE=nes emux_sms:MACHINE=sms emux_chip8:MACHINE=chip8 emux_gb:MACHINE=gb

Then run the following command:

ENABLED=1 CMAKE=cmake VERBOSE=1 SINGLE_CORE=emux ./libretro-buildbot-recipe.sh recipes/apple/cores-ios-arm64-generic

flycast

frodo

lutro

Mesen-s

Mupen64plus_next

Openlara

PCSX Rearmed

Run CMAKE=cmake VERBOSE=1 SINGLE_CORE=pcsx_rearmed_interpreter FORCE=YES EXIT_ON_ERROR=1 ./libretro-buildbot-recipe.sh recipes/apple/cores-ios-arm64-generic

play

Run the command CMAKE=cmake VERBOSE=1 SINGLE_CORE=play FORCE=YES EXIT_ON_ERROR=1 ./libretro-buildbot-recipe.sh recipes/apple/cores-ios-arm64-generic

sameboy

install brew (https://brew.sh) and then install rgbds via brew install rgbds.

To get the core to fully work currently, you will need to run the build script twice. The first time will likely fail due to ‘Bad CPU type in executable’ errors. But if you re-run it, it will compile.

test

Run this command CMAKE=cmake VERBOSE=1 SINGLE_CORE=test FORCE=YES EXIT_ON_ERROR=1 ./libretro-buildbot-recipe.sh recipes/apple/cores-ios-arm64-generic

thepowdertoy

Add the following line to recipes/apple/cores-ios-arm64-generic

thepowdertoy libretro-thepowdertoy https://github.com/libretro/ThePowderToy.git master YES CMAKE Makefile build -DCMAKE_TOOLCHAIN_FILE=../ios.cmake -DCMAKE_BUILD_TYPE="Release" --target thepowdertoy_libretro

Then run the following command:

ENABLED=1 CMAKE=cmake VERBOSE=1 SINGLE_CORE=thepowdertoy ./libretro-buildbot-recipe.sh recipes/apple/cores-ios-arm64-generic

TIC-80

Add the following line to recipes/apple/cores-ios-arm64-generic

tic80 libretro-tic80 https://github.com/jet082/TIC-80.git master YES CMAKE Makefile build2 -DCMAKE_TOOLCHAIN_FILE=../ios.cmake -DCMAKE_BUILD_TYPE="Release"

Then run the following command:

ENABLED=1 CMAKE=cmake VERBOSE=1 SINGLE_CORE=tic80 ./libretro-buildbot-recipe.sh recipes/apple/cores-ios-arm64-generic

uzem


Cores I’ve compiled for arm64

2048
3dengine
4do
81
atari800
basilisk2
bluemsx
bnes
bsnes2014
bsnes_accuracy
bsnes_balanced
bsnes_cplusplus98
bsnes_hd
bsnes_mercury_accuracy
bsnes_mercury_balanced
bsnes_mercury_performance
bsnes_performance
cannonball
cap32
chailove
craft
crocods
daphne
desmume
dinothawr
dosbox
easyrpg
emux_chip8
emux_gb
emux_nes
emux_sms
fbalpha2012_cps1
fbalpha2012_cps2
fbalpha2012_cps3
fbalpha2012
fbalpha2012_neogeo
fbneo
fceumm
ffmpeg
flycast
fmsx
freechaf
freeintv
frodo
fuse
gambatte
gearboy
gearsystem
genesis_plus_gx
gme
gpsp
gw
handy
hatari
lutro
mame2000
mame2003
mame2003_plus
mame2010
mame
mednafen_gba
mednafen_lynx
mednafen_ngp
mednafen_pce_fast
mednafen_pcfx
mednafen_psx
mednafen_saturn
mednafen_snes
mednafen_supergrafx
mednafen_vb
mednafen_wswan
melonds
mesen-s
mesen
meteor
mgba
mrboom
mu
mupen64plus_next
nekop2
nestopia
np2kai
nxengine
o2em
openlara
parallel_n64
pcsx_rearmed_interpreter
picodrive
play
pocketcdg
pokemini
prboom
prosystem
puae
px68k
quasi88
quicknes
reminiscence
sameboy
scummvm
snes9x2002
snes9x2005
snes9x2010
snes9x
squirreljme
stella2014
stella
stonesoup
test
tgbdual
theodore
thepowdertoy
tic80
tyrquake
uzem
vba_next
vbam
vecx
vice_x128
vice_x64
vice_xplus4
vice_xvic
virtualjaguar
xrick
yabause

Building for other OSX/iOS/tvOS systems

Just change the line finalPackage and listOfFallbacks to reflect what you want to build and fall back on.

If you are building for tvOS, open the RetroArch_iOS11.xcodeproj file once beforehand in xcode and set the team, etc. to yourself. Then make sure that eraseLocalChanges and manualSigning are set to False.


THE SCRIPT


import os, subprocess, glob, shutil, git, tinydb
from datetime import datetime

libretroSuperDir = os.path.expanduser("~/retroarch-stuff/libretro-super")
retroarchDir = os.path.expanduser("~/retroarch-stuff/libretro-super/retroarch")
outputDir = os.path.expanduser("~/retroarch-stuff/output")
coreArchiveDir = os.path.expanduser("~/retroarch-stuff/core-archive")
developerName = "DeveloperNameHere"
profileName = "ProfileNameHere"
teamName = "yourTeamNameHere"
finalPackage = "ios-arm64"
listOfFallbacks = ["ios10", "ios9"]
extension = "dylib"
debug = False
manualSigning = True
eraseLocalChanges = True
eraseBeforeFetching = False

directoryNameTranslation = {}
directoryNameTranslation["ios-theos"] = "theos_ios"

finalBuildTranslation = {}
finalBuildTranslation["ios-arm64"] = {"modules": "apple/iOS", "projectName": "apple/RetroArch_iOS11.xcodeproj", "targetName": "RetroArchiOS11", "endPlacement": "apple"}
finalBuildTranslation["tvos-arm64"] = {"modules": "apple/tvOS", "projectName": "apple/RetroArch_iOS11.xcodeproj", "targetName": "RetroArchTV", "endPlacement": "apple"}
finalBuildTranslation["ios10"] = {"modules": "apple/iOS", "projectName": "apple/RetroArch_iOS10.xcodeproj", "targetName": "RetroArchiOS10", "endPlacement": "apple"}
finalBuildTranslation["ios10"] = {"modules": "apple/iOS", "projectName": "apple/RetroArch_iOS9.xcodeproj", "targetName": "RetroArch iOS9", "endPlacement": "apple"}
finalBuildTranslation["ios"] = {"modules": "apple/iOS", "projectName": "apple/RetroArch_iOS8.xcodeproj", "targetName": "RetroArch iOS8", "endPlacement": "apple"}
finalBuildTranslation["ios-theos"] = {"modules": "apple/iOS", "projectName": "apple/RetroArch_iOS6.xcodeproj", "targetName": "RetroArch iOS6", "endPlacement": "apple"}

stupidInconsistentNameTranslation = {}
stupidInconsistentNameTranslation["mesen-s"] = "mesens"
stupidInconsistentNameTranslation["mednafen_pce"] = "mednafen_pce_fast"
stupidInconsistentNameTranslation["mupen64plus_next_gles3"] = "mupen64plus_next"
stupidInconsistentNameTranslation["test"] = "samples"

stuffToRemove = ["vice_x64sc", "vice_xcbm2", "vice_xpet", "redbook", "bsnes", "flycast_wince", "bsnes_mercury", "snes9x2005_plus", "mednafen_psx_hw", "dosbox_svn_glide", "higan_sfc_balanced", "pcsx_rearmed_interpreter", "higan_sfc"]

coreArchiveDatabase = tinydb.TinyDB(os.path.join(outputDir, "buildDatabase.json"))

def updateSomeDir(someDirectory):
	someGitDir = git.Repo(someDirectory)
	if eraseLocalChanges:
		try:
			someGitDir.git.clean("-xfd")
			someGitDir.git.submodule("foreach", "--recursive", "git", "clean", "-xfd")
			someGitDir.git.submodule("foreach", "--recursive", "git", "reset", "--hard")
			someGitDir.git.reset("--hard")
			someGitDir.git.stash()
			someGitDir.git.stash("drop")
		except:
			pass
	try:
		someGitDir.git.pull()
		someGitDir.git.submodule("update", "--init", "--recursive")
	except:
		pass
	return someGitDir.head.object.hexsha

def file_as_bytes(file):
	with open(file, "rb") as toSha:
		return hashlib.sha256(toSha.read()).hexdigest()

def safeRemove(someFile):
	if os.path.isfile(someFile):
		os.remove(someFile)

def translateStupidMisnamedDirectories(someName):
	if someName in directoryNameTranslation:
		return directoryNameTranslation[someName]
	else:
		return someName

def runCommandWithDebug(somePopenArray):
	with open(os.devnull, "w+") as devnull:
		if debug:
			result = subprocess.Popen(somePopenArray)
			result.wait()
		else:
			result = subprocess.Popen(somePopenArray, stdout=devnull, stderr=devnull)
			result.wait()

def tryToFetch(someBuildOption):
	os.chdir(libretroSuperDir)
	if someBuildOption in stupidInconsistentNameTranslation:
		fetchAndDirectoryCommand = stupidInconsistentNameTranslation[someBuildOption]
	else:
		fetchAndDirectoryCommand = someBuildOption
	theFetchedDirectory = os.path.join(libretroSuperDir, "libretro-" + fetchAndDirectoryCommand)
	if eraseBeforeFetching and os.path.isdir(theFetchedDirectory):
		shutil.rmtree(theFetchedDirectory)
	runCommandWithDebug([os.path.join(libretroSuperDir, "libretro-fetch.sh"), fetchAndDirectoryCommand])
	if not os.path.isdir(theFetchedDirectory):
		print("Failed to fetch " + someBuildOption + " - RetroArch recipe problem!")
		return False
	return updateSomeDir(theFetchedDirectory)

def tryToBuild(someBuildOption, someMethodToBuild):
	print("Attempting to build " + someBuildOption + " with " + someMethodToBuild)
	if someBuildOption in stupidInconsistentNameTranslation:
		fetchAndDirectoryCommand = stupidInconsistentNameTranslation[someBuildOption]
	else:
		fetchAndDirectoryCommand = someBuildOption
	if debug:
		result = subprocess.Popen([os.path.join(libretroSuperDir, "libretro-build-" + someMethodToBuild + ".sh"), fetchAndDirectoryCommand], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
		result.wait()
		resultStdout, resultStderr = result.communicate()
	else:
		runCommandWithDebug([os.path.join(libretroSuperDir, "libretro-build-" + someMethodToBuild + ".sh"), fetchAndDirectoryCommand])
	checkPath = translateStupidMisnamedDirectories(someMethodToBuild)
	queryObject = tinydb.Query()
	if len(glob.glob(os.path.join(libretroSuperDir, "dist", checkPath, someBuildOption + "*." + extension))) == 1:
		print("Successfully built " + someBuildOption + " with " + someMethodToBuild)
		#Copy built core(s) to the archive
		for someCompiledModule in glob.glob(os.path.join(libretroSuperDir, "dist", translateStupidMisnamedDirectories(someMethodToBuild), "*." + extension)):
			copyPath = os.path.join(coreArchiveDir, translateStupidMisnamedDirectories(someMethodToBuild))
			if not os.path.isdir(copyPath):
				os.mkdir(copyPath)
			shutil.copy2(someCompiledModule, copyPath)
			safeRemove(someCompiledModule)
		coreArchiveDatabase.update({"buildSuccess": True}, (queryObject.coreName == someBuildOption) & (queryObject.buildType == someMethodToBuild))
		return True
	else:
		print("Failed to build " + someBuildOption + " with " + someMethodToBuild)
		if debug:
			with open(os.path.join(outputDir, "failedLog.txt"), "a+") as failedLog:
				for someStdOutLine in resultStdout.split("\n"):
					if len(someStdOutLine) >= 1:
						failedLog.write(someBuildOption + " (" + someMethodToBuild + "): " + someStdOutLine + "\n")
				for someStdErrLine in resultStdout.split("\n"):
					if len(someStdOutLine) >= 1:
						failedLog.write(someBuildOption + " (" + someMethodToBuild + "): " + someStdOutLine + "\n")
		coreArchiveDatabase.update({"buildSuccess": False}, (queryObject.coreName == someBuildOption) & (queryObject.buildType == someMethodToBuild))
		return False

def cleanup():
	for someExistingCore in glob.glob(os.path.join(libretroSuperDir, "dist/*/*." + extension)):
		safeRemove(someExistingCore)
	for someOldModule in glob.glob(os.path.join(retroarchDir, "pkg/*/*/modules/*." + extension)):
		safeRemove(someOldModule)
	safeRemove(os.path.join(outputDir, "failedLog.txt"))
	for someOldBuild in glob.glob(os.path.join(retroarchDir, "pkg/*/build/*")):
		shutil.rmtree(someOldBuild)
	for someOldIpa in glob.glob(os.path.join(outputDir, "*.ipa")):
		safeRemove(someOldIpa)

def init():
	updateSomeDir(libretroSuperDir)
	os.chdir(libretroSuperDir)
	buildScripts = glob.glob(os.path.join(libretroSuperDir, '*.sh'))
	for someScript in buildScripts:
		os.chmod(someScript, 0o775)
	listOfRecipes = set(glob.glob(os.path.join(libretroSuperDir, "recipes/*/cores-*"))) - set(glob.glob(os.path.join(libretroSuperDir, "recipes/*/cores-*.conf")))
	masterRecipeSet = set()
	for someRecipe in listOfRecipes:
		with open(someRecipe) as f:
			for line in f.readlines():
				if line.split(' ')[0] != "\n":
					masterRecipeSet.add(line.split(' ')[0])
	with open(os.path.join(libretroSuperDir, "rules.d/core-rules.sh")) as coreRules:
		for line in coreRules:
			if re.findall(r"register_module core", line):
				result = re.sub('.*"(.*)".*', r"\1", line, flags=re.DOTALL)
				masterRecipeSet.add(result)
	for someDuplicate in stuffToRemove:
		if someDuplicate in masterRecipeSet:
			masterRecipeSet.remove(someDuplicate)
	return sorted(masterRecipeSet, key=str.lower)

def updateTheDatabase(toBuild, buildFor, coreGitVersion):
	queryObject = tinydb.Query()
	lastBuiltCoreInfo = coreArchiveDatabase.search((queryObject.coreName == toBuild) & (queryObject.buildType == buildFor))
	sameVersion = False
	successfulBuild = False
	if len(lastBuiltCoreInfo) > 0:
		if lastBuiltCoreInfo[0]["latestHash"] != coreGitVersion:
			coreArchiveDatabase.update({"latestHash": coreGitVersion}, (queryObject.coreName == toBuild) & (queryObject.buildType == buildFor))
		else:
			sameVersion = True
			successfulBuild = lastBuiltCoreInfo[0]["buildSuccess"]
	else:
		coreArchiveDatabase.insert({"coreName": toBuild, "latestHash": coreGitVersion, "buildSuccess": -1, "buildType": buildFor})
	if (sameVersion and successfulBuild == True):
		return 1
	elif (sameVersion and successfulBuild == False):
		return 2
	else:
		return 3
	
def tryToBuildTheCores(masterRecipeSet):
	for toBuild in masterRecipeSet:
		coreGitVersion = tryToFetch(toBuild)
		alreadyBuilt = updateTheDatabase(toBuild, finalPackage, coreGitVersion)
		if not alreadyBuilt == 1:
			if alreadyBuilt == 2:
				print("You've already tried and failed to build this version of " + toBuild + " for " + finalPackage)
				success = False
			else:
				success = tryToBuild(toBuild, finalPackage)
			if not success:
				for someFallback in listOfFallbacks:
					alreadyBuiltFallback = updateTheDatabase(toBuild, someFallback, coreGitVersion)
					if not alreadyBuiltFallback == 1:
						if alreadyBuiltFallback == 2:
							print("You've already tried and failed to build this version of " + toBuild + " for " + someFallback)
							success = False
						else:
							success = tryToBuild(toBuild, someFallback)
						if success:
							break
					else:
						print("You've already built this version of " + toBuild + " for " + someFallback + ". No need to rebuild...")
						break
		else:
			print("You've already built this version of " + toBuild + " for " + finalPackage + ". No need to rebuild...")

def preppingForFinalBuild():
	print("Okay we're all done building cores... Now we move some files...")
	updateSomeDir(retroarchDir)
	if not os.path.isdir(os.path.join(retroarchDir, "pkg", finalBuildTranslation[finalPackage]["modules"], "modules")):
		os.mkdir(os.path.join(retroarchDir, "pkg", finalBuildTranslation[finalPackage]["modules"], "modules"))
	#Copy archive to the modules for building in reverse
	for someFallback in reversed(listOfFallbacks):
		for someCompiledModule in glob.glob(os.path.join(coreArchiveDir, translateStupidMisnamedDirectories(someFallback), "*." + extension)):
			shutil.copy2(someCompiledModule, os.path.join(retroarchDir, "pkg", finalBuildTranslation[finalPackage]["modules"], "modules"))
	#Copy the final archive over to the modules for building
	for someCompiledModule in glob.glob(os.path.join(coreArchiveDir, translateStupidMisnamedDirectories(finalPackage), "*." + extension)):
		shutil.copy2(someCompiledModule, os.path.join(retroarchDir, "pkg", finalBuildTranslation[finalPackage]["modules"], "modules"))

def finalBuild():
	print("And now, we build RetroArch itself...")
	os.chdir(retroarchDir)
	if manualSigning:
		runCommandWithDebug(["xcprovisioner", "--target", finalBuildTranslation[finalPackage]["targetName"], "--configuration", "Release", "--specifier", profileName, "--identity", developerName, "--team", teamName, "--project", os.path.join(retroarchDir, "pkg", finalBuildTranslation[finalPackage]["projectName"])])
	runCommandWithDebug(["xcodebuild", "-target", finalBuildTranslation[finalPackage]["targetName"], "-configuration", "Release", "-project", os.path.join(retroarchDir, "pkg", finalBuildTranslation[finalPackage]["projectName"])])
	print("And now, we build your IPA...")
	proc = subprocess.Popen(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE)
	proc.wait()
	gitVersion = proc.communicate()[0].replace("\n", "")
	currentDate = datetime.utcnow().strftime("%Y_%m_%d_%I_%M_%p")
	finalBuildDirectory = glob.glob(os.path.join(retroarchDir, "pkg", finalBuildTranslation[finalPackage]["endPlacement"], "build", "Release*/*.app"))[0]
	os.mkdir(os.path.join(outputDir, "Payload"))
	shutil.move(finalBuildDirectory, os.path.join(outputDir, "Payload"))
	filename = os.path.join(outputDir, finalPackage + "-" + gitVersion + "-" + currentDate + ".ipa")
	os.chdir(outputDir)
	runCommandWithDebug(["zip", "-r", filename, "Payload"])
	shutil.rmtree(os.path.join(outputDir, "Payload"))
	print("All finished! Your IPA file is located at " + filename)

cleanup()
tryToBuildTheCores(init())
preppingForFinalBuild()
finalBuild()

@jet082 That’s great !

Can you send me a compiled version of these cores for arm64 as I can’t get them to compile ? Here they are :

  • craft
  • easyrpg
  • mame
  • mesen-s
  • mesen
  • stonesoup

I won’t be sharing my cores since I don’t know what potentially identifying metadata xcode might bake into them.

However, if you do the changes explained in the github issues I linked above, they should compile. If you’re having an issue with them, I am willing to help you get them compiled.

I also cannot get mesen, mesen-s, or easyrpg to compile. I am currently using your easyrpg and the mesen versions I linked above (that are in the buildbot).

You can strip codesign from the dylib files, if they are signed, but no other identifying information is contained inside…

What errors are you getting compiling craft, mame(2010?), and stonesoup?

@jet082 Ok no worries, I got 96 cores to compile for arm64 right now, thanks in part to your wonderful bug-solving…

Here are the cores (soon in the buildbot & ipa version…) :

4do
81
2048
bluemsx
bsnes_accuracy
bsnes_balanced
bsnes_mercury_accuracy
bsnes_mercury_balanced
bsnes_mercury_performance
bsnes_performance
cannonball
cap32
craft
crocods
desmume
dosbox
fbalpha2012_cps1
fbalpha2012_cps2
fbalpha2012_cps3
fbalpha2012
fbalpha2012_neogeo
fbneo
fceumm
ffmpeg
fmsx
freechaf
freeintv
fuse
gambatte
gearboy
gearsystem
genesis_plus_gx
gme
gpsp
gw
handy
hatari
lutro
mame
mame2000
mame2003
mame2003_plus
mednafen_gba
mednafen_lynx
mednafen_ngp
mednafen_pce_fast
mednafen_pcfx
mednafen_psx
mednafen_saturn
mednafen_snes
mednafen_supergrafx
mednafen_vb
mednafen_wswan
melonds
meteor
mgba
mrboom
mu
nestopia
np2kai
nxengine
o2em
pcsx_rearmed
picodrive
pocketcdg
pokemini
prboom
prosystem
puae
px68k
quasi88
quicknes
reminiscence
sameboy
snes9x
snes9x2002
snes9x2005
snes9x2010
squirreljme
stella
stella2014
stonesoup
tgbdual
theodore
tyrquake
uzem
vba_next
vbam
vecx
vice_x64
vice_x128
vice_xplus4
vice_xvic
virtualjaguar
xrick
yabause

Thanks again for your help !

Please note I’ve also updated my post further since your last comment. Most importantly, I got scummvm to work :). As well as some others.

@jet082 Ok, I could compile 3 more, now at 99 !

daphne
nekop2
scummvm

I believe you are still missing atari800. My current core count is 104 (counting test), but I don’t know where other differences are. I’m including the cores I can’t compile, but have old arm64 versions of (easyrpg, mesen, and mesen-s) in that count.

Later tonight, I plan to work on getting Dinothawr and mesen/mesen-s to compile. I BELIEVE that I may be able to do so. After that, I will possibly poke more at mame2010 and bsnes_cplusplus98. Those two seem somewhat close to compiling, maybe. I currently have no idea how to fix easyrpg.

Play is something I’m very interested in getting working, for obvious reasons. However, as of now, even getting it to try to compile is a bit of a strange beast.

I am also interested in getting TIC-80 working, so I will possibly poke at that. I started doing so last night and made a bit of progress. But we will see.

I am also very interested in looking at other cores that 1) Don’t currently compile, but 2) Do compile on arm64 processors like those found on Android. There’s obvious differences and not everything is clean-cut. However, nonetheless, it might be a good way to find more cores that can work on ios-arm64 with minimal editing effort.

On one note - pretty much all of the changes I’m making are minor and basically all well known changes for 64-bit iOS compiling (suppressing inline declaration errors) or current versions of xcode (commenting out depricated/useless libraries, making sure it uses the right C++11 libraries, etc). However, any of them might theoretically break a core. Most/all of them ought to work, but you can never really predict these things.

I am very interested in getting feedback on the cores I’m posting compiling instructions for.

Whether they work or not, mostly.

Hi! Thanks for documenting all of this! I really strongly encourage you to create pull requests when you’re able to fix compiling cores. That way we can get the fixes in so that everyone can build it - any help that anyone can provide would be greatly appreciated.

I was able to get Mesen and Mesen-S to compile, and have open pull requests for those:

The cores you see in buildbot are the ones I built and uploaded. You don’t have to worry about any personal metadata being in the cores - it’s only when you build and codesign RetroArch in Xcode that the code signature will be in the application binary.

I’ve been going through all the cores and making pull requests for fixes as I find them, and am going through all of them again to get them to compile using the tvOS SDK to support tvOS 13.

I’ve gotten play! to compile for libretro, but I can’t actually run any content. To build the core, you need to install cmake on your mac first. Use the buildbot recipe script to build the core using cmake in the libretro-super repo:

CMAKE=/Applications/CMake.app/Contents/bin/cmake VERBOSE=1 SINGLE_CORE=play FORCE=YES EXIT_ON_ERROR=1 ./libretro-buildbot-recipe.sh recipes/apple/cores-ios-arm64-generic

I’ve tried debugging why it can’t load content but it has something to do with opening a file on the core side. I was able to get the standalone iOS app to run ok.

For tvOS, i’m in the process of building all the cores again, and I’ll make a pull request to include a libtretro-build-tvos-arm64.sh script. I’m compiling each core in order, and i’m about halfway done (just finished compiling mame). I’m making pull requests as I support each tvOS core.

Thanks!

2 Likes

Ok, I could compile 3 more, now at 99 !

daphne
nekop2
scummvm

That’s awesome! Please please make a pull request when you have a fix:

  1. Fork the repo to your github account
  2. If you have an existing checkout of the repo:
git remote rename origin upstream
git remote add origin [your forked repo]
git merge upstream/master
  1. Make a branch:
git checkout -b ios-arm64-fixes
  1. Add and commit to your branch:
git add Makefile
git commit -m '(iOS) support arm64'
git push origin ios-arm64-fixes
  1. Follow link in output to create the pull request

The fixes he used were the one I posted above. You can find the issues with the fixes listed in the first post.

As far as making pull requests - the problem is that I do not really know libretro best practices, etc. I am somewhat sloppily editing Makefiles to get things to work. Ideally, I’d like someone to look at my edits and massage them in so they are nice and standardized (as you did with my atari800 and picodrive fixes).

I have also gotten dinothawr to compile. Happy days, I guess :P. The opening post has been updated.

I am currently working a bit on openlara, since that seems quite possible to get compiled.

1 Like

I have also gotten easyrpg to compile. Instructions above. It’s a one line fix.

1 Like

@jet082 Ok, I was able to compile 4 more (now at 103 newly compiled cores, soon in the buildbot…)

atari800
dinothawr
mesen
mesen-s

I am still unable to compile EasyRPG, even with the current fix…

What error do you get? @Weedy_Weed_Smoker

As far as making pull requests - the problem is that I do not really know libretro best practices, etc. I am somewhat sloppily editing Makefiles to get things to work. Ideally, I’d like someone to look at my edits and massage them in so they are nice and standardized (as you did with my atari800 and picodrive fixes).

Hah ok yeah I totally understand - i’ve gotten a little used to seeing how most of the cores are built using platform-specific flags. But your suggested fixes lead into what needs to be fixed so it’s helpful so thanks for that. I can create the PRs for the fixes you mentioned so we can get that in the core repo.

Somehow, after substantial struggle, I have managed to get chailove to compile as well. Instructions above.

I’ve also got bsnes_cplusplus98 compiled.

1 Like

Mame2010 has now been compiled. Instructions in the op.

This marks, finally, the completion of compiling every iOS9 core on ARM64. Plus a few extra.

1 core(s) successfully processed:
	parallel_n64

:eyes:

1 Like

Does it work? Give loading N64 roms?