snmalloc/.github/workflows/main.yml

445 строки
18 KiB
YAML

name: snmalloc CI
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ main ]
pull_request:
branches: [ main, snmalloc1 ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
linux:
strategy:
matrix:
# Build each combination of OS and release/debug variants
os: [ "ubuntu-latest", "ubuntu-20.04", "macos-11", "macos-12" ]
build-type: [ Release, Debug ]
# Extra cmake flags. GitHub Actions matrix overloads `include` to mean
# 'add extra things to a job' and 'add jobs'. You can add extra things
# to a job by specifying things that exist in a job created from the
# matrix definition and adding things. You can specify extra jobs by
# specifying properties that don't match existing jobs. We use
# `cmake-flags` to add cmake flags to all jobs matching a pattern and
# `extra-cmake-flags` to specify a new job with custom CMake flags.
extra-cmake-flags: [ "" ]
# Modify the complete matrix
include:
# Provide the dependency installation for each platform
- os: "ubuntu-20.04"
dependencies: "sudo apt install ninja-build"
cmake-flags: "-DSNMALLOC_USE_CXX17=ON"
- os: "ubuntu-20.04"
dependencies: "sudo apt install ninja-build"
- os: "ubuntu-latest" # 22.04 at time of writing
dependencies: "sudo apt install ninja-build"
- os: "macos-11"
# The homebrew packages are broken at the moment and error out
# after trying to install Python as a dependency of ninja because
# 2to3 exists. As a quick hack, delete it first. This should be
# removed once the homebrew install is fixed.
dependencies: "rm -f /usr/local/bin/2to3 ; brew update && brew install ninja"
- os: "macos-12"
dependencies: "rm -f /usr/local/bin/2to3 ; brew update && brew install ninja"
- os: "macos-12"
variant: "C++17"
dependencies: "rm -f /usr/local/bin/2to3 ; brew update && brew install ninja"
cmake-flags: "-DSNMALLOC_USE_CXX17=ON"
# Add the self-host build, using the bounds-checked memcpy in
# maximally paranoid mode (checking loads and stores)
- os: "ubuntu-latest"
build-type: Debug
self-host: true
extra-cmake-flags: "-DSNMALLOC_MEMCPY_BOUNDS=ON -DSNMALLOC_CHECK_LOADS=ON"
dependencies: "sudo apt install ninja-build"
# Extra build to check using pthread library for destructing local state.
- os: "ubuntu-latest"
variant: "with pthread destructors"
dependencies: "sudo apt install ninja-build"
build-type: Debug
self-host: true
extra-cmake-flags: "-DSNMALLOC_USE_PTHREAD_DESTRUCTORS=On"
# Extra build to check using individual mitigations works.
- os: "ubuntu-latest"
variant: "individual mitigations"
dependencies: "sudo apt install ninja-build"
build-type: Release
self-host: true
extra-cmake-flags: "-DSNMALLOC_BENCHMARK_INDIVIDUAL_MITIGATIONS=On -DSNMALLOC_BUILD_TESTING=Off"
# Check that we can build specifically with libstdc++
- os: "ubuntu-latest"
variant: "libstdc++ (Build only)"
dependencies: "sudo apt install ninja-build"
extra-cmake-flags: "-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS=-stdlib=libstdc++"
build-only: yes
# Replay some of the above tests with clang-10 specifically
- os: "ubuntu-20.04"
variant: "clang-10 (with pthread destructors)."
dependencies: "sudo apt install ninja-build"
build-type: Debug
self-host: true
extra-cmake-flags: "-DSNMALLOC_USE_PTHREAD_DESTRUCTORS=On -DCMAKE_CXX_COMPILER=clang++-10 -DCMAKE_C_COMPILER=clang-10"
- os: "ubuntu-20.04"
variant: "clang-10 libstdc++ (Build only)"
dependencies: "sudo apt install ninja-build"
extra-cmake-flags: "-DCMAKE_CXX_COMPILER=clang++-10 -DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_FLAGS=-stdlib=libstdc++"
build-only: yes
# Don't abort runners if a single one fails
fail-fast: false
runs-on: ${{ matrix.os }}
name: ${{ matrix.os }} ${{ matrix.build-type }} ${{ matrix.variant }}
steps:
- uses: actions/checkout@v3
- name: Install build dependencies
run: ${{ matrix.dependencies }}
- uses: mjp41/workaround8649@c8550b715ccdc17f89c8d5c28d7a48eeff9c94a8
with:
os: ${{ matrix.os }}
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.build-type}} -G Ninja ${{ matrix.cmake-flags }} ${{ matrix.extra-cmake-flags }}
# Build with a nice ninja status line
- name: Build
working-directory: ${{github.workspace}}/build
run: NINJA_STATUS="%p [%f:%s/%t] %o/s, %es" ninja
- name: Test file size of binaries is sane
working-directory: ${{github.workspace}}/build
run: "ls -l libsnmallocshim.* ; [ $(ls -l libsnmallocshim.* | awk '{ print $5}') -lt 10000000 ]"
# If the tests are enabled for this job, run them
- name: Test
if: ${{ matrix.build-only != 'yes' }}
working-directory: ${{github.workspace}}/build
run: ctest --output-on-failure -j 4 -C ${{ matrix.build-type }} --timeout 400
- name: Selfhost
if: ${{ matrix.self-host }}
working-directory: ${{github.workspace}}/build
run: |
mkdir libs
cp libsnmallocshim*.so libs
for lib in `ls libs`; do echo; echo Testing $lib; ninja clean; LD_PRELOAD=libs/$lib ninja libsnmallocshim.so; done
# GitHub doesn't natively support *BSD, but we can run them in VMs on Mac /
# Linux runners
freebsd:
strategy:
matrix:
# Build each combination of OS, version, and release/debug variants
# FreeBSD and OpenBSD run on xhyve, netbsd needs qemu
os:
- version: '13.2'
dependencies: pkg ins -y cmake ninja
build-type: [ Release, Debug ]
# Don't abort runners if a single one fails
fail-fast: false
# Kill these jobs if they take too long.
timeout-minutes: 25
runs-on: ubuntu-22.04
name: FreeBSD-${{ matrix.os.version}} ${{ matrix.build-type }}
steps:
- uses: actions/checkout@v3
- uses: vmactions/freebsd-vm@v1
with:
release: ${{ matrix.os.version}}
usesh: true
mem: 8192
copyback: false
prepare: |
${{ matrix.os.dependencies }}
run: |
set -e
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.build-type}} -G Ninja
cd ${{github.workspace}}/build
NINJA_STATUS="%p [%f:%s/%t] %o/s, %es" ninja
ctest -j 4 --output-on-failure -E '(perf-.*)|(.*-malloc$)' --timeout 400
netbsd:
strategy:
matrix:
os:
- version: '9.2'
dependencies: |
/usr/sbin/pkg_add cmake ninja-build gcc10
build-type: [ Release ]
# Don't abort runners if a single one fails
fail-fast: false
# Kill these jobs if they take too long.
timeout-minutes: 25
runs-on: ubuntu-22.04
name: NetBSD-${{ matrix.os.version}} ${{ matrix.build-type }}
steps:
- uses: actions/checkout@v3
- uses: vmactions/netbsd-vm@v1
with:
release: ${{ matrix.os.version}}
usesh: true
mem: 8192
copyback: false
prepare: |
${{ matrix.os.dependencies }}
run: |
set -e
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.build-type}} -G Ninja -DCMAKE_CXX_COMPILER=/usr/pkg/gcc10/bin/g++ -DCMAKE_C_COMPILER=/usr/pkg/gcc10/bin/gcc
cd ${{github.workspace}}/build
NINJA_STATUS="%p [%f:%s/%t] %o/s, %es" ninja
ctest -j 4 --output-on-failure -E '(perf-.*)|(.*-malloc$)' --timeout 400
## Without overcommit, or explicit commit the current implementation cannot be made to work on openbsd.
## We could add a layered pagemap for openbsd, that would address the requirements.
# openbsd:
# strategy:
# matrix:
# # Build each combination of OS, version, and release/debug variants
# os:
# - version: '7.2'
# dependencies: pkg_add -I cmake ninja
# build-type: [ Release, Debug ]
# # Don't abort runners if a single one fails
# fail-fast: false
# # Kill these jobs if they take too long.
# timeout-minutes: 25
# runs-on: macos-latest
# name: OpenBSD-${{ matrix.os.version}} ${{ matrix.build-type }}
# steps:
# - uses: actions/checkout@v3
# - uses: vmactions/openbsd-vm@v0
# with:
# release: ${{ matrix.os.version}}
# usesh: true
# mem: 8192
# copyback: false
# prepare: |
# ${{ matrix.os.dependencies }}
# run: |
# set -e
# cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.build-type}} -G Ninja
# cd ${{github.workspace}}/build
# NINJA_STATUS="%p [%f:%s/%t] %o/s, %es" ninja
# ctest -j 4 --output-on-failure -E '(perf-.*)|(.*-malloc$)' --timeout 400
sanitizer:
strategy:
matrix:
# Build just release variant as Debug is too slow.
build-type: [ Release ]
include:
- os: "ubuntu-latest"
continue-on-error: # Don't class as an error if this fails, until we have a more reliablity.
variant: "libc++ (TSan + UBSan)"
dependencies: "sudo apt install ninja-build"
extra-cmake-flags: "-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS=-stdlib=\"libc++ -g\" -DSNMALLOC_SANITIZER=undefined,thread"
# Also test specifically with clang-10 (on ubuntu-20.04)
- os: "ubuntu-20.04"
continue-on-error: # Don't class as an error if this fails, until we have a more reliablity.
variant: "clang-10 libc++ (TSan + UBSan)"
dependencies: "sudo apt install ninja-build"
extra-cmake-flags: "-DCMAKE_CXX_COMPILER=clang++-10 -DCMAKE_CXX_FLAGS=-stdlib=\"libc++ -g\" -DSNMALLOC_SANITIZER=undefined,thread"
# Don't abort runners if a single one fails
fail-fast: false
runs-on: ${{ matrix.os }}
name: ${{ matrix.os }} ${{ matrix.build-type }} ${{ matrix.variant }}
steps:
- uses: actions/checkout@v3
- name: Install build dependencies
run: ${{ matrix.dependencies }}
- uses: mjp41/workaround8649@c8550b715ccdc17f89c8d5c28d7a48eeff9c94a8
with:
os: ${{ matrix.os }}
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.build-type}} -G Ninja ${{ matrix.cmake-flags }} ${{ matrix.extra-cmake-flags }}
# Build with a nice ninja status line
- name: Build
working-directory: ${{github.workspace}}/build
run: NINJA_STATUS="%p [%f:%s/%t] %o/s, %es" ninja
- name: Test
working-directory: ${{github.workspace}}/build
run: ctest --output-on-failure -j 4 -C ${{ matrix.build-type }} --timeout 400 -E "memcpy|external_pointer" --repeat-until-fail 2
qemu-crossbuild:
strategy:
matrix:
build-type: [ Release, Debug ]
arch:
- name: armhf
system-processor: arm
triple: arm-linux-gnueabihf
rtld: ld-linux-armhf.so.3
ld-flavour: lld
host-os: ubuntu-latest
- name: arm64
system-processor: aarch64
triple: aarch64-linux-gnu
rtld: ld-linux-aarch64.so.1
ld-flavour: lld
host-os: ubuntu-latest
- name: ppc64el
system-processor: powerpc64le
triple: powerpc64le-linux-gnu
rtld: ld64.so.2
ld-flavour: lld
# See https://github.com/microsoft/snmalloc/issues/576
host-os: ubuntu-20.04
- name: riscv64
system-processor: riscv64
triple: riscv64-linux-gnu
rtld: ld-linux-riscv64-lp64d.so.1
extra-packages: binutils-riscv64-linux-gnu
ld-flavour: bfd
ld: /usr/bin/riscv64-linux-gnu-ld.bfd
host-os: ubuntu-latest
# Don't abort runners if a single one fails
fail-fast: false
runs-on: ${{matrix.arch.host-os}}
name: ${{matrix.build-type}} cross-build for ${{ matrix.arch.triple }}
steps:
- uses: actions/checkout@v3
- name: "Install cross-compile toolchain and QEMU (ubuntu-20.04)"
# Install the dependencies and clang 13. Earlier versions of clang don't
# find the multilib things for this week's Ubuntu filesystem layout.
if: matrix.arch.host-os == 'ubuntu-20.04'
run: |
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo add-apt-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-13 main"
sudo apt update
sudo apt install libstdc++-9-dev-${{ matrix.arch.name }}-cross qemu-user ninja-build clang-13 lld-13
sudo apt install ${{matrix.arch.extra-packages}}
- name: "Install cross-compile toolchain and QEMU (ubuntu-latest)"
if: matrix.arch.host-os == 'ubuntu-latest'
run: |
sudo apt update
sudo apt install libstdc++-12-dev-${{ matrix.arch.name }}-cross qemu-user ninja-build
sudo apt install ${{matrix.arch.extra-packages}}
- name: Reconfigure for PowerPC64LE
if: startsWith(matrix.arch.triple, 'powerpc64le')
# The default PowerPC qemu configuration uses the wrong page size.
# Wrap it in a script that fixes this.
run: |
sudo update-binfmts --disable qemu-ppc64le
sudo sh -c 'echo ":qemu-ppc64le:M:0:\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15\x00:\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\x00:`pwd`/ppc64.sh:" > /proc/sys/fs/binfmt_misc/register'
echo '#!/bin/sh' > ppc64.sh
echo '/usr/bin/qemu-ppc64le -p 65536 $@' >> ppc64.sh
chmod +x ppc64.sh
- name: Configure
env:
SNMALLOC_CI_CLANG_VERSION: ${{ (matrix.arch.host-os == 'ubuntu-latest') && 14 || 13 }}
RTLD_NAME: ${{ matrix.arch.rtld }}
ARCH: ${{ matrix.arch.system-processor }}
TRIPLE: ${{ matrix.arch.triple}}
run: >
cmake
-B ${{github.workspace}}/build
-DCMAKE_BUILD_TYPE=${{matrix.build-type}}
-G Ninja
-DSNMALLOC_CI_BUILD=ON
-DSNMALLOC_QEMU_WORKAROUND=ON
-DSNMALLOC_STATIC_LIBRARY=OFF
-DCMAKE_TOOLCHAIN_FILE=ci/Toolchain.cmake
-DSNMALLOC_LINKER=${{matrix.arch.ld}}
-DSNMALLOC_LINKER_FLAVOUR=${{matrix.arch.ld-flavour}}
- name: Build
working-directory: ${{github.workspace}}/build
run: NINJA_STATUS="%p [%f:%s/%t] %o/s, %es" ninja
# For debugging: verify that we've actually cross-compiled.
- name: Run `file` for inspection
working-directory: ${{github.workspace}}/build
run: file func*
# Run the tests, skipping the -malloc and perf- tests (perf doesn't make
# sense in an emulator and the pass-through malloc is slightly flaky in
# QEMU)
- name: Test
working-directory: ${{github.workspace}}/build
run: ctest -j 2 --output-on-failure -E '(perf-.*)|(.*-malloc$)' --timeout 400
timeout-minutes: 30
windows:
strategy:
matrix:
# Build each combination of OS and release/debug variants
os: [ windows-2019 ]
build-type: [ Release, Debug ]
arch: [ Win32, x64 ]
toolchain: [ "", "-T ClangCL" ]
extra-cmake-flags: [ "" ]
# Add an extra check for the Windows 8 compatible PAL
include:
- os: windows-2019
build-type: Release
arch: x64
toolchain: ""
extra-cmake-flags: -DWIN8COMPAT=TRUE
variant: Windows 8 compatible
- os: windows-2022
build-type: Release
arch: Win32
toolchain: ""
- os: windows-2022
build-type: Debug
arch: Win32
toolchain: ""
- os: windows-2022
build-type: Release
arch: x64
toolchain: ""
- os: windows-2022
build-type: Debug
arch: x64
toolchain: ""
# Don't abort runners if a single one fails
fail-fast: false
runs-on: ${{ matrix.os }}
name: ${{ matrix.os }} ${{ matrix.arch }} ${{ matrix.build-type }} ${{ matrix.toolchain }} ${{ matrix.variant }}
steps:
- uses: actions/checkout@v3
- name: Configure CMake
run: |
cmake -B ${{github.workspace}}/build -A ${{ matrix.arch }} ${{ matrix.toolchain }} ${{ matrix.extra-cmake-flags }} -DSNMALLOC_CI_BUILD=On -DSNMALLOC_RUST_SUPPORT=On
# Build with whatever version of msbuild was configured, for a single build configuration.
- name: Build
run: cmake --build ${{github.workspace}}/build -- /m /p:Configuration=${{ matrix.build-type }}
# Run the tests.
- name: Test
working-directory: ${{ github.workspace }}/build
run: ctest -j 2 --interactive-debug-mode 0 --output-on-failure -C ${{ matrix.build-type }} --timeout 400
timeout-minutes: 20
# Job to run clang-format and report errors
format:
runs-on: ubuntu-22.04
# We don't need to do the build for this job, but we need to configure it to get the clang-format target
steps:
- uses: actions/checkout@v3
- name: Install clang-tidy and clang-format
run: |
sudo apt update
sudo apt install clang-tidy-15 clang-format-15
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DSNMALLOC_USE_CXX17=ON
# Run the clang-format check and error if it generates a diff
- name: Run clang-format
working-directory: ${{github.workspace}}/build
run: |
set -eo pipefail
make clangformat
git diff --exit-code
- name: Run clang-tidy
run: |
clang-tidy-15 src/snmalloc/override/malloc.cc -header-filter="`pwd`/*" -warnings-as-errors='*' -export-fixes=tidy.fail -- -std=c++17 -mcx16 -DSNMALLOC_PLATFORM_HAS_GETENTROPY=0
if [ -f tidy.fail ] ; then
cat tidy.fail
exit 1
fi
all-checks:
# Currently FreeBSD and NetBSD CI are not working, so we do not require them to pass.
needs: [linux, qemu-crossbuild, windows, format, sanitizer]
runs-on: ubuntu-latest
steps:
- name: Dummy step
run: true