Cross Compile to RasPi from Linux
This page is about setting up a Cross Compiler from a Linux Box to a Raspberry Pi. You should be able to select arm as the CPU in Lazarus or if just using FPC, choose to use the ppcrossarm compiler and produce v6 arm binaries. Raspberry Pi is just a specific example of arm, only small changes would seem necessary on other similar platforms.
- Tested on an Ubuntu 21.04 and Debian Bullseye System. Its should be similar on most mainstream Linux platforms.
- This recipe assumes you already have a current FPC and, possibly Lazarus installed. You MUST use packages downloaded from the FPC/Lazarus SourceForge site, its most likely that FPC and Lazarus packages from your Distribution will not work as expected.
- A large part of this install is done as root. Working like that gives you the potential to make a real mess of your system, please be very careful.
This page is under development and the recipe presented is still being tested.
Getting the necessary libraries
Firstly, we are going to need some reasonably current libraries from your Raspberry Pi, as near as I can determine this is the best way to get the necessary libraries.
On the pi, we will tar up what we need, this does not need to be done as root.
tar czf usr_lib_arm-linux-gnueabihf.tgz /usr/lib/arm-linux-gnueabihf tar czf lib_arm-linux-gnueabihf.tgz /lib/arm-linux-gnueabihf
Next, we need the crt files, first, find where they are, yours may be in a directory other than the '8' shown here.
raspberrypi:~ $ find / -name "crtbegin.o" 2>null /usr/lib/gcc/arm-linux-gnueabihf/8/crtbegin.o raspberrypi:~ $ (cd /usr/lib/gcc/arm-linux-gnueabihf/8 && tar czf $HOME/crt.tgz crt*.o)
Take these three files, 248M, 7M and 3K respectively to the Intel box and put them in your home directory, then, we will deal with them as root further down. They will use up some 640M of disk and probably includes libraries you will never use but its easier than trying to work out exactly what you do need.
Only one change is necessary, the way fpc.cfg uses replacable variables means it will workout itself where the libraries mentioned above are. However, the crt*.o files needed by the linker are not so easy. So, in the section marked "path to the gcclib" add this -
# path to the gcclib #ifdef cpuarm -Fl/usr/lib/arm-linux-gnueabihf #endif
If your fpc.cfg is in /etc and it probably is, you will need to do that edit as root, thats OK, we are about to do a whole load of stuff as root. So, from now on, you will be running as root, that means great care must be used. Note these instructions are meant to be copied and pasted, one by one. They are not a script !
First, edit, with your favorite editor /etc/fpc as mentioned above.
Install the Pi Libraries
Next, we need to install the needed libraries from a Pi from those tar balls we moved over before. The new libraries all end up in /usr/lib/arm-linux-gnueabihf - so easy clean up if necessary.
cd / tar xzf /home/"$SUDO_USER"/usr_lib_arm-linux-gnueabihf.tgz tar xzf /home/"$SUDO_USER"/lib_arm-linux-gnueabihf.tgz tar xzf /home/"$SUDO_USER"/crt.tgz -C /usr/lib/arm-linux-gnueabihf
Next, install some needed things and symlink them up to what Lazarus expects to find.
apt install binutils-arm-linux-gnueabihf ln -s /usr/bin/arm-linux-gnueabihf-ld /usr/bin/arm-linux-ld ln -s /usr/bin/arm-linux-gnueabihf-as /usr/bin/arm-linux-as
Build the Cross Compiler
OK, now we build the cross compiler and a set of pre compiled arm units.
export FPCVER="3.2.2" cd /usr/share/fpcsrc/"$FPCVER"/ make clean all OS_TARGET=linux CPU_TARGET=arm CROSSBINDIR=/usr/lib/arm-linux-gnueabihf/bin CROSSOPT="-CpARMV6 -CfVFPV2 -OoFASTMATH" make crossinstall OS_TARGET=linux CPU_TARGET=arm INSTALL_PREFIX=/usr ln -sf /usr/lib/fpc/"$FPCVER"/ppcrossarm /usr/bin/ppcrossarm
OK, done, Control-D to get out of that somewhat dangerous root access and test !
Testing fpc functionality is easy, put the hello world source in a file, hello.pas and try this -
db@U2104G-VirtualBox:~/Pascal/console$ ppcrossarm hello.pas Free Pascal Compiler version 3.2.2 [2021/07/19] for arm Copyright (c) 1993-2021 by Florian Klaempfl and others Target OS: Linux for ARMEL Compiling hello.pas Linking hello 4 lines compiled, 0.1 sec
db@U2104G-VirtualBox:~/Pascal/console$ file hello hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.0.0, stripped
You can move that binary over to a Pi and test it really works.
Testing the Lazarus functionality is more involved, fire up Lazarus, open a new project, maybe set a control or two on it, open Project->ProjectOptions->ConfigAndTarget and set ProjectCPUFamily to 'arm'.
Compile and see if the binary looks like this -
db@U2104G-VirtualBox:~/Pascal/ArmTest$ file project1 project1: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 2.0.0, not stripped