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
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 |
- Install buildroot/Batocera Lite SDK Toolchain
- Use the installed toolchain to compile RetroArch
- Copy the new built binary to RG35XX(PLUSH)
- Run and test
Let's clone RetroArch
cd ~
git clone https://github.com/libretro/RetroArch.git
1 Install 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
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
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 XHOST=arm-buildroot-linux-gnueabihf
export XTOOL=$HOME/toolchain
export PATH="${PATH}:$XTOOL/bin"
export SYSROOT=$XTOOL/$XHOST/sysroot
export DESTDIR=$SYSROOT
export CC=$XTOOL/bin/$XHOST-gcc
export CXX=$XTOOL/bin/$XHOST-g++
export AR=$XTOOL/bin/$XHOST-ar
export LD=$XTOOL/bin/$XHOST-ld
export STRIP=$XTOOL/bin/$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/$ARMABI
export PKG_CONFIG_PATH=$XTOOL/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/pkgconfig
export PKG_CONF_PATH=$XTOOL/bin/pkgconf
export CROSS_COMPILE=$XTOOL/bin/$XHOST-
export SDL_CONFIG=$TOOLCHAIN_DIR/sysroot/usr/bin/sdl-config
export FREETYPE_CONFIG=$TOOLCHAIN_DIR/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
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 --disable-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
Assume that we are in RetroArch
's directory, all we need now is
make
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
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
On your device
muOS MAIN MENU -> Configuration -> WI-FI NETWORK
Then connect there, you can verify it by running ping <ip-showed-up>
Assume that the IP of your RG35XX(PLUSH) is 192.168.1.217, run the following to ssh into it
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 [email protected]
[email protected]'s password:
[~]#
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 connectivty, 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 cp .retroarch/retroarch.cfg.bak
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
cp retroarch [email protected]:/mnt/mmc/MUOS/retroarch
The output looks something like
$ scp retroarch [email protected]:/mnt/mmc/MUOS/retroarch
[email protected]'s password:
retroarch 100% 16MB 2.9MB/s 00:05
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
If you made it this far then congratulations :) you just learned how to cross-compile RetroArch for muOS
- Instead of using the SDK, use buildroot to compile
- Insetad of using the real devise to test, use qemu