ci: build Linux binary in Alpine container

This makes it easier to move the TinyGo compiler between Linux versions
because it doesn't depend on any system libraries anymore. For example,
binaries should be able to run on old Linux versions and on
distributions without glibc (such as Alpine Linux).
Этот коммит содержится в:
Ayke van Laethem 2022-05-01 23:07:07 +02:00 коммит произвёл Ron Evans
родитель 1d99b1ed84
коммит 56780c2691
2 изменённых файлов: 45 добавлений и 18 удалений

42
.github/workflows/linux.yml предоставленный
Просмотреть файл

@ -14,19 +14,25 @@ concurrency:
jobs: jobs:
build-linux: build-linux:
# Build Linux binaries, ready for release. # Build Linux binaries, ready for release.
# This intentionally uses an older Linux image, so that we compile against # This runs inside an Alpine Linux container so we can more easily create a
# an older glibc version and therefore are compatible with a wide range of # statically linked binary.
# Linux distributions. runs-on: ubuntu-latest
runs-on: ubuntu-18.04 container:
image: alpine:3.16
steps: steps:
- name: Install apk dependencies
# tar: needed for actions/cache@v2
# git+openssh: needed for checkout (I think?)
# gcompat: needed for go binary
# ruby: needed to install fpm
run: apk add tar git openssh gcompat make g++ ruby
- name: Work around CVE-2022-24765
# We're not on a multi-user machine, so this is safe.
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
submodules: true submodules: true
- name: Install apt dependencies
run: |
sudo apt-get install --no-install-recommends \
ninja-build
- name: Install Go - name: Install Go
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
@ -34,7 +40,7 @@ jobs:
- name: Cache Go - name: Cache Go
uses: actions/cache@v2 uses: actions/cache@v2
with: with:
key: go-cache-linux-v1-${{ hashFiles('go.mod') }} key: go-cache-linux-alpine-v1-${{ hashFiles('go.mod') }}
path: | path: |
~/.cache/go-build ~/.cache/go-build
~/go/pkg/mod ~/go/pkg/mod
@ -42,7 +48,7 @@ jobs:
uses: actions/cache@v2 uses: actions/cache@v2
id: cache-llvm-source id: cache-llvm-source
with: with:
key: llvm-source-14-linux-v2 key: llvm-source-14-linux-alpine-v1
path: | path: |
llvm-project/clang/lib/Headers llvm-project/clang/lib/Headers
llvm-project/clang/include llvm-project/clang/include
@ -56,7 +62,7 @@ jobs:
uses: actions/cache@v2 uses: actions/cache@v2
id: cache-llvm-build id: cache-llvm-build
with: with:
key: llvm-build-14-linux-v1 key: llvm-build-14-linux-alpine-v1
path: llvm-build path: llvm-build
- name: Build LLVM - name: Build LLVM
if: steps.cache-llvm-build.outputs.cache-hit != 'true' if: steps.cache-llvm-build.outputs.cache-hit != 'true'
@ -64,6 +70,8 @@ jobs:
# fetch LLVM source # fetch LLVM source
rm -rf llvm-project rm -rf llvm-project
make llvm-source make llvm-source
# install dependencies
apk add cmake samurai python3
# build! # build!
make llvm-build make llvm-build
# Remove unnecessary object files (to reduce cache size). # Remove unnecessary object files (to reduce cache size).
@ -72,26 +80,28 @@ jobs:
uses: actions/cache@v2 uses: actions/cache@v2
id: cache-binaryen id: cache-binaryen
with: with:
key: binaryen-linux-v1 key: binaryen-linux-alpine-v1
path: build/wasm-opt path: build/wasm-opt
- name: Build Binaryen - name: Build Binaryen
if: steps.cache-binaryen.outputs.cache-hit != 'true' if: steps.cache-binaryen.outputs.cache-hit != 'true'
run: make binaryen run: |
apk add cmake samurai python3
make binaryen STATIC=1
- name: Cache wasi-libc - name: Cache wasi-libc
uses: actions/cache@v2 uses: actions/cache@v2
id: cache-wasi-libc id: cache-wasi-libc
with: with:
key: wasi-libc-sysroot-linux-asserts-v5 key: wasi-libc-sysroot-linux-alpine-v1
path: lib/wasi-libc/sysroot path: lib/wasi-libc/sysroot
- name: Build wasi-libc - name: Build wasi-libc
if: steps.cache-wasi-libc.outputs.cache-hit != 'true' if: steps.cache-wasi-libc.outputs.cache-hit != 'true'
run: make wasi-libc run: make wasi-libc
- name: Install fpm - name: Install fpm
run: | run: |
sudo gem install --no-document fpm gem install --no-document fpm
- name: Build TinyGo release - name: Build TinyGo release
run: | run: |
make release deb -j3 make release deb -j3 STATIC=1
cp -p build/release.tar.gz /tmp/tinygo.linux-amd64.tar.gz cp -p build/release.tar.gz /tmp/tinygo.linux-amd64.tar.gz
cp -p build/release.deb /tmp/tinygo_amd64.deb cp -p build/release.deb /tmp/tinygo_amd64.deb
- name: Publish release artifact - name: Publish release artifact

Просмотреть файл

@ -56,6 +56,23 @@ else
LLVM_OPTION += '-DLLVM_ENABLE_ASSERTIONS=OFF' LLVM_OPTION += '-DLLVM_ENABLE_ASSERTIONS=OFF'
endif endif
ifeq (1, $(STATIC))
# Build TinyGo as a fully statically linked binary (no dynamically loaded
# libraries such as a libc). This is not supported with glibc which is used
# on most major Linux distributions. However, it is supported in Alpine
# Linux with musl.
CGO_LDFLAGS += -static
# Also set the thread stack size to 1MB. This is necessary on musl as the
# default stack size is 128kB and LLVM uses more than that.
# For more information, see:
# https://wiki.musl-libc.org/functional-differences-from-glibc.html#Thread-stack-size
CGO_LDFLAGS += -Wl,-z,stack-size=1048576
# Build wasm-opt with static linking.
# For details, see:
# https://github.com/WebAssembly/binaryen/blob/version_102/.github/workflows/ci.yml#L181
BINARYEN_OPTION += -DCMAKE_CXX_FLAGS="-static" -DCMAKE_C_FLAGS="-static"
endif
# Cross compiling support. # Cross compiling support.
ifneq ($(CROSS),) ifneq ($(CROSS),)
CC = $(CROSS)-gcc CC = $(CROSS)-gcc
@ -246,9 +263,9 @@ lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a:
# Build the Go compiler. # Build the Go compiler.
tinygo: tinygo:
@if [ ! -f "$(LLVM_BUILDDIR)/bin/llvm-config" ]; then echo "Fetch and build LLVM first by running:"; echo " make llvm-source"; echo " make $(LLVM_BUILDDIR)"; exit 1; fi @if [ ! -f "$(LLVM_BUILDDIR)/bin/llvm-config" ]; then echo "Fetch and build LLVM first by running:"; echo " make llvm-source"; echo " make $(LLVM_BUILDDIR)"; exit 1; fi
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GOENVFLAGS) $(GO) build -buildmode exe -o build/tinygo$(EXE) -tags byollvm -ldflags="-X github.com/tinygo-org/tinygo/goenv.GitSha1=`git rev-parse --short HEAD`" . CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GOENVFLAGS) $(GO) build -buildmode exe -o build/tinygo$(EXE) -tags "byollvm osusergo" -ldflags="-X github.com/tinygo-org/tinygo/goenv.GitSha1=`git rev-parse --short HEAD`" .
test: wasi-libc test: wasi-libc
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=20m -buildmode exe -tags byollvm ./builder ./cgo ./compileopts ./compiler ./interp ./transform . CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=20m -buildmode exe -tags "byollvm osusergo" ./builder ./cgo ./compileopts ./compiler ./interp ./transform .
# Standard library packages that pass tests on darwin, linux, wasi, and windows, but take over a minute in wasi # Standard library packages that pass tests on darwin, linux, wasi, and windows, but take over a minute in wasi
TEST_PACKAGES_SLOW = \ TEST_PACKAGES_SLOW = \