Citra macOS M1 arm64 build

Oh haha that’s probably the only menu option I didn’t check :slight_smile:
Ah well, I found the option in the config file but good to know anways.
Also thank you for your hard work!

Looking at the apple crash log, it seems to be an assert that’s crashing (on purpose, something went wrong somewhere)
The assert message should show up on a citra log file (instructions here), and if my reasoning is correct the assert message is probably "Failed to allocate executable memory". Please confirm this if you can.

Looking at the code and searching around I found this Apple Developer Documentation which seems to describe what needs to be done, but I don’t know how difficult it’d be to go and implement.

The last entry in the log after the crash with CPU Jit enabled is:

[ 9.231722] Frontend <Info> citra_qt/main.cpp:BootGame:1022: Citra starting...

It seems Citra crashes faster than it can write the log file…

If you need the complete logfile let me know, then I’ll paste it somewhere

Ok, I did some work based on apple’s document on my branch here, and you can see the changes to dynarmic here. I have opened a PR and I’m waiting for code review from the dynarmic gods (merry).

If you want to test it out, you can do so by pulling the changes via the following commands:
git pull https://github.com/vitor-k/citra.git update-dynarmic
git submodule update
and then building normally.

Two suggestions that SachinV made on discord about getting more information from the assert that’s being triggered:

You can probably get the assert message if you run citra from the terminal (dynarmic prints stuff to stdout)

Alt strategy, you could ask them to compile and run just dynarmic tests

For the second one, should be somewhat straightforward:
git clone https://github.com/citra-emu/dynarmic.git
cd dynarmic
git checkout citra_merged
mkdir build
cd build
cmake … -DCMAKE_OSX_ARCHITECTURES="arm64"
make -j4
and then run dynarmic_tests via command line
you may also need to run brew install boost if you don’t have a system “boost” library already.

Thank you, I’ll try to build your patch a little later and let you know the results, if the crash still happens I’ll try to get the assert message as proposed (also I can post it to discord too if that’s easier for you)

Okay it seem something broke the M1 build on the current branch, as I did a git pull before merging your patch and now I’m unable to build it (it is without your new code…). I’m far from a git pro so I need to figure out how to revert back to the last working merge… (if you have a hint on how to do it I’d appreciate it but obviously this has nothing to to Citra itself so if not - no worries)

I get some weird errors now:

In file included from /Users/xxx/source/citra/externals/dynarmic/src/backend/A64/exception_handler_posix.cpp:15:
/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/usr/include/ucontext.h:51:2: error: The deprecated ucontext routines require _XOPEN_SOURCE to be defined
#error The deprecated ucontext routines require _XOPEN_SOURCE to be defined
^
[ 21%] Building CXX object src/audio_core/CMakeFiles/audio_core.dir/hle/decoder.cpp.o
[ 63%] Built target crypto
[ 63%] Building CXX object src/audio_core/CMakeFiles/audio_core.dir/hle/filter.cpp.o
/Users/xxx/source/citra/externals/dynarmic/src/backend/A64/exception_handler_posix.cpp:102:80: error: member reference type 'struct __darwin_mcontext64 ’ is a pointer; did you mean to use ‘->’?
auto PC = reinterpret_cast(((ucontext_t
)raw_context)->uc_mcontext.pc);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^

/Users/xxx/source/citra/externals/dynarmic/src/backend/A64/exception_handler_posix.cpp:102:81: error: no member named ‘pc’ in ‘__darwin_mcontext64’
auto PC = reinterpret_cast(((ucontext_t*)raw_context)->uc_mcontext.pc);

I’ll try some more things and come back later with some results (hopefully)

Edit: I have no idea what I did wrong but now it works -still without patches but disregard this, the latest git version is at least compiling now

Edit2: Actually it’s not building after all - I cloned the current master in a new directory and started fresh and got the error after all. There must have been something that broke the M1 build. I’ll try now to add the patch on my own to the last working commit…

Okay, instead of fumbling around with git I just restored my TimeMachine backup from yesterday - crude but working :slight_smile:
Anyway, this is the output on the command line of the crash (without your new code vitor-k):

qt.qpa.fonts: Populating font family aliases took 220 ms. Replace uses of missing font family “Monospace” with one that exists to avoid this cost.
dynarmic assertion failed: ptr != nullptr
Message: Failed to allocate executable memorylibc++abi: terminating
zsh: abort ./citra-qt

I’ll now try to get it compiled with your patch let’s see how it goes

Edit (can’t make new reply):

When I try to follow the second suggestion I get the following build errors:

Consolidate compiler generated dependencies of target dynarmic
[ 3%] Building CXX object src/CMakeFiles/dynarmic.dir/backend/A64/a32_emit_a64.cpp.o
/Users/xxx/source/dynarmic/src/backend/A64/a32_emit_a64.cpp:295:55: error: lambda capture ‘fast_dispatch_entry_reg’ is not required to be captured for this use [-Werror,-Wunused-lambda-capture]
const auto calculate_location_descriptor = [this, fast_dispatch_entry_reg, location_descriptor_reg] {
^~~~~~~~~~~~~~~~~~~~~
/Users/xxx/source/dynarmic/src/backend/A64/a32_emit_a64.cpp:295:80: error: lambda capture ‘location_descriptor_reg’ is not required to be captured for this use [-Werror,-Wunused-lambda-capture]
const auto calculate_location_descriptor = [this, fast_dispatch_entry_reg, location_descriptor_reg] {
^~~~~~~~~~~~~~~~~~~~~
2 errors generated.
make[2]: *** [src/CMakeFiles/dynarmic.dir/backend/A64/a32_emit_a64.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs…
make[1]: *** [src/CMakeFiles/dynarmic.dir/all] Error 2
make: *** [all] Error 2

Edit 2:
So I cloned your branch vitor-k (instead of pulling it into the working directory and keep it clean) but otherwise followed your suggestions.
When I then try to build it I get lots of warnings and finally a build error. It’s too long to paste here I put it here on pastebin: [ 70%] Building CXX object src/web_service/CMakeFiles/web_service.dir/verify_log - Pastebin.com

There was a mistake when merging a commit to master that undid the updates necessary to compile on M1, so compiling from master wasn’t working for a while. but should be back to working now…

The assert message confirms that it’s a problem allocating memory with mmap. The patch should fix it, but I’ll take a look at it again anyway.

On that last comment were you trying to compile dynarmic directly? From the errors seems like it errored out due to -Werror treating warnings as errors. Good to know that dynarmic can’t be compiled on its own.
To disable these you can pass -DDYNARMIC_WARNINGS_AS_ERRORS=OFF on the cmake step.

Yes indeed I was trying to compile dynarmic on its own.
Can’t test it right now as I’m away from the Mac but will try later if master can be compiled again and if I’m able to compile your branch with the dynarmic patches.

Edit: Ah just saw on github that you didn’t update your branch with the dynarmic patches yet (misunderstood your comment) so I guess no need to try to compile this again (unless I miss something…). If you have something else to test though please let me know and I’ll see what I can do.

So didn’t have time anymore yesterday to try, but now did this and was able to compile it and run it with CPU JIT enabled (built with your changes against current master) - so indeed it seems to work now.
Only quickly started a random game so there may be crashes or something later, but at least so far it’s working - great work!
It still has the same grey screen before resizing error as the version with Rosetta but otherwise it seems to run fine - though speed is not great but that may very well be because it’s probably not very optimized…

Edit: Okay it doesn’t crash immediately but some games still crash the emulator (I’ve Tried Zelda Link Between Worlds that crashes, Ace Attorney Trilogy seems fine). I haven’t set up shared fonts and a nand though on the Mac so before I submit a crash report I’ll try that first (just to rule out that that’s the culprit)
Edit 2: The crash seems to related to the Hardware Renderer, when I disable it these games start fine (they’re very slow though obviously), if you require a crash report please let me know, but not sure if you also work on the graphics part of Citra. I think these are the same crashes as with Rosetta though (so likely to do with Apples not very great OpenGL implementation…)
Edit 3: Tested a few more games, the games that do work, even 3D games like Ocarina of Time 3D (I don’t have that many though… haven’t dumped all I have from my 3DS will do that when I have time) run close to or at 100% speed (though some with graphical glitches) even with 3x internal resolution with hardware renderer, hardware shader, accurate multiplicaton and shader JIT enabled

An update on this:
The code modifications on dynarmic were approved and merged (after a few changes), so I’ve opened a PR to update the dynarmic version used on citra. Update dynarmic by vitor-k · Pull Request #5784 · citra-emu/citra · GitHub

You may test again if you want to, but it should be functionally the same.
The only major change is that it might be necessary to pass -DDYNARMIC_ENABLE_NO_EXECUTE_SUPPORT=ON when running cmake. It’s enabled by default, but you may need to do it if you build citra before and the value is cached.

Whenever the PR is merged, I’ll see about adding a note on the wiki about building for the M1.
Even so, it’ll still not be “officially supported” (still a long way for that), but we may start to recommend users to build from source if they can.

Thank you I’ll try this later just to check if it’s building (I don’t see much reason why it shouldn’t though).

And yeah I agree that it doesn’t make much sense to officially supoort ARM-Macs at this time, the OpenGL troubles (thank you Apple…) and crashes are just too many (and probably not trivial to fix unless a major rewrite is done or somebody is working on a Vulkan/MoltenVK backend ) but at least it’s building so that’s a big step in the right direction.

Edit: unsurprisingly it built fine and works as before, so unless this breaks something elsewhere I (not a developer :)) would see no reason to not merge the patch

I just noticed your patch was merged a few hours ago.
I just compiled the git master successfully and can run Citra it with CPU jit enabled, thanks again for your hard work vitor-k!

so what will be the final instructions to make this work, are the initial ones in the post working properly? want to give it a shot on my M1

The instructions outlined on this post should work and the wiki page has been updated with Apple Silicon specific instructions as well.
One thing to note is that the instructions on the linked post were based on the OP’s instructions, which are from before official apple silicon support from homebrew, so the instructions should be simpler now.
I’ll copy/paste the instructions here with some modifications.

Install Homebrew on arm64 macOS native

Further details about installation here.

Now install compiling packages

brew install pkgconfig
brew install sdl2
brew install qt5
brew install ffmpeg
brew install cmake

Create clone of Citra in git

git clone --recursive https://github.com/citra-emu/citra
cd citra

Run this line or add it to ~/.zshrc

export Qt5_DIR=$(brew --prefix)/opt/qt5

Create build directory

mkdir build
cd build

Run cmake

cmake .. -DCMAKE_OSX_ARCHITECTURES="arm64" -DCMAKE_BUILD_TYPE=Release -DENABLE_FFMPEG_AUDIO_DECODER=ON

The DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT flag should be set automatically to ON when building on apple silicon as it’s necessary to run the JIT. If for some reason it isn’t being set automatically (like cross compilation from an intel machine) you need to add -DDYNARMIC_ENABLE_NO_EXECUTE_SUPPORT=ON.
There are other flags you may want to set when building too, you can see which ones our releases normally use here.

Now execute the make command.

make -j4

2 Likes

Please do “unofficial build” release/file hoste(gdrive/mega) for arm I can’t compile by my ownn :frowning: (some % have a deference errors even when force inore flags)

4 Likes

How do I uninstall. I went through all this trouble thinking it was for Nintendo Switch lol

I also realized how gangsta anyone who has coded all this truly is - it was like matrix level stuff - all I did was follow the path.

Seriously thought, what Brew command do I initiate to uninstall the Citra-QT application? Is it as simple as tossing the whole folder in the trash?

1 Like

Hi there,

I know this is an old topic but i just can’t get the build to work. I followed the instructions and everything works perfectly until I go to make -j4, and then I get an Error 2 at the end and it won’t build fully to be opened. Any help anyone could send my way would be greatly appreciated. I saw that this also happened up above but I didn’t totally understand the answer/solution. Thanks so much.

Hello, i was just wandering if this build works on most games like pokemon now because when I installed your build ( Which was long ago ) on Andrew Tsai’s tutorial, it only worked for one game, Majora’s mask but has the crashing issue been fixed with other games like pokemon yet?