Approvals: 0/1
Table of Contents
How to compile RetroArch for muOS
Overview
This is a “guide” for people who want to compile RetroArch as complete beginners to embedded linux. I hope it would help the next person when they want to cross-compile RetroArch for muOS
Terminology
Name | Description |
---|---|
cross-compile | Compile binary to target a different architecture/operating system, for example compiling linux binaries on windows is also cross compile, in my case I'm compiling an ARM binary in WSL2(Linux) |
toolchain | All sorts of binaries libraries you need to compile the project |
buildroot/Batocera Lite SDK Toolchain | Exported toolchain instead of image to cross-compile |
buildroot | A tool which can create an image for you to cross-compile, I didn't use it this time |
General Idea
- Use the installed toolchain to compile RetroArch
- Copy the new built binary to RG35XX(PLUSH)
- Run and test
Steps
0 Preparation
Let's clone RetroArch
cd ~ git clone https://github.com/libretro/RetroArch.git
1 Install buildroot/Batocera Lite SDK Toolchain
buildroot/Batocera Lite SDK Toolchain
# this would download arm-buildroot-linux-gnueabihf_sdk-buildroot.tar.gz to current directory wget https://github.com/rg35xx-cfw/rg35xx-cfw.github.io/releases/download/rg35xx_plus_h_sdk_20240207/arm-buildroot-linux-gnueabihf_sdk-buildroot.tar.gz # unzip and rename folder tar zxvf arm-buildroot-linux-gnueabihf_sdk-buildroot.tar.gz mv arm-buildroot-linux-gnueabihf_sdk-buildroot toolchain # run relocate-sdk.sh cd toolchain ./relocate-sdk.sh
2 Use the installed toolchain to compile RetroArch
Now we have the toolchain on our machine, but to compile RetroArch you need to let it know that you are using this toolchain instead of the one that your system has by default. To do that we would need to setup some environment variables
The following is from Adixal with some modifications
2.1 Config environment variables for toolchain
Create a file with the following contents and call it cc-plus.sh
(the name doesn't matter I'm just using the same name that Adixal uses)
#!/bin/bash export DEVICE=RG35XXPLUS export XTOOL=$HOME/x-tools export XHOST=arm-buildroot-linux-gnueabihf export XBIN=$XTOOL/$XHOST/bin export PATH="${PATH}:$XBIN" export SYSROOT=$XTOOL/$XHOST/$XHOST/sysroot export DESTDIR=$SYSROOT export CC=$XBIN/$XHOST-gcc export CXX=$XBIN/$XHOST-g++ export AR=$XBIN/$XHOST-ar export LD=$XBIN/$XHOST-ld export STRIP=$XBIN/$XHOST-strip export LD_LIBRARY_PATH="$SYSROOT/usr/lib" export CPP_FLAGS="--sysroot=$SYSROOT -I$SYSROOT/usr/include" export LD_FLAGS="-L$SYSROOT -L$SYSROOT/lib -L$SYSROOT/usr/lib -L$SYSROOT/usr/local/lib -L$SYSROOT/usr/include/sound" export CPPFLAGS=$CPP_FLAGS export LDFLAGS=$LD_FLAGS export CFLAGS="-marm -mfpu=neon -mfloat-abi=hard $CPP_FLAGS" export CCFLAGS=$CPP_FLAGS export CXXFLAGS=$CPP_FLAGS export INC_DIR=$CPP_FLAGS export LIB_DIR=$LD_FLAGS export ARMABI=$XHOST export TOOLCHAIN_DIR=$XTOOL/$XHOST export PKG_CONFIG_PATH=$SYSROOT/usr/lib/pkgconfig export PKG_CONF_PATH=$XBIN/pkgconf export CROSS_COMPILE=$XBIN/$XHOST- export SDL_CONFIG=$SYSROOT/usr/bin/sdl-config export FREETYPE_CONFIG=$SYSROOT/usr/bin/freetype-config
Run the following to have the environment variables in your shell
. ./cc-plus.sh
At this point you should have all the environment variables in your current shell, you can check with env
2.2 Run ./configure in RetroArch aka Automake
We cloned RetroArch in Step 0, let's go into that directory and run ./configure
with a lot of options
cd RetroArch ./configure --disable-nvda --disable-materialui --disable-systemd --disable-x11 --disable-xrandr --disable-xinerama --disable-wayland --enable-sunxi --disable-cdrom --enable-libshake --disable-crtswitchres --enable-hid --enable-screenshots --disable-vulkan --disable-qt --disable-online_updater --disable-update_cores --disable-update_core_info --disable-update_assets --enable-neon --disable-pulse --disable-oss --enable-alsa --enable-mali_fbdev --enable-command --enable-threads --enable-bluetooth --disable-parport --enable-opengles
Because we are passing –enable-mali_fbdev
we would need to also pass in –enable-opengles
per this README
To enable mali_fbdev you must configure RetroArch with –enable-opengles and –enable-mali_fbdev.
Important Note
the previous ./configure
would generate config.mk
in ~/RetroArch
, for some reason the config.mk
I generated had -I/usr/include
and -L/usr/lib
flags
# INCORRECT ALSA_CFLAGS = -I/usr/include ALSA_LIBS = -L/usr/lib -lasound
When I compile with this the toolchain is complaining
$ make CC input/drivers/linuxraw_input.c arm-buildroot-linux-gnueabihf-gcc: ERROR: unsafe header/library path used in cross-compilation: '-I/usr/include' make: *** [Makefile:209: obj-unix/release/input/drivers/linuxraw_input.o] Error 1
I don't know how to let ./configure
generate the correct flags but I ended up replacing -I/usr/include
with -I/home/shengy/toolchain/arm-buildroot-linux-gnueabihf/sysroot/usr/include
. You would probably change to your username
If you want to do it by sed
sed -i s#/usr/include#"$SYSROOT"/usr/include#g config.mk sed -i s#/usr/lib#"$SYSROOT"/usr/lib#g config.mk
2.3 Compile RetroArch
Assume that we are in RetroArch
's directory, all we need now is
make -j`nproc`
After a while it would complete and you would have retroarch
in RetroArch/
, to confirm it was a cross compile you can do
readelf -h retroarch
and it should show something like the following (note that Machine is ARM)
ELF Header: Magic: 7f 45 4c 46 01 01 01 03 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - GNU ABI Version: 0 Type: DYN (Position-Independent Executable file) Machine: ARM Version: 0x1 Entry point address: 0x362f0 Start of program headers: 52 (bytes into file) Start of section headers: 16538188 (bytes into file) Flags: 0x5000400, Version5 EABI, hard-float ABI Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 9 Size of section headers: 40 (bytes) Number of section headers: 31 Section header string table index: 30
3 Copy the new built binary to RG35XX(PLUSH)
The idea is to replace the binary that came with muOS with the one we compiled and run it, you could plug the SD card to your computer or access it via ssh/scp, I would be access it via ssh/scp
3.1 Connect to WIFI
On your device
muOS MAIN MENU → Configuration → WI-FI NETWORK
Then connect there, you can verify it by running ping <ip-showed-up>
3.2 ssh into your RG35XX(PLUSH)
Assume that the IP of your RG35XX(PLUSH) is 192.168.1.217, run the following to ssh into it
ssh root@192.168.1.217
You would be prompted to enter a password, the password is root
.
Note that when you type the password nothing is going to show, just type and hit enter when done
If you see the shell prompt similar to the following then you are in
$ ssh root@192.168.1.217 root@192.168.1.217's password: [~]#
3.3 Backup the current retroarch just in case
It's always a good idea to backup the current binary just in case yours are not working, when doing my testing I noticed if my retroarch binary isn't functioning I lose WI-FI connectivity, so I had to plug the SD card to my computer to restore from backup to regain the ability to use WI-FI
Assuming we are in ssh
cd /mnt/mmc/MUOS/ cp retroarch retroarch.bak
You can also copy the config if you want to
cd /mnt/mmc/MUOS/ cp .retroarch/retroarch.cfg .retroarch/retroarch.cfg.bak
3.4 Upload current binary
We already have the backup so now we can replace retroarch
in /mnt/mmc/MUOS
. Again this could be done by pluging in the SD card and copy/paste from your file explorer. But I am doing it via scp
. The following example assumes that your RG35XX(PLUSH)'s IP is 192.168.1.217
On your machine's shell, cd into RetroArch (where the binary is)
cd ~/RetroArch scp retroarch root@192.168.1.217:/mnt/mmc/MUOS/retroarch
The output looks something like
$ scp retroarch root@192.168.1.217:/mnt/mmc/MUOS/retroarch root@192.168.1.217's password: retroarch 100% 16MB 2.9MB/s 00:05
4 Run and test
On your device
muOS MAIN MENU → RetroArch
Here if your binary crashes you would see a flash screen, and at that point you have to figure out what went wrong during compile. If your binary crashes you can try to run it in ssh
and see if there are any error messages.
I got into another situation where RetroArch started but all the button configs are messed up so I can't exit, instead of restarting the handheld, you could run the following to kill it
[~]# pkill retroarch
The End
If you made it this far then congratulations :) you just learned how to cross-compile RetroArch for muOS
TODOs
- Instead of using the SDK, use buildroot to compile - Insetad of using the real device to test, use qemu