diff --git a/Dockerfile b/Dockerfile index 8df7f97..acee53e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,56 @@ -FROM rust:bookworm AS builder +ARG TARGET=x86_64-hermit +ARG PREFIX=/opt/hermit +FROM --platform=$BUILDPLATFORM rust:bookworm AS kernel +ADD --link https://github.com/hermit-os/kernel.git /kernel +WORKDIR /kernel +RUN cargo xtask build \ + --artifact-dir . \ + --arch x86_64 \ + --release \ + --no-default-features \ + --features pci,smp,acpi,newlib,tcp,dhcpv4 + +FROM buildpack-deps:bookworm AS binutils +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + bison \ + flex \ + texinfo \ + ; \ + rm -rf /var/lib/apt/lists/*; +ADD --link https://github.com/hermit-os/binutils.git /binutils +WORKDIR /binutils +ENV CFLAGS="-w" \ + CXXFLAGS="-w" +ARG TARGET +ARG PREFIX +RUN set -eux; \ + ./configure \ + --target=$TARGET \ + --prefix=$PREFIX \ + --with-sysroot \ + --disable-werror \ + --disable-multilib \ + --disable-shared \ + --disable-nls \ + --disable-gdb \ + --disable-libdecnumber \ + --disable-readline \ + --disable-sim \ + --enable-tls \ + --enable-lto \ + --enable-plugin; \ + make -O -j$(nproc); \ + make install; \ + make clean + +FROM buildpack-deps:bookworm AS gcc RUN set -eux; \ apt-get update; \ apt-get install -y --no-install-recommends \ bison \ - git \ flex \ libgmp-dev \ libisl-dev \ @@ -13,13 +59,92 @@ RUN set -eux; \ texinfo \ ; \ rm -rf /var/lib/apt/lists/*; +ARG TARGET +ARG PREFIX +COPY --link --from=binutils $PREFIX $PREFIX +ENV CFLAGS="-w" \ + CXXFLAGS="-w" \ + CFLAGS_FOR_TARGET="-fPIE -pie" \ + GOFLAGS_FOR_TARGET="-fPIE -pie" \ + FCFLAGS_FOR_TARGET="-fPIE -pie" \ + FFLAGS_FOR_TARGET="-fPIE -pie" \ + CXXFLAGS_FOR_TARGET="-fPIE -pie" -WORKDIR /root/ -ADD ./toolchain.sh /root/toolchain.sh -RUN ./toolchain.sh x86_64-hermit /opt/hermit +ADD --link https://github.com/hermit-os/gcc.git /gcc +WORKDIR /gcc/builddir-bootstrap +RUN set -eux; \ + ../configure \ + --target=$TARGET \ + --prefix=$PREFIX \ + --without-headers \ + --disable-multilib \ + --with-isl \ + --enable-languages=c,c++,lto \ + --disable-nls \ + --disable-shared \ + --disable-libssp \ + --disable-libgomp \ + --enable-threads=posix \ + --enable-tls \ + --enable-lto \ + --disable-symvers; \ + make -O -j$(nproc) all-gcc; \ + make install-gcc; \ + make clean +ENV PATH=$PREFIX/bin:$PATH +COPY --link --from=kernel /kernel/libhermit.a /kernel/libhermit.a +ENV LDFLAGS_FOR_TARGET="-L/kernel -lhermit" + +ADD --link https://github.com/hermit-os/newlib.git /newlib +WORKDIR /newlib +RUN set -eux; \ + ./configure \ + --target=$TARGET \ + --prefix=$PREFIX \ + --disable-shared \ + --disable-multilib \ + --enable-lto \ + --enable-newlib-io-c99-formats \ + --enable-newlib-multithread; \ + make -O -j$(nproc); \ + make install; \ + make clean + +ADD --link https://github.com/hermit-os/pthread-embedded.git /pthread-embedded +WORKDIR /pthread-embedded +RUN set -eux; \ + ./configure \ + --target=$TARGET \ + --prefix=$PREFIX; \ + make -O -j$(nproc); \ + make install; \ + make clean + +WORKDIR /gcc/builddir +RUN set -eux; \ + ../configure \ + --target=$TARGET \ + --prefix=$PREFIX \ + --with-newlib \ + --with-isl \ + --disable-multilib \ + --without-libatomic \ + --enable-languages=c,c++,fortran,lto \ + --disable-nls \ + --disable-shared \ + --enable-libssp \ + --enable-threads=posix \ + --enable-libgomp \ + --enable-tls \ + --enable-lto \ + --disable-symver; \ + make -O -j$(nproc); \ + make install; \ + make clean FROM rust:bookworm AS toolchain -COPY --from=builder /opt/hermit /opt/hermit -ENV PATH=/opt/hermit/bin:$PATH \ - LD_LIBRARY_PATH=/opt/hermit/lib:$LD_LIBRARY_PATH +ARG PREFIX +COPY --from=gcc $PREFIX $PREFIX +ENV PATH=$PREFIX/bin:$PATH \ + LD_LIBRARY_PATH=$PREFIX/lib:$LD_LIBRARY_PATH diff --git a/README.md b/README.md index 0f0f535..6ca9440 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,31 @@ # hermit-gcc -This repository contains scripts to build the cross-compiler for the Rust-based library OS [HermitCore](https://github.com/hermit-os/libhermit-rs). +This repository provides an OCI image ([`ghcr.io/hermit-os/hermit-gcc`], [`Dockerfile`]) containing the GCC cross-compiler for the [Hermit Operating System]. -## Requirements +[`ghcr.io/hermit-os/hermit-gcc`]: https://github.com/hermit-os/hermit-gcc/pkgs/container/hermit-gcc +[`Dockerfile`]: Dockerfile +[Hermit Operating System]: http://hermit-os.org -The build process works currently only on **x86-based Linux** systems. The following software packets are required to build HermitCore's toolchain on a Linux system: +## Available Components -* Netwide Assembler (NASM) -* GNU Make, GNU Binutils, cmake -* Tools and libraries to build *linux*, *binutils* and *gcc* (e.g. flex, bison, MPFR library, ISL library, GMP library, MPC library) -* Rust +- [hermit-os/binutils](https://github.com/hermit-os/binutils) +- [hermit-os/newlib](https://github.com/hermit-os/newlib) +- [hermit-os/pthread-embedded](https://github.com/hermit-os/pthread-embedded) +- [hermit-os/gcc](https://github.com/hermit-os/gcc) -On Debian-based systems the packets can be installed by executing: -``` - sudo apt-get install cmake nasm libmpfr-dev libisl-dev libmpc-dev libgmp-dev flex bison -``` - -Note: If issues arise during the build, try using requirements.sh to check the versions of the necessary packets and the configuration of the LD_LIBRARY_PATH (it should contain the MPFR library, GMP library and MPC library). +## Usage -## Building the HermitCore's toolchain +To compile Hermit applications using this image, you need a built [Hermit kernel] (`libhermit.a`). +You can then compile applications like this: -To build the toolchain just call the script as follow: +[Hermit kernel]: https://github.com/hermit-os/kernel ```bash -$ ./toolchain.sh x86_64-hermit /home/usr/hermit +docker run --rm -v .:/mnt -w /mnt ghcr.io/hermit-os/hermit-gcc:latest x86_64-hermit-gcc -o app app.c libhermit.a ``` -The first argument of the script specifies the target architecture, where the second argument defines the path to the installation directory. -To create the toolchain, write access to the installation directory is required. +You can also use the image interactively: + +```bash +docker run --rm -it -v .:/mnt -w /mnt ghcr.io/hermit-os/hermit-gcc:latest +``` diff --git a/requirements.sh b/requirements.sh deleted file mode 100755 index 8c1b445..0000000 --- a/requirements.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -if echo "$LD_LIBRARY_PATH" | grep -q libgmp && echo "$LD_LIBRARY_PATH" | grep -q libisl && echo "$LD_LIBRARY_PATH" | grep -q libmpc && echo "$LD_LIBRARY_PATH" | grep -q libmpfr; then - echo "LD_LIBRARY_PATH contains MPFR library, ISL library, GMP library, and MPC library" -elif ! echo "$LD_LIBRARY_PATH" | grep -q libgmp; then - echo "LD_LIBRARY_PATH missing GMP library" -elif ! echo "$LD_LIBRARY_PATH" | grep -q libisl; then - echo "LD_LIBRARY_PATH missing ISL library" -elif ! echo "$LD_LIBRARY_PATH" | grep -q libmpc; then - echo "LD_LIBRARY_PATH missing MPC library" -elif ! echo "$LD_LIBRARY_PATH" | grep -q libmpfr; then - echo "LD_LIBRARY_PATH missing MPFR library" -fi - -check_version() { - package=$1 - version_command=$2 - - echo -n "Checking $package... " - if $version_command &> /dev/null; then - version=$($version_command | head -n 1) - echo "Installed ($version)" - else - echo "Not installed" - fi -} - -# Check versions of packages -check_version "CMake" "cmake --version" -check_version "NASM" "nasm -v" -check_version "Flex" "flex --version" -check_version "Bison" "bison --version" \ No newline at end of file diff --git a/toolchain.sh b/toolchain.sh deleted file mode 100755 index 841d9cd..0000000 --- a/toolchain.sh +++ /dev/null @@ -1,153 +0,0 @@ -#!/bin/bash -# -# script to build HermitCore's toolchain -# -# $1 = specifies the target architecture -# $2 = specifies the installation directory - -# exit when any command fails -set -e - -BUILDDIR=build -CLONE_DEPTH="--depth=50" -PREFIX="$2" -TARGET=$1 -NJOBS=-j"$(nproc)" -PATH=$PATH:$PREFIX/bin -export CFLAGS="-w" -export CXXFLAGS="-w" -export CFLAGS_FOR_TARGET="-fPIE -pie" -export GOFLAGS_FOR_TARGET="-fPIE -pie" -export FCFLAGS_FOR_TARGET="-fPIE -pie" -export FFLAGS_FOR_TARGET="-fPIE -pie" -export CXXFLAGS_FOR_TARGET="-fPIE -pie" - -echo "Build bootstrap toolchain for $TARGET with $NJOBS jobs for $PREFIX" - -mkdir -p $BUILDDIR -cd $BUILDDIR - -if [ ! -d "binutils" ]; then -git clone $CLONE_DEPTH https://github.com/hermit-os/binutils.git -fi - -if [ ! -d "gcc" ]; then -git clone $CLONE_DEPTH https://github.com/hermit-os/gcc.git -fi - -if [ ! -d "kernel" ]; then -git clone https://github.com/hermit-os/kernel -fi - -if [ ! -d "newlib" ]; then -git clone $CLONE_DEPTH -b path2rs https://github.com/hermit-os/newlib.git -fi - -if [ ! -d "pte" ]; then -git clone $CLONE_DEPTH -b path2rs https://github.com/hermit-os/pthread-embedded.git pte -fi - -if [ ! -d "tmp/binutils" ]; then -mkdir -p tmp/binutils -cd tmp/binutils -../../binutils/configure \ - --target=$TARGET \ - --prefix=$PREFIX \ - --with-sysroot \ - --disable-werror \ - --disable-multilib \ - --disable-shared \ - --disable-nls \ - --disable-gdb \ - --disable-libdecnumber \ - --disable-readline \ - --disable-sim \ - --enable-tls \ - --enable-lto \ - --enable-plugin -make -O $NJOBS -make install -cd - -fi - -if [ ! -d "tmp/bootstrap" ]; then -mkdir -p tmp/bootstrap -cd tmp/bootstrap -../../gcc/configure \ - --target=$TARGET \ - --prefix=$PREFIX \ - --without-headers \ - --disable-multilib \ - --with-isl \ - --enable-languages=c,c++,lto \ - --disable-nls \ - --disable-shared \ - --disable-libssp \ - --disable-libgomp \ - --enable-threads=posix \ - --enable-tls \ - --enable-lto \ - --disable-symvers -make -O $NJOBS all-gcc -make install-gcc -cd - -fi - -cd kernel -cargo xtask build \ - --arch x86_64 \ - --release \ - --no-default-features \ - --features pci,smp,acpi,newlib,tcp,dhcpv4 -export LDFLAGS_FOR_TARGET="-L$PWD/target/x86_64/release -lhermit" -cd - - -if [ ! -d "tmp/newlib" ]; then -mkdir -p tmp/newlib -cd tmp/newlib -../../newlib/configure \ - --target=$TARGET \ - --prefix=$PREFIX \ - --disable-shared \ - --disable-multilib \ - --enable-lto \ - --enable-newlib-io-c99-formats \ - --enable-newlib-multithread -make -O $NJOBS -make install -cd - -fi - -cd pte -./configure \ - --target=$TARGET \ - --prefix=$PREFIX -make -O $NJOBS -make install -cd .. - -if [ ! -d "tmp/gcc" ]; then -mkdir -p tmp/gcc -cd tmp/gcc -../../gcc/configure \ - --target=$TARGET \ - --prefix=$PREFIX \ - --with-newlib \ - --with-isl \ - --disable-multilib \ - --without-libatomic \ - --enable-languages=c,c++,fortran,lto \ - --disable-nls \ - --disable-shared \ - --enable-libssp \ - --enable-threads=posix \ - --enable-libgomp \ - --enable-tls \ - --enable-lto \ - --disable-symver -make -O $NJOBS -make install -cd - -fi - -cd ..