Skip to content
Snippets Groups Projects
latest.Dockerfile 5.85 KiB
Newer Older
Olivier Benz's avatar
Olivier Benz committed
ARG GHC_VERSION
ARG CABAL_VERSION
ARG STACK_VERSION
Olivier Benz's avatar
Olivier Benz committed
ARG GHC_VERSION_BUILD=${GHC_VERSION}
ARG CABAL_VERSION_BUILD=${CABAL_VERSION}

Olivier Benz's avatar
Olivier Benz committed
FROM glcr.b-data.ch/ghc/ghc-musl:9.10.1 AS bootstrap
RUN case "$(uname -m)" in \
    x86_64) linker="gold" ;; \
    aarch64) linker="gold" ;; \
  esac \
  && apk upgrade --no-cache \
  && apk add --no-cache \
Olivier Benz's avatar
Olivier Benz committed
    autoconf \
    automake \
    binutils${linker:+-}${linker} \
Olivier Benz's avatar
Olivier Benz committed
    build-base \
Olivier Benz's avatar
Olivier Benz committed
    clang18 \
Olivier Benz's avatar
Olivier Benz committed
    coreutils \
    cpio \
    curl \
    gnupg \
    linux-headers \
    libffi-dev \
Olivier Benz's avatar
Olivier Benz committed
    llvm18 \
Olivier Benz's avatar
Olivier Benz committed
    ncurses-dev \
    perl \
    python3 \
    xz \
    zlib-dev

Olivier Benz's avatar
Olivier Benz committed
FROM bootstrap AS bootstrap-ghc

ARG GHC_VERSION_BUILD

ENV GHC_VERSION=${GHC_VERSION_BUILD}

Olivier Benz's avatar
Olivier Benz committed
RUN cd /tmp \
  && curl -sSLO https://downloads.haskell.org/~ghc/"$GHC_VERSION"/ghc-"$GHC_VERSION"-src.tar.xz \
  && curl -sSLO https://downloads.haskell.org/~ghc/"$GHC_VERSION"/ghc-"$GHC_VERSION"-src.tar.xz.sig \
  && gpg --keyserver hkps://keyserver.ubuntu.com:443 \
Olivier Benz's avatar
Olivier Benz committed
    --receive-keys 88B57FCF7DB53B4DB3BFA4B1588764FBE22D19C4 || \
    gpg --keyserver hkp://keyserver.ubuntu.com:80 \
Olivier Benz's avatar
Olivier Benz committed
    --receive-keys 88B57FCF7DB53B4DB3BFA4B1588764FBE22D19C4 \
  && gpg --verify "ghc-$GHC_VERSION-src.tar.xz.sig" "ghc-$GHC_VERSION-src.tar.xz" \
  && tar -xJf "ghc-$GHC_VERSION-src.tar.xz" \
  && cd "ghc-$GHC_VERSION" \
  ## Configure and build
  && if [ "$(uname -m)" = "riscv64" ]; then \
    flavour="quick+llvm"; \
  fi \
Olivier Benz's avatar
Olivier Benz committed
  && ./boot.source \
Olivier Benz's avatar
Olivier Benz committed
  && ./configure \
Olivier Benz's avatar
Olivier Benz committed
    --build=$(uname -m)-alpine-linux \
    --host=$(uname -m)-alpine-linux \
    --target=$(uname -m)-alpine-linux \
  ## Use the LLVM backend
  ## Switch llvm-targets from unknown-linux-gnueabihf->alpine-linux
  ## so we can match the llvm vendor string alpine uses
Olivier Benz's avatar
Olivier Benz committed
  && sed -i -e 's/unknown-linux-gnueabihf/alpine-linux/g' llvm-targets \
  && sed -i -e 's/unknown-linux-gnueabi/alpine-linux/g' llvm-targets \
  && sed -i -e 's/unknown-linux-gnu/alpine-linux/g' llvm-targets \
  && cabal update \
Olivier Benz's avatar
Olivier Benz committed
  && cabal install alex \
  && export PATH=/root/.local/bin:$PATH \
  ## See https://unix.stackexchange.com/questions/519092/what-is-the-logic-of-using-nproc-1-in-make-command
  && hadrian/build binary-dist -j"$(($(nproc)+1))" \
    --flavour=${flavour:-perf+llvm+split_sections} \
Olivier Benz's avatar
Olivier Benz committed
FROM bootstrap AS bootstrap-cabal
ARG CABAL_VERSION_BUILD

ENV CABAL_VERSION=${CABAL_VERSION_BUILD}

## Build Cabal (the tool) with the GHC bootstrap version
RUN cabal update \
  ## See https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/libraries/version-history
  && cabal install "cabal-install-$CABAL_VERSION"
FROM alpine:3.21 AS ghc-base
Olivier Benz's avatar
Olivier Benz committed
ARG IMAGE_LICENSE="MIT"
ARG IMAGE_SOURCE="https://gitlab.b-data.ch/ghc/ghc-musl"
ARG IMAGE_VENDOR="Olivier Benz"
ARG IMAGE_AUTHORS="Olivier Benz <olivier.benz@b-data.ch>"

LABEL org.opencontainers.image.licenses="$IMAGE_LICENSE" \
      org.opencontainers.image.source="$IMAGE_SOURCE" \
      org.opencontainers.image.vendor="$IMAGE_VENDOR" \
      org.opencontainers.image.authors="$IMAGE_AUTHORS"
Olivier Benz's avatar
Olivier Benz committed
ARG GHC_VERSION_BUILD
ARG CABAL_VERSION_BUILD
Olivier Benz's avatar
Olivier Benz committed
ARG STACK_VERSION
Olivier Benz's avatar
Olivier Benz committed
ENV GHC_VERSION=${GHC_VERSION_BUILD} \
Olivier Benz's avatar
Olivier Benz committed
    CABAL_VERSION=${CABAL_VERSION_BUILD} \
    STACK_VERSION=${STACK_VERSION}
RUN apk add --no-cache \
Olivier Benz's avatar
Olivier Benz committed
    bash \
    build-base \
    bzip2 \
    bzip2-dev \
    bzip2-static \
Olivier Benz's avatar
Olivier Benz committed
    clang18 \
Olivier Benz's avatar
Olivier Benz committed
    curl \
    curl-static \
    dpkg \
    fakeroot \
    git \
    gmp-dev \
    libcurl \
    libffi \
    libffi-dev \
Olivier Benz's avatar
Olivier Benz committed
    llvm18 \
Olivier Benz's avatar
Olivier Benz committed
    ncurses-dev \
    ncurses-static \
    openssl-dev \
    openssl-libs-static \
    pcre \
    pcre-dev \
    pcre2 \
    pcre2-dev \
    perl \
Olivier Benz's avatar
Olivier Benz committed
    ## Install shadow for `stack --docker`
    shadow \
Olivier Benz's avatar
Olivier Benz committed
    wget \
    xz \
    xz-dev \
    zlib \
    zlib-dev \
    zlib-static

Olivier Benz's avatar
Olivier Benz committed
FROM ghc-base AS ghc-stage1
COPY --from=bootstrap-ghc /tmp/ghc-"$GHC_VERSION"/_build/bindist/ghc-"$GHC_VERSION"-*-alpine-linux.tar.xz /tmp/
Olivier Benz's avatar
Olivier Benz committed

RUN cd /tmp \
Olivier Benz's avatar
Olivier Benz committed
  ## Install GHC
  && tar -xJf ghc-"$GHC_VERSION"-*-alpine-linux.tar.xz \
  && cd ghc-"$GHC_VERSION"-*-alpine-linux \
Olivier Benz's avatar
Olivier Benz committed
  && ./configure \
Olivier Benz's avatar
Olivier Benz committed
  && make install \
Olivier Benz's avatar
Olivier Benz committed
  ## Install Stack
  && cd /tmp \
  && if [ "$(uname -m)" = "riscv64" ]; then \
    curl -sSLO https://gitlab.b-data.ch/commercialhaskell/stack/-/releases/v"$STACK_VERSION"/downloads/builds/stack-"$STACK_VERSION"-linux-"$(uname -m)".tar.gz; \
    curl -sSLO https://gitlab.b-data.ch/commercialhaskell/stack/-/releases/v"$STACK_VERSION"/downloads/builds/stack-"$STACK_VERSION"-linux-"$(uname -m)".tar.gz.sha256; \
  else \
    curl -sSLO https://github.com/commercialhaskell/stack/releases/download/v"$STACK_VERSION"/stack-"$STACK_VERSION"-linux-"$(uname -m)".tar.gz; \
    curl -sSLO https://github.com/commercialhaskell/stack/releases/download/v"$STACK_VERSION"/stack-"$STACK_VERSION"-linux-"$(uname -m)".tar.gz.sha256; \
  fi \
Olivier Benz's avatar
Olivier Benz committed
  && sha256sum -cs stack-"$STACK_VERSION"-linux-"$(uname -m)".tar.gz.sha256 \
  && tar -xzf stack-"$STACK_VERSION"-linux-"$(uname -m)".tar.gz \
  && mv stack-"$STACK_VERSION"-linux-"$(uname -m)"/stack /usr/local/bin/stack \
  ## Clean up
Olivier Benz's avatar
Olivier Benz committed
  && rm -rf /tmp/*
Olivier Benz's avatar
Olivier Benz committed
FROM ghc-stage1 AS ghc-stage2
## Install Cabal (the tool) built with the GHC bootstrap version
COPY --from=bootstrap-cabal /root/.local/bin/cabal /usr/local/bin/cabal

## Rebuild Cabal (the tool) with the GHC target version
Olivier Benz's avatar
Olivier Benz committed
RUN cabal update \
  && cabal install --allow-newer "cabal-install-$CABAL_VERSION"
Olivier Benz's avatar
Olivier Benz committed
FROM ghc-stage1 AS test
WORKDIR /usr/local/src

## Install Cabal (the tool) built with the GHC target version
COPY --from=ghc-stage2 /root/.local/bin/cabal /usr/local/bin/cabal

Olivier Benz's avatar
Olivier Benz committed
COPY Main.hs Main.hs

RUN ghc -static -optl-pthread -optl-static Main.hs \
  && file Main \
  && ./Main \
Olivier Benz's avatar
Olivier Benz committed
  && mkdir cabal-test \
  && cd cabal-test \
  && cabal update \
  && cabal init -n --is-executable -p tester -l MIT \
Olivier Benz's avatar
Olivier Benz committed
  && cabal run

FROM ghc-base

## Install GHC and Stack
COPY --from=ghc-stage1 /usr/local /usr/local

## Install Cabal (the tool) built with the GHC target version
COPY --from=ghc-stage2 /root/.local/bin/cabal /usr/local/bin/cabal
Olivier Benz's avatar
Olivier Benz committed

CMD ["ghci"]