Skip to content

Instantly share code, notes, and snippets.

@ivakyb
Last active January 24, 2024 22:19
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ivakyb/6d6d8aa3766b3ed1807cfd2a214b516e to your computer and use it in GitHub Desktop.
Save ivakyb/6d6d8aa3766b3ed1807cfd2a214b516e to your computer and use it in GitHub Desktop.
Build Linaro toolchain for Mac

Build Linaro for Mac

1. Prepare env


Abe requires Bash version 4+.

brew install bash autogen dejagnu coreutils gcc gawk #binutils
#brew install libmpc gmp mpf

for ubuntu apt install flex bison autogen texinfo gawk zlib1g-dev libncurses5-dev libpython2.7-dev dejagnu gcc g++ wget curl make automake rsync python expect

gcc 7 doesn’t compile with guile 2.2, so you have to downgrade it:

brew uninstall --ignore-dependencies guile
brew install guile@2.0

Be aware that guile will live /usr/local/opt/guile@2.0 and you need additional actions to move it to /usr/local

export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
==> Caveats
guile@2.0 is keg-only, which means it was not symlinked into /usr/local,
because this is an alternate version of another formula.

If you need to have guile@2.0 first in your PATH run:
  echo 'export PATH="/usr/local/opt/guile@2.0/bin:$PATH"' >> ~/.bash_profile

For compilers to find guile@2.0 you may need to set:
  export LDFLAGS="-L/usr/local/opt/guile@2.0/lib"
  export CPPFLAGS="-I/usr/local/opt/guile@2.0/include"

For pkg-config to find guile@2.0 you may need to set:
  export PKG_CONFIG_PATH="/usr/local/opt/guile@2.0/lib/pkgconfi

date: illegal option -- -

ln -s gdate /usr/local/bin/date

If you met error about epsond git-new-workdir fix it with

curl -L https://raw.githubusercontent.com/git/git/master/contrib/workdir/git-new-workdir >/usr/local/bin/git-new-workdir && chmod +x /usr/local/bin/git-new-workdir 

GCC built by Homebrew adds /usr/local/bin/gcc-8 but not gcc

cd /usr/local/bin
ln -s c++-8 c++
ln -s cpp-8 cpp
ln -s g++-8 g++
ln -s gcc-8 gcc
ln -s gcc-ar-8 gcc-ar
ln -s gcc-nm-8 gcc-nm
ln -s gcc-ranlib-8 gcc-ranlib
ln -s gcov-8 gcov
ln -s gcov-dump-8 gcov-dump
ln -s gcov-tool-8 gcov-tool
#ln -s gfortran-8 gfortran
  1. Get ABE

git clone https://git.linaro.org/toolchain/abe.git --depth 1 --single-branch -b master
cd abe

Make sure /bin/sh and /bin/bash are pointing to /usr/local/bin/bash or modify shebangs in scripts.
On MacOS /bin/bash is very old version 3.2.57 (2007).
Modify shebangs in Abe's Bash scripts:

find . -name '*.sh' -type f -print0 | xargs -0 sed -i '' -e 's|#!/bin/bash|#!/usr/bin/env bash|g' -e 's|#!/bin/sh|#!/usr/bin/env bash|g'

Note: '' after -i is required for old default MacOS's sed and not for newer GNU sed.

Prepare build

cd ..
mkdir build
cd build
../abe/configure

For 5.2:

Open /abe/config/sources.conf and change gcc url to ‘http://snapshots.linaro.org/components/toolchain/gcc-linaro/5.2-2015.11’

Build

look at this link or the similar one for other version you’re interested in xxx_revision and xxx_filespec values, replace then in following command if needed

$ ../abe/abe.sh --target arm-linux-gnueabihf gcc=gcc.git@5104f2473987407575bfc63ee965394252433bb5 binutils=binutils-gdb.git@e0f59b0a7b5a2d879b0afc665ca0f28fb5b3d54e glibc=glibc.git@02aaa3c749bf18a3dbafff4c1f0180f135cad7ed --release 2017.08 --tarbin --build all

#  we probably should replace --build all with --checkout all in previous command:
$ ../abe/abe.sh --target arm-linux-gnueabihf gcc=gcc.git@5104f2473987407575bfc63ee965394252433bb5 binutils=binutils-gdb.git@e0f59b0a7b5a2d879b0afc665ca0f28fb5b3d54e glibc=glibc.git@02aaa3c749bf18a3dbafff4c1f0180f135cad7ed --release 2017.08 --tarbin --checkout all

For 5.2:

../abe/abe.sh --target arm-linux-gnueabihf gcc=gcc-linaro-snapshot-5.2-2015.11.tar.xz binutils=binutils-gdb.git@ef90a4718f535cbe6345b4e7168baea7b1972abf glibc=glibc.git@dbcaca73cb0a19698ea1b424087e8997a9b7c3c4 --release 2015.11 --tarbin --checkout all

# you should fail :D
# patch ./snapshots/glibc.git~master_rev_<revision>/sunrpc/Makefile: add “BUILD_LDFLAGS += -L/usr/local/lib -lintl” near BUILD_ CPPFLAGS
# restart build without downloading
$ ../abe/abe.sh --disable update --target arm-linux-gnueabihf gcc=gcc.git@5104f2473987407575bfc63ee965394252433bb5 binutils=binutils-gdb.git@e0f59b0a7b5a2d879b0afc665ca0f28fb5b3d54e glibc=glibc.git@02aaa3c749bf18a3dbafff4c1f0180f135cad7ed --release 2017.08 --tarbin --build all

For 5.2

../abe/abe.sh --disable update --target arm-linux-gnueabihf gcc=gcc-linaro-snapshot-5.2-2015.11.tar.xz binutils=binutils-gdb.git@ef90a4718f535cbe6345b4e7168baea7b1972abf glibc=glibc.git@dbcaca73cb0a19698ea1b424087e8997a9b7c3c4 --release 2015.11 --tarbin --build all

For 5.2

You should fail

Open ‘builds/<host_arch>/binutils<revision>/gold/Makefile’ or `/snapshots/binutils-gdb.git~master_rev_<revision>/gold/Makefile.in` and add ‘diststuff: $(EXTRA_DIST) info’ to line ~1331

For 5.2

Goto makefiles and replace this:

gperf -o -C -E -k '1-6,$$' -j1 -D -N 'libc_name_p' -L ANSI-C

to this:

gperf -o -C -E -k '1-6,$$' -j1 -D -N 'libc_name_p' -L C++

LINKS

  1. https://vivinuthappa.wordpress.com/articles/build-from-source-an-official-release-of-linaro-toolchain/
  2. https://wiki.linaro.org/ABE
  3. https://wiki.osdev.org/GCC_Cross-Compiler
  4. https://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/
  5. https://solarianprogrammer.com/2018/05/06/building-gcc-cross-compiler-raspberry-pi/
  6. https://www.linux.com/blog/cross-compiling-arm
  7. https://solarianprogrammer.com/2017/05/21/compiling-gcc-macos/
  8. https://wiki.linaro.org/WorkingGroups/ToolChain/FAQ
  9. http://www.linuxfromscratch.org/lfs/view/development/index.html
  10. https://releases.linaro.org/components/toolchain/gcc-linaro/
  11. https://wiki.linaro.org/Toolchain
  12. https://docs.google.com/document/d/1CL6u_NXTDDEXnie64JDKkjcKCTyNDh_3IFTg06bpACY/edit# by Max Lepekh
  13. https://git.linaro.org
  14. https://releases.linaro.org/components/toolchain/gcc-linaro/
  15. https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloads

Building Cross Compiler

  1. Environment

    export TARGET=arm-linux-gnueabihf
    export CROSS_PREFIX=/opt/crosstools/$TARGET
    mkdir -p $CROSS_PREFIX
    mkdir ~/src ~/build

  1. Build binutils - pass 1

    cd ~/src
    git clone git://sourceware.org/git/binutils-gdb.git --depth 1 --single-branch -b binutils-2_32

    mkdir -p ~/build/binutils-$TARGET
    cd $_
    ~/src/binutils-gdb/configure  \
        --prefix=/opt/crosstools/$TARGET  \
        --target=$TARGET  \
        --disable-nls  \
        --disable-werror  \
        --with-lib-path=/opt/crosstools/arm-linux-gnueabihf/lib  \
        --with-sysroot=/opt/crosstools/arm-linux-gnueabihf/SYSROOT
    make -sj$(nproc)
    make install

  1. Build GCC-8.3.0 - pass 1

    cd ~/src
    git clone git://gcc.gnu.org/git/gcc.git --depth 1 --single-branch -b gcc-8_3_0-release
    cd gcc
    curl -L ftp://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.1.0.tar.bz2 | tar xf -
    curl -L ftp://gcc.gnu.org/pub/gcc/infrastructure/mpfr-3.1.4.tar.bz2 | tar xf -
    curl -L ftp://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.0.3.tar.gz | tar xf -
    curl -L ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.18.tar.bz2 | tar xf -

http://www.linuxfromscratch.org/lfs/view/development/chapter05/gcc-pass1.html tell about fixes in configuration header for cross-compilation.

OR

    cd ~/src
    curl -LO https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-a/8.2-2019.01/gcc-arm-src-snapshot-8.2-2019.01.tar.xz
    tar -xf gcc-arm-src-snapshot-8.2-2019.01.tar.xz
    cd gcc-arm-src-snapshot-8.2-2019.01

Prepare GCC for compilation:

    mkdir -p ~/build/gcc-arm-linux-gnueabihf
    cd $_
    ~/src/gcc/configure                              \
        --target=arm-linux-gnueabihf                   \
        --prefix=/opt/crosstools/arm-linux-gnueabihf   \
        --disable-nls                                  \
        --with-glibc-version=2.11                      \
        --with-newlib                                  \
        --without-headers                              \
        --disable-shared                               \
        --disable-multilib                             \
        --disable-decimal-float                        \
        --disable-threads                              \
        --disable-libatomic                            \
        --disable-libgomp                              \
        --disable-libmpx                               \
        --disable-libquadmath                          \
        --disable-libssp                               \
        --disable-libvtv                               \
        --disable-libstdcxx                            \
        --enable-languages=c,c++                       \
        --with-local-prefix=/opt/crosstools/arm-linux-gnueabihf                     \
        --with-native-system-header-dir=/opt/crosstools/arm-linux-gnueabihf/include \
        --with-sysroot=/opt/crosstools/arm-linux-gnueabihf/SYSROOT

The meaning of the configure options:

  • --with-newlib
    Since a working C library is not yet available, this ensures that the inhibit_libc constant is defined when building libgcc. This prevents the compiling of any code that requires libc support.
  • --without-headers
    When creating a complete cross-compiler, GCC requires standard headers compatible with the target system. For our purposes these headers will not be needed. This switch prevents GCC from looking for them.
  • --with-local-prefix=/tools
    The local prefix is the location in the system that GCC will search for locally installed include files. The default is /usr/local. Setting this to /tools helps keep the host location of /usr/local out of this GCC's search path.
  • --with-native-system-header-dir=/tools/include
    By default GCC searches /usr/include for system headers. In conjunction with the sysroot switch, this would normally translate to $LFS/usr/include. However the headers that will be installed in the next two sections will go to $LFS/tools/include. This switch ensures that gcc will find them correctly. In the second pass of GCC, this same switch will ensure that no headers from the host system are found.
  • --disable-shared
    This switch forces GCC to link its internal libraries statically. We do this to avoid possible issues with the host system.
  • --disable-decimal-float, --disable-threads, --disable-libatomic, --disable-libgomp, --disable-libmpx, --disable-libquadmath, --disable-libssp, --disable-libvtv, --disable-libstdcxx
    These switches disable support for the decimal floating point extension, threading, libatomic, libgomp (Gnu OpenMP), libmpx, libquadmath, libssp (Stack Smashing Protector https://wiki.osdev.org/Stack_Smashing_Protector), libvtv, and the C++ standard library respectively. These features will fail to compile when building a cross-compiler and are not necessary for the task of cross-compiling the temporary libc.
  • --disable-multilib
    On x86_64, LFS does not yet support a multilib configuration. This switch is harmless for x86.
  • --enable-languages=c,c++
    This option ensures that only the C and C++ compilers are built. These are the only languages needed now.
    make -sj$(nproc)
    make install

  1. Linux-3.10 headers

cd ~/src
cp -r /amba-sdk/ambarella/kernel/linux-3.10 ~/src/
cd linux-3.10
make mrproper
make INSTALL_HDR_PATH=dest headers_install
cp -rv dest/include/* /opt/crosstools/arm-linux-gnueabihf/include/

  1. glibc-2.29

cd ~/src
git clone git://sourceware.org/git/glibc.git --depth 1 --single-branch -b glibc-2.29
mkdir -p ~/build/glibc-arm-linux-gnueabihf
cd $_
~/src/glibc/configure  \
    --prefix=/opt/crosstools/arm-linux-gnueabihf  \
    --host=arm-linux-gnueabihf  \
    --enable-kernel=3.10  \
    --with-headers=/opt/crosstools/arm-linux-gnueabihf/include

LINKS

Linux From Scratch - Version SVN-20190312

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment