Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 30 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ ENV GHCUP_INSTALL_BASE_PREFIX=/usr/local
RUN apt-get update \
&& apt-get install -qq -y --no-install-recommends \
curl build-essential git libffi-dev libffi8 libgmp-dev \
libgmp10 libncurses-dev libncurses6 libtinfo6 zlib1g-dev openssh-client \
procps libnuma-dev pkg-config jq wget file \
libncurses-dev libncurses6 zlib1g-dev openssh-client \
procps libnuma-dev pkg-config jq \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& ldconfig
Expand Down Expand Up @@ -82,10 +82,24 @@ FROM with-ghc-cabal AS with-hls
# a particular release. We make sure to remove the cache as part of
# building this layer to avoid extra space being taken up in the final
# image.
#
# The hls executable is dynamically linked against the .so libraries in
# the cabal store it was built from, so that store must ship in the
# image. XDG_STATE_HOME gives the build a store of its own: the default
# store (~/.local/state/cabal/store) is also where cabal builds run in
# downstream containers (as root) resolve already-installed packages,
# so it must not contain packages whose compile- and link-time
# artifacts have been pruned. With the store isolated, everything hls
# does not load at runtime (.a and .hi files) is deleted and the .so
# libraries are stripped.
ARG HLS_VERSION
RUN ghcup compile hls -g "$HLS_VERSION" --ghc "$GHC_VERSION" --cabal-update -- --flags="-hlint" && \
RUN XDG_STATE_HOME=/usr/local/.ghcup/hls-cabal \
ghcup compile hls -g "$HLS_VERSION" --ghc "$GHC_VERSION" --cabal-update -- --flags="-hlint" && \
ghcup gc --share-dir --tmpdirs && \
rm -rf ~/.cache
rm -rf ~/.cache && \
find /usr/local/.ghcup/hls-cabal/cabal/store \( -name '*.a' -o -name '*.hi' -o -name '*.dyn_hi' \) -delete && \
find /usr/local/.ghcup/hls-cabal/cabal/store -name '*.so' -exec strip --strip-unneeded '{}' + && \
strip /usr/local/.ghcup/bin/haskell-language-server-*

# Each tool below is built in its own stage (all versions are managed in
# tool-versions.env) so that bumping one tool's version rebuilds only that
Expand All @@ -98,6 +112,12 @@ RUN ghcup compile hls -g "$HLS_VERSION" --ghc "$GHC_VERSION" --cabal-update -- -
# version we want of a tool cannot compile with our lts. Since these
# tools are all binary executables copied into the final image they
# don't need to share dependency versions with each other or the lts.
#
# cabal does not strip executables by default, and the debug symbols
# account for roughly a third of each binary, so every stage passes
# --enable-executable-stripping. The hls layer above strips explicitly
# instead because ghcup places its binaries and libraries outside
# cabal's install step, which is where this flag takes effect.

FROM base AS tool-ghciwatch
ARG GHCIWATCH_VERSION
Expand All @@ -107,27 +127,27 @@ RUN curl --fail -Lo /ghciwatch \

FROM with-ghc-cabal AS tool-weeder
ARG WEEDER_VERSION
RUN cabal update && cabal install --install-method=copy --installdir=/tool-bin "weeder-$WEEDER_VERSION"
RUN cabal update && cabal install --install-method=copy --installdir=/tool-bin --enable-executable-stripping "weeder-$WEEDER_VERSION"

FROM with-ghc-cabal AS tool-fourmolu
ARG FOURMOLU_VERSION
RUN cabal update && cabal install --install-method=copy --installdir=/tool-bin "fourmolu-$FOURMOLU_VERSION"
RUN cabal update && cabal install --install-method=copy --installdir=/tool-bin --enable-executable-stripping "fourmolu-$FOURMOLU_VERSION"

FROM with-ghc-cabal AS tool-ghcid
ARG GHCID_VERSION
RUN cabal update && cabal install --install-method=copy --installdir=/tool-bin "ghcid-$GHCID_VERSION"
RUN cabal update && cabal install --install-method=copy --installdir=/tool-bin --enable-executable-stripping "ghcid-$GHCID_VERSION"

FROM with-ghc-cabal AS tool-hlint
ARG HLINT_VERSION
RUN cabal update && cabal install --install-method=copy --installdir=/tool-bin "hlint-$HLINT_VERSION"
RUN cabal update && cabal install --install-method=copy --installdir=/tool-bin --enable-executable-stripping "hlint-$HLINT_VERSION"

FROM with-ghc-cabal AS tool-shellcheck
ARG SHELLCHECK_VERSION
RUN cabal update && cabal install --install-method=copy --installdir=/tool-bin "ShellCheck-$SHELLCHECK_VERSION"
RUN cabal update && cabal install --install-method=copy --installdir=/tool-bin --enable-executable-stripping "ShellCheck-$SHELLCHECK_VERSION"

FROM with-ghc-cabal AS tool-stan
ARG STAN_VERSION
RUN cabal update && cabal install --install-method=copy --installdir=/tool-bin "stan-$STAN_VERSION"
RUN cabal update && cabal install --install-method=copy --installdir=/tool-bin --enable-executable-stripping "stan-$STAN_VERSION"

FROM with-hls AS final

Expand Down