15 minutes
Creating an embedded OS that runs a DOS game
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.
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 optionVersion of gcc
is set to the second to latest option (10.3.0
at time of writing) - Under
Operating System
, the optionVersion of linux
is set to5.10.79
(this is the version of linux that will be compiled later in this post) - Under
Debug facilities
, the optiongdb
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 optionEnable compiler cache
is enabled - Under
Build options
, the optionRELR0 protection
is set toPartial
- Under
Build options
, the optionStack Smashing Protection
is set toNone
- Under
Bootloaders
, all the options are disabled (the bootloader will be compiled manually) - Under
Kernel
, the optionLinux Kernel
is disabled (the kernel will be compiled manually) - Under
Filesystem images
, the optionext2/3/4 root filesystem
is disabled - Under
Filesystem images
, the optiontar the root filesystem
is enabled, along with theCompression method
set togzip
- Under
Toolchain
, the optionToolchain type
is set toExternal toolchain
(this post uses a toolchain built by crosstool-NG) - Under
Toolchain
, the optionToolchain
is set toCustom toolchain
- Under
Toolchain
, the optionToolchain origin
is set toPre-installed toolchain
- Under
Toolchain
, the optionToolchain 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 optionToolchain prefix
is set toaarch64-rpi4-linux-gnu
- Under
Toolchain
, the optionExternal toolchain C library
is set toglibc/eglibc
- Under
Toolchain
, the optionExternal toolchain gcc version
is set to10.x
(matching the version from the toolchain) - Under
Toolchain
, the optionExternal toolchain kernel headers series
is set to5.10.x
(matching the version from the toolchain) - Under
Toolchain
, the optionToolchain has locale support?
is enabled - Under
Toolchain
, the optionToolchain has threads support?
is enabled, along with the two extra options for threads support - Under
Toolchain
, the optionToolchain has SSP support?
is enabled - Under
Toolchain
, the optionToolchain has RPC support
is disabled - Under
Toolchain
, the optionToolchain has C++ support?
is enabled - Under
System configuration
, the optionSystem hostname
is set togaming
- Under
System configuration
, the optionSystem banner
is set toWelcome to gaming!
- Under
System configuration
, the optionRoot password
is set toroot
(the root login will be bypassed later, so this value does not matter too much) - Under
System configuration
, the option/dev management
is set toDynamic using devtmpfs + mdev
(to load drivers automatically when the target device boots) - Under
System configuration
, the optionEnable 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 optionrpi 4 (default)
is disabled (all the extra firmware is not needed) - Under
Target packages
->Hardware handling
->Firmware
, the optionrpi 4 (cut-down)
is enabled - Under
Target packages
->Graphic libraries and applications (graphic/text)
, the optionratpoison
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 optionX.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 optionmesa3d
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 optionsdl2
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 optionxterm
is enabled (for debugging) - Under
Target packages
->Audio and video applications
, the optionfluidsynth
is enabled, along with the following extra options:- alsa
- jack2
- sdl2
- Under
Target packages
->Libraries
->Graphics
, the optionlibglew
is enabled - Under
Target packages
->Libraries
->Graphics
, the optionlibglfw
is enabled - Under
Target packages
->Libraries
->Graphics
, the optionlibglu
is enabled - Under
Target packages
->Libraries
->Graphics
, the optionlibgtk3
is enabled, along with the optionX11 GDK backend
(the rest is disabled) - Under
Target packages
->Libraries
->Filesystem
, the optionphysfs
is enabled - Under
Target packages
->Libraries
->Audio/Sound
, the optionopusfile
is enabled - Under
Target packages
->Libraries
->Audio/Sound
, the optionlibmad
is enabled - Under
Target packages
->Libraries
->Audio/Sound
, the optionalsa-lib
is enabled, as well as all the extra options it provides - Under
Target packages
->Libraries
->Multimedia
, the optionlibtheora
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