Skip to content

Build Lamina Interpreter #579

Build Lamina Interpreter

Build Lamina Interpreter #579

Workflow file for this run

name: Build Lamina Interpreter
# Nightly build + manual trigger
on:
# Run nightly at 01:00 PT (Pacific Time) -> UTC 08:00; adjust cron as needed
schedule:
- cron: '0 8 * * *'
# Allow manual runs from the Actions UI
workflow_dispatch: {}
# Keep PR-triggered builds enabled for pull requests
pull_request:
jobs:
build:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
# Windows targets
- os: windows-latest
target: x86_64-pc-windows-msvc
generator: "Visual Studio 17 2022"
arch: "x64"
toolchain: ""
# - os: windows-latest
# target: i686-pc-windows-msvc
# generator: "Visual Studio 17 2022"
# arch: "Win32"
# toolchain: ""
- os: windows-latest
target: aarch64-pc-windows-msvc
generator: "Visual Studio 17 2022"
arch: "ARM64"
# macOS targets
- os: macos-latest
target: x86_64-apple-darwin
generator: "Unix Makefiles"
arch: x86_64
toolchain: ""
- os: macos-latest
target: aarch64-apple-darwin
generator: "Unix Makefiles"
arch: arm64
toolchain: ""
# Linux targets
- os: ubuntu-latest
target: "i386-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "i686-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "i686-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "i686-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "x86_64-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "x86_64-linux-gnu"
pcknm: "x86-64-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "x32-unknown-linux-gnux32"
generator: "Unix Makefiles"
arch: "x86_64-linux-gnux32"
pcknm: "x86-64-linux-gnux32"
toolchain: ""
- os: ubuntu-latest
target: "arm-unknown-linux-gnueabi"
generator: "Unix Makefiles"
arch: "arm-linux-gnueabi"
toolchain: ""
- os: ubuntu-latest
target: "armv7-unknown-linux-gnueabihf"
generator: "Unix Makefiles"
arch: "arm-linux-gnueabihf"
toolchain: ""
- os: ubuntu-latest
target: "aarch64-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "aarch64-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "mips-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "mips-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "mipsel-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "mipsel-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "mips64-unknown-linux-gnuabi64"
generator: "Unix Makefiles"
arch: "mips64-linux-gnuabi64"
toolchain: ""
- os: ubuntu-latest
target: "mips64el-unknown-linux-gnuabi64"
generator: "Unix Makefiles"
arch: "mips64el-linux-gnuabi64"
toolchain: ""
- os: ubuntu-latest
target: "mipsr6-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "mipsisa32r6-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "mipsr6el-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "mipsisa32r6el-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "powerpc-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "powerpc-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "ppc64-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "powerpc64-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "ppc64le-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "powerpc64le-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "alpha-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "alpha-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "arc-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "arc-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "hppa-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "hppa-linux-gnu"
toolchain: ""
#- os: ubuntu-latest
# target: "hppa64-unknown-linux-gnu"
# generator: "Unix Makefiles"
# arch: "hppa64-linux-gnu"
# toolchain: ""
- os: ubuntu-latest
target: "loongarch64-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "loongarch64-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "m68k-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "m68k-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "riscv64-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "riscv64-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "s390x-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "s390x-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "sh4-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "sh4-linux-gnu"
toolchain: ""
- os: ubuntu-latest
target: "sparc64-unknown-linux-gnu"
generator: "Unix Makefiles"
arch: "sparc64-linux-gnu"
toolchain: ""
# Linux musl targets
# TODO
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Extract Lamina version
id: extract-version
shell: bash
run: |
set -euo pipefail
echo "PWD: $(pwd)"
# Locate CMakeLists.txt (repo root or first match tracked by git)
if [ -f "CMakeLists.txt" ]; then
SRC="CMakeLists.txt"
else
SRC=$(git ls-files | grep -i 'CMakeLists.txt' | head -n1 || true)
fi
if [ -z "$SRC" ]; then
echo "CMakeLists.txt not found in repo" >&2
echo "version=" >> $GITHUB_OUTPUT
exit 0
fi
echo "Using CMake file: $SRC"
# Use sed to extract project(lamina VERSION 1.1.1 ...)
VERSION=$(sed -nE 's/.*project\([[:space:]]*[Ll]amina[^V]*VERSION[[:space:]]*([0-9A-Za-z.+-]+).*/\1/p' "$SRC" | head -n1 || true)
echo "Extracted version: [$VERSION]"
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Install dependencies (Linux)
if: runner.os == 'Linux'
run: |
PACKAGE_NAME=""
sudo apt-get update
sudo apt-get install -y \
build-essential \
cmake \
ninja-build \
pkg-config \
gcc-13-multilib \
g++-13-multilib \
gcc-13-${{ matrix.pcknm || matrix.arch }} \
g++-13-${{ matrix.pcknm || matrix.arch }} \
musl-tools
- name: Install dependencies (Windows)
if: runner.os == 'Windows'
run: |
choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' -y
choco install ninja -y
- name: Install dependencies (macOS)
if: runner.os == 'macOS'
run: |
brew update
brew install cmake ninja pkg-config openssl@3
brew link --force openssl@3
- name: Setup build environment
run: |
mkdir -p build
echo "GENERATOR=${{ matrix.generator }}" >> $GITHUB_ENV
echo "ARCH=${{ matrix.arch }}" >> $GITHUB_ENV
echo "TOOLCHAIN=${{ matrix.toolchain }}" >> $GITHUB_ENV
- name: Setup MSVC environment(Windows)
uses: ilammy/msvc-dev-cmd@v1
if: runner.os == 'Windows'
with:
arch: ${{ matrix.arch }}
- name: Configure CMake(Windows)
if: runner.os == 'Windows'
run: |
$cmakeArgs = @(
"-B", "build",
"-G", "${{ matrix.generator }}",
"-A", "${{ matrix.arch }}",
"-DCMAKE_BUILD_TYPE=Release"
)
cmake @cmakeArgs
- name: Configure CMake(UNIX)
if: runner.os == 'macOS' || runner.os == 'Linux'
env:
MUSL: "${{ matrix.musl }}"
run: |
# 平台检测
case "$(uname -s)" in
Linux*)
PLATFORM="Linux"
# 安装环境时已设置好编译器后缀
;;
Darwin*)
PLATFORM="MacOS"
# macOS:仅添加架构指定(框架链接在 CMakeLists.txt 中处理)
CMAKE_EXTRA_FLAGS="-DCMAKE_OSX_ARCHITECTURES=$ARCH"
;;
esac
# 构建命令
if [ -n "$TOOLCHAIN" ]; then
echo "Using toolchain: $TOOLCHAIN"
cmake -B build \
-G "$GENERATOR" \
-DCMAKE_TOOLCHAIN_FILE="../$TOOLCHAIN" \
-DCMAKE_BUILD_TYPE=Release \
$CMAKE_EXTRA_FLAGS \
.
else
echo "Building for $ARCH on $PLATFORM"
# 设置编译器(Linux)
if [ "$PLATFORM" = "Linux" ] && [ -n "$ARCH" ]; then
if [ -z "$MUSL" ]; then
export CC="$ARCH-gcc-13"
export CXX="$ARCH-g++-13"
else
export CC="gcc-13-$ARCH"
export CXX="g++-13-$ARCH"
fi
fi
cmake -B build \
-G "$GENERATOR" \
-DCMAKE_BUILD_TYPE=Release \
$CMAKE_EXTRA_FLAGS \
.
fi
- name: Build project (Linux)
if: runner.os == 'Linux'
run: cmake --build build --config Release --parallel $(nproc)
# 使用sysctl
- name: Build project (macOS)
if: runner.os == 'macOS'
run: cmake --build build --config Release --parallel $(sysctl -n hw.ncpu)
- name: Build project (Windows)
if: runner.os == 'Windows'
run: cmake --build build --config Release --parallel $env:NUMBER_OF_PROCESSORS
- name: Prepare artifacts(Windows)
if: runner.os == 'Windows'
run: |
$buildConfig = "Release"
$artifactDir = New-Item -ItemType Directory -Path "artifacts/" -Force
# 拷贝二进制文件
$binSource = "build/bin/$buildConfig"
$binDest = "$artifactDir/bin"
New-Item -ItemType Directory -Path $binDest -Force | Out-Null
if (Test-Path $binSource) {
Copy-Item -Path "$binSource/*" -Destination $binDest -Recurse -Force
Write-Output "✅ Copied binaries from $binSource to $binDest"
Get-ChildItem $binDest | Format-Table Name, Length
} else {
Write-Error "❌ Binary directory not found: $binSource"
exit 1
}
# 拷贝库文件
$libSource = "build/lib/lamina/$buildConfig"
$libDest = "$artifactDir/lib/lamina"
New-Item -ItemType Directory -Path $libDest -Force | Out-Null
if (Test-Path $libSource) {
Copy-Item -Path "$libSource/*" -Destination $libDest -Recurse -Force
Write-Output "✅ Copied libraries from $libSource to $libDest"
Get-ChildItem $libDest | Format-Table Name, Length
} else {
Write-Warning "⚠️ Library directory not found: $libSource"
}
New-Item -ItemType Directory -Path $libDest/examples -Force | Out-Null
New-Item -ItemType Directory -Path $libDest/doc -Force | Out-Null
Copy-Item -Path "examples/*" -Destination $libDest/examples -Recurse -Force
Copy-Item -Path "docs/*" -Destination $libDest/doc -Recurse -Force
# 验证产物结构
Write-Output "`n📦 Final artifact structure ($buildConfig):"
tree $artifactDir /F
- name: Prepare artifacts(UNIX)
if: runner.os == 'macOS' || runner.os == 'Linux'
run: |
mkdir -p artifacts/bin
mkdir -p artifacts/lib/lamina
mkdir -p artifacts/lib/lamina/doc
mkdir -p artifacts/lib/lamina/examples
# 复制可执行文件
if [ -f "build/bin/lamina" ]; then
cp -R build/bin/lamina artifacts/bin/
echo "✅ Binary copied: artifacts/bin/"
else
echo "❌ Binary not found at: build/bin/lamina"
exit 1
fi
# 复制动态库文件
if [ -d "build/lib/lamina" ]; then
cp -R build/lib/lamina/* artifacts/lib/lamina/
# 确保动态库有正确的权限
if [ -f "artifacts/lib/lamina/lamina_core.1.dylib" ] || [ -f "artifacts/lib/lamina/lamina_core.so.1" ]; then
chmod 755 artifacts/lib/lamina/*
echo "✅ Libraries copied and permissions set"
else
echo "⚠️ Warning: Core library not found in expected location"
fi
else
echo "❌ Library directory not found"
exit 1
fi
# 验证动态库链接(仅在 macOS 上)
if [ "$(uname)" = "Darwin" ]; then
echo "� Checking dynamic library dependencies:"
otool -L artifacts/bin/lamina
fi
# 拷贝文档和示例
cp -R examples/* artifacts/lib/lamina/examples/
cp -R docs/* artifacts/lib/lamina/doc/
# 显示最终产物和权限
echo "📦 Final artifacts:"
ls -la artifacts/bin/
ls -la artifacts/lib/lamina/
# 验证文件结构
echo "📂 Directory structure:"
find artifacts -type f
- name: Upload artifact
id: upload-artifact
uses: actions/upload-artifact@v4
with:
name: Lamina-${{ matrix.target }}
path: artifacts/*
if-no-files-found: error
retention-days: 30
- name: Submit signing request (Windows only)
if: runner.os == 'Windows'
id: signpath
continue-on-error: true
uses: signpath/github-action-submit-signing-request@v1
env:
SIGNING_API_TOKEN: "${{ secrets.SIGNING_API_TOKEN }}"
with:
api-token: ${{ env.SIGNING_API_TOKEN }}
organization-id: '7e544555-678f-4f64-a945-ad61c35f957f'
project-slug: 'Lamina'
signing-policy-slug: 'release-signing'
artifact-configuration-slug: 'Lamina_on_Windows'
github-artifact-id: '${{ steps.upload-artifact.outputs.artifact-id }}'
wait-for-completion: true
output-artifact-directory: 'artifacts/signed'
parameters: |
version: "1.1.1"
- name: Package signed artifacts (Windows)
if: runner.os == 'Windows'
shell: pwsh
env:
ZIP_NAME: "Lamina-${{ matrix.target }}-signed.zip"
run: |
# Ensure output dir exists
New-Item -ItemType Directory -Path artifacts -Force | Out-Null
# Remove existing zip if present
if (Test-Path "artifacts/$env:ZIP_NAME") { Remove-Item "artifacts/$env:ZIP_NAME" -Force }
# Package all signed files into a single zip
Compress-Archive -Path "artifacts/signed/*" -DestinationPath "artifacts/$env:ZIP_NAME" -Force
Write-Output "Packaged signed artifacts: artifacts/$env:ZIP_NAME"
- name: Upload signed artifact (Windows)
if: runner.os == 'Windows'
uses: actions/upload-artifact@v4
with:
name: Lamina-${{ matrix.target }}-signed
path: artifacts/Lamina-${{ matrix.target }}-signed.zip
if-no-files-found: error
retention-days: 30