-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MacOS + Linux arm64 build support, consolidated build scripts
- Loading branch information
1 parent
047d502
commit 3af7f31
Showing
10 changed files
with
266 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
elm-stuff | ||
dist | ||
dist-newstyle | ||
cabal-dev | ||
.cabal-sandbox/ | ||
cabal.sandbox.config | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#!/usr/bin/env bash | ||
set -ex # Be verbose and exit immediately on error instead of trying to continue | ||
|
||
buildTag="elm-linux-aarch64-glibc" | ||
|
||
scriptDir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) | ||
|
||
cd "$scriptDir/.." # Move into the project root | ||
|
||
# Build in Docker | ||
docker build --platform linux/arm64 \ | ||
-t $buildTag \ | ||
-f distribution/docker/aarch64-glibc.dockerfile . | ||
|
||
mkdir -p distribution/dist # Ensure the dist directory is present | ||
|
||
|
||
bin=distribution/dist/$buildTag # Copy built binary to dist | ||
docker run --rm --entrypoint cat $buildTag /elm/elm > $bin | ||
chmod a+x $bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#!/usr/bin/env bash | ||
set -ex # Be verbose and exit immediately on error instead of trying to continue | ||
|
||
buildTag="elm-linux-aarch64-musl" | ||
|
||
scriptDir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) | ||
|
||
cd "$scriptDir/.." # Move into the project root | ||
|
||
# Build in Docker | ||
docker build --platform linux/arm64 \ | ||
-t $buildTag \ | ||
-f distribution/docker/aarch64-musl.dockerfile . | ||
|
||
mkdir -p distribution/dist # Ensure the dist directory is present | ||
|
||
|
||
bin=distribution/dist/$buildTag # Copy built binary to dist | ||
docker run --rm --entrypoint cat $buildTag /elm/elm > $bin | ||
chmod a+x $bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#!/usr/bin/env bash | ||
set -ex # Be verbose and exit immediately on error instead of trying to continue | ||
|
||
buildTag="elm-linux-x86_64-musl" | ||
|
||
scriptDir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) | ||
|
||
cd "$scriptDir/.." # Move into the project root | ||
|
||
# Build in Docker | ||
docker build --platform linux/amd64 \ | ||
-t $buildTag \ | ||
-f distribution/docker/x86_64-musl.dockerfile . | ||
|
||
mkdir -p distribution/dist # Ensure the dist directory is present | ||
|
||
|
||
bin=distribution/dist/$buildTag # Copy built binary to dist | ||
docker run --rm --entrypoint cat $buildTag /elm/elm > $bin | ||
chmod a+x $bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/usr/bin/env bash | ||
set -ex # Be verbose and exit immediately on error instead of trying to continue | ||
|
||
buildTag="elm-macos-arm64" | ||
|
||
ghcup install ghc 9.0.2 --set | ||
ghcup install cabal 3.6.2.0 --set | ||
|
||
opt --version # The arm64 build currently requires llvm until we get to GHC 9.4+ | ||
|
||
scriptDir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) | ||
|
||
cd "$scriptDir/.." # Move into the project root | ||
|
||
ffiLibs="$(xcrun --show-sdk-path)/usr/include/ffi" # Workaround for GHC9.0.2 bug until we can use GHC9.2.3+ | ||
export C_INCLUDE_PATH=$ffiLibs # https://gitlab.haskell.org/ghc/ghc/-/issues/20592#note_436353 | ||
|
||
|
||
cabal update | ||
cabal build -j4 # Build with concurrency 4 | ||
|
||
mkdir -p distribution/dist # Ensure the dist directory is present | ||
|
||
bin=distribution/dist/$buildTag | ||
cp "$(cabal list-bin .)" $bin # Copy built binary to dist | ||
strip $bin # Strip symbols to reduce binary size (90M -> 56M) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/usr/bin/env bash | ||
set -ex # Be verbose and exit immediately on error instead of trying to continue | ||
|
||
buildTag="elm-macos-x86_64" | ||
|
||
ghcup install ghc 9.0.2 --set | ||
ghcup install cabal 3.6.2.0 --set | ||
|
||
|
||
|
||
scriptDir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) | ||
|
||
cd "$scriptDir/.." # Move into the project root | ||
|
||
|
||
|
||
|
||
|
||
cabal update | ||
cabal build -j4 # Build with concurrency 4 | ||
|
||
mkdir -p distribution/dist # Ensure the dist directory is present | ||
|
||
bin=distribution/dist/$buildTag | ||
cp "$(cabal list-bin .)" $bin # Copy built binary to dist | ||
strip $bin # Strip symbols to reduce binary size (90M -> 56M) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
FROM registry.gitlab.b-data.ch/ghc/ghc4pandoc:8.10.7 as bootstrap | ||
|
||
# @TODO having issues on subsequent versions of GHC, retry in future | ||
# FROM registry.gitlab.b-data.ch/ghc/ghc4pandoc:9.0.2 as bootstrap | ||
|
||
RUN cabal update | ||
|
||
# Install packages | ||
WORKDIR /elm | ||
COPY elm.cabal ./ | ||
|
||
ENV CABALOPTS="-f-export-dynamic -fembed_data_files --enable-executable-static -j4" | ||
ENV GHCOPTS="-j4 +RTS -A256m -RTS -split-sections -optc-Os -optl=-pthread" | ||
|
||
RUN cabal build $CABALOPTS --ghc-options="$GHCOPTS" --only-dependencies | ||
|
||
# Import source code | ||
COPY builder builder | ||
COPY compiler compiler | ||
COPY reactor reactor | ||
COPY terminal terminal | ||
COPY LICENSE ./ | ||
|
||
RUN cabal build $CABALOPTS --ghc-options="$GHCOPTS" | ||
RUN cp `cabal list-bin .` ./elm | ||
RUN strip elm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
FROM alpine:3.15 as build | ||
|
||
RUN apk add --no-cache \ | ||
alpine-sdk \ | ||
autoconf \ | ||
gcc \ | ||
gmp \ | ||
gmp-dev \ | ||
libffi \ | ||
libffi-dev \ | ||
llvm10 \ | ||
make \ | ||
musl-dev \ | ||
ncurses-dev \ | ||
ncurses-static \ | ||
tree \ | ||
wget \ | ||
zlib-dev \ | ||
zlib-static \ | ||
curl | ||
|
||
RUN curl https://downloads.haskell.org/~ghcup/0.1.18.0/x86_64-linux-ghcup-0.1.18.0 -o /usr/local/bin/ghcup && chmod a+x /usr/local/bin/ghcup | ||
|
||
# Setup GHC | ||
RUN ghcup install ghc 9.0.2 --set | ||
RUN ghcup install cabal 3.6.2.0 --set | ||
|
||
ENV PATH="${PATH}:/root/.ghcup/bin" | ||
|
||
|
||
# FIX https://bugs.launchpad.net/ubuntu/+source/gcc-4.4/+bug/640734 | ||
# Use the next line to debug the right file source if this area starts failing in future | ||
# RUN tree /usr/lib/gcc/x86_64-alpine-linux-musl | ||
# @TODO is there a sure-fire way of getting this path? | ||
WORKDIR /usr/lib/gcc/x86_64-alpine-linux-musl/10.3.1/ | ||
RUN cp crtbeginT.o crtbeginT.o.orig | ||
RUN cp crtbeginS.o crtbeginT.o | ||
RUN cp crtend.o crtend.o.orig | ||
RUN cp crtendS.o crtend.o | ||
|
||
RUN cabal update | ||
|
||
# Install packages | ||
WORKDIR /elm | ||
COPY elm.cabal ./ | ||
RUN cabal build --ghc-option=-optl=-static --ghc-option=-split-sections -O2 --only-dependencies | ||
|
||
|
||
# Import source code | ||
COPY builder builder | ||
COPY compiler compiler | ||
COPY reactor reactor | ||
COPY terminal terminal | ||
COPY LICENSE ./ | ||
|
||
RUN cabal build --ghc-option=-optl=-static --ghc-option=-split-sections -O2 | ||
RUN cp `cabal list-bin .` ./elm | ||
RUN strip elm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
|
||
## Supported architectures | ||
|
||
Distributions for the following architectures are currently supported: | ||
|
||
| Build | Linking | Supported build hosts | | ||
| ----------------------- | ------- | --------------------------------------- | | ||
| `elm-macos-x86_64` | Dynamic | `macos-x86_64`, `macos-arm64` (Rosetta) | | ||
| `elm-macos-arm64` | Dynamic | `macos-arm64` + llvm | | ||
| `elm-linux-x86_64-musl` | Static | `linux-x86_64`, `macos-x86_64` (Docker) | | ||
| `elm-linux-arm64-glibc` | Dynamic | `linux-arm64`, `macos-arm64` (Docker) | | ||
| `elm-win-x86_64` | Dynamic | `win-x86_64` | | ||
|
||
|
||
## Building an Elm compiler binary | ||
|
||
### Pre-requisites | ||
|
||
- [ghcup](https://www.haskell.org/ghcup/) (scripts will attempt to install GHC 9.0.2 + Cabal 3.6.2.0) | ||
- LLVM v13+ (MacOS arm64 only, suggest [homebrew](https://brew.sh/) `brew install llvm@13`) | ||
|
||
How to install these varies depending on your build host. [GHCup](https://www.haskell.org/ghcup/) is a convenient option for trying out multiple versions. | ||
|
||
Once you have these dependencies, running the relevant `build-<os>-<aarch>.sh` should result in an Elm binary. | ||
|
||
|
||
## Macos cross-compiling | ||
|
||
Elm should compile on both `x86_64` (Intel) and `arm64` (M-series) chipset macs. | ||
|
||
If you have an `x86_64` mac, you can only build `x86_64` binaries. | ||
|
||
If you have an `arm64` mac and [Rosetta 2](https://support.apple.com/en-gb/HT211861), you can also cross-compile the `x86_64` binary, however it will require the prerequisite toolchain in the respective CPU flavour, i.e. | ||
|
||
- llvm-arm64 + GHC-arm64 + cabal-arm64 => elm-macos-arm64 | ||
- GHC-x86_64 + cabal-x86_64 => elm-macos-x86-64 | ||
|
||
If you use `ghcup`, you can force install the x86 tools to replace the arm64 ones like follows: | ||
|
||
``` | ||
ghcup install ghc 9.0.2 --force -p x86_64-apple-darwin --set | ||
ghcup install cabal 3.6.2.0 --force -p x86_64-apple-darwin --set | ||
ghcup set ghc 9.0.2 | ||
``` | ||
|
||
It seems ghcup doesn't currently support multi-arch installs. Check the arch of your currently installed binaries as follows: | ||
|
||
``` | ||
file ~/.ghcup/bin/cabal | ||
file ~/.ghcup/ghc/9.0.2/lib/ghc-9.0.2/bin/ghc | ||
``` | ||
|
||
|
||
## Linux builds with Docker | ||
|
||
Docker provides us with the convenience of being able to run encapsulated Linux builds on both Linux and MacOS. | ||
|
||
The Docker philosophy of immutable layers is great for reproducibility, but a pain for debugging. To get back some of the benefits of tool-level caching, break up expensive operations whenever possible. | ||
|
||
I.e. where `cabal install` run directly will resume based on prior progress (i.e. expensive package compilation), to get similar behaviour via Docker we need to: | ||
|
||
```bash | ||
COPY elm.cabal ./ # only add elm.cabal | ||
RUN cabal build --only-dependencies # single layer for building deps based on elm.cabal only | ||
COPY ... # add all remaining project files afterward | ||
RUN cabal build # run the actual elm build | ||
``` | ||
|
||
Without this, even changing the readme would mean Docker decides all the packages need recompiling from scratch. |
This file was deleted.
Oops, something went wrong.