Introduction

This page explains how the game “Dune Dynasty II” can be ran on an embedded linux OS. The OS is created using buildroot.
All required configurations and compile-commands are documented on this page.

The below image shows the game (and embedded OS) running.

Buildroot OS running Dune Dynasty II

Previous work

This post is based on another post in which a basic embedded OS is created. However, the toolchain used uClibc as C library, which will not work here. This is why a new toolchain and Buildroot OS will be created. It is assumed that the previous post was followed and that all the tools and source code are already downloaded.

The previous post showed how to make a basic OS (using crosstool-NG, U-boot and Buildroot), which did very little of value. It just started a shell and that was it.
Not very interesting.

In this post, the goals are as follows:

  • Make a buildroot OS containing Allegro5 and Dune Dynasty
  • Compile the kernel without using Buildroot
  • Make the OS start as fast as possible

Creating a new toolchain

For this OS, a new toolchain using glibc will be used. This is because uClibc creates lots of segfaults (probably while resolving libraries).

Creating a new toolchain configuration

First, a new toolchain configuration is created inside the crosstool-NG folder:

./ct-ng distclean
./ct-ng aarch64-rpi4-linux-gnu

Making a few changes to the toolchain configuration

Then, the toolchain options are changed using:

./ct-ng menuconfig

The following options were changed:

  • Under C compiler, the option Version of gcc is set to the second to latest option (10.3.0 at time of writing)
  • Under Operating System, the option Version of linux is set to 5.10.79 (this is the version of linux that will be compiled later in this post)
  • Under Debug facilities, the option gdb is disabled.

Building the new toolchain

If ~/x-tools/ already contains a toolchain with the same name; move, rename or delete that toolchain. If it is not dealt with, the wrong linux headers might still be present and the target OS will fail to run. crosstool-NG will not build a shiny new toolchain automatically.

To then build the new toolchain, execute the build command:

./ct-ng build -j`nproc`

Creating a new Buildroot OS

The previous post describes how to make a Buildroot OS using uClibc. Because this does not apply here anymore, a completely new Buildroot OS will be created.

Creating a new configuration

Within Buildroot, using make menuconfig, the following options are changed to create a new OS:

  • Under Build options, the option Enable compiler cache is enabled
  • Under Build options, the option RELR0 protection is set to Partial
  • Under Build options, the option Stack Smashing Protection is set to None
  • Under Bootloaders, all the options are disabled (the bootloader will be compiled manually)
  • Under Kernel, the option Linux Kernel is disabled (the kernel will be compiled manually)
  • Under Filesystem images, the option ext2/3/4 root filesystem is disabled
  • Under Filesystem images, the option tar the root filesystem is enabled, along with the Compression method set to gzip
  • Under Toolchain, the option Toolchain type is set to External toolchain (this post uses a toolchain built by crosstool-NG)
  • Under Toolchain, the option Toolchain is set to Custom toolchain
  • Under Toolchain, the option Toolchain origin is set to Pre-installed toolchain
  • Under Toolchain, the option Toolchain path is set to /home/<YOUR_USERNAME_GOES_HERE>/x-tools/aarch64-rpi4-linux-gnu (the path has to be absolute and may not contain ~/ or /home/$USER/!).
  • Under Toolchain, the option Toolchain prefix is set to aarch64-rpi4-linux-gnu
  • Under Toolchain, the option External toolchain C library is set to glibc/eglibc
  • Under Toolchain, the option External toolchain gcc version is set to 10.x (matching the version from the toolchain)
  • Under Toolchain, the option External toolchain kernel headers series is set to 5.10.x (matching the version from the toolchain)
  • Under Toolchain, the option Toolchain has locale support? is enabled
  • Under Toolchain, the option Toolchain has threads support? is enabled, along with the two extra options for threads support
  • Under Toolchain, the option Toolchain has SSP support? is enabled
  • Under Toolchain, the option Toolchain has RPC support is disabled
  • Under Toolchain, the option Toolchain has C++ support? is enabled
  • Under System configuration, the option System hostname is set to gaming
  • Under System configuration, the option System banner is set to Welcome to gaming!
  • Under System configuration, the option Root password is set to root (the root login will be bypassed later, so this value does not matter too much)
  • Under System configuration, the option /dev management is set to Dynamic using devtmpfs + mdev (to load drivers automatically when the target device boots)
  • Under System configuration, the option Enable Native Language Support (NLS) is enabled

The following additional options are changed to install all required dependencies for X.org and Allegro5:

  • Under Target packages -> Hardware handling -> Firmware, the option rpi 4 (default) is disabled (all the extra firmware is not needed)
  • Under Target packages -> Hardware handling -> Firmware, the option rpi 4 (cut-down) is enabled
  • Under Target packages -> Graphic libraries and applications (graphic/text), the option ratpoison is enabled (Dune Dynasty refuses to run without a WM and ratpoison places windows in the middle of the screen by default)
  • Under Target packages -> Graphic libraries and applications (graphic/text), the option X.org X Window System is enabled, along with the following options:
    • X11R7 Servers -> xorg-server
    • X11R7 Servers -> Xvfb server
    • X11R7 Applications -> xinit
    • X11R7 Applications -> xinput
    • X11R7 Applications -> xrandr
    • X11R7 Drivers -> xf86-input-keyboard
    • X11R7 Drivers -> xf86-input-mouse
    • X11R7 Drivers -> xf86-video-fbdev
    • X11R7 Drivers -> xf86-video-fbturbo
  • Under Target packages -> Graphic libraries and applications (graphic/text), the option mesa3d is enabled, along with the following options:
    • Gallium v3d driver
    • Gallium vc4 driver
    • DRI nouveau driver (Enable DRI support by enabling at least one driver, or Dune Dynasty will give a black screen with the following error log: bo.1: permission denied)
    • OSMesa (Gallium) library
    • OpenGL GLX
    • OpenGL EGL
    • OpenGL ES
  • Under Target packages -> Graphic libraries and applications (graphic/text), the option sdl2 is enabled, along with the following extra options:
    • X11 video driver
    • KMS/DRM video driver
    • OpenGL (GLX)
    • OpenGL ES
    • sdl2_gfx
    • sdl2_ttf
    • sdl2_image
    • sdl2_mixer
  • Under Target packages -> Graphic libraries and applications (graphic/text), the option xterm is enabled (for debugging)
  • Under Target packages -> Audio and video applications, the option fluidsynth is enabled, along with the following extra options:
    • alsa
    • jack2
    • sdl2
  • Under Target packages -> Libraries -> Graphics, the option libglew is enabled
  • Under Target packages -> Libraries -> Graphics, the option libglfw is enabled
  • Under Target packages -> Libraries -> Graphics, the option libglu is enabled
  • Under Target packages -> Libraries -> Graphics, the option libgtk3 is enabled, along with the option X11 GDK backend (the rest is disabled)
  • Under Target packages -> Libraries -> Filesystem, the option physfs is enabled
  • Under Target packages -> Libraries -> Audio/Sound, the option opusfile is enabled
  • Under Target packages -> Libraries -> Audio/Sound, the option libmad is enabled
  • Under Target packages -> Libraries -> Audio/Sound, the option alsa-lib is enabled, as well as all the extra options it provides
  • Under Target packages -> Libraries -> Multimedia, the option libtheora is enabled

The target OS should now have all required dependencies enabled.

Automatic post-build system changes

There are a few changes made to the system after it’s built. These changes are as follows:

  • Make sure mdev loads device firmware
  • Bypass the login prompt
  • Make sure X.org starts correctly when xinit is executed inside the target OS
  • Make sure Dune Dynasty is started when the WM starts
  • Disable automatic network setup

To make sure these changes are always present in the target OS, the following will be appended to /path/to/buildroot-<VERSION_GOES_HERE>/board/raspberrypi/post-build.sh:

# Make sure device firmware is being loaded during boot
cp package/busybox/S10mdev ${TARGET_DIR}/etc/init.d/S10mdev
chmod 755 ${TARGET_DIR}/etc/init.d/S10mdev
chmod +x ${TARGET_DIR}/etc/init.d/S10mdev
cp package/busybox/mdev.conf ${TARGET_DIR}/etc/mdev.conf

# Skip login by changing /etc/inittab
sed -i s'|console::respawn:/sbin/getty -L  console 0 vt100 # GENERIC_SERIAL|# login bypass|g' ${TARGET_DIR}/etc/inittab
sed -i 's|tty1::respawn:/sbin/getty -L  tty1 0 vt100 # HDMI console|::respawn:-/bin/sh -c "xinit"|g' ${TARGET_DIR}/etc/inittab

# Make sure X.org works
sed -i 's| Driver|#Driver|g' ${TARGET_DIR}/etc/X11/xorg.conf

# Configure ratpoison WM
echo "startup_message off" > ${TARGET_DIR}/.ratpoisonrc
echo "exec /usr/local/bin/dunedynasty" >> ${TARGET_DIR}/.ratpoisonrc

# Configure xinit
echo 'export LD_LIBRARY_PATH="/lib:/usr/lib:/usr/local/lib"' > ${TARGET_DIR}/.xinitrc
echo "ratpoison" >> ${TARGET_DIR}/.xinitrc

# Delete X.org and networking init files
rm ${TARGET_DIR}/etc/init.d/S40xorg
rm ${TARGET_DIR}/etc/init.d/S40network

Automatically build and install Allegro5 and Dune Dynasty to target OS

The post-build.sh file will also be used to automatically install Allegro5 and Dune Dynasty to the target OS.

There are two directories within Buildroot that are required when building and installing Allegro5 and Dune Dynasty:

  • target: buildroot-<VERSION_GOES_HERE>/output/target (post-build.sh refers to this as ${TARGET_DIR})
  • sysroot: buildroot-<VERSION_GOES_HERE>/output/host/aarch64-buildroot-linux-gnu/sysroot (or, ${TARGET_DIR}/../host/aarch64-buildroot-linux-gnu/sysroot)

Compiling can only be done against the sysroot directory, while the target OS is stored in the target directory. For this reason, Allegro5 must be installed to both directories to compile and run Dune Dynasty correctly.

Creating a toolchain for both Allegro5 and Dune Dynasty

A file called Toolchain-raspberrypi4_64.cmake is created inside the /path/to/buildroot-<VERSION_GOES_HERE>/board/raspberrypi, with the following contents:

#############
# Set target OS
#############

set(CMAKE_SYSTEM_NAME Linux)

######################################################
# Force CMake to use the toolchain built by crosstool-NG
# (both 64 bit and 32 bit cross-compiling toolchains can
# be used here)
######################################################

set(CMAKE_TOOLCHAIN_FILE /home/<YOUR_USERNAME_GOES_HERE>/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu)
set(CMAKE_C_COMPILER ${CMAKE_TOOLCHAIN_FILE}-gcc)
set(CMAKE_CXX_COMPILER ${CMAKE_TOOLCHAIN_FILE}-g++)
set(CMAKE_LINKER ${CMAKE_TOOLCHAIN_FILE}-ld)

set(MAKE_C_LINK_EXECUTABLE ${CMAKE_LINKER})
set(MAKE_CXX_LINK_EXECUTABLE ${CMAKE_LINKER})

#########################################################
# Tell CMake to do all compiling against the target sysroot
#########################################################

set(CMAKE_SYSROOT /path/to/buildroot-<VERSION_GOES_HERE>/output/host/aarch64-buildroot-linux-gnu/sysroot)
set(CMAKE_SYSROOT_COMPILE ${CMAKE_SYSROOT}/)
set(CMAKE_SYSROOT_LINK ${CMAKE_SYSROOT}/)
set(CMAKE_SYSTEM_PREFIX_PATH ${CMAKE_SYSROOT}/)
set(CMAKE_INSTALL_PREFIX ${CMAKE_SYSROOT})

#######################################################
# Make sure CMake does not link against host OS libraries
#######################################################

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FINE_ROOT_PATH_MODE_PACKAGE ONLY)

###############################################
# Make sure Allegro5 is found (using pkg-config).
# Only Dune Dynasty needs this. When building
# Allegro5, this part is ignored by CMake.
###############################################

set(ENV{PKG_CONFIG_DIR} "")
set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig:${CMAKE_SYSROOT}/usr/local/lib/pkgconfig/)
set(ENV{PKG_CONFIG_PATH} ${PKG_CONFIG_LIBDIR})
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})

This toolchain file is used by Allegro5 and Dune Dynasty to cross-compile and link to the target Buildroot OS.

Automate the installation of Allegro5 and Dune Dynasty

To make sure Allegro5 and Dune Dynasty are added to the target OS after Buildroot is done creating it, the following is appended to /path/to/buildroot-<VERSION_GOES_HERE>/board/raspberrypi/post-build.sh:

# Add Allegro5 and Dune Dynasty to the target rootfs

# Create a temporary download directory
rm -rf tmp
mkdir tmp
cd tmp

# Install Allegro5 to target OS and development sysroot
wget https://github.com/liballeg/allegro5/releases/download/5.2.7.0/allegro-5.2.7.0.tar.gz
tar -xvf allegro-5.2.7.0.tar.gz
rm -rf allegro-5.2.7.0.tar.gz
cp ../board/raspberrypi/Toolchain-raspberrypi4_64.cmake allegro-5.2.7.0/cmake/
cd allegro-5.2.7.0/
mkdir build
cd build
rm -rf CMakeFiles CMakeCache.txt addons cmake_install.cmake demos docs examples include lib Makefile tests
cmake -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-raspberrypi4_64.cmake -DSHARED=on -DCMAKE_LINKER_FLAGS="-static-libgcc -static-libstdc++" ..
make -j`nproc`
DESTDIR=${TARGET_DIR}/../host/aarch64-buildroot-linux-gnu/sysroot make install # install to target sysroot to compile dune dynasty against
DESTDIR=${TARGET_DIR} make install # install to target system

cd ../../

# Install Dune Dynasty to target OS
rm -rf dunedynasty-1.5.7/
wget https://versaweb.dl.sourceforge.net/project/dunedynasty/dunedynasty-1.5/dunedynasty-1.5.7.tar.gz
tar -xvf dunedynasty-1.5.7.tar.gz
rm -rf dunedynasty-1.5.7.tar.gz
cp ../board/raspberrypi/Toolchain-raspberrypi4_64.cmake dunedynasty-1.5.7/cmake/
cd dunedynasty-1.5.7/
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-raspberrypi4_64.cmake ..
make -j`nproc`
DESTDIR=${TARGET_DIR} make install # install to target system

cd ../../../

Creating a new Buildroot OS

To then create a new OS, the make command is executed within Buildroot:

make clean
make

After Buildroot is done, a file called rootfs.tar.gz is created inside the /path/to/buildroot-<VERSION_GOES_HERE>/output/images directory. This is the entire OS, minus the kernel.

Compiling the linux kernel

While Buildroot is doing it’s thing, a linux kernel can be compiled. There exists a github repository containing a complete kernel source for the Raspberry Pi. This source will be used to create a kernel.

Downloading the source

git clone https://github.com/raspberrypi/linux
git checkout rpi-5.10.y # version 5.10.y matches the one from the toolchain
git checkout d261fd9f97da8b6b3ed1fa613cc3fd6abb41f0be # known working commit for the paranoid (optional)
cd linux

Configuring the source

To see all available default configurations:

ls arch/arm64/configs/

To pick the one for the Raspberry Pi 4:

ARCH=arm64 CROSS_COMPILE=~/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu- make bcm2711_defconfig

Compiling

ARCH=arm64 CROSS_COMPILE=~/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu- make clean
ARCH=arm64 CROSS_COMPILE=~/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu- make -j`nproc`
ARCH=arm64 CROSS_COMPILE=~/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu- make modules -j`nproc`

After the compiling process is done, there should be a file called Image inside the /path/to/linux/arch/arm64/boot directory.

Creating a system image

Buildroot is done, Linux is compiled. Everything can now be put inside of a system image. This process will be automated using a file called build_image.sh.

Creating Raspberry Pi 4 boot configuration (config.txt)

Before build_image.sh can do it’s thing, a file called config.txt will be created in the root directory of the project. The file will have the following contents:

# Enable 64 bit mode
arm_64bit=1

# Make the raspberry Pi 4 start the linux binary called "Image"
kernel=Image

# Disable bluetooth
dtoverlay=disable-bt

# Run cut-down files
start_file=start4cd.elf
fixup_file=fixup4cd.dat

# Go fast
arm_boost=1
initial_turbo=20
boot_delay=0
boot_delay_ms=0
force_eeprom_read=0
start_cd=1
start_x=0
enable_uart=0

# Disable rainbow splash screen
disable_splash=1

# Enable DRM VC4 V3D driver overlay
dtoverlay=vc4-fkms-v3d-pi4
max_framebuffers=2
gpu_mem=128

# Enable audio
dtparam=audio=on

Creating Raspberry Pi 4 boot configuration (cmdline.txt)

rng_core.default_quality=100 dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait quiet

Creating the build script

The file build_image.sh is created inside the root directory of the project, and has the following contents:

#########################################
# Create a system image called "system.img"
#########################################

rm -rf system.img
sudo dd if=/dev/zero of=system.img bs=1MiB count=300 status=progress
sudo sync

echo "mklabel msdos" | sudo parted system.img
echo "mkpart primary fat16 2048s 30MiB" | sudo parted system.img
echo "mkpart primary ext4 30MiB 100%" | sudo parted system.img
echo "set 1 boot on" | sudo parted system.img
# echo "print" | sudo parted system.img
# sleep 10
sudo chmod 777 system.img

###########################################
# Mount the system image, as if it's a device
###########################################

SYSTEM_IMAGE=`sudo losetup -Pf system.img --show`

##########################
# Partition the system image
##########################

sudo mkfs.vfat -n BOOT `echo "${SYSTEM_IMAGE}p1"`   # Create a fat16 partition for boot files
sudo mkfs.ext4 -L ROOTFS `echo "${SYSTEM_IMAGE}p2"` # Create an ext4 partition for rootfs files

########################
# Mount the new partitions
########################

sudo rm -rf ./target_mnt
mkdir ./target_mnt
sudo mount `echo "${SYSTEM_IMAGE}p2"` ./target_mnt
sudo mkdir ./target_mnt/boot
sudo mount `echo "${SYSTEM_IMAGE}p1"` ./target_mnt/boot

###############
# Copy boot files
###############

# Raspberry Pi 4 boot configuration
sudo cp ./config.txt ./target_mnt/boot/
sudo cp ./cmdline.txt ./target_mnt/boot/

# firmware
sudo cp ./buildroot-2021.11/output/images/rpi-firmware/bcm2711-rpi-4-b.dtb ./target_mnt/boot/
sudo cp ./buildroot-2021.11/output/images/rpi-firmware/start4cd.elf ./target_mnt/boot/
sudo cp ./buildroot-2021.11/output/images/rpi-firmware/fixup4cd.dat ./target_mnt/boot/
sudo cp ./buildroot-2021.11/output/images/rpi-firmware/overlays ./target_mnt/boot -r

# kernel
sudo cp ./linux/arch/arm64/boot/Image ./target_mnt/boot/

sleep 3

#################
# Copy rootfs files
#################

# buildroot's rootfs
cd target_mnt/
sudo tar -xvf ../buildroot-2021.11/output/images/rootfs.tar.gz .
cd ..

sleep 3

# kernel
cd linux
sudo INSTALL_MOD_PATH=../target_mnt/ ARCH=arm64 CROSS_COMPILE=/home/tom/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu- make modules_install
cd ..

sleep 3

# game files
sudo cp ./data ./target_mnt -r

########################
# Unmount the system image
########################

sudo sync
sudo umount ./target_mnt/boot -l
sudo umount ./target_mnt -l
sudo losetup -D
sudo rm -rf ./target_mnt

The system should now be ready to run Dune Dynasty. Flash the system.img file to any Raspberry Pi 4’s SD card and see the OS in action!

Debugging

If the system does not boot into ratpoison automatically, the game can be started manually, using the following commands:

# start X.org (will start one xterm window for now)
xinit
# start twm window manager
exec twm &
# load some kernel modules related to hardware acceleration (still in testing phase)
modprobe v3d
modprobe vc4
# make sure the Dune Dynasty binary can find the Allegro5 library files
export LD_LIBRARY_PATH="/lib:/usr/lib:/usr/local/lib"
# start Dune Dynasty
/usr/local/bin/dunedynasty

Extra’s

Building Allegro5 manually (optional)

To compile Dune Dynasty, the Allegro5 game programming library is needed.

Buildroot must be done building before Allegro5 is built; Allegro5 cannot compile against an incomplete OS.

Downloading the source files

To download and extract the Allegro5 library source file, the following commands are executed:

wget https://github.com/liballeg/allegro5/releases/download/5.2.7.0/allegro-5.2.7.0.tar.gz
tar -xvf allegro-5.2.7.0.tar.gz
rm -rf allegro-5.2.7.0.tar.gz
cd allegro-5.2.7.0/

Configuring CMake

In the folder allegro-5.2.7.0/cmake are a bunch of files related to CMake. Within the list of files there is a file called Toolchain-raspberrypi.cmake. This file contains configuration that tells CMake how to build the library for the first Raspberry Pi. The first Raspberry Pi is 32 bit and the toolchain does not have multilib support enabled. Therefor, a new toolchain must be created.

A custom file called Toolchain-raspberrypi4_64.cmake will be created and placed inside the allegro-5.2.7.0/cmake directory. The file will contain the following contents:

#############
# Set target OS
#############

set(CMAKE_SYSTEM_NAME Linux)

######################################################
# Force CMake to use the toolchain built by crosstool-NG
# (both 64 bit and 32 bit cross-compiling toolchains can
# be used here)
######################################################

set(CMAKE_TOOLCHAIN_FILE /home/<YOUR_USERNAME_GOES_HERE>/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu)
set(CMAKE_C_COMPILER ${CMAKE_TOOLCHAIN_FILE}-gcc)
set(CMAKE_CXX_COMPILER ${CMAKE_TOOLCHAIN_FILE}-g++)
set(CMAKE_LINKER ${CMAKE_TOOLCHAIN_FILE}-ld)

set(MAKE_C_LINK_EXECUTABLE ${CMAKE_LINKER})
set(MAKE_CXX_LINK_EXECUTABLE ${CMAKE_LINKER})

#########################################################
# Tell CMake to do all compiling against the target sysroot
#########################################################

set(CMAKE_SYSROOT /path/to/buildroot-<VERSION_GOES_HERE>/output/host/aarch64-rpi4-linux-gnu/sysroot)
set(CMAKE_SYSROOT_COMPILE ${CMAKE_SYSROOT}/)
set(CMAKE_SYSROOT_LINK ${CMAKE_SYSROOT}/)
set(CMAKE_SYSTEM_PREFIX_PATH ${CMAKE_SYSROOT}/)
set(CMAKE_INSTALL_PREFIX ${CMAKE_SYSROOT})

#######################################################
# Make sure CMake does not link against host OS libraries
#######################################################

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FINE_ROOT_PATH_MODE_PACKAGE ONLY)

When the following commands are then executed, the Allegro library will be built:

# create a build directory and go into it, to separate source code from binaries
mkdir build/
cd build/

# delete old build files (in case the previous build failed)
rm -rf CMakeFiles CMakeCache.txt addons cmake_install.cmake demos docs examples include lib Makefile tests

# configure CMake
cmake -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-raspberrypi4_64.cmake -DSHARED=on -DCMAKE_LINKER_FLAGS="-static-libgcc -static-libstdc++" ..

# build Allegro5
make -j`nproc`

Manually installing Allegro5 to the target Buildroot OS

After Allegro5 is done compiling, it can be installed to the target OS using the environment variable DESTDIR:

# dune dynasty will compile against this sysroot, it cannot compile against target
DESTDIR=path/to/buildroot-<VERSION_GOES_HERE>/output/host/<COMPILING_TOOLCHAIN_GOES_HERE>/sysroot make install
# install to target OS as well
DESTDIR=path/to/buildroot-<VERSION_GOES_HERE>/output/target/ make install

Manually compiling Dune Dynasty against the target Buildroot OS

It it assumed that Allegro5 was installed to the target Buildroot OS. If it’s not, this has to be done before continuing.

First, download and extract the game:

wget https://versaweb.dl.sourceforge.net/project/dunedynasty/dunedynasty-1.5/dunedynasty-1.5.7.tar.gz
tar -xvf dunedynasty-1.5.7.tar.gz
rm -rf dunedynasty-1.5.7.tar.gz

Then, create a toolchain file in the dunedynasty-1.5.7/cmake directory, called Toolchain-raspberrypi4_64.cmake. The toolchain is almost the same as the one from Allegro5, but with some extra configuration at the bottom:

#############
# Set target OS
#############
set(CMAKE_SYSTEM_NAME Linux)

######################################################
# Force CMake to use the toolchain built by crosstool-NG
# (both 64 bit and 32 bit cross-compiling toolchains can
# be used here)
######################################################

set(CMAKE_TOOLCHAIN_FILE /home/<YOUR_USERNAME_GOES_HERE>/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu)
set(CMAKE_C_COMPILER ${CMAKE_TOOLCHAIN_FILE}-gcc)
set(CMAKE_CXX_COMPILER ${CMAKE_TOOLCHAIN_FILE}-g++)
set(CMAKE_LINKER ${CMAKE_TOOLCHAIN_FILE}-ld)

set(MAKE_C_LINK_EXECUTABLE ${CMAKE_LINKER})
set(MAKE_CXX_LINK_EXECUTABLE ${CMAKE_LINKER})

#########################################################
# Tell CMake to do all compiling against the target sysroot
#########################################################

set(CMAKE_SYSROOT /path/to/buildroot-<VERSION_GOES_HERE>/output/host/<COMPILING_TOOLCHAIN_GOES_HERE>/sysroot)
set(CMAKE_SYSROOT_COMPILE ${CMAKE_SYSROOT}/)
set(CMAKE_SYSROOT_LINK ${CMAKE_SYSROOT}/)
set(CMAKE_SYSTEM_PREFIX_PATH ${CMAKE_SYSROOT}/)
set(CMAKE_INSTALL_PREFIX ${CMAKE_SYSROOT})

#######################################################
# Make sure CMake does not link against host OS libraries
#######################################################

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FINE_ROOT_PATH_MODE_PACKAGE ONLY)

##############################################
# Make sure Allegro5 is found (using pkg-config)
##############################################

set(ENV{PKG_CONFIG_DIR} "")
set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig:${CMAKE_SYSROOT}/usr/local/lib/pkgconfig/)
set(ENV{PKG_CONFIG_PATH} ${PKG_CONFIG_LIBDIR})
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})

To then compile the game, create a directory called build, go into it and compile everything:

# go inside a build directory to separate binaries from source code
mkdir build/
cd build/

# configure CMake
cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-raspberrypi4_64.cmake ..

# build the game
make -j`nproc`

Installing the game to the target sysroot

Installing the binaries to the target sysroot is exactly the same process as installing Allegro5:

sudo DESTDIR=path/to/buildroot-<VERSION_GOES_HERE>/output/target/ make install # install to target OS