Skip to content

Commit

Permalink
Cross compiler toolchain refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
mattjlewis committed Oct 15, 2024
1 parent db157e6 commit a8ef9c7
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 184 deletions.
6 changes: 3 additions & 3 deletions diozero-ws281x-native/cc_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ rebuild_rpi_ws281x () {

echo "ARMv6"
old_path=${PATH}
PATH=${PI_GCC_TARGET_DIR}/bin:${PATH} && scons V=yes TOOLCHAIN=arm-linux-gnueabihf CFLAGS="-march=armv6 -mfloat-abi=hard"
sudo mv libws2811.a ${PI_GCC_TARGET_DIR}/arm-linux-gnueabihf/lib/.
PATH=${PI_CC_TARGET_DIR}/bin:${PATH} && scons V=yes TOOLCHAIN=arm-linux-gnueabihf CFLAGS="-march=armv6 -mfloat-abi=hard"
sudo mv libws2811.a ${PI_CC_TARGET_DIR}/arm-linux-gnueabihf/lib/.
PATH=${old_path}
}

Expand Down Expand Up @@ -56,7 +56,7 @@ echo
# Finally build ARMv6 to be extra sure that PATH has no reference to the Pi ARMv6 cross compiler
echo "Compiling for ARMv6"
OLD_PATH=${PATH}
PATH=${PI_GCC_TARGET_DIR}/bin:${PATH} && make clean && make CROSS_PREFIX=arm-linux-gnueabihf- CFLAGS="-mfpu=vfp -mfloat-abi=hard -march=armv6" RPI_WS281X_DIR=/home/develop/rpi_ws281x
PATH=${PI_CC_TARGET_DIR}/bin:${PATH} && make clean && make CROSS_PREFIX=arm-linux-gnueabihf- CFLAGS="-mfpu=vfp -mfloat-abi=hard -march=armv6" RPI_WS281X_DIR=/home/develop/rpi_ws281x
if [ $? -eq 0 ]; then
TARGET=${LIB_DIR}/linux-armv6 && mkdir -p ${TARGET} && mv ${LIB_NAME} ${TARGET}/.
make clean
Expand Down
19 changes: 9 additions & 10 deletions diozero-ws281x-native/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
FROM diozero/diozero-cc

ARG HOME_DIR=/home/${RUN_AS_USER}

RUN sudo apt-get update && sudo apt-get -y install scons

#RUN sudo apt-get -y install python3-distutils

WORKDIR ${CC_HOME_DIR}
RUN git clone https://github.com/jgarff/rpi_ws281x.git --depth 1
WORKDIR ${HOME_DIR}/rpi_ws281x
WORKDIR ${CC_HOME_DIR}/rpi_ws281x

# aarch64
RUN scons V=yes TOOLCHAIN=aarch64-linux-gnu CFLAGS="-march=armv8-a"
Expand All @@ -21,11 +20,11 @@ RUN scons V=yes TOOLCHAIN=arm-linux-gnueabihf CFLAGS="-march=armv7"
RUN sudo mv libws2811.a /usr/lib/arm-linux-gnueabihf/.

# armv6 - building this last out of paranoia to ensure PATH isn't modified
RUN PATH=${PI_GCC_TARGET_DIR}/bin:${PATH} && scons V=yes TOOLCHAIN=arm-linux-gnueabihf CFLAGS="-march=armv6 -mfloat-abi=hard"
#RUN PATH=${PI_GCC_TARGET_DIR}/bin:${PATH} \
RUN PATH=${PI_CC_TARGET_DIR}/bin:${PATH} && scons V=yes TOOLCHAIN=arm-linux-gnueabihf CFLAGS="-march=armv6 -mfloat-abi=hard"
#RUN PATH=${PI_CC_TARGET_DIR}/bin:${PATH} \
# && make clean && make CROSS_PREFIX=arm-linux-gnueabihf- \
# CFLAGS="-march=armv6 -mfpu=vfp -mfloat-abi=hard" PREFIX=${PI_GCC_TARGET_DIR} \
# && sudo make install DESTDIR=${PI_GCC_TARGET_DIR}/arm-linux-gnueabihf
RUN sudo mv libws2811.a ${PI_GCC_TARGET_DIR}/arm-linux-gnueabihf/lib/.
# CFLAGS="-march=armv6 -mfpu=vfp -mfloat-abi=hard" PREFIX=${PI_CC_TARGET_DIR} \
# && sudo make install DESTDIR=${PI_CC_TARGET_DIR}/arm-linux-gnueabihf
RUN sudo mv libws2811.a ${PI_CC_TARGET_DIR}/arm-linux-gnueabihf/lib/.

WORKDIR ${HOME_DIR}
WORKDIR ${CC_HOME_DIR}
1 change: 1 addition & 0 deletions diozero-ws281x-native/docker/build.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/bin/sh

BUILDAH_LAYERS="false"
podman build --rm -t diozero/diozero-ws281x-cc .
53 changes: 42 additions & 11 deletions docker/diozero-cc-base/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,53 @@ FROM debian:buster

ARG DEBIAN_FRONTEND=noninteractive

# Install some tools and compilers + clean up
RUN apt-get update && apt-get -y upgrade && \
apt-get install -y sudo git wget build-essential gawk texinfo bison file \
# Update packages
RUN apt-get update && apt-get -y upgrade
# Install required tools and compilers
RUN apt-get install -y sudo git wget build-essential gawk texinfo bison file \
gcc g++ gcc-8 g++-8 make cmake autoconf automake \
bzip2 python python3 rsync libtool libtool-bin i2c-tools libi2c-dev && \
apt-get clean autoclean && apt-get autoremove -y

bzip2 python python3 rsync libtool libtool-bin i2c-tools libi2c-dev
# Generic cross-compilation toolchain
RUN sudo apt-get update && apt-get -y install build-essential lib32z1 \
RUN apt-get -y install build-essential lib32z1 \
gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf binutils-aarch64-linux-gnu binutils-arm-linux-gnueabihf \
crossbuild-essential-arm64 crossbuild-essential-armhf
crossbuild-essential-arm64 crossbuild-essential-armhf zlib1g-dev
# Cleanup
RUN apt-get clean autoclean && apt-get autoremove -y

# Enable x86
RUN sudo dpkg --add-architecture i386
RUN sudo apt-get update && apt-get -y install libstdc++6:i386 libgcc1:i386 zlib1g:i386
RUN dpkg --add-architecture i386
RUN apt-get update && apt-get -y install libstdc++6:i386 libgcc1:i386 zlib1g:i386

# Install JDK 11
RUN sudo apt-get update && apt-get -y install openjdk-11-jdk-headless
RUN apt-get update && apt-get -y install openjdk-11-jdk-headless
ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

ENV PI_CC_TARGET_DIR=/opt/pi_cross_compiler

# Create the folder in which we’ll put the Pi cross compiler
RUN mkdir -p ${PI_CC_TARGET_DIR}

# Install the Raspberry Pi Linux headers
RUN git clone --depth=1 https://github.com/raspberrypi/linux
# Target architecture
ARG TARGET=arm-linux-gnueabihf
RUN cd linux && make ARCH=arm KERNEL=kernel7 INSTALL_HDR_PATH=${PI_CC_TARGET_DIR}/${TARGET} headers_install
# Cleanup
RUN rm -rf ./linux

# Environment variables
ENV RUN_AS_USER=develop
ENV CC_HOME_DIR=/home/${RUN_AS_USER}
# Working directory for building GCC
ENV BUILD_WORKING_DIR=${CC_HOME_DIR}/build

# Add a user so that we don't run as root
RUN useradd -m ${RUN_AS_USER} && echo "${RUN_AS_USER}:${RUN_AS_USER}" | chpasswd && adduser ${RUN_AS_USER} sudo
RUN echo "${RUN_AS_USER} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/01_${RUN_AS_USER}-nopasswd

# Switch to the non-root user
USER ${RUN_AS_USER}

# Working directory
RUN mkdir -p ${BUILD_WORKING_DIR}
WORKDIR ${BUILD_WORKING_DIR}
1 change: 1 addition & 0 deletions docker/diozero-cc-base/build.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/bin/sh

export BUILDAH_LAYERS="false"
podman build --rm -t diozero/diozero-cc-base .
124 changes: 124 additions & 0 deletions docker/diozero-cc-gcc/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
FROM diozero/diozero-cc-base

# Original instructions: https://solarianprogrammer.com/2018/05/06/building-gcc-cross-compiler-raspberry-pi/

# These should match the versions on the Raspberry Pi
# Now 2.31 on Pi Bullseye image as of Aug 2022
ARG GLIBC_VERSION=glibc-2.29
# Now 2.35.2 on Pi Bullseye image as of Aug 2022
ARG BINUTILS_VERSION=binutils-2.31.1
# Now 10.2.1 on Pi Bullseye image as of Aug 2022
ARG GCC_VERSION=gcc-8.3.0
# Target architecture to compile for
ARG TARGET=arm-linux-gnueabihf
# Number of jobs value to pass the make -j command
ARG MAKE_JOBS=4

# Use GCC 8 as the default compiler otherwise there will be compilation errors
RUN sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 999 && \
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 999 && \
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-8 999 && \
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-8 999

# Save the current PATH variable value, ensure that the cross compiler is first in the PATH
ARG OLD_PATH=${PATH}
ENV PATH=${PI_CC_TARGET_DIR}/bin:$PATH

# Download and extract LibC
RUN wget -q -O - https://ftp.gnu.org/gnu/libc/${GLIBC_VERSION}.tar.bz2 | tar xj
# Download and extract Binutils
RUN wget -q -O - https://ftp.gnu.org/gnu/binutils/${BINUTILS_VERSION}.tar.bz2 | tar xj
# Download and extract GCC
RUN wget -q -O - https://ftp.gnu.org/gnu/gcc/${GCC_VERSION}/${GCC_VERSION}.tar.gz | tar xz
# Download the GCC prerequisites
RUN cd ${GCC_VERSION} && contrib/download_prerequisites && rm *.tar.*

# Build Binutils
RUN mkdir -p ${BUILD_WORKING_DIR}/build-binutils
WORKDIR ${BUILD_WORKING_DIR}/build-binutils
RUN ../${BINUTILS_VERSION}/configure \
--prefix=${PI_CC_TARGET_DIR} \
--with-arch=armv6 --with-fpu=vfp --with-float=hard \
--target=${TARGET} \
--disable-multilib
RUN make -j${MAKE_JOBS}
RUN sudo make install

# Build the first part of GCC
RUN mkdir -p ${BUILD_WORKING_DIR}/build-gcc
WORKDIR ${BUILD_WORKING_DIR}/build-gcc
# Fixing limits.h: https://stackoverflow.com/questions/58199020/locally-built-gcc-cross-compiler-reports-mb-len-max-wrong-with-d-fortify-source
#WORKDIR ${GCC_VERSION}
#RUN cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
# `dirname $(${TARGET}-gcc -print-libgcc-file-name)`/include-fixed/limits.h
# Removed: --enable-bootstrap
RUN ../${GCC_VERSION}/configure \
--prefix=${PI_CC_TARGET_DIR} \
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=${TARGET} \
--enable-languages=c,c++ \
--with-arch=armv6 --with-fpu=vfp --with-float=hard \
--disable-multilib \
--with-headers=${PI_CC_TARGET_DIR}/${TARGET}/include/linux \
--program-prefix=${TARGET}- \
--with-gcc-major-version-only \
--enable-shared --enable-linker-build-id \
--without-included-gettext --enable-threads=posix \
--enable-nls --enable-clocale=gnu --enable-libstdcxx-debug \
--enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object \
--enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib \
--disable-libitm --disable-libquadmath --disable-libquadmath-support --disable-sjlj-exceptions \
--disable-werror --enable-checking=release \
--libdir=${PI_CC_TARGET_DIR}/${TARGET}/lib
RUN make -j${MAKE_JOBS} all-gcc
RUN sudo make install-gcc
# https://stackoverflow.com/questions/44419593/gcc-4-9-4-cross-compiler-build-limits-h-issue
RUN sudo rm -rf ${PI_CC_TARGET_DIR}/${TARGET}/sys-include

# Build GLIBC
RUN mkdir -p ${BUILD_WORKING_DIR}/build-glibc
WORKDIR ${BUILD_WORKING_DIR}/build-glibc
RUN ../${GLIBC_VERSION}/configure \
--prefix=${PI_CC_TARGET_DIR}/${TARGET} \
--build=x86_64-linux-gnu --host=${TARGET} --target=${TARGET} \
--with-arch=armv6 --with-fpu=vfp --with-float=hard \
--with-headers=${PI_CC_TARGET_DIR}/${TARGET}/include \
--disable-multilib libc_cv_forced_unwind=yes
RUN sudo make install-bootstrap-headers=yes install-headers
# Cludge - fix file permissions from the above command
RUN sudo chown -R ${RUN_AS_USER}:users .
RUN make -j${MAKE_JOBS} csu/subdir_lib
RUN sudo install csu/crt1.o csu/crti.o csu/crtn.o ${PI_CC_TARGET_DIR}/${TARGET}/lib
RUN sudo ${TARGET}-gcc -nostdlib -nostartfiles -shared -x c /dev/null \
-o ${PI_CC_TARGET_DIR}/${TARGET}/lib/libc.so
RUN sudo touch ${PI_CC_TARGET_DIR}/${TARGET}/include/gnu/stubs.h

# Continue building GCC
WORKDIR ${BUILD_WORKING_DIR}/build-gcc
RUN make -j${MAKE_JOBS} all-target-libgcc
RUN sudo make install-target-libgcc

# Finish building GLIBC
WORKDIR ${BUILD_WORKING_DIR}/build-glibc
RUN make -j${MAKE_JOBS}
RUN sudo make install

# Finish building GCC
WORKDIR ${BUILD_WORKING_DIR}/build-gcc
RUN make -j${MAKE_JOBS}
RUN sudo make install

# FIXME Fix the limits.h header file. Why is the cross-compiler one missing some info?
# https://stackoverflow.com/questions/44419593/gcc-4-9-4-cross-compiler-build-limits-h-issue
RUN sudo cp /usr/lib/gcc-cross/arm-linux-gnueabihf/8/include-fixed/limits.h ${PI_CC_TARGET_DIR}/arm-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/8/include-fixed/limits.h

# Cleanup
WORKDIR ${CC_HOME_DIR}
RUN rm -rf ${BUILD_WORKING_DIR}/build-binutils
RUN rm -rf ${BUILD_WORKING_DIR}/${BINUTILS_VERSION}
RUN rm -rf ${BUILD_WORKING_DIR}/build-glibc
RUN rm -rf ${BUILD_WORKING_DIR}/${GLIBC_VERSION}
RUN rm -rf ${BUILD_WORKING_DIR}/build-gcc
RUN rm -rf ${BUILD_WORKING_DIR}/${GCC_VERSION}

# Restore the old path value
ENV PATH=${OLD_PATH}
4 changes: 4 additions & 0 deletions docker/diozero-cc-gcc/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh

export BUILDAH_LAYERS="false"
podman build --rm -t diozero/diozero-cc-gcc .
Loading

0 comments on commit a8ef9c7

Please sign in to comment.