Wiki Cross Compilation
Cross Compilation Anatomy
Cross-Compilation ecosystem involves the following components:
- host system
- cross-Compilation toolchain
- cross compiler
- cross linker
- cross debugger
- sysroot
- target system library files
- target system header files
- target system other files
- cross-Compilation toolchain
- target system
Cross-Compilation toolchain:
- GCC
- Buildroot
- Yocto Project
- Crosstool-NG
- Linaro
- Clang/LLVM
GCC
Let's explore what a toolchain is like and what are needed to build something for a aarch64
platform on x86_64
debian-like host.
Obtaining a cross-compilation toolchain for aarch64
For simplicity and in a super fast way, we will use a prebuilt and ready-on toolchain in x86_64
Ubuntu.
apt install gcc make gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu
Where is cross compiler
We see cross compiler
binary type in host is x86-64
,
$ file /usr/bin/aarch64-linux-gnu-gcc-11
/usr/bin/aarch64-linux-gnu-gcc-11: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=b1112487d0dcb759db32e15b8f40f28a05484272, for GNU/Linux 3.2.0, stripped
Where is sysroot
The sysroot
locates in /usr/aarch64-linux-gnu
,
$ tree --filelimit=100 /usr/aarch64-linux-gnu
/usr/aarch64-linux-gnu
├── bin
│ ├── ar -> ../../bin/aarch64-linux-gnu-ar
│ ├── as -> ../../bin/aarch64-linux-gnu-as
│ ├── ld -> ../../bin/aarch64-linux-gnu-ld
│ ├── ld.bfd -> ../../bin/aarch64-linux-gnu-ld.bfd
│ ├── ld.gold -> ../../bin/aarch64-linux-gnu-ld.gold
│ ├── nm -> ../../bin/aarch64-linux-gnu-nm
│ ├── objcopy -> ../../bin/aarch64-linux-gnu-objcopy
│ ├── objdump -> ../../bin/aarch64-linux-gnu-objdump
│ ├── ranlib -> ../../bin/aarch64-linux-gnu-ranlib
│ ├── readelf -> ../../bin/aarch64-linux-gnu-readelf
│ └── strip -> ../../bin/aarch64-linux-gnu-strip
├── include [139 entries exceeds filelimit, not opening dir]
└── lib
├── Mcrt1.o
├── Scrt1.o
├── crt1.o
├── crti.o
├── crtn.o
├── gcrt1.o
├── grcrt1.o
├── ld-linux-aarch64.so.1
As you see, the binutils-aarch64-linux-gnu
will install binutils
tools in /usr/aarch64-linux-gnu/bin
,
These binutils
are also x86_64
binaries,
file $(readlink -f /usr/aarch64-linux-gnu/bin/ar)
/usr/bin/aarch64-linux-gnu-ar: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=4f75b6dc6fe5ae92c78a51e6479ca2c65bbf5335, for GNU/Linux 3.2.0, stripped
While target libraries are aarch64
type,
file /usr/aarch64-linux-gnu/lib/crt1.o
/usr/aarch64-linux-gnu/lib/crt1.o: ELF 64-bit LSB relocatable, ARM aarch64, version 1 (SYSV), for GNU/Linux 3.7.0, not stripped
Compile hello.c
$ aarch64-linux-gnu-gcc-11 hello.c -o a.out
$ file a.out
a.out: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=367c436db0697f16039d9249e4a4e809ef9e68b3, for GNU/Linux 3.7.0, not stripped
Clang/LLVM
Cross compilation with Clang and LLVM tools
Cross compiling made easy, using Clang and LLVM · mcilloni's blog
apt install lld clang llvm
$ wget https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/aarch64-linux-gnu/sysroot-glibc-linaro-2.25-2019.12-aarch64-linux-gnu.tar.xz
$ tar -xvf sysroot-glibc-linaro-2.25-2019.12-aarch64-linux-gnu.tar.xz
$ mv sysroot-glibc-linaro-2.25-2019.12-aarch64-linux-gnu aarch64-linux-gnu
$ ll aarch64-linux-gnu
total 20K
drwxr-xr-x 2 11827 9000 4.0K Dec 4 2019 etc
drwxr-xr-x 3 11827 9000 4.0K Dec 4 2019 lib
drwxr-xr-x 2 11827 9000 4.0K Dec 4 2019 sbin
drwxr-xr-x 8 11827 9000 4.0K Dec 4 2019 usr
drwxr-xr-x 3 11827 9000 4.0K Dec 4 2019 var
$ cat > hello.c << EOL
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("Hello cross-compilation world!\n");
return 0;
}
EOL
sysroot=~/Documents/sysroot/aarch64-linux-gnu/usr
clang --target=aarch64-linux-gnu hello.c -o hello_aarch64 -v
clang --target=aarch64-linux-gnu hello.c -o hello_aarch64 --sysroot=$sysroot -v
clang --target=aarch64-linux-gnu -fsanitize=undefined \
-fuse-ld=lld \
--rtlib=compiler-rt -stdlib=libc++ \
-nostdinc++ -nostdlib \
-I${sysroot}/usr/include/ \
-Wl,-L${sysroot}/usr/lib \
--sysroot=$sysroot \
--verbose \
hello.c -o hello
Resources
https://wiki.osdev.org/GCC_Cross-Compiler
https://github.com/generia/buildroot-osx
https://crosstool-ng.github.io/docs/
https://github.com/messense/homebrew-macos-cross-toolchains/blob/main/.github/workflows/aarch64.yml