diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..4541204 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,251 @@ +# Contributing + +## Getting started + +## How to add a new image ? (With crosstool-ng) + +In this part, we will see how to add a new image, we will take example with `linux-arm64` for a raspberry pi 4, with [crosstool-ng](https://github.com/crosstool-ng/crosstool-ng). + +### Build and config crosstool-ng + +To start, you need to download the source code of crosstool-ng: + +```bash +git clone --recurse-submodules --remote-submodules https://github.com/crosstool-ng/crosstool-ng.git +``` + +Go to crosstool-ng folder: + +```bash +cd crosstool-ng +``` + +Change git branch: + +```bash +git checkout crosstool-ng-1.25.0 +``` + +Once in the **crosstool-ng** folder, you must first run the **bootstrap** script: + +```bash +./bootstrap +``` + +Then run the **configure** script: + +*Note: ***--enable-local*** Do a portable install of crosstool-ng.*: + +```bash +./configure --enable-local +``` + +Finally, launch the building of crosstool-ng: + +```bash +make -j$(nproc) +``` + +Once the crosstool-ng build is complete, you can run this command to test crosstool-ng: + +```bash +./ct-ng --version +``` + +Before starting the configuration of the toolchains, i recommend you to use one of the examples from crosstool-ng and then make your changes, the command to display the examples: + +```bash +./ct-ng list-samples +``` + +We will take the example of **aarch64-rpi4-linux-gnu**, a **.config** file will be created: + +```bash +./ct-ng aarch64-rpi4-linux-gnu +``` + +We will configure the toolchains according to our needs: + +```bash +./ct-ng menuconfig +``` + +Once the modifications are made, we will display the name of the toolchains, it will be useful later: + +```bash +./ct-ng show-tuple +``` + +### Configuring docker image + +You must create a file with the **same** name of the docker image (**linux-arm64**). + +Copy the **.config** of crosstool-ng to this file (**linux-arm64**) and rename it to **crosstool-ng.config**. + +You need to create a file named **Toolchain.cmake** in **linux-arm64**. + +Copy text to **Toolchain.cmake** file: + +```cmake +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_VERSION 1) +set(CMAKE_SYSTEM_PROCESSOR ARM64) + +set(cross_triple $ENV{CROSS_TRIPLE}) +set(cross_root $ENV{CROSS_ROOT}) + +set(CMAKE_C_COMPILER $ENV{CC}) +set(CMAKE_CXX_COMPILER $ENV{CXX}) +set(CMAKE_Fortran_COMPILER $ENV{FC}) + +set(CMAKE_CXX_FLAGS "-I ${cross_root}/include/") + +set(CMAKE_FIND_ROOT_PATH ${cross_root} ${cross_root}/${cross_triple}) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) +set(CMAKE_SYSROOT ${cross_root}/${cross_triple}/sysroot) + +set(CMAKE_CROSSCOMPILING_EMULATOR /usr/bin/qemu-arm64) +``` + +Then ou must change these lines according to the targeted architecture, here **ARM64**: + +```cmake +set(CMAKE_SYSTEM_PROCESSOR ARM64) +set(CMAKE_CROSSCOMPILING_EMULATOR /usr/bin/qemu-arm64) +``` + +Then you must create a file named **Dockerfile.in** in the image folder (**linux-arm64**). + +Copy text to **Dockerfile.in** file: + +```docker +FROM dockcross/base:latest + +LABEL maintainer="Matt McCormick matt.mccormick@kitware.com" + +# This is for 64-bit ARM Linux machine + +# Crosstool-ng crosstool-ng-1.25.0 2022-05-13 +ENV CT_VERSION crosstool-ng-1.25.0 + +#include "common.crosstool" + +# The cross-compiling emulator +RUN apt-get update \ +&& apt-get install -y \ + qemu-user \ + qemu-user-static \ +&& apt-get clean --yes + +# The CROSS_TRIPLE is a configured alias of the "aarch64-unknown-linux-gnu" target. +ENV CROSS_TRIPLE aarch64-unknown-linux-gnu + +ENV CROSS_ROOT ${XCC_PREFIX}/${CROSS_TRIPLE} +ENV AS=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-as \ + AR=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-ar \ + CC=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-gcc \ + CPP=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-cpp \ + CXX=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-g++ \ + LD=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-ld \ + FC=${CROSS_ROOT}/bin/${CROSS_TRIPLE}-gfortran + +ENV QEMU_LD_PREFIX "${CROSS_ROOT}/${CROSS_TRIPLE}/sysroot" +ENV QEMU_SET_ENV "LD_LIBRARY_PATH=${CROSS_ROOT}/lib:${QEMU_LD_PREFIX}" + +COPY Toolchain.cmake ${CROSS_ROOT}/ +ENV CMAKE_TOOLCHAIN_FILE ${CROSS_ROOT}/Toolchain.cmake + +ENV PKG_CONFIG_PATH /usr/lib/aarch64-linux-gnu/pkgconfig + +# Linux kernel cross compilation variables +ENV PATH ${PATH}:${CROSS_ROOT}/bin +ENV CROSS_COMPILE ${CROSS_TRIPLE}- +ENV ARCH arm64 + +#include "common.label-and-env" +``` + +Then ou must change these lines according to the targeted architecture. + +Here you have to change the value according to the name of the toolchain (./ct-ng show-tuple): + +```docker +ENV CROSS_TRIPLE aarch64-unknown-linux-gnu +``` + +These lines also need to be changed: + +```docker +LABEL maintainer="Matt McCormick matt.mccormick@kitware.com" +ENV PKG_CONFIG_PATH /usr/lib/aarch64-linux-gnu/pkgconfig +ENV ARCH arm64 +``` + +Once this part is finished, there must be 3 files in the **linux-arm64** folder: + +- **crosstool-ng.config**, the configuration of the toolchain/crosstool-ng. +- **Dockerfile.in**, the docker file. +- **Toolchain.cmake**, the CMake file for the toolchains. + +### Makefile and CI + +For this last part, we will see how to add the image to the [Makefile](Makefile) and to a github action. + +You need to add the image/folder name (**linux-arm64**) to the **STANDARD_IMAGES** variable in the [Makefile](Makefile): + +```make +# These images are built using the "build implicit rule" +STANDARD_IMAGES = android-arm android-arm64 android-x86 android-x86_64 \ + linux-x86 linux-x64 linux-x64-clang linux-arm64 linux-arm64-musl linux-arm64-full \ + linux-armv5 linux-armv5-musl linux-armv5-uclibc linux-m68k-uclibc linux-s390x linux-x64-tinycc \ + linux-armv6 linux-armv6-lts linux-armv6-musl linux-arm64-lts \ + linux-armv7l-musl linux-armv7 linux-armv7a linux-armv7-lts linux-x86_64-full \ + linux-mips linux-ppc64le linux-riscv64 linux-riscv32 linux-xtensa-uclibc \ + web-wasi \ + windows-static-x86 windows-static-x64 windows-static-x64-posix windows-armv7 \ + windows-shared-x86 windows-shared-x64 windows-shared-x64-posix windows-arm64 +``` + +You need to add the image/folder name (**linux-arm64**) to the **GEN_IMAGES** variable in the [Makefile](Makefile): + +```make +# Generated Dockerfiles. +GEN_IMAGES = android-arm android-arm64 \ + linux-x86 linux-x64 linux-x64-clang linux-arm64 linux-arm64-musl linux-arm64-full \ + manylinux2014-x64 manylinux2014-x86 \ + manylinux2014-aarch64 linux-arm64-lts \ + web-wasm web-wasi linux-mips windows-arm64 windows-armv7 \ + windows-static-x86 windows-static-x64 windows-static-x64-posix \ + windows-shared-x86 windows-shared-x64 windows-shared-x64-posix \ + linux-armv7 linux-armv7a linux-armv7l-musl linux-armv7-lts linux-x86_64-full \ + linux-armv6 linux-armv6-lts linux-armv6-musl \ + linux-armv5 linux-armv5-musl linux-armv5-uclibc linux-ppc64le linux-s390x \ + linux-riscv64 linux-riscv32 linux-m68k-uclibc linux-x64-tinycc linux-xtensa-uclibc +``` + +To finish, you have to add to [Github Action](.github/workflows/main.yml) the image/folder name: + +```yml + # Linux arm64/armv8 images + - { + image: "linux-arm64", + stockfish: "yes", + stockfish_arg: "ARCH=armv8", + ninja: "yes", + ninja_arg: "", + openssl: "yes", + openssl_arg: "linux-aarch64", + C: "yes", + C_arg: "", + C-Plus-Plus: "yes", + C-Plus-Plus_arg: "", + fmt: "yes", + fmt_arg: "", + cpython: "yes", + cpython_arg: "--host=aarch64-unknown-linux-gnu --target=aarch64-unknown-linux-gnu", + } +``` + +You can disable and enable the build of certain tests which can cause problems with certain CPU architectures (eg. OpenSSL with Risc-V...). diff --git a/README.md b/README.md index 965208f..9589a07 100644 --- a/README.md +++ b/README.md @@ -9,32 +9,37 @@ Cross compiling toolchains in Docker images. ## Features -- Pre-built and configured toolchains for cross compiling. -- Most images also contain an emulator for the target system. -- Clean separation of build tools, source code, and build artifacts. -- Commands in the container are run as the calling user, so that any created files have the expected ownership, (i.e. not root). -- Make variables **CC**, **CXX**, **LD**, **AS** etc) are set to point to the appropriate tools in the container. -- Recent [CMake](https://cmake.org) and ninja are precompiled. -- [Conan.io](https://www.conan.io) can be used as a package manager. -- Toolchain files configured for CMake. -- Current directory is mounted as the container\'s workdir, `/work`. -- Works with the [Docker for Mac](https://docs.docker.com/docker-for-mac/) and [Docker for Windows](https://docs.docker.com/docker-for-windows/). -- Support using alternative container executor by setting **OCI_EXE** environment variable. By default, it searches for [docker](https://www.docker.com) and [podman](https://podman.io) executable. -- [crosstool-ng](https://github.com/crosstool-ng/crosstool-ng) and [buildroot](https://github.com/buildroot/buildroot) configuration files. +- Pre-built and configured toolchains for cross compiling. +- Most images also contain an emulator for the target system. +- Clean separation of build tools, source code, and build artifacts. +- Commands in the container are run as the calling user, so that any created files have the expected ownership, (i.e. not root). +- Make variables **CC**, **CXX**, **LD**, **AS** etc) are set to point to the appropriate tools in the container. +- Recent [CMake](https://cmake.org) and ninja are precompiled. +- [Conan.io](https://www.conan.io) can be used as a package manager. +- Toolchain files configured for CMake. +- Current directory is mounted as the container\'s workdir, `/work`. +- Works with the [Docker for Mac](https://docs.docker.com/docker-for-mac/) and [Docker for Windows](https://docs.docker.com/docker-for-windows/). +- Support using alternative container executor by setting **OCI_EXE** environment variable. By default, it searches for [docker](https://www.docker.com) and [podman](https://podman.io) executable. +- [crosstool-ng](https://github.com/crosstool-ng/crosstool-ng) and [buildroot](https://github.com/buildroot/buildroot) configuration files. ## Examples -1. `dockcross make`: Build the *Makefile* in the current directory. -2. `dockcross cmake -Bbuild -H. -GNinja`: Run CMake with a build directory `./build` for a *CMakeLists.txt* file in the current directory and generate `ninja` build configuration files. -3. `dockcross ninja -Cbuild`: Run ninja in the `./build` directory. -4. `dockcross bash -c '$CC test/C/hello.c -o hello'`: Build the *hello.c* file with the compiler identified with the `CC` environmental variable in the build environment. -5. `dockcross bash`: Run an interactive shell in the build environment. +1. `dockcross make`: Build the *Makefile* in the current directory. +2. `dockcross cmake -Bbuild -H. -GNinja`: Run CMake with a build directory `./build` for a *CMakeLists.txt* file in the current directory and generate `ninja` build configuration files. +3. `dockcross ninja -Cbuild`: Run ninja in the `./build` directory. +4. `dockcross bash -c '$CC test/C/hello.c -o hello'`: Build the *hello.c* file with the compiler identified with the `CC` environmental variable in the build environment. +5. `dockcross bash`: Run an interactive shell in the build environment. Note that commands are executed verbatim. If any shell processing for environment variable expansion or redirection is required, please use + ```bash bash -c "" ``` +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md). + ## Installation This image does not need to be run manually. Instead, there is a helper script to execute build commands on source code existing on the local host filesystem. This script is bundled with the image. @@ -546,5 +551,6 @@ The key difference is that [dockbuild](https://github.com/dockbuild/dockbuild#re \-\-- Credits: + - [sdt/docker-raspberry-pi-cross-compiler](https://github.com/sdt/docker-raspberry-pi-cross-compiler), who invented the base of the **dockcross** script. - [https://github.com/steeve/cross-compiler](https://github.com/steeve/cross-compiler),