#!/bin/bash # Slackware build script for fpc-mingw-w64 # Copyright 2026 Pablo Romano, Seville, Spain # All rights reserved. # # Redistribution and use of this script, with or without modification, is # permitted provided that the following conditions are met: # # 1. Redistributions of this script must retain the above copyright # notice, this list of conditions and the following disclaimer. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. cd "$(dirname "$0")" ; CWD=$(pwd) PRGNAM=fpc-mingw-w64 VERSION=${VERSION:-3.2.2} BOOTSTRAPVER=${BOOTSTRAPVER:-3.2.2} BUILD=${BUILD:-1} TAG=${TAG:-_SBo} PKGTYPE=${PKGTYPE:-tgz} if [ -z "$ARCH" ]; then ARCH=$(uname -m) fi case "$ARCH" in x86_64) LIBDIRSUFFIX=64 ;; *) echo "$ARCH is not supported." exit 1 ;; esac if [ -n "$PRINT_PACKAGE_NAME" ]; then echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE" exit 0 fi TMP=${TMP:-/tmp/SBo} PKG=$TMP/package-$PRGNAM OUTPUT=${OUTPUT:-/tmp} WORK=$TMP/$PRGNAM-$VERSION SRCDIR=$WORK/fpcbuild-$VERSION FPCSRC=$SRCDIR/fpcsrc BOOTDIR=$WORK/bootstrap STAGEDIR=$WORK/stage CHECKDIR=$WORK/check set -e find_one() { find "$1" -type f -name "$2" -print -quit } build_cross() { CPU_TARGET=$1 OS_TARGET=$2 BINUTILSPREFIX=$3 CROSS_COMPILER=$4 UNIT_TARGET=$5 NATIVE_COMPILER=$6 make -C "$FPCSRC" -j1 compiler_clean \ CPU_TARGET="$CPU_TARGET" \ OS_TARGET="$OS_TARGET" # crossall builds the cross compiler, target RTL, and target units. # Only the cross compiler and RTL are installed by this package. make -C "$FPCSRC" -j1 crossall \ PP="$NATIVE_COMPILER" \ FPC="$NATIVE_COMPILER" \ CPU_TARGET="$CPU_TARGET" \ OS_TARGET="$OS_TARGET" \ BINUTILSPREFIX="$BINUTILSPREFIX" \ CROSSOPT="-O2" \ NOGDB=1 # Preserve the output before the next compiler_clean invocation. install -Dm755 "$FPCSRC/compiler/$CROSS_COMPILER" \ "$STAGEDIR/$CROSS_COMPILER" mkdir -p "$STAGEDIR/units" rm -rf "$STAGEDIR/units/$UNIT_TARGET" cp -a "$FPCSRC/rtl/units/$UNIT_TARGET" \ "$STAGEDIR/units/$UNIT_TARGET" } rm -rf "$PKG" "$WORK" mkdir -p "$TMP" "$PKG" "$OUTPUT" "$WORK" "$BOOTDIR" "$STAGEDIR" cd "$WORK" tar xvf "$CWD/fpcbuild-$VERSION.tar.gz" # The official binary archive is used only to create a native temporary # compiler. No file from the downloaded binary archive is packaged. tar xvf "$CWD/fpc-$BOOTSTRAPVER.x86_64-linux.tar" -C "$BOOTDIR" BINARY_ARCHIVE=$(find_one "$BOOTDIR" binary.x86_64-linux.tar) if [ -z "$BINARY_ARCHIVE" ]; then echo "Unable to locate binary.x86_64-linux.tar in the bootstrap archive." exit 1 fi tar xvf "$BINARY_ARCHIVE" -C "$BOOTDIR" BASE_ARCHIVE=$(find_one "$BOOTDIR" base.x86_64-linux.tar.gz) if [ -z "$BASE_ARCHIVE" ]; then echo "Unable to locate base.x86_64-linux.tar.gz in the bootstrap archive." exit 1 fi tar xvf "$BASE_ARCHIVE" -C "$BOOTDIR" START_COMPILER=$(find_one "$BOOTDIR" ppcx64) if [ -z "$START_COMPILER" ]; then echo "Unable to locate ppcx64 in the bootstrap archive." exit 1 fi chmod 755 "$START_COMPILER" cd "$SRCDIR" chown -R root:root . find -L . \ \( -perm 777 -o -perm 775 -o -perm 750 \) -exec chmod 755 {} + -o \ \( -perm 666 -o -perm 664 -o -perm 640 \) -exec chmod 644 {} + # Build a native compiler from the same source release. This compiler is # temporary and is not installed in the resulting package. make -C "$FPCSRC" -j1 compiler_cycle PP="$START_COMPILER" install -Dm755 "$FPCSRC/compiler/ppcx64" \ "$STAGEDIR/ppcx64-bootstrap" NATIVE_COMPILER=$STAGEDIR/ppcx64-bootstrap # Rebuild the native RTL with the newly created temporary compiler. make -C "$FPCSRC" -j1 rtl_clean rtl_all PP="$NATIVE_COMPILER" # Build the 32-bit and 64-bit Windows cross compilers and their RTLs. build_cross i386 win32 i686-w64-mingw32- \ ppcross386 i386-win32 "$NATIVE_COMPILER" build_cross x86_64 win64 x86_64-w64-mingw32- \ ppcrossx64 x86_64-win64 "$NATIVE_COMPILER" # Compile minimal programs without reading any system FPC configuration. mkdir -p "$CHECKDIR/win32" "$CHECKDIR/win64" cat > "$CHECKDIR/hello.pas" <<'EOF_PASCAL' program hello; begin writeln('hello from a cross-compiled binary'); end. EOF_PASCAL "$STAGEDIR/ppcross386" -n -Twin32 -Pi386 \ -XPi686-w64-mingw32- \ -Fu"$STAGEDIR/units/i386-win32" \ -FE"$CHECKDIR/win32" \ "$CHECKDIR/hello.pas" "$STAGEDIR/ppcrossx64" -n -Twin64 -Px86_64 \ -XPx86_64-w64-mingw32- \ -Fu"$STAGEDIR/units/x86_64-win64" \ -FE"$CHECKDIR/win64" \ "$CHECKDIR/hello.pas" file "$CHECKDIR/win32/hello.exe" | grep -q "PE32 executable" file "$CHECKDIR/win64/hello.exe" | grep -q "PE32+ executable" FPCLIB=usr/lib$LIBDIRSUFFIX/fpc/$VERSION install -Dm755 "$STAGEDIR/ppcross386" "$PKG/$FPCLIB/ppcross386" install -Dm755 "$STAGEDIR/ppcrossx64" "$PKG/$FPCLIB/ppcrossx64" mkdir -p "$PKG/usr/bin" ( cd "$PKG/usr/bin" ln -s "../lib$LIBDIRSUFFIX/fpc/$VERSION/ppcross386" ppcross386 ln -s "../lib$LIBDIRSUFFIX/fpc/$VERSION/ppcrossx64" ppcrossx64 ) # Install only the target RTL units, not the remaining cross-built packages. mkdir -p \ "$PKG/$FPCLIB/units/i386-win32" \ "$PKG/$FPCLIB/units/x86_64-win64" cp -a "$STAGEDIR/units/i386-win32" \ "$PKG/$FPCLIB/units/i386-win32/rtl" cp -a "$STAGEDIR/units/x86_64-win64" \ "$PKG/$FPCLIB/units/x86_64-win64/rtl" install -Dm644 "$CWD/fpc-mingw-w64.cfg" \ "$PKG/etc/fpc-mingw-w64.cfg.new" DOCDIR=$PKG/usr/doc/$PRGNAM-$VERSION mkdir -p "$DOCDIR" for DOC in COPYING.v2 rtl/COPYING.FPC; do if [ -f "$FPCSRC/$DOC" ]; then cp -a "$FPCSRC/$DOC" "$DOCDIR/" fi done cat "$CWD/README" > "$DOCDIR/README" cat "$CWD/$PRGNAM.SlackBuild" > "$DOCDIR/$PRGNAM.SlackBuild" # Strip only native ELF executables. Windows objects and RTL archives must not # be processed with the host strip utility. find "$PKG" -type f -perm /111 -print0 | \ xargs -0 -r file -m /etc/file/magic/elf | \ grep -E "ELF.*(executable|shared object)" | \ cut -d: -f1 | \ xargs -r strip --strip-unneeded 2> /dev/null || true mkdir -p "$PKG/install" cat "$CWD/slack-desc" > "$PKG/install/slack-desc" cat "$CWD/doinst.sh" > "$PKG/install/doinst.sh" cd "$PKG" /sbin/makepkg -l y -c n \ "$OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"