Brand New Build!

Features Linux x86_64 docker builds for all archs
This commit is contained in:
Vidar Holen
2021-02-11 17:18:43 -08:00
parent 15ff87cf80
commit b9b6975bfa
25 changed files with 461 additions and 254 deletions

13
build/README.md Normal file
View File

@@ -0,0 +1,13 @@
This directory contains Dockerfiles for all builds.
A build image will:
* Run on Linux x86\_64 with vanilla Docker (no exceptions)
* Not contain any software that would restrict easy modification or copying
* Take a `cabal sdist` style tar.gz of the ShellCheck directory on stdin
* Output a tar.gz of artifacts on stdout, in a directory named for the arch
This makes it simple to build any release without exotic hardware or software.
An image can be built and tagged using `build_builder`,
and run on a source tarball using `run_builder`.

12
build/build_builder Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/sh
if [ $# -eq 0 ]
then
echo >&2 "No build image directories specified"
echo >&2 "Example: $0 build/*/"
exit 1
fi
for dir
do
( cd "$dir" && docker build -t "$(cat tag)" . ) || exit 1
done

View File

@@ -0,0 +1,31 @@
# DIGEST:sha256:fa32af4677e2860a1c5950bc8c360f309e2a87e2ddfed27b642fddf7a6093b76
FROM liushuyu/osxcross:latest
ENV TARGET x86_64-apple-darwin18
ENV TARGETNAME darwin.x86_64
# Build dependencies
USER root
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y ghc automake autoconf llvm curl
# Build GHC
WORKDIR /ghc
RUN curl -L "https://downloads.haskell.org/~ghc/8.10.4/ghc-8.10.4-src.tar.xz" | tar xJ --strip-components=1
RUN ./boot && ./configure --host x86_64-linux-gnu --build x86_64-linux-gnu --target "$TARGET"
RUN cp mk/flavours/quick-cross.mk mk/build.mk && make -j "$(nproc)"
RUN make install
RUN curl -L "https://downloads.haskell.org/~cabal/cabal-install-3.2.0.0/cabal-install-3.2.0.0-x86_64-unknown-linux.tar.xz" | tar xJv -C /usr/local/bin
# Due to an apparent cabal bug, we specify our options directly to cabal
# It won't reuse caches if ghc-options are specified in ~/.cabal/config
ENV CABALOPTS "--with-ghc=$TARGET-ghc;--with-hc-pkg=$TARGET-ghc-pkg"
# Prebuild the dependencies
RUN cabal update && IFS=';' && cabal install $CABALOPTS --lib Diff-0.4.0 base-compat-0.11.2 base-orphans-0.8.4 dlist-1.0 hashable-1.3.0.0 indexed-traversable-0.1.1 integer-logarithms-1.0.3.1 primitive-0.7.1.0 regex-base-0.94.0.0 splitmix-0.1.0.3 tagged-0.8.6.1 th-abstraction-0.4.2.0 transformers-compat-0.6.6 base-compat-batteries-0.11.2 time-compat-1.9.5 unordered-containers-0.2.13.0 data-fix-0.3.1 vector-0.12.2.0 scientific-0.3.6.2 regex-tdfa-1.3.1.0 random-1.2.0 distributive-0.6.2.1 attoparsec-0.13.2.5 uuid-types-1.0.3 comonad-5.0.8 bifunctors-5.5.10 assoc-1.0.2 these-1.1.1.1 strict-0.4.0.1 aeson-1.5.5.1
# Copy the build script
COPY build /usr/bin
WORKDIR /scratch
ENTRYPOINT ["/usr/bin/build"]

14
build/darwin.x86_64/build Executable file
View File

@@ -0,0 +1,14 @@
#!/bin/sh
set -xe
{
tar xzv --strip-components=1
./striptests
mkdir "$TARGETNAME"
cabal update
( IFS=';'; cabal build $CABALOPTS )
find . -name shellcheck -type f -exec mv {} "$TARGETNAME/" \;
ls -l "$TARGETNAME"
"$TARGET-strip" -Sx "$TARGETNAME/shellcheck"
ls -l "$TARGETNAME"
} >&2
tar czv "$TARGETNAME"

1
build/darwin.x86_64/tag Normal file
View File

@@ -0,0 +1 @@
koalaman/scbuilder-darwin-x86_64

View File

@@ -0,0 +1,30 @@
FROM ubuntu:20.04
ENV TARGET aarch64-linux-gnu
ENV TARGETNAME linux.aarch64
# Build dependencies
USER root
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y ghc automake autoconf build-essential llvm curl qemu-user-static gcc-$TARGET
# Build GHC
WORKDIR /ghc
RUN curl -L "https://downloads.haskell.org/~ghc/8.10.4/ghc-8.10.4-src.tar.xz" | tar xJ --strip-components=1
RUN ./boot && ./configure --host x86_64-linux-gnu --build x86_64-linux-gnu --target "$TARGET"
RUN cp mk/flavours/quick-cross.mk mk/build.mk && make -j "$(nproc)"
RUN make install
RUN curl -L "https://downloads.haskell.org/~cabal/cabal-install-3.2.0.0/cabal-install-3.2.0.0-x86_64-unknown-linux.tar.xz" | tar xJv -C /usr/local/bin
# Due to an apparent cabal bug, we specify our options directly to cabal
# It won't reuse caches if ghc-options are specified in ~/.cabal/config
ENV CABALOPTS "--ghc-options;-split-sections -optc-Os -optc-Wl,--gc-sections;--with-ghc=$TARGET-ghc;--with-hc-pkg=$TARGET-ghc-pkg"
# Prebuild the dependencies
RUN cabal update && IFS=';' && cabal install $CABALOPTS --lib Diff-0.4.0 base-compat-0.11.2 base-orphans-0.8.4 dlist-1.0 hashable-1.3.0.0 indexed-traversable-0.1.1 integer-logarithms-1.0.3.1 primitive-0.7.1.0 regex-base-0.94.0.0 splitmix-0.1.0.3 tagged-0.8.6.1 th-abstraction-0.4.2.0 transformers-compat-0.6.6 base-compat-batteries-0.11.2 time-compat-1.9.5 unordered-containers-0.2.13.0 data-fix-0.3.1 vector-0.12.2.0 scientific-0.3.6.2 regex-tdfa-1.3.1.0 random-1.2.0 distributive-0.6.2.1 attoparsec-0.13.2.5 uuid-types-1.0.3 comonad-5.0.8 bifunctors-5.5.10 assoc-1.0.2 these-1.1.1.1 strict-0.4.0.1 aeson-1.5.5.1
# Copy the build script
COPY build /usr/bin
WORKDIR /scratch
ENTRYPOINT ["/usr/bin/build"]

15
build/linux.aarch64/build Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
set -xe
{
tar xzv --strip-components=1
./striptests
mkdir "$TARGETNAME"
cabal update
( IFS=';'; cabal build $CABALOPTS --enable-executable-static )
find . -name shellcheck -type f -exec mv {} "$TARGETNAME/" \;
ls -l "$TARGETNAME"
"$TARGET-strip" -s "$TARGETNAME/shellcheck"
ls -l "$TARGETNAME"
qemu-aarch64-static "$TARGETNAME/shellcheck" --version
} >&2
tar czv "$TARGETNAME"

1
build/linux.aarch64/tag Normal file
View File

@@ -0,0 +1 @@
koalaman/scbuilder-linux-aarch64

View File

@@ -0,0 +1,59 @@
# I've again spent days trying to get a working armv6hf compiler going.
# God only knows how many recompilations of GCC, GHC, libraries, and
# ShellCheck itself, has gone into it.
#
# I tried Debian's toolchain. I tried my custom one built according to
# RPi `gcc -v`. I tried GHC9, glibc, musl, registerised vs not, but
# nothing has yielded an armv6hf binary that does not immediately
# segfault on qemu-arm-static or the RPi itself.
#
# I then tried the same but with armv7hf. Same story.
#
# Emulating the entire userspace with balenalib again? Very strange build
# failures where programs would fail to execute with > ~100 arguments.
#
# Finally, creating our own appears to work when using a custom QEmu
# patched to follow execve calls.
#
# PS: $100 bounty for getting a RPi1 compatible static build going
# with cross-compilation, similar to what the aarch64 build does.
#
FROM ubuntu:20.04
ENV TARGETNAME linux.armv6hf
# Build QEmu with execve follow support
USER root
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y build-essential git ninja-build python3 pkg-config libglib2.0-dev libpixman-1-dev
WORKDIR /build
RUN git clone --depth 1 https://github.com/koalaman/qemu
RUN cd qemu && ./configure --static && cd build && ninja qemu-arm
RUN cp qemu/build/qemu-arm /build/qemu-arm-static
ENV QEMU_EXECVE 1
# Set up an armv6 userspace
WORKDIR /
RUN apt-get install -y debootstrap qemu-user-static
# We expect this to fail if the host doesn't have binfmt qemu support
RUN qemu-debootstrap --arch armhf bullseye pi http://mirrordirector.raspbian.org/raspbian || [ -e /pi/etc/issue ]
RUN cp /build/qemu-arm-static /pi/usr/bin/qemu-arm-static
RUN printf > /bin/pirun '%s\n' '#!/bin/sh' 'chroot /pi /usr/bin/qemu-arm-static /usr/bin/env "$@"' && chmod +x /bin/pirun
# If the debootstrap process didn't finish, continue it
RUN [ ! -e /pi/debootstrap ] || pirun '/debootstrap/debootstrap' --second-stage
# Install deps in the chroot
RUN pirun apt-get update
RUN pirun apt-get install -y ghc cabal-install
# Finally we can build the current dependencies. This takes hours.
ENV CABALOPTS "--ghc-options;-split-sections -optc-Os -optc-Wl,--gc-sections;--gcc-options;-Os -Wl,--gc-sections -ffunction-sections -fdata-sections"
RUN pirun cabal update
RUN IFS=";" && pirun cabal install --lib $CABALOPTS Diff-0.4.0 base-compat-0.11.2 base-orphans-0.8.4 dlist-1.0 hashable-1.3.1.0 indexed-traversable-0.1.1 integer-logarithms-1.0.3.1 primitive-0.7.1.0 regex-base-0.94.0.1 splitmix-0.1.0.3 tagged-0.8.6.1 th-abstraction-0.4.2.0 transformers-compat-0.6.6 base-compat-batteries-0.11.2 time-compat-1.9.5 unordered-containers-0.2.13.0 data-fix-0.3.1 vector-0.12.2.0 scientific-0.3.6.2 regex-tdfa-1.3.1.0 random-1.2.0 distributive-0.6.2.1 attoparsec-0.13.2.5 uuid-types-1.0.4 comonad-5.0.8 bifunctors-5.5.10 assoc-1.0.2 these-1.1.1.1 strict-0.4.0.1 aeson-1.5.6.0
# Copy the build script
WORKDIR /pi/scratch
COPY build /pi/usr/bin
ENTRYPOINT ["/bin/pirun", "/usr/bin/build"]

16
build/linux.armv6hf/build Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
set -xe
cd /scratch
{
tar xzv --strip-components=1
./striptests
mkdir "$TARGETNAME"
# This script does not cabal update because compiling anything new is slow
( IFS=';'; cabal build $CABALOPTS --enable-executable-static )
find . -name shellcheck -type f -exec mv {} "$TARGETNAME/" \;
ls -l "$TARGETNAME"
strip -s "$TARGETNAME/shellcheck"
ls -l "$TARGETNAME"
"$TARGETNAME/shellcheck" --version
} >&2
tar czv "$TARGETNAME"

1
build/linux.armv6hf/tag Normal file
View File

@@ -0,0 +1 @@
koalaman/scbuilder-linux-armv6hf

View File

@@ -0,0 +1,26 @@
FROM ubuntu:20.04
ENV TARGETNAME linux.x86_64
# Install GHC and cabal
USER root
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y ghc curl xz-utils
# So we'd like a later version of Cabal that supports --enable-executable-static,
# but we can't use Ubuntu 20.10 because coreutils has switched to new syscalls that
# the TravisCI kernel doesn't support. Download it manually.
RUN curl "https://downloads.haskell.org/~cabal/cabal-install-3.2.0.0/cabal-install-3.2.0.0-x86_64-unknown-linux.tar.xz" | tar xJv -C /usr/bin
# Use ld.bfd instead of ld.gold due to
# x86_64-linux-gnu/libpthread.a(pthread_cond_init.o)(.note.stapsdt+0x14): error:
# relocation refers to local symbol "" [2], which is defined in a discarded section
ENV CABALOPTS "--ghc-options;-optl-Wl,-fuse-ld=bfd -split-sections -optc-Os -optc-Wl,--gc-sections"
# Other archs pre-build dependencies here, but this one doesn't to detect ecosystem movement
# Copy the build script
COPY build /usr/bin
WORKDIR /scratch
ENTRYPOINT ["/usr/bin/build"]

15
build/linux.x86_64/build Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
set -xe
{
tar xzv --strip-components=1
./striptests
mkdir "$TARGETNAME"
cabal update
( IFS=';'; cabal build $CABALOPTS --enable-executable-static )
find . -name shellcheck -type f -exec mv {} "$TARGETNAME/" \;
ls -l "$TARGETNAME"
strip -s "$TARGETNAME/shellcheck"
ls -l "$TARGETNAME"
"$TARGETNAME/shellcheck" --version
} >&2
tar czv "$TARGETNAME"

1
build/linux.x86_64/tag Normal file
View File

@@ -0,0 +1 @@
koalaman/scbuilder-linux-x86_64

30
build/run_builder Executable file
View File

@@ -0,0 +1,30 @@
#!/bin/bash
if [ $# -lt 2 ]
then
echo >&2 "This script builds a source archive (as produced by cabal sdist)"
echo >&2 "Usage: $0 sourcefile.tar.gz builddir..."
exit 1
fi
file=$(realpath "$1")
shift
if [ ! -e "$file" ]
then
echo >&2 "$file does not exist"
exit 1
fi
set -ex -o pipefail
for dir
do
tagfile="$dir/tag"
if [ ! -e "$tagfile" ]
then
echo >&2 "$tagfile does not exist"
exit 2
fi
docker run -i "$(< "$tagfile")" < "$file" | tar xz
done

View File

@@ -0,0 +1,27 @@
FROM ubuntu:20.04
ENV TARGETNAME windows.x86_64
# We don't need wine32, even though it complains
USER root
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y curl busybox wine
# Fetch Windows version, will be available under z:\haskell
WORKDIR /haskell
RUN curl -L "https://downloads.haskell.org/~ghc/8.10.4/ghc-8.10.4-x86_64-unknown-mingw32.tar.xz" | tar xJ --strip-components=1
WORKDIR /haskell/bin
RUN curl -L "https://downloads.haskell.org/~cabal/cabal-install-3.2.0.0/cabal-install-3.2.0.0-x86_64-unknown-mingw32.zip" | busybox unzip -
RUN curl -L "https://curl.se/windows/dl-7.75.0/curl-7.75.0-win64-mingw.zip" | busybox unzip - && mv curl-7.75.0-win64-mingw/bin/* .
ENV WINEPATH /haskell/bin
# It's unknown whether Cabal on Windows suffers from the same issue
# that necessitated this but I don't care enough to find out
ENV CABALOPTS "--ghc-options;-split-sections -optc-Os -optc-Wl,--gc-sections"
# Precompile some deps to speed up later builds. This list is just copied from `cabal build`
RUN wine /haskell/bin/cabal.exe update && IFS=';' && wine /haskell/bin/cabal.exe install $CABALOPTS --lib Diff-0.4.0 base-compat-0.11.2 base-orphans-0.8.4 dlist-1.0 hashable-1.3.0.0 indexed-traversable-0.1.1 integer-logarithms-1.0.3.1 primitive-0.7.1.0 regex-base-0.94.0.0 splitmix-0.1.0.3 tagged-0.8.6.1 th-abstraction-0.4.2.0 transformers-compat-0.6.6 base-compat-batteries-0.11.2 time-compat-1.9.5 unordered-containers-0.2.13.0 data-fix-0.3.1 vector-0.12.2.0 scientific-0.3.6.2 regex-tdfa-1.3.1.0 random-1.2.0 distributive-0.6.2.1 attoparsec-0.13.2.5 uuid-types-1.0.3 comonad-5.0.8 bifunctors-5.5.10 assoc-1.0.2 these-1.1.1.1 strict-0.4.0.1 aeson-1.5.5.1
COPY build /usr/bin
WORKDIR /scratch
ENTRYPOINT ["/usr/bin/build"]

19
build/windows.x86_64/build Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/sh
cabal() {
wine /haskell/bin/cabal.exe "$@"
}
set -xe
{
tar xzv --strip-components=1
./striptests
mkdir "$TARGETNAME"
cabal update
( IFS=';'; cabal build $CABALOPTS )
find dist*/ -name shellcheck.exe -type f -ls -exec mv {} "$TARGETNAME/" \;
ls -l "$TARGETNAME"
wine "/haskell/mingw/bin/strip.exe" -s "$TARGETNAME/shellcheck.exe"
ls -l "$TARGETNAME"
wine "$TARGETNAME/shellcheck.exe" --version
} >&2
tar czv "$TARGETNAME"

1
build/windows.x86_64/tag Normal file
View File

@@ -0,0 +1 @@
koalaman/scbuilder-windows-x86_64