Build linux binary with cross #177
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Github Release | |
on: | |
push: | |
tags: | |
- "[0-9]+.[0-9]+.[0-9]+" | |
# We need this to be able to create releases. | |
permissions: | |
contents: write | |
jobs: | |
# The create-release job runs purely to initialize the GitHub release itself, | |
# and names the release after the `x.y.z` tag that was pushed. It's separate | |
# from building the release so that we only create the release once. | |
create-release: | |
name: create-release | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Get the release version from the tag | |
if: env.VERSION == '' | |
run: echo "VERSION=${{ github.ref_name }}" >> $GITHUB_ENV | |
- name: Show the version | |
run: | | |
echo "version is: $VERSION" | |
- name: Check that tag version and Cargo.toml version are the same | |
shell: bash | |
run: | | |
if ! grep -q "version = \"$VERSION\"" Cargo.toml; then | |
echo "version does not match Cargo.toml" >&2 | |
exit 1 | |
fi | |
- name: Create GitHub release | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: gh release create $VERSION --draft --verify-tag --title $VERSION | |
outputs: | |
version: ${{ env.VERSION }} | |
build-release: | |
name: build-release | |
needs: ["create-release"] | |
runs-on: ${{ matrix.os }} | |
env: | |
# For some builds, we use cross to test on 32-bit and big-endian | |
# systems. | |
CARGO: cargo | |
# When CARGO is set to CROSS, this is set to `--target matrix.target`. | |
TARGET_FLAGS: "" | |
# When CARGO is set to CROSS, TARGET_DIR includes matrix.target. | |
TARGET_DIR: ./target | |
# Bump this as appropriate. We pin to a version to make sure CI | |
# continues to work as cross releases in the past have broken things | |
# in subtle ways. | |
CROSS_VERSION: v0.2.5 | |
# Emit backtraces on panics. | |
RUST_BACKTRACE: 1 | |
BINARY: "orly" | |
PKG_CONFIG_ALL_STATIC: "true" | |
PKG_CONFIG_ALLOW_CROSS: "true" | |
PKG_CONFIG_PATH: "/usr/local/opt/libxml2/lib/pkgconfig" | |
MACOSX_DEPLOYMENT_TARGET: "10.7" | |
LIBXML_VER: "2.9.14" | |
PREFIX: "/musl" | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
# - build: linux-arm | |
# os: ubuntu-18.04 | |
# rust: nightly | |
# target: arm-unknown-linux-gnueabihf | |
# - build: win32-msvc | |
# os: windows-latest | |
# rust: nightly | |
# target: i686-pc-windows-msvc | |
- build: linux | |
os: ubuntu-latest | |
rust: stable | |
target: x86_64-unknown-linux-musl | |
strip: x86_64-linux-musl-strip | |
# - build: macos | |
# os: macos-13 # macos-latest is arm-based | |
# rust: stable | |
# target: x86_64-apple-darwin | |
# - build: win-msvc | |
# os: windows-latest | |
# rust: stable | |
# target: x86_64-pc-windows-msvc | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
- name: Install dependencies (linux) | |
if: matrix.os == 'ubuntu-latest' | |
run: | | |
export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig | |
mkdir $PREFIX | |
echo "$PREFIX/lib" >> /etc/ld-musl-x86_64.path | |
ln -s /usr/include/x86_64-linux-gnu/asm /usr/include/x86_64-linux-musl/asm | |
ln -s /usr/include/asm-generic /usr/include/x86_64-linux-musl/asm-generic | |
ln -s /usr/include/linux /usr/include/x86_64-linux-musl/linux | |
sudo apt-get install musl-dev musl-tools | |
curl -sSL https://download.gnome.org/sources/libxml2/2.9/libxml2-$LIBXML_VER.tar.xz | tar xJ | |
cd libxml2-$LIBXML_VER | |
CC="musl-gcc -fPIC -pie" LDFLAGS="-L$PREFIX/lib" CFLAGS="-I$PREFIX/include" \ | |
./configure --with-lzma=no --with-zlib=no --with-python=no --prefix=$PREFIX --host=x86_64-unknown-linux-musl | |
make -j$(nproc) | |
sudo make install | |
- name: Install dependencies (macOS) | |
if: matrix.os == 'macos-13' | |
run: | | |
# Todo: find a way to link with icu | |
# Since version 2.9.14 brew ships libxml2 with icu support which I wasn't able | |
# to make to statically link correctly. Force-install pre-icu version | |
# https://github.com/Homebrew/homebrew-core/commit/51f729ec63ff8963a300f2e779e51f3a1706cbd0 | |
curl -SsL https://raw.githubusercontent.com/Homebrew/homebrew-core/937e2800a2e37ddc26ae40229ff5b86cc79a58af/Formula/libxml2.rb > libxml2.rb | |
brew install libxml2.rb | |
brew install zlib | |
# pkg-config-rs hack to force static linking for zlib | |
ln -s $(brew --prefix)/opt/zlib/include/zlib.h $(brew --prefix)/opt/libxml2/include/zlib.h | |
ln -s $(brew --prefix)/opt/zlib/lib/libz.a $(brew --prefix)/opt/libxml2/lib/libz.a | |
- name: Restore from cache and install vcpkg (Windows x64) | |
if: matrix.os == 'windows-latest' | |
uses: lukka/run-vcpkg@v10 | |
with: | |
vcpkgGitCommitId: "f6a5d4e8eb7476b8d7fc12a56dff300c1c986131" | |
- name: Install dependencies (Windows x64) | |
shell: bash | |
if: matrix.os == 'windows-latest' | |
run: | | |
# Using static libxml version along with "crt-static" rustflags | |
# in .cargo/config/toml allows building static binaries | |
$VCPKG_ROOT/vcpkg install libxml2:x64-windows-static | |
$VCPKG_ROOT/vcpkg install libxml2:x86-windows-static | |
- name: Install Rust | |
uses: dtolnay/rust-toolchain@stable | |
with: | |
toolchain: ${{ matrix.rust }} | |
target: ${{ matrix.target }} | |
- name: Use Cross | |
if: matrix.os == 'ubuntu-latest' && matrix.target != '' | |
run: | | |
# In the past, new releases of 'cross' have broken CI. So for now, we | |
# pin it. We also use their pre-compiled binary releases because cross | |
# has over 100 dependencies and takes a bit to compile. | |
dir="$RUNNER_TEMP/cross-download" | |
mkdir "$dir" | |
echo "$dir" >> $GITHUB_PATH | |
cd "$dir" | |
curl -LO "https://github.com/cross-rs/cross/releases/download/$CROSS_VERSION/cross-x86_64-unknown-linux-musl.tar.gz" | |
tar xf cross-x86_64-unknown-linux-musl.tar.gz | |
echo "CARGO=cross" >> $GITHUB_ENV | |
- name: Set target variables | |
shell: bash | |
run: | | |
echo "TARGET_FLAGS=--target ${{ matrix.target }}" >> $GITHUB_ENV | |
echo "TARGET_DIR=./target/${{ matrix.target }}" >> $GITHUB_ENV | |
- name: Show command used for Cargo | |
shell: bash | |
run: | | |
echo "cargo command is: ${{ env.CARGO }}" | |
echo "target flag is: ${{ env.TARGET_FLAGS }}" | |
echo "target dir is: ${{ env.TARGET_DIR }}" | |
- name: Build release binary | |
shell: bash | |
run: | | |
# Required for windows builds | |
export PATH=$PATH:${{env.VCPKG_ROOT}} | |
${{ env.CARGO }} build ${{ env.TARGET_FLAGS }} --release --locked | |
if [ "${{ matrix.os }}" = "windows-latest" ]; then | |
bin="target/${{ matrix.target }}/release/$BINARY.exe" | |
else | |
bin="target/${{ matrix.target }}/release/$BINARY" | |
fi | |
echo "BIN=$bin" >> $GITHUB_ENV | |
- name: Strip release binary (macos) | |
if: matrix.os == 'macos-13' | |
shell: bash | |
run: strip "$BIN" | |
- name: Strip release binary (cross) | |
if: env.CARGO == 'cross' | |
shell: bash | |
run: | | |
docker run --rm -v \ | |
"$PWD/target:/target:Z" \ | |
"ghcr.io/cross-rs/${{ matrix.target }}:main" \ | |
"${{ matrix.strip }}" \ | |
"/$BIN" | |
- name: Build archive | |
shell: bash | |
run: | | |
staging="$BINARY-${{ needs.create-release.outputs.version }}-${{ matrix.target }}" | |
if [ "${{ matrix.os }}" = "windows-latest" ]; then | |
cp "target/${{ matrix.target }}/release/$BINARY.exe" "$BINARY.exe" | |
7z a "$staging.zip" "$BINARY.exe" | |
echo "ASSET=$staging.zip" >> $GITHUB_ENV | |
else | |
cp "target/${{ matrix.target }}/release/$BINARY" "$BINARY" | |
tar -czvf "$staging.tar.gz" "$BINARY" | |
echo "ASSET=$staging.tar.gz" >> $GITHUB_ENV | |
fi | |
- name: Upload release archive | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: gh release upload ${{ needs.create-release.outputs.version }} ${{ env.ASSET }} | |
# Building musl version requires all dependencies to be built with musl too. | |
# There are some issues when building musl version of libxml with cross | |
# (specifically with openssl). clux/muslrust has musl-compiled version of openssl | |
# which solves the issue | |
# build-release-musl: | |
# if: ${{ always() }} | |
# needs: ["create-release"] | |
# runs-on: ubuntu-latest | |
# container: clux/muslrust:1.71.0 | |
# env: | |
# LIBXML_VER: "2.9.14" | |
# BINARY: "orly" | |
# steps: | |
# - name: Checkout repository | |
# uses: actions/checkout@v4 | |
# | |
# - name: Link to predefined musl toolchain | |
# run: | | |
# ln -s /root/.cargo $HOME/.cargo | |
# ln -s /root/.rustup $HOME/.rustup | |
# | |
# - name: Compile libxml2 against musl | |
# run: | | |
# curl -sSL https://download.gnome.org/sources/libxml2/2.9/libxml2-$LIBXML_VER.tar.xz | tar xJ | |
# cd libxml2-$LIBXML_VER | |
# PREFIX=/musl CC="musl-gcc -fPIC -pie" LDFLAGS="-L$PREFIX/lib" CFLAGS="-I$PREFIX/include" \ | |
# ./configure --with-lzma=no --prefix=$PREFIX --host=x86_64-unknown-linux-musl | |
# make -j$(nproc) | |
# make install | |
# | |
# - name: Build release binary | |
# run: | | |
# cargo build --release --locked | |
# | |
# - name: Build archive | |
# shell: bash | |
# run: | | |
# ARCHIVE="$BINARY-${{ needs.create-release.outputs.version }}-x86_64-unknown-linux-musl.tar.gz" | |
# cp "target/x86_64-unknown-linux-musl/release/$BINARY" "$BINARY" | |
# tar -czvf "$ARCHIVE" "$BINARY" | |
# echo "ASSET=$ARCHIVE" >> $GITHUB_ENV | |
# | |
# - name: Upload release archive | |
# env: | |
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
# run: | | |
# # Install gh cli | |
# curl -sSL https://github.com/cli/cli/releases/download/v2.32.0/gh_2.32.0_linux_amd64.tar.gz | tar xz | |
# mv gh*/bin/gh /usr/local/bin | |
# # Upload asset to release | |
# git config --global --add safe.directory '*' | |
# gh release upload ${{ needs.create-release.outputs.version }} ${{ env.ASSET }} | |
# | |
# publish-crate: | |
# name: publish-crate | |
# runs-on: ubuntu-latest | |
# needs: ["build-release", "build-release-musl"] | |
# steps: | |
# - uses: actions/checkout@v4 | |
# - run: cargo login ${CRATES_IO_TOKEN} | |
# env: | |
# CRATES_IO_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} | |
# - run: cargo publish |