Skip to content

feat(match): match scrutinees now support call like expressions and m… #30

feat(match): match scrutinees now support call like expressions and m…

feat(match): match scrutinees now support call like expressions and m… #30

Workflow file for this run

name: Build & Release
on:
push:
branches: [main, master]
tags: ["v*"]
pull_request:
branches: [main, master]
permissions:
contents: write
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
name: linux-amd64
arch: x86_64
pkgos: linux
ext: tar.gz
- os: macos-14
name: macos-arm64
arch: arm64
pkgos: macos
ext: tar.gz
- os: windows-2022
name: windows-amd64
arch: x86_64
pkgos: windows
ext: zip
runs-on: ${{ matrix.os }}
name: Build (${{ matrix.name }})
steps:
- uses: actions/checkout@v4
- name: Extract version from tag
id: version
shell: bash
run: |
if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
echo "ver=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
else
echo "ver=dev" >> "$GITHUB_OUTPUT"
fi
# ===================== Linux =====================
- name: Install LLVM 20 and dependencies (Linux)
if: runner.os == 'Linux'
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 20
sudo apt-get install -y llvm-20-dev lld-20 liblld-20-dev clang-20 flex bison patchelf
# ===================== macOS =====================
- name: Install LLVM and dependencies (macOS)
if: runner.os == 'macOS'
run: |
brew update
brew install llvm@20 lld@20 flex bison
LLVM_PREFIX="$(brew --prefix llvm@20)"
echo "${LLVM_PREFIX}/bin" >> $GITHUB_PATH
echo "$(brew --prefix lld@20)/bin" >> $GITHUB_PATH
echo "$(brew --prefix bison)/bin" >> $GITHUB_PATH
echo "$(brew --prefix flex)/bin" >> $GITHUB_PATH
echo "CMAKE_PREFIX_PATH=${LLVM_PREFIX}:$(brew --prefix lld@20)" >> $GITHUB_ENV
# ===================== Windows =====================
- name: Setup MSYS2 (Windows)
if: runner.os == 'Windows'
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: >-
mingw-w64-x86_64-llvm
mingw-w64-x86_64-lld
mingw-w64-x86_64-cmake
mingw-w64-x86_64-gcc
mingw-w64-x86_64-ninja
zip
flex
bison
# ===================== Configure =====================
- name: Configure (Linux)
if: runner.os == 'Linux'
run: cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/usr/lib/llvm-20
- name: Configure (macOS)
if: runner.os == 'macOS'
run: |
cmake -B build -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \
-DFLEX_EXECUTABLE="$(brew --prefix flex)/bin/flex" \
-DBISON_EXECUTABLE="$(brew --prefix bison)/bin/bison"
- name: Configure (Windows)
if: runner.os == 'Windows'
shell: msys2 {0}
run: |
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH=/mingw64 \
-DCMAKE_C_COMPILER=gcc \
-DCMAKE_CXX_COMPILER=g++
# ===================== Build =====================
- name: Build (Linux/macOS)
if: runner.os != 'Windows'
run: cmake --build build --config Release --parallel
- name: Build (Windows)
if: runner.os == 'Windows'
shell: msys2 {0}
run: cmake --build build --config Release --parallel
# ===================== Package =====================
- name: Package (Linux)
if: runner.os == 'Linux'
run: |
PKG_NAME="vixc-${{ steps.version.outputs.ver }}-${{ matrix.arch }}-${{ matrix.pkgos }}"
mkdir -p dist
cp build/vixc dist/vixc
# 复制非系统共享库并设置 RPATH 为 $ORIGIN
ldd dist/vixc | awk '/=>/ { print $3 }' | while read lib; do
case "$lib" in
/lib/*|/usr/lib/x86_64-linux-gnu/libc.*|/lib64/*|/usr/lib/x86_64-linux-gnu/libm.*|/usr/lib/x86_64-linux-gnu/libpthread.*|/usr/lib/x86_64-linux-gnu/libdl.*|/usr/lib/x86_64-linux-gnu/librt.*|/usr/lib/x86_64-linux-gnu/ld-*) continue ;;
esac
cp -L "$lib" dist/ 2>/dev/null || true
done
# 设置 RPATH 使得 vixc 从同目录加载 .so
patchelf --set-rpath '$ORIGIN' dist/vixc
chmod +x dist/vixc
tar czf "${PKG_NAME}.tar.gz" -C dist .
- name: Package (macOS)
if: runner.os == 'macOS'
run: |
PKG_NAME="vixc-${{ steps.version.outputs.ver }}-${{ matrix.arch }}-${{ matrix.pkgos }}"
mkdir -p dist
cp build/vixc dist/vixc
chmod +x dist/vixc
# 复制非系统 dylib
LLVM_PREFIX="$(brew --prefix llvm@20)"
LLD_PREFIX="$(brew --prefix lld@20)"
for dylib in \
"${LLVM_PREFIX}/lib/libLLVM.dylib" \
"${LLVM_PREFIX}/lib/libLLVM-20.dylib" \
"${LLD_PREFIX}/lib/liblldCommon.dylib" \
"${LLD_PREFIX}/lib/liblldELF.dylib" \
"${LLD_PREFIX}/lib/liblldMachO.dylib" \
"${LLD_PREFIX}/lib/liblldCOFF.dylib" \
"${LLD_PREFIX}/lib/liblldWasm.dylib" \
"${LLD_PREFIX}/lib/liblldMinGW.dylib"; do
if [ -f "$dylib" ]; then
cp -L "$dylib" dist/ 2>/dev/null || true
fi
done
# 用 otool 检查并复制其他缺失的 Homebrew dylib
otool -L dist/vixc | awk 'NR>1 { print $1 }' | while read lib; do
case "$lib" in
/usr/lib/*|/System/*) continue ;;
esac
libname="$(basename "$lib")"
if [ ! -f "dist/${libname}" ]; then
if [ -f "$lib" ]; then
cp -L "$lib" dist/ 2>/dev/null || true
fi
fi
done
# 修复 dylib 的 install name 指向 @executable_path/
for f in dist/*.dylib; do
[ -f "$f" ] || continue
chmod +w "$f"
otool -L "$f" | awk 'NR>1 { print $1 }' | while read dep; do
case "$dep" in
/usr/lib/*|/System/*) continue ;;
esac
depname="$(basename "$dep")"
if [ -f "dist/${depname}" ]; then
install_name_tool -change "$dep" "@executable_path/${depname}" "$f" 2>/dev/null || true
fi
done
install_name_tool -id "@executable_path/${depname}" "$f" 2>/dev/null || true
done
# 修复 vixc 本身的 dylib 引用
otool -L dist/vixc | awk 'NR>1 { print $1 }' | while read dep; do
case "$dep" in
/usr/lib/*|/System/*) continue ;;
esac
depname="$(basename "$dep")"
if [ -f "dist/${depname}" ]; then
install_name_tool -change "$dep" "@executable_path/${depname}" dist/vixc 2>/dev/null || true
fi
done
tar czf "${PKG_NAME}.tar.gz" -C dist .
- name: Package (Windows)
if: runner.os == 'Windows'
shell: msys2 {0}
run: |
PKG_NAME="vixc-${{ steps.version.outputs.ver }}-${{ matrix.arch }}-${{ matrix.pkgos }}"
mkdir -p dist/bin dist/libc
cp build/vixc.exe dist/bin/vixc.exe
# ── 复制 vixc.exe 自身依赖的运行时 DLL ──
ldd dist/bin/vixc.exe | grep -vi '/c/WINDOWS/' | awk '{ print $3 }' | while read dll; do
[ -f "$dll" ] && cp "$dll" dist/bin/ 2>/dev/null || true
done
# ── 检测 MSYS2 环境(优先使用当前 msystem,其次目录检测)──
MSYS_PREFIX=""
case "${MSYSTEM:-}" in
UCRT64) MSYS_PREFIX="/ucrt64" ;;
MINGW64) MSYS_PREFIX="/mingw64" ;;
CLANG64) MSYS_PREFIX="/clang64" ;;
*)
if [ -d "/mingw64" ]; then
MSYS_PREFIX="/mingw64"
elif [ -d "/ucrt64" ]; then
MSYS_PREFIX="/ucrt64"
fi
;;
esac
if [ -z "$MSYS_PREFIX" ]; then
echo "WARNING: No MSYS2 environment found (neither /ucrt64 nor /mingw64), skipping libc extraction"
else
echo "Using MSYS2 prefix: $MSYS_PREFIX"
# 查找 GCC 版本目录(用于 libgcc.a 等)
GCC_VER=""
for d in "$MSYS_PREFIX"/lib/gcc/x86_64-w64-mingw32/*/; do
[ -d "$d" ] && GCC_VER="$d"
done
echo "GCC version dir: ${GCC_VER:-<not found>}"
# 通用查找并复制函数:在 GCC_VER、lib/、bin/ 中搜索
copy_if_found() {
local name="$1"
for dir in "$GCC_VER" "$MSYS_PREFIX/lib" "$MSYS_PREFIX/bin"; do
if [ -f "$dir/$name" ]; then
cp "$dir/$name" dist/libc/
echo " Copied: $name (from $dir)"
return 0
fi
done
echo " WARNING: $name not found, skipping"
return 0
}
# 动态库(供编译后的程序运行时使用)
for dll in ucrtbase.dll vcruntime140.dll vcruntime140_1.dll; do
copy_if_found "$dll"
done
# 静态库
for lib in libucrt.a libvcruntime.a libmingw32.a libgcc.a libgcc_eh.a libmingwex.a libmsvcrt.a libkernel32.a; do
copy_if_found "$lib"
done
# CRT 对象文件
for obj in crt2.o crtbegin.o crtend.o crtbeginS.o crtendS.o; do
copy_if_found "$obj"
done
fi
cd dist
zip -r "../${PKG_NAME}.zip" .
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: vixc-${{ matrix.name }}
path: |
vixc-${{ steps.version.outputs.ver }}-${{ matrix.arch }}-${{ matrix.pkgos }}.${{ matrix.ext }}
release:
needs: build
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: release
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: |
release/**/*.tar.gz
release/**/*.zip
generate_release_notes: true