Skip to content

Clarify Unalign ABI guarantees #361

Clarify Unalign ABI guarantees

Clarify Unalign ABI guarantees #361

Workflow file for this run

name: Build & Tests
on:
pull_request:
push:
branches: main
env:
CARGO_TERM_COLOR: always
RUSTFLAGS: -Dwarnings
RUSTDOCFLAGS: -Dwarnings
# `ZC_NIGHTLY_XXX` are flags that we add to `XXX` only on the nightly
# toolchain.
ZC_NIGHTLY_RUSTFLAGS: -Zrandomize-layout
ZC_NIGHTLY_MIRIFLAGS: "-Zmiri-symbolic-alignment-check -Zmiri-strict-provenance"
jobs:
build_test:
runs-on: ubuntu-latest
strategy:
matrix:
# See `INTERNAL.md` for an explanation of these pinned toolchain
# versions.
toolchain: [ "msrv", "stable", "nightly" ]
target: [ "i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu", "arm-unknown-linux-gnueabi", "aarch64-unknown-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "wasm32-wasi" ]
features: [ "--no-default-features", "" , "--features __internal_use_only_features_that_work_on_stable", "--all-features" ]
crate: [ "zerocopy", "zerocopy-derive" ]
exclude:
# Exclude any combination which uses a non-nightly toolchain but
# enables nightly features.
- toolchain: "msrv"
features: "--all-features"
- toolchain: "stable"
features: "--all-features"
# Exclude any combination for the zerocopy-derive crate which
# uses zerocopy features.
- crate: "zerocopy-derive"
features: "--no-default-features"
- crate: "zerocopy-derive"
features: "--features __internal_use_only_features_that_work_on_stable"
- crate: "zerocopy-derive"
features: "--all-features"
name: Build & Test (crate:${{ matrix.crate }}, toolchain:${{ matrix.toolchain }}, target:${{ matrix.target }}, features:${{ matrix.features }})
steps:
- uses: actions/checkout@v3
# We use toolchain descriptors ("msrv", "stable", and "nightly") in the
# matrix. This step converts the current descriptor to a particular
# toolchain version by looking up the corresponding key in `Cargo.toml`. It
# sets the `ZC_TOOLCHAIN` environment variable for future steps to use.
#
# Note that all metadata is stored in zerocopy's `Cargo.toml` (the one at
# the repository root). zerocopy-derive is tested with the same versions,
# and we have another CI job (see below) that makes sure that the
# `package.rust_version` key in zerocopy-derive's `Cargo.toml` is the same
# as the one in zerocopy's `Cargo.toml`. This key indicates the crate's
# MSRV, and if this check weren't present, it would be possible for
# zerocopy-derive to be published with an earlier MSRV than the one we test
# for in CI - and thus potentially an MSRV that zerocopy-derive isn't
# actually compatible with.
- name: Set toolchain version
run: |
set -e
function pkg-meta {
cargo metadata --format-version 1 | jq -r ".packages[] | select(.name == \"zerocopy\").$1"
}
case ${{ matrix.toolchain }} in
msrv)
ZC_TOOLCHAIN="$(pkg-meta rust_version)"
;;
stable)
ZC_TOOLCHAIN="$(pkg-meta 'metadata.ci."pinned-stable"')"
;;
nightly)
ZC_TOOLCHAIN="$(pkg-meta 'metadata.ci."pinned-nightly"')"
;;
*)
echo 'Unrecognized toolchain: ${{ matrix.toolchain }}' | tee -a $GITHUB_STEP_SUMMARY >&2
exit 1
;;
esac
echo "Found that the '${{ matrix.toolchain }}' toolchain is $ZC_TOOLCHAIN" | tee -a $GITHUB_STEP_SUMMARY
echo "ZC_TOOLCHAIN=$ZC_TOOLCHAIN" >> $GITHUB_ENV
- name: Configure environment variables
run: |
set -e
if [[ '${{ matrix.toolchain }}' == 'nightly' ]]; then
RUSTFLAGS="$RUSTFLAGS $ZC_NIGHTLY_RUSTFLAGS"
MIRIFLAGS="$MIRIFLAGS $ZC_NIGHTLY_MIRIFLAGS"
echo "Using nightly toolchain; setting RUSTFLAGS='$RUSTFLAGS' and MIRIFLAGS='$MIRIFLAGS'" | tee -a $GITHUB_STEP_SUMMARY
echo "RUSTFLAGS=$RUSTFLAGS" >> $GITHUB_ENV
echo "MIRIFLAGS=$MIRIFLAGS" >> $GITHUB_ENV
else
echo "Using non-nightly toolchain; not modifying RUSTFLAGS='$RUSTFLAGS' or MIRIFLAGS='$MIRIFLAGS'" | tee -a $GITHUB_STEP_SUMMARY
fi
- name: Install Rust with toolchain ${{ env.ZC_TOOLCHAIN }} and target ${{ matrix.target }}
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.ZC_TOOLCHAIN }}
targets: ${{ matrix.target }}
# Only nightly has a working Miri, so we skip installing on all other
# toolchains. This expression is effectively a ternary expression -
# see [1] for details.
#
# [1]
# https://github.com/actions/runner/issues/409#issuecomment-752775072
components: clippy ${{ matrix.toolchain == 'nightly' && ', miri' || '' }}
- name: Rust Cache
uses: Swatinem/rust-cache@v2.0.0
with:
key: "${{ matrix.target }}"
- name: Check
run: cargo +${{ env.ZC_TOOLCHAIN }} check --package ${{ matrix.crate }} --target ${{ matrix.target }} ${{ matrix.features }} --verbose
- name: Build
run: cargo +${{ env.ZC_TOOLCHAIN }} build --package ${{ matrix.crate }} --target ${{ matrix.target }} ${{ matrix.features }} --verbose
# When building tests for the i686 target, we need certain libraries which
# are not installed by default; `gcc-multilib` includes these libraries.
- name: Install gcc-multilib
run: sudo apt-get install gcc-multilib
if: ${{ contains(matrix.target, 'i686') }}
- name: Run tests
run: cargo +${{ env.ZC_TOOLCHAIN }} test --package ${{ matrix.crate }} --target ${{ matrix.target }} ${{ matrix.features }} --verbose
# Only run tests when targetting x86 (32- or 64-bit) - we're executing on
# x86_64, so we can't run tests for any non-x86 target.
#
# TODO(https://github.com/dtolnay/trybuild/issues/184#issuecomment-1269097742):
# Run compile tests when building for other targets.
if: ${{ contains(matrix.target, 'x86_64') || contains(matrix.target, 'i686') }}
- name: Run tests under Miri
# Skip the `ui` test since it invokes the compiler, which we can't do from
# Miri (and wouldn't want to do anyway).
run: cargo +${{ env.ZC_TOOLCHAIN }} miri test --package ${{ matrix.crate }} --target ${{ matrix.target }} ${{ matrix.features }} -- --skip ui
# Only nightly has a working Miri, so we skip installing on all other
# toolchains.
#
# TODO(#22): Re-enable testing on wasm32-wasi once it works.
if: ${{ matrix.toolchain == 'nightly' && matrix.target != 'wasm32-wasi' }}
- name: Clippy check
run: cargo +${{ env.ZC_TOOLCHAIN }} clippy --package ${{ matrix.crate }} --target ${{ matrix.target }} ${{ matrix.features }} --verbose
- name: Cargo doc
run: cargo +${{ env.ZC_TOOLCHAIN }} doc --package ${{ matrix.crate }} ${{ matrix.features }}
# When the `alloc` feature is disabled, `cargo doc` fails because we link
# to `alloc::vec::Vec` in a doc comment, and the `alloc` crate is not in
# scope without the `alloc` feature. This isn't a big deal because we care
# primarily about `cargo doc` working for `docs.rs`, which enables the
# `alloc` feature.
if: ${{ matrix.features != '' && matrix.features != '--no-default-features' }}
check_fmt:
runs-on: ubuntu-latest
name: Check Rust formatting
steps:
- uses: actions/checkout@v3
- name: Check Rust formatting
run: |
set -e
cargo fmt --check -p zerocopy
cargo fmt --check -p zerocopy-derive
rustfmt --check tests/ui/*.rs
rustfmt --check zerocopy-derive/tests/ui/*.rs
check_readme:
runs-on: ubuntu-latest
name: Check README.md
steps:
- uses: actions/checkout@v3
# Cache the `cargo-readme` installation.
- name: Rust Cache
uses: Swatinem/rust-cache@v2.0.0
- name: Check README.md
run: |
set -e
cargo install cargo-readme --version 3.2.0
diff <(./generate-readme.sh) README.md
exit $?
check_msrv:
runs-on: ubuntu-latest
name: Check MSRVs match
steps:
- uses: actions/checkout@v3
# Make sure that the MSRV in zerocopy's and zerocopy-derive's `Cargo.toml`
# files are the same.
- name: Check MSRVs match
run: |
set -e
# Usage: msrv <crate-name>
function msrv {
cargo metadata --format-version 1 | jq -r ".packages[] | select(.name == \"$1\").rust_version"
}
ver_zerocopy=$(msrv zerocopy)
ver_zerocopy_derive=$(msrv zerocopy-derive)
if [[ "$ver_zerocopy" == "$ver_zerocopy_derive" ]]; then
echo "Same MSRV ($ver_zerocopy) found for zerocopy and zerocopy-derive." | tee -a $GITHUB_STEP_SUMMARY
exit 0
else
echo "Different MSRVs found for zerocopy ($ver_zerocopy) and zerocopy-derive ($ver_zerocopy_derive)." \
| tee -a $GITHUB_STEP_SUMMARY >&2
exit 1
fi
check_versions:
runs-on: ubuntu-latest
name: Check crate versions match
steps:
- uses: actions/checkout@v3
# Make sure that both crates are at the same version, and that zerocopy
# depends exactly upon the current version of zerocopy-derive. See
# `INTERNAL.md` for an explanation of why we do this.
- name: Check crate versions match
run: |
set -e
# Usage: version <crate-name>
function version {
cargo metadata --format-version 1 | jq -r ".packages[] | select(.name == \"$1\").version"
}
ver_zerocopy=$(version zerocopy)
ver_zerocopy_derive=$(version zerocopy-derive)
zerocopy_derive_dep_ver=$(cargo metadata --format-version 1 \
| jq -r ".packages[] | select(.name == \"zerocopy\").dependencies[] | select(.name == \"zerocopy-derive\").req")
if [[ "$ver_zerocopy" == "$ver_zerocopy_derive" ]]; then
echo "Same crate version ($ver_zerocopy) found for zerocopy and zerocopy-derive." | tee -a $GITHUB_STEP_SUMMARY
else
echo "Different crate versions found for zerocopy ($ver_zerocopy) and zerocopy-derive ($ver_zerocopy_derive)." \
| tee -a $GITHUB_STEP_SUMMARY >&2
exit 1
fi
# Note the leading `=` sign - the dependency needs to be an exact one.
if [[ "=$ver_zerocopy_derive" == "$zerocopy_derive_dep_ver" ]]; then
echo "zerocopy depends upon same version of zerocopy-derive in-tree ($zerocopy_derive_dep_ver)." | tee -a $GITHUB_STEP_SUMMARY
else
echo "zerocopy depends upon different version of zerocopy-derive ($zerocopy_derive_dep_ver) than the one in-tree ($ver_zerocopy_derive)." \
| tee -a $GITHUB_STEP_SUMMARY >&2
exit 1
fi