Created
June 13, 2025 06:02
-
-
Save vsajip/76375ce8a62bcf3c8a54ba75be94910d to your computer and use it in GitHub Desktop.
Script to build Lazarus from source on Linux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# ====================================================== | |
# by rvk (v.2.1, 2024-12-06) | |
# ====================================================== | |
echo "" | |
echo "==============================================================" | |
echo "Running on: $(sed 's/\x0/ /' /sys/firmware/devicetree/base/model 2>/dev/null || cat /sys/devices/virtual/dmi/id/product_name 2>/dev/null || echo Unknown)" | |
# ====================================================== | |
# setup versions, download and compile | |
# ====================================================== | |
#fpc_version="release_3_2_0" | |
#laz_version="lazarus_2_0_12" | |
#fast | |
zip=1 | |
# repository | |
fpc_git=1 | |
laz_git=1 | |
# compile | |
fpc_compile=1 | |
laz_compile=1 | |
LCL_PLATFORM=qt5 | |
#LCL_PLATFORM=gtk2 | |
# ====================================================== | |
# check if we are running in bash instead of sh | |
ps $$ 2>&1 | grep bash > /dev/null 2>&1 && echo "Running in bash. continuing..." || { echo "Not running in bash. Aborting..."; exit 1; } | |
# ====================================================== | |
# optional use zram as swapfile | |
# ====================================================== | |
# not done yet | |
# ====================================================== | |
# minimal swap space needed is 1024MB | |
# ====================================================== | |
while true; do | |
FREESWAP=$(free | grep -i swap | awk '{print $2}') | |
if [ $FREESWAP -lt 900000 ]; then | |
echo "==============================================================" | |
echo "Current swapsize is $FREESWAP" | |
echo "Swapsize is really small. Recomended size is 1024MB (1GB)."; | |
echo "==============================================================" | |
read -n1 -p "Do you want to increase it to 1024MB (1GB) or continue without swap? [y/n/c] " yn | |
echo "" | |
case $yn in | |
[Cc]* ) break;; | |
[Yy]* ) ;; | |
[Nn]* ) echo >&2 "Please increase the swap space manually. Aborting..."; exit 1;; | |
[Qq]* ) exit 1;; | |
* ) echo "Please answer yes or no."; echo ""; continue;; | |
esac | |
# we can increase this if /etc/dphys-swapfile exists | |
[ -f /etc/dphys-swapfile ] && { | |
echo "==============================================================" | |
echo "Setting in /etc/dphys-swapfile $(cat /etc/dphys-swapfile | grep CONF_SWAPSIZE)" | |
echo "Increasing value and restarting swap" | |
sudo sed -i 's/CONF_SWAPSIZE=[0-9]*$/CONF_SWAPSIZE=1024/g' /etc/dphys-swapfile | |
sudo /etc/init.d/dphys-swapfile stop | |
sudo /etc/init.d/dphys-swapfile restart | |
echo "==============================================================" | |
} || { | |
echo "==============================================================" | |
echo "Setting up /swapfile" | |
DATE=$(date +%s) | |
sudo fallocate -l 4G "/swapfile.$DATE" \ | |
&& sudo chmod 600 "/swapfile.$DATE" \ | |
&& sudo mkswap "/swapfile.$DATE" \ | |
&& sudo swapon "/swapfile.$DATE" \ | |
&& sudo swapon --show \ | |
&& echo "Created and turned on /swapfile.$DATE" \ | |
&& echo "Note: This is not permanent." | |
echo "==============================================================" | |
} | |
else | |
echo "Current swapsize is $FREESWAP. Ok" | |
break; | |
fi | |
done | |
# ====================================================== | |
begin=$(date +%s) | |
# ====================================================== | |
# update packages list to latest version | |
# ====================================================== | |
echo "==============================================================" | |
echo "" | |
echo "Updating package list to latest version (sudo needed)" | |
echo "" | |
PKG_MANAGER="" | |
command -v dnf >&1 >/dev/null && PKG_MANAGER="dnf" | |
command -v apt-get >&1 >/dev/null && PKG_MANAGER="apt" | |
# ====================================================== | |
# some other essentials | |
# ====================================================== | |
echo "==============================================================" | |
echo "" | |
echo "Installing required packages (sudo used)" | |
echo "" | |
if [ "$PKG_MANAGER" = "apt" ]; then | |
sudo apt-get -y install make binutils build-essential gdb git subversion zip unzip pv | |
sudo apt-get -y install libx11-dev libgtk2.0-dev # for Lazarus, includes all dependencies | |
if [ "$LCL_PLATFORM" = "qt5" ]; then sudo apt-get -y install libqt5pas-dev; fi | |
elif [ "$PKG_MANAGER" = "dnf" ]; then | |
# dnf search gtk2* | |
sudo dnf -y install make binutils gdb git zip unzip pv | |
sudo dnf -y install libX11-devel gtk2-devel gtk+-devel # for Lazarus, includes all dependencies | |
sudo dnf -y install gcc gcc-c++ kernel-devel | |
if [ "$LCL_PLATFORM" = "qt5" ]; then sudo dnf -y install qt5pas-devel; fi | |
else | |
echo >&2 "Neither yum/dnf nor apt-get found. Aborting."; exit 1; | |
fi | |
# sudo apt-get -y install libx11-dev libgdk-pixbuf2.0-dev libcairo2-dev lpango-1.0 libpangox-1.0-dev xorg-dev libatk1.0-dev libgtk2.0-dev | |
# libgtk2.0-dev libcairo2-dev libpango1.0-dev libgdk-pixbuf2.0-dev libatk1.0-dev libghc-x11-dev | |
# or | |
# xorg-dev libssl-dev libx11-dev libgdk-pixbuf2.0-dev | |
# libcairo2-dev lpango-1.0 libpangox-1.0-dev libatk1.0-dev libgtk2.0-dev | |
git --version >/dev/null 2>&1 || { echo >&2 "I require git but it's not installed. Aborting."; exit 1; } | |
# ====================================================== | |
# | |
# ====================================================== | |
BASE=$HOME/dev | |
mkdir -p $BASE | |
cd $BASE | |
# ====================================================== | |
# We need a bootstrap compiler fpc 3.2.2 | |
# There is NONE AVAILABLE so we need to download complete | |
# fpc-3.2.2.arm-linux-raspberry1wq.tar | |
# in virtualbox Rasbian stretch we need i386 | |
# ====================================================== | |
echo "==============================================================" | |
echo "" | |
CPU=$(uname -m) # armv7l, aarch64, x86_64 # note L not 1 | |
#CPU=$(dpkg --print-architecture) # armhf, arm64, | |
if [ "$CPU" = "armv7l" ]; then # note L not 1 | |
echo "Compiling for ARMv7 Processor (Pi2 and higher only)" | |
OPTIONS_FPC="-g -gl -gw3 -O2 -Xs -CX -XX -v0 -dFPC_ARMHF" | |
OPTIONS_LAZ="-g -gl -gw3 -v0" | |
OS_TARGET="linux" | |
CPU_TARGET="arm" | |
COMP3_DOWNLOAD="https://downloads.freepascal.org/fpc/dist/3.2.2/arm-linux/fpc-3.2.2.arm-linux.tar" # complete version | |
COMP=ppcarm | |
elif [ "$CPU" = "aarch64" ]; then | |
echo "Compiling for ARM64 Processor (Pi2 and higher only)" | |
OPTIONS_FPC="-g -gl -gw3 -O2 -Xs -CX -XX -v0 -dFPC_ARMHF" | |
OPTIONS_LAZ="-g -gl -gw3 -v0" | |
OS_TARGET="linux" | |
CPU_TARGET="aarch64" | |
COMP3_DOWNLOAD="https://downloads.freepascal.org/fpc/dist/3.2.2/aarch64-linux/fpc-3.2.2.aarch64-linux.tar" # complete version | |
COMP=ppca64 | |
elif [ "$CPU" = "x86_64" ]; then | |
echo "Compiling for x64 Processor" | |
OPTIONS_FPC="-g -gl -gw3 -O2 -Xs -CX -XX -v0" | |
OPTIONS_LAZ="-g -gl -gw3 -v0" | |
OS_TARGET="linux" | |
CPU_TARGET="x86_64" | |
COMP3_DOWNLOAD="https://downloads.freepascal.org/fpc/dist/3.2.2/x86_64-linux/fpc-3.2.2.x86_64-linux.tar" # complete version | |
COMP=ppcx64 | |
elif [ "$CPU" = "i686" ]; then | |
echo "Compiling for i686 Processor" | |
OPTIONS_FPC="-g -gl -gw3 -O2 -Xs -CX -XX -v0 -dFPC_I386" | |
OPTIONS_LAZ="-g -gl -gw3 -v0" | |
OS_TARGET="linux" | |
CPU_TARGET="i386" | |
COMP3_DOWNLOAD="https://downloads.freepascal.org/fpc/dist/3.2.2/i386-linux/fpc-3.2.2.i386-linux.tar" # complete version | |
COMP=ppc386 | |
else | |
echo >&2 "$CPU is not supported as processor (needed armv7l/x86_64/i686). Aborting."; exit 1; | |
fi | |
# ------------------------------------------------------ | |
echo "==============================================================" | |
if [ ! -x ./bootstrap/$COMP ]; then | |
echo "Downloading compiler 3.2.2" | |
echo "" | |
wget --continue --quiet -O- $COMP3_DOWNLOAD |\ | |
tar -O -xf- --wildcards --no-anchored "binary*-linux.tar" --strip=1 |\ | |
tar -O -xf- --wildcards --no-anchored "base.*-linux.tar.gz" |\ | |
tar -xzf- --wildcards --no-anchored "lib/fpc/*/ppc*" --transform "s|lib/fpc/.*/ppc|./bootstrap/ppc|" | |
fi | |
[ -x ./bootstrap/$COMP ] || { echo >&2 "Bootstrap $BASE/bootstrap/$COMP compiler not found. Aborting."; exit 1; } | |
echo "Using bootstrap $BASE/bootstrap/$COMP compiler" | |
echo "" | |
# ====================================================== | |
# downloading fpc and lazarus | |
# ====================================================== | |
if [ "$zip" = "1" ]; then | |
wget --continue --quiet -O fpc.zip "https://gitlab.com/freepascal.org/fpc/source/-/archive/main/source-main.zip" | |
wget --continue --quiet -O laz.zip "https://gitlab.com/freepascal.org/lazarus/lazarus/-/archive/main/lazarus-main.zip" | |
unzip -q fpc.zip | |
unzip -q laz.zip | |
mv lazarus-main lazarus | |
mv source-main fpc | |
else | |
if [ "$fpc_git" = "1" ]; then | |
echo "==============================================================" | |
echo "" | |
echo "Downloading FPC sources $(git -C fpc log -1 2>&1 | grep Date)" | |
echo "" | |
[ -d ./fpc ] && { git -C fpc reset --hard && git -C fpc pull -q; } || { git clone https://gitlab.com/freepascal.org/fpc/source.git fpc; } | |
[ -f ./fpc/Makefile ] || { echo >&2 "Download of fpc failed. Aborting."; exit 1; } | |
echo "Now: $(git -C fpc log -1 | grep Date 2>&1)" | |
echo "" | |
fi | |
if [ "$laz_git" = "1" ]; then | |
echo "Downloading Lazarus sources $(git -C lazarus log -1 2>&1 | grep Date)" | |
[ -d ./lazarus ] && { git -C lazarus reset --hard && git -C lazarus pull -q; } || { git clone https://gitlab.com/freepascal.org/lazarus/lazarus.git lazarus; } | |
[ -f ./lazarus/Makefile ] || { echo >&2 "Download of fpc failed. Aborting."; exit 1; } | |
echo "Now: $(git -C lazarus log -1 | grep Date 2>&1)" | |
echo "" | |
fi | |
if [ "$fpc_version" != "" ]; then | |
echo "Switch to fpc $fpc_version" | |
git -C fpc checkout tags/$fpc_version | |
fi | |
if [ "$laz_version" != "" ]; then | |
echo "Switch to lazarus $laz_version" | |
git -C lazarus checkout tags/$laz_version | |
fi | |
fi | |
# ====================================================== | |
# compiling fpc | |
# ====================================================== | |
if [ "$fpc_compile" = "1" ]; then | |
echo "==============================================================" | |
echo "" | |
echo "Now compiling FPC, this will take some time" | |
echo "" | |
cd $BASE/fpc | |
echo "Cleaning up" | |
# find . -name "*.ppu" -type f -delete | |
# find . -name "*.o" -type f -delete | |
# make clean distclean cleanall > /dev/null 2>&1 | |
git clean -xdf > /dev/null 2>&1 # will clean untracked files and directories | |
echo "make -s all install OPT=\"$OPTIONS_FPC\" OS_TARGET=$OS_TARGET CPU_TARGET=$CPU_TARGET INSTALL_PREFIX=$BASE/fpc PP=$BASE/bootstrap/$COMP" | |
make -s all install OPT="$OPTIONS_FPC" OS_TARGET=$OS_TARGET CPU_TARGET=$CPU_TARGET INSTALL_PREFIX=$BASE/fpc PP=$BASE/bootstrap/$COMP \ | |
| pv -l -bp -s2500 >$BASE/fpc.log \ | |
|| { echo >&2 "Compilation of FPC failed. Aborting."; exit 1; } | |
cd $BASE | |
[ -x ./fpc/bin/fpc ] || { echo >&2 "Something went wrong compiling FPC. Aborting."; exit 1; } | |
echo "" | |
echo "Doing some extra configuration" | |
# remove old config | |
[ -f $HOME/.fpc.cfg ] && rm $HOME/.fpc.cfg | |
ln -sf $(find $BASE/fpc/lib -name $COMP ) $BASE/fpc/bin/$COMP | |
ln -sf $(find $BASE/fpc/lib -name samplecfg) $BASE/fpc/bin/samplecfg | |
# ln -sf $BASE/fpc/lib/fpc/3.3.1/$COMP $BASE/fpc/bin/$COMP | |
# ln -sf $BASE/fpc/lib/fpc/3.3.1/samplecfg $BASE/fpc/bin/samplecfg | |
$BASE/fpc/bin/fpcmkcfg -d basepath=$BASE/fpc -o $HOME/.fpc.cfg | |
# sudo find / -name crtbegin.o | |
# This library needs to be added to the fpc.cfg file. | |
cat << EOF >> $HOME/.fpc.cfg | |
-Fu$BASE/fpc/lib/fpc/\$fpcversion/units/\$fpctarget | |
-Fu$BASE/fpc/lib/fpc/\$fpcversion/units/\$fpctarget/* | |
-Fu$BASE/fpc/lib/fpc/\$fpcversion/units/\$fpctarget/rtl | |
-Fl$(dirname $(gcc --print-file-name=crtbegin.o)) | |
-FD$BASE/fpc/bin | |
EOF | |
echo "" | |
echo "Doing some extra configuration" | |
echo "" | |
# set path withhout old fpc | |
PATH=$(echo $PATH | sed "s|$BASE/fpc/bin\:||g") | |
# strip previous $BASE from .profile | |
sed -i '/# FPC PATH/,/fi/d' $HOME/.bash_profile | |
cat << EOF >> $HOME/.bash_profile | |
# FPC PATH | |
if [ -d $BASE/fpc/bin ] ; then | |
PATH="$BASE/fpc/bin:\$PATH" | |
fi | |
EOF | |
# replace all double empty lines with one | |
sed -i '/^$/N;/^\n$/D' $HOME/.bash_profile | |
echo "" | |
fi # fpc_compile | |
# ====================================================== | |
# compiling lazarus | |
# ====================================================== | |
if [ "$laz_compile" = "1" ]; then | |
echo "==============================================================" | |
echo "" | |
echo "Now compiling Lazarus, this will take some time" | |
echo "" | |
cd $BASE/lazarus | |
echo "Cleaning up" | |
# find . -name "*.ppu" -type f -delete | |
# find . -name "*.o" -type f -delete | |
# make clean distclean cleanall > /dev/null 2>&1 | |
git clean -xdf > /dev/null 2>&1 # will clean untracked files and directories | |
echo "make -s bigide OS_TARGET=$OS_TARGET CPU_TARGET=$CPU_TARGET OPT=\"$OPTIONS_LAZ\" PP=$BASE/fpc/bin/fpc" | |
# make bigide OS_TARGET="linux" CPU_TARGET="x86_64" OPT="-g -gl -gw3 -v0" LCL_PLATFORM=qt5 | |
# make bigide LCL_PLATFORM=qt5 | |
make -s bigide LCL_PLATFORM=$LCL_PLATFORM OS_TARGET=$OS_TARGET CPU_TARGET=$CPU_TARGET OPT="$OPTIONS_LAZ" PP=$BASE/fpc/bin/fpc \ | |
| pv -l -bp >$BASE/laz.log \ | |
|| { echo >&2 "Compilation of Lazarus failed. Aborting."; exit 1; } | |
cd $BASE | |
[ -f ./lazarus/lazarus ] || { echo >&2 "Something went wrong compiling Lazarus. Aborting."; exit 1; } | |
echo "" | |
echo "Creating desktop icon" | |
echo "" | |
# ~/.local/share/applications/Lazarus.desktop | |
# $HOME/Desktop/Lazarus.desktop | |
# $(INSTALL_PREFIX)/share/applications/lazarus.desktop | |
cat << EOF > $HOME/Desktop/Lazarus.desktop | |
[Desktop Entry] | |
Name=Lazarus | |
Comment=Lazarus | |
Icon=$BASE/lazarus/images/ide_icon48x48.png | |
Exec=$BASE/lazarus/startlazarus | |
Path=$BASE/lazarus | |
Type=Application | |
Encoding=UTF-8 | |
Terminal=false | |
Categories=None; | |
EOF | |
fi | |
end=$(date +%s) | |
echo "==============================================================" | |
echo "" | |
echo "$((($end-$begin) / 60)) minutes and $((($end-$begin) % 60)) seconds elapsed." | |
echo "" | |
echo "We are done. Please logout and back in before starting Lazarus" | |
echo "Otherwise you need to supply the fpc location on 1st start" | |
echo "" | |
echo "==============================================================" | |
echo "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment