# Scripts for creating Ada/Algol68/etc CROSS-COMPILER for AARCH64 - Minimal Dependencies

**URL:** https://forum.ada-lang.io/t/scripts-for-creating-ada-algol68-etc-cross-compiler-for-aarch64-minimal-dependencies/4590
**Category:** General
**Created:** [July 24, 2026, 2:44pm UTC](https://forum.ada-lang.io/t/scripts-for-creating-ada-algol68-etc-cross-compiler-for-aarch64-minimal-dependencies/4590 "2026-07-24T14:44:24Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![BlueAlmost](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/bluealmost/32/953_2.png) [@BlueAlmost](https://forum.ada-lang.io/u/BlueAlmost)
#### Post date: [July 24, 2026, 2:44pm UTC](https://forum.ada-lang.io/t/scripts-for-creating-ada-algol68-etc-cross-compiler-for-aarch64-minimal-dependencies/4590/1 "2026-07-24T14:44:24Z")

</div>

I hope this may be helpful to others. Please accept my apologies its lengthiness.

This post is for anyone interested in building an up-to-date gcc cross-compiler for aarch64 without having to wait for their linux distro. It been verified to produce running executables in 4 languages on a Raspberry Pi running Linux.

Below are a collection of small bash scripts to be run sequentially.

These build a gcc cross-compiler for aarch64 for the languages (ada, algol68, fortran, c, c++).

The approach aims for minimal dependencies, building everything from source. This also will compile glibc, and thus requires a couple of extra (but painless steps).

The first file is _ **not** _ a bash script. It needs to be “ **sourced** ” (since we need to propagate the environment variables we define herein. There are 3 env. variables you need to set to match your file placement desires: _ **$PREFIX** _, _ **$WORK** _, and _ **$FETCHED\_FILES\_DIR** _. And three more to set to define versions to build (GCC, GlibC, and Binutils).

**step\_0\_env\_variables\_and\_install\_directory**

```bash
# This must be run using "source".
echo "step_0_env_variables_and_install_directory"

# Set PREFIX - the directory in which compiled software shall reside
export PREFIX="${HOME}/my_cross_compiler"

# WORK in a temporary location for the working files used during compilation
export WORK="${HOME}/Build_Tmp_Files/my_gcc_build"

# FETCHED_FILES_DIR is a place to store fetched files, can copy files from
# here to avoid multiple downloads
export FETCHED_FILES_DIR="${HOME}/My_Fetched_Files"

# Set versions of GCC, GLIBC, and Binutils desired
export GCC_VERSION_TO_BUILD="16.1.0"
export GLIBC_VERSION_TO_BUILD="2.43"
export BINUTILS_VERSION="2.46.1"

# Create installation directory for the compiled compiler,
if [-d "$PREFIX"]; then
   echo "Installation directory: "${PREFIX}" already exists, terminating."
   echo "Either use a different PREFIX, or remove this directory and try again."
   return
fi

echo "Creating installation directory: "${PREFIX}" ..."
mkdir -p $PREFIX
export PATH=${PREFIX}"/bin:$PATH"
echo ${PREFIX}" has been added to PATH"
echo "done."

# Create clean working directory for use during compilation
if [-d "$WORK"]; then
   echo "The temporary work directory: "${WORK}" already exists."

   read -p "Shall this be nuked? (yes/no) ? " choice
   case "$choice" in
      yes ) echo "nuking ${WORK} in 3 seconds and then will be remade"; \
            sleep 3; rm -Rf ${WORK} ;;
      * ) echo "nothing deleted.";;
   esac
fi
echo "Creating temporary work directory: "${WORK}" ..."
mkdir -p $WORK
echo "done."

echo "Creating fetched files directory: "${FETCHED_FILES_DIR}" ..."
mkdir -p $FETCHED_FILES_DIR
echo "done."

# Define temporary working directory for downloads and compilation.
export BINUTILS_FILE="binutils-"${BINUTILS_VERSION}".tar.bz2"
export GCC_FILE="gcc-"${GCC_VERSION_TO_BUILD}".tar.gz"
export GLIBC_FILE="glibc-"${GLIBC_VERSION_TO_BUILD}".tar.bz2"
echo "Defined version and filenames, created directories."

```

Next is to download and extract the source files needed  
**step\_1a\_download\_and\_extract\_files.sh**

```bash
#!/bin/bash
echo "step_1a_download_and_extract_files.sh"

# exit script on any error
set -e

if [! -d "$WORK"]; then
   echo "Work directory: "${WORK}" does not exist, exiting."
   exit 1
fi
cd $WORK

if [-f ${WORK}/${BINUTILS_FILE}]; then
   echo ${BINUTILS_FILE} " already exists, not fetching."
else
   echo ". . . . . . . . . . . . . . . . . . . . . ."
   echo " attempting fetch of: " ${BINUTILS_FILE}
   wget https://ftpmirror.gnu.org/binutils/${BINUTILS_FILE}
   echo " fetched."
   tar xf ${BINUTILS_FILE}
   echo " extracted."
   mv $BINUTILS_FILE $FETCHED_FILES_DIR
   echo " moved to: ${FETCHED_FILES_DIR}"
   echo ". . . . . . . . . . . . . . . . . . . . . ."
   echo
fi

if [-f ${WORK}/${GCC_FILE}]; then
   echo ${GCC_FILE} " already exists, not fetching."
else
   echo ". . . . . . . . . . . . . . . . . . . . . ."
   echo " attempting fetch of: " ${GCC_FILE}
   wget https://ftpmirror.gnu.org/gcc/gcc-${GCC_VERSION_TO_BUILD}/${GCC_FILE}
   echo " fetched."
   tar xf ${GCC_FILE}
   echo " extracted."
   mv $GCC_FILE $FETCHED_FILES_DIR
   echo " moved to: ${FETCHED_FILES_DIR}"
   echo ". . . . . . . . . . . . . . . . . . . . . ."
   echo 
fi

if [-f ${WORK}/${GLIBC_FILE}]; then
   echo ${GLIBC_FILE} " already exists, not fetching."
else
   echo ". . . . . . . . . . . . . . . . . . . . . ."
   echo " attempting fetch of: " ${GLIBC_FILE}
   wget https://ftpmirror.gnu.org/glibc/${GLIBC_FILE}
   echo " fetched."
   tar xf ${GLIBC_FILE}
   echo " extracted."
   mv $GLIBC_FILE $FETCHED_FILES_DIR
   echo " moved to: ${FETCHED_FILES_DIR}"
   echo ". . . . . . . . . . . . . . . . . . . . . ."
fi

git clone --depth=1 https://github.com/raspberrypi/linux
   echo ". . . . . . . . . . . . . . . . . . . . . ."
   echo " raspberry pi linux cloned"
   cp -R linux $FETCHED_FILES_DIR
   echo " copied linux to: ${FETCHED_FILES_DIR}"
   echo ". . . . . . . . . . . . . . . . . . . . . ."

```

Once the files have been downloaded, you could use this next step as _ **alternative** _ to re-downloading if you ever need to re-run any build steps. (For example, if you decide to “start-over” from the beginning.)

**step\_1b\_copy\_local\_files\_and\_extract\_files.sh**

```bash
#!/bin/bash
echo "step_1b_copy_local_files_and_extract_files.sh"
# exit script on any error
set -e

if [! -d "$WORK"]; then
   echo "Work directory: "${WORK}" does not exist, exiting."
   exit 1
fi

cd $WORK

echo "extracting fetched files."
tar xf $FETCHED_FILES_DIR/$BINUTILS_FILE
tar xf $FETCHED_FILES_DIR/$GCC_FILE
tar xf $FETCHED_FILES_DIR/$GLIBC_FILE

echo "copying linux from: $FETCHED_FILES_DIR"
cp -r $FETCHED_FILES_DIR/linux .

echo "done."

```

**step\_2\_build\_binutils.sh**

```bash
#!/bin/bash
echo "step_2_build_binutils.sh"
# exit script on any error
set -e

if [! -d "$WORK"]; then
   echo "Work directory: "${WORK}" does not exist, exiting."
   exit 1
fi

cd $WORK

mkdir build-binutils
cd build-binutils

echo ${BINUITLS_VERSION}

../"binutils-"${BINUTILS_VERSION}/configure \
   --prefix=$PREFIX \
   --target=aarch64-linux-gnu \
   --disable-multilib

make -j 4
make install

```

**step\_3\_gcc\_prerequisites.sh**

```bash
#!/bin/bash
echo "step_3_gcc_prerequisites.sh"
# exit script on any error
set -e

if [! -d "$WORK"]; then
   echo "Work directory: "${WORK}" does not exist, exiting."
   exit 1
fi

cd $WORK

echo "Downloading GCC prerequisties ... "

cd "gcc-"${GCC_VERSION_TO_BUILD}
contrib/download_prerequisites
rm *.tar.*

cd $WORK

echo " ... done. "

```

**step\_4\_kernel\_headers.sh**

```bash
#!/bin/bash
echo "step_4_kernel_headers.sh"
# exit script on any error
set -e

if [! -d "$WORK"]; then
   echo "Work directory: "${WORK}" does not exist, exiting."
   exit 1
fi

cd $WORK
cd linux

KERNEL=kernel7

make ARCH=arm64 INSTALL_HDR_PATH=$PREFIX/aarch64-linux-gnu headers_install

```

**step\_5\_partial\_gcc-16.1\_build\_SEE\_NOTE.sh**

```bash
#!/bin/bash
echo "step_5_partial_gcc-16.1_build_SEE_NOTE.sh"
# exit script on any error
set -e

if [! -d "$WORK"]; then
   echo "Work directory: "${WORK}" does not exist, exiting."
   exit 1
fi
cd $WORK

echo "Configuring GCC ... "

mkdir build-gcc
cd build-gcc

../"gcc-"${GCC_VERSION_TO_BUILD}/configure \
   --prefix=$PREFIX \
   --target=aarch64-linux-gnu \
   --enable-languages=c,c++,ada,algol68,fortran \
   --enable-libada \
   --with-arch=armv8-a \
   --disable-multilib

make -j4 all-gcc
make install-gcc

echo
echo ". . . . . . . . . . . . . . . . . . . . . . . . ."
echo " NOTE: step_9_install_libada.sh (and others) is needed, because trying to"
echo " do 'make all-target-libada' at this stage would cause a compilation"
echo " complaint about pthread."
echo ". . . . . . . . . . . . . . . . . . . . . . . . ."
echo

```

**step\_6\_partial\_Glibc\_build.sh**

```bash
#!/bin/bash
echo "step_6_partial_Glibc_build.sh"
# exit script on any error
set -e

if [! -d "$WORK"]; then
   echo Work directory: $WORK does not exist, exiting.
   exit 1
fi
cd $WORK

echo "Configuring GLIBC ... "

mkdir build-glibc 
cd build-glibc

 ../glibc-2.43/configure \
    --prefix=$PREFIX/aarch64-linux-gnu \
    --build=$MACHTYPE \
    --host=aarch64-linux-gnu \
    --target=aarch64-linux-gnu \
    --with-arch=armv8-a \
    --with-headers=$PREFIX/aarch64-linux-gnu/include \
    --disable-multilib libc_cv_forced_unwind=yes

make install-bootstrap-headers=yes install-headers
make -j4 csu/subdir_lib

install csu/crt1.o csu/crti.o csu/crtn.o $PREFIX/aarch64-linux-gnu/lib

aarch64-linux-gnu-gcc \
   -nostdlib -nostartfiles -shared -x c /dev/null \
   -o $PREFIX/aarch64-linux-gnu/lib/libc.so

touch $PREFIX/aarch64-linux-gnu/include/gnu/stubs.h

```

**step\_7\_back\_to\_gcc.sh**

```bash
#!/bin/bash
echo "step_7_back_to_gcc.sh"
# exit script on any error
set -e

if [! -d "$WORK"]; then
   echo "Work directory: "${WORK}" does not exist, exiting."
   exit 1
fi

cd $WORK
cd build-gcc

make -j4 all-target-libgcc
make -j4 -C gcc cross-gnattools ada.all.cross
make -j4 install-strip-gcc install-target-libgcc

```

**step\_8\_finish\_building\_Glibc\_with\_hack\_fix.sh**

```bash
#!/bin/bash
echo "step_8_finish_building_Glibc_with_hack_fix.sh"
# exit script on any error
set -e

if [! -d "$WORK"]; then
   echo "Work directory: "${WORK}" does not exist, exiting."
   exit 1
fi

cd $WORK

# Step 8 would fail with error about "cannot find libatomic_asneeded".
# A quick hack solution avoids this by touching the expected file:
#
touch $PREFIX/aarch64-linux-gnu/lib/libatomic_asneeded.a

cd build-glibc
make -j1
make install

echo
echo ". . . . . . . . . . . . . . . . . . . . . . . . ."
echo "To avoid a compilation error, a fix hack has been performed here, namely:"
echo "touch $PREFIX/aarch64-linux-gnu/lib/libatomic_asneeded.a"
echo
echo "Everything is probably just fine."
echo ". . . . . . . . . . . . . . . . . . . . . . . . ."

```

**step\_9\_install\_libada\_libga68\_libgfortran.sh**

```bash
#!/bin/bash
echo "step_9_install_libada_libga68_libgfortran.sh"
# exit script on any error
set -e

if [! -d "$WORK"]; then
   echo "Work directory: "${WORK}" does not exist, exiting."
   exit 1
fi
cd $WORK

echo "Installing libada, libga68, libgfortran ... "

cd build-gcc

make all-target-libada 
make install-target-libada

make all-target-libga68
make install-target-libga68

make all-target-libgfortran
make install-target-libgfortran

echo "installed: libada, libga68, libgfortran."

```

If all went well, we can do a quick verification now.

**step\_10\_verify\_it\_works.sh**

```bash
#!/bin/bash
echo "step_10_verify_it_works.sh"

echo "The executables produced should work on a Raspberry Pi running linux."

echo "Compiling aarch64 c program"
$PREFIX/bin/aarch64-linux-gnu-gcc -o hello_from_c hello_from_c.c

echo "Compiling aarch64 ada program"
$PREFIX/bin/aarch64-linux-gnu-gnatmake hello_from_ada.adb

echo "Compiling aarch64 algol68 program"
$PREFIX/bin/aarch64-linux-gnu-ga68 -o hello_from_algol68 hello_from_algol68.a68

echo "Compiling aarch64 fortran program"
$PREFIX/bin/aarch64-linux-gnu-gfortran -static -o hello_from_fortran hello_from_fortran.f90

```

Which uses source files:

**hello\_from\_c.c**

```c
#include <stdio.h>

int main() {
   printf("Hello, from C!\n");
   return 0;
}

```

**hello\_from\_ada.adb**

```ada
with Ada.Text_IO; use Ada.Text_IO;

procedure hello_from_ada is
begin
  Put_Line("Hello from Ada!");
end hello_from_ada;

```

**hello\_from\_algol68.a68**

```ada
begin
  puts("Hello from Algol68!'n")
end

```

**hello\_from\_fortran.f90**

```ada
program hello_from_fortran
   print *, 'Hello from Fortran!'
end program hello_from_fortran

```
