tinygo/.circleci/config.yml
Ayke van Laethem 403d93560b builder: build static binaries using musl on Linux
This commit adds support for musl-libc and uses it by default on Linux.
The main benefit of it is that binaries are always statically linked
instead of depending on the host libc, even when using CGo.

Advantages:
  - The resulting binaries are always statically linked.
  - No need for any tools on the host OS, like a compiler, linker, or
    libc in a release build of TinyGo.
  - This also simplifies cross compilation as no cross compiler is
    needed (it's all built into the TinyGo release build).

Disadvantages:
  - Binary size increases by 5-6 kilobytes if -no-debug is used. Binary
    size increases by a much larger margin when debugging symbols are
    included (the default behavior) because musl is built with debugging
    symbols enabled.
  - Musl does things a bit differently than glibc, and some CGo code
    might rely on the glibc behavior.
  - The first build takes a bit longer because musl needs to be built.

As an additional bonus, time is now obtained from the system in a way
that fixes the Y2038 problem because musl has been a bit more agressive
in switching to 64-bit time_t.
2021-11-04 17:15:38 +01:00

400 строки
13 КиБ
YAML

version: 2.1
commands:
submodules:
steps:
- run:
name: "Pull submodules"
command: git submodule update --init
apt-dependencies:
parameters:
llvm:
type: string
steps:
- run:
name: "Install apt dependencies"
command: |
echo 'deb https://apt.llvm.org/buster/ llvm-toolchain-buster-<<parameters.llvm>> main' | sudo tee /etc/apt/sources.list.d/llvm.list
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
sudo apt-get update
sudo apt-get install --no-install-recommends \
llvm-<<parameters.llvm>>-dev \
clang-<<parameters.llvm>> \
libclang-<<parameters.llvm>>-dev \
lld-<<parameters.llvm>> \
qemu-system-arm \
qemu-user \
gcc-avr \
avr-libc
install-node:
steps:
- run:
name: "Install node.js"
command: |
wget https://nodejs.org/dist/v10.15.1/node-v10.15.1-linux-x64.tar.xz
sudo tar -C /usr/local -xf node-v10.15.1-linux-x64.tar.xz
sudo ln -s /usr/local/node-v10.15.1-linux-x64/bin/node /usr/bin/node
rm node-v10.15.1-linux-x64.tar.xz
install-chrome:
steps:
- run:
name: "Install Chrome"
command: |
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install ./google-chrome-stable_current_amd64.deb
install-wasmtime:
steps:
- run:
name: "Install wasmtime"
command: |
curl https://wasmtime.dev/install.sh -sSf | bash
sudo ln -s ~/.wasmtime/bin/wasmtime /usr/local/bin/wasmtime
install-xtensa-toolchain:
parameters:
variant:
type: string
steps:
- run:
name: "Install Xtensa toolchain"
command: |
curl -L https://github.com/espressif/crosstool-NG/releases/download/esp-2020r2/xtensa-esp32-elf-gcc8_2_0-esp-2020r2-<<parameters.variant>>.tar.gz -o xtensa-esp32-elf-gcc8_2_0-esp-2020r2-<<parameters.variant>>.tar.gz
sudo tar -C /usr/local -xf xtensa-esp32-elf-gcc8_2_0-esp-2020r2-<<parameters.variant>>.tar.gz
sudo ln -s /usr/local/xtensa-esp32-elf/bin/xtensa-esp32-elf-ld /usr/local/bin/xtensa-esp32-elf-ld
rm xtensa-esp32-elf-gcc8_2_0-esp-2020r2-<<parameters.variant>>.tar.gz
llvm-source-linux:
steps:
- restore_cache:
keys:
- llvm-source-11-v2
- run:
name: "Fetch LLVM source"
command: make llvm-source
- save_cache:
key: llvm-source-11-v2
paths:
- llvm-project/clang/lib/Headers
- llvm-project/clang/include
- llvm-project/lld/include
- llvm-project/llvm/include
build-wasi-libc:
steps:
- restore_cache:
keys:
- wasi-libc-sysroot-v4
- run:
name: "Build wasi-libc"
command: make wasi-libc
- save_cache:
key: wasi-libc-sysroot-v4
paths:
- lib/wasi-libc/sysroot
test-linux:
parameters:
llvm:
type: string
steps:
- checkout
- submodules
- apt-dependencies:
llvm: "<<parameters.llvm>>"
- install-node
- install-chrome
- install-wasmtime
- restore_cache:
keys:
- go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
- go-cache-v2-{{ checksum "go.mod" }}
- llvm-source-linux
- run: go install -tags=llvm<<parameters.llvm>> .
- restore_cache:
keys:
- wasi-libc-sysroot-systemclang-v3
- run: make wasi-libc
- save_cache:
key: wasi-libc-sysroot-systemclang-v3
paths:
- lib/wasi-libc/sysroot
- run:
name: "Test TinyGo"
command: go test -v -timeout=20m -tags=llvm<<parameters.llvm>> ./builder ./cgo ./compileopts ./compiler ./interp ./transform .
no_output_timeout: 20m
- run: make gen-device -j4
- run: make smoketest XTENSA=0
- run: make tinygo-test
- run: make wasmtest
- save_cache:
key: go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
paths:
- ~/.cache/go-build
- /go/pkg/mod
- run: make fmt-check
assert-test-linux:
steps:
- checkout
- submodules
- run:
name: "Install apt dependencies"
command: |
sudo apt-get update
sudo apt-get install --no-install-recommends \
libgnutls30 libssl1.0.2 \
qemu-system-arm \
qemu-user \
gcc-avr \
avr-libc
- install-node
- install-wasmtime
- install-xtensa-toolchain:
variant: "linux-amd64"
- restore_cache:
keys:
- go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
- go-cache-v2-{{ checksum "go.mod" }}
- llvm-source-linux
- restore_cache:
keys:
- llvm-build-11-linux-v4-assert
- run:
name: "Build LLVM"
command: |
if [ ! -f llvm-build/lib/liblldELF.a ]
then
# fetch LLVM source
rm -rf llvm-project
make llvm-source
# install dependencies
sudo apt-get install cmake ninja-build
# hack ninja to use less jobs
echo -e '#!/bin/sh\n/usr/bin/ninja -j3 "$@"' > /go/bin/ninja
chmod +x /go/bin/ninja
# build!
make ASSERT=1 llvm-build
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
fi
- save_cache:
key: llvm-build-11-linux-v4-assert
paths:
llvm-build
- run: make ASSERT=1
- build-wasi-libc
- run:
name: "Test TinyGo"
command: make ASSERT=1 test
no_output_timeout: 20m
environment:
# Note: -p=2 limits parallelism to two jobs at a time, which is
# necessary to keep memory consumption down and avoid OOM (for a
# 2CPU/4GB executor).
GOFLAGS: -p=2
- save_cache:
key: go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
paths:
- ~/.cache/go-build
- /go/pkg/mod
- run: make gen-device -j4
- run: make smoketest TINYGO=build/tinygo
build-linux:
steps:
- checkout
- submodules
- run:
name: "Install apt dependencies"
command: |
sudo apt-get update
sudo apt-get install --no-install-recommends \
libgnutls30 libssl1.0.2 \
qemu-system-arm \
qemu-user \
gcc-avr \
avr-libc
- install-node
- install-wasmtime
- install-xtensa-toolchain:
variant: "linux-amd64"
- restore_cache:
keys:
- go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
- go-cache-v2-{{ checksum "go.mod" }}
- llvm-source-linux
- restore_cache:
keys:
- llvm-build-11-linux-v4-noassert
- run:
name: "Build LLVM"
command: |
if [ ! -f llvm-build/lib/liblldELF.a ]
then
# fetch LLVM source
rm -rf llvm-project
make llvm-source
# install dependencies
sudo apt-get install cmake ninja-build
# hack ninja to use less jobs
echo -e '#!/bin/sh\n/usr/bin/ninja -j3 "$@"' > /go/bin/ninja
chmod +x /go/bin/ninja
# build!
make llvm-build
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
fi
- save_cache:
key: llvm-build-11-linux-v4-noassert
paths:
llvm-build
- build-wasi-libc
- run:
name: "Test TinyGo"
command: make test
no_output_timeout: 20m
- run:
name: "Install fpm"
command: |
sudo apt-get install ruby ruby-dev
sudo gem install --no-document fpm
- run:
name: "Build TinyGo release"
command: |
make release deb -j3
cp -p build/release.tar.gz /tmp/tinygo.linux-amd64.tar.gz
cp -p build/release.deb /tmp/tinygo_amd64.deb
- store_artifacts:
path: /tmp/tinygo.linux-amd64.tar.gz
- store_artifacts:
path: /tmp/tinygo_amd64.deb
- save_cache:
key: go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
paths:
- ~/.cache/go-build
- /go/pkg/mod
- run:
name: "Extract release tarball"
command: |
mkdir -p ~/lib
tar -C ~/lib -xf /tmp/tinygo.linux-amd64.tar.gz
ln -s ~/lib/tinygo/bin/tinygo /go/bin/tinygo
tinygo version
- run: make smoketest
build-macos:
steps:
- checkout
- submodules
- run:
name: "Install dependencies"
command: |
curl https://dl.google.com/go/go1.17.darwin-amd64.tar.gz -o go1.17.darwin-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.17.darwin-amd64.tar.gz
ln -s /usr/local/go/bin/go /usr/local/bin/go
HOMEBREW_NO_AUTO_UPDATE=1 brew install qemu
- install-xtensa-toolchain:
variant: "macos"
- restore_cache:
keys:
- go-cache-macos-v3-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
- go-cache-macos-v3-{{ checksum "go.mod" }}
- restore_cache:
keys:
- llvm-source-11-macos-v3
- run:
name: "Fetch LLVM source"
command: make llvm-source
- save_cache:
key: llvm-source-11-macos-v3
paths:
- llvm-project/clang/lib/Headers
- llvm-project/clang/include
- llvm-project/lld/include
- llvm-project/llvm/include
- restore_cache:
keys:
- llvm-build-11-macos-v5
- run:
name: "Build LLVM"
command: |
if [ ! -f llvm-build/lib/liblldELF.a ]
then
# fetch LLVM source
rm -rf llvm-project
make llvm-source
# install dependencies
HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake ninja
# build!
make llvm-build
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
fi
- save_cache:
key: llvm-build-11-macos-v5
paths:
llvm-build
- restore_cache:
keys:
- wasi-libc-sysroot-macos-v4
- run:
name: "Build wasi-libc"
command: make wasi-libc
- save_cache:
key: wasi-libc-sysroot-macos-v4
paths:
- lib/wasi-libc/sysroot
- run:
name: "Test TinyGo"
command: make test
no_output_timeout: 20m
- run:
name: "Build TinyGo release"
command: |
make release -j3
cp -p build/release.tar.gz /tmp/tinygo.darwin-amd64.tar.gz
- store_artifacts:
path: /tmp/tinygo.darwin-amd64.tar.gz
- run:
name: "Extract release tarball"
command: |
mkdir -p ~/lib
tar -C /usr/local/opt -xf /tmp/tinygo.darwin-amd64.tar.gz
ln -s /usr/local/opt/tinygo/bin/tinygo /usr/local/bin/tinygo
tinygo version
- run: make smoketest AVR=0
- save_cache:
key: go-cache-macos-v3-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
paths:
- ~/.cache/go-build
- /go/pkg/mod
jobs:
test-llvm11-go115:
docker:
- image: circleci/golang:1.15-buster
steps:
- test-linux:
llvm: "11"
test-llvm11-go116:
docker:
- image: circleci/golang:1.16-buster
steps:
- test-linux:
llvm: "11"
assert-test-linux:
docker:
- image: circleci/golang:1.17-stretch
steps:
- assert-test-linux
build-linux:
docker:
- image: circleci/golang:1.17-stretch
steps:
- build-linux
build-macos:
macos:
xcode: "11.1.0" # macOS 10.14
steps:
- build-macos
workflows:
test-all:
jobs:
- test-llvm11-go115
- test-llvm11-go116
- build-linux
- build-macos
- assert-test-linux