build llvm #15
This file contains hidden or 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: build llvm | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| llvm_version: | |
| description: "LLVM version to build (e.g., 21.1.8)" | |
| required: true | |
| type: string | |
| skip_upload: | |
| description: "Skip upload and PR creation (build-only mode)" | |
| required: false | |
| type: boolean | |
| default: false | |
| skip_pr: | |
| description: "Skip PR creation (upload only, no PR)" | |
| required: false | |
| type: boolean | |
| default: false | |
| pull_request: | |
| # if you want to run this workflow, change the branch name to main, | |
| # if you want to turn off it, change it to non existent branch. | |
| branches: [main-turn-off] | |
| jobs: | |
| build: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # ── Native builds ────────────────────────────────────────────── | |
| - os: windows-2025 | |
| llvm_mode: Debug | |
| lto: OFF | |
| - os: windows-2025 | |
| llvm_mode: RelWithDebInfo | |
| lto: OFF | |
| - os: windows-2025 | |
| llvm_mode: RelWithDebInfo | |
| lto: ON | |
| - os: ubuntu-24.04 | |
| llvm_mode: Debug | |
| lto: OFF | |
| - os: ubuntu-24.04 | |
| llvm_mode: RelWithDebInfo | |
| lto: OFF | |
| - os: ubuntu-24.04 | |
| llvm_mode: RelWithDebInfo | |
| lto: ON | |
| - os: macos-15 | |
| llvm_mode: Debug | |
| lto: OFF | |
| - os: macos-15 | |
| llvm_mode: RelWithDebInfo | |
| lto: OFF | |
| - os: macos-15 | |
| llvm_mode: RelWithDebInfo | |
| lto: ON | |
| # ── Cross-compilation builds ─────────────────────────────────── | |
| # macOS x64 (from arm64 macos-15) | |
| - os: macos-15 | |
| llvm_mode: RelWithDebInfo | |
| lto: OFF | |
| target_triple: x86_64-apple-darwin | |
| - os: macos-15 | |
| llvm_mode: RelWithDebInfo | |
| lto: ON | |
| target_triple: x86_64-apple-darwin | |
| # Linux aarch64 (from x64 ubuntu-24.04) | |
| - os: ubuntu-24.04 | |
| llvm_mode: RelWithDebInfo | |
| lto: OFF | |
| target_triple: aarch64-linux-gnu | |
| - os: ubuntu-24.04 | |
| llvm_mode: RelWithDebInfo | |
| lto: ON | |
| target_triple: aarch64-linux-gnu | |
| # Windows arm64 (from x64 windows-2025) | |
| - os: windows-2025 | |
| llvm_mode: RelWithDebInfo | |
| lto: OFF | |
| target_triple: aarch64-pc-windows-msvc | |
| - os: windows-2025 | |
| llvm_mode: RelWithDebInfo | |
| lto: ON | |
| target_triple: aarch64-pc-windows-msvc | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Free Disk Space | |
| if: runner.os == 'Linux' | |
| uses: jlumbroso/free-disk-space@main | |
| - name: Increase Swap Space | |
| if: runner.os == 'Linux' | |
| run: | | |
| echo "===== Initial Status =====" | |
| sudo swapon --show | |
| free -h | |
| echo "===== Creating Swap File =====" | |
| sudo swapoff -a | |
| sudo fallocate -l 16G /mnt/swapfile | |
| sudo chmod 600 /mnt/swapfile | |
| sudo mkswap /mnt/swapfile | |
| sudo swapon /mnt/swapfile | |
| echo "===== Final Status =====" | |
| sudo swapon --show | |
| free -h | |
| df -h | |
| - name: Setup Pixi | |
| uses: prefix-dev/setup-pixi@v0.9.3 | |
| with: | |
| pixi-version: v0.59.0 | |
| environments: package | |
| activate-environment: true | |
| cache: true | |
| locked: true | |
| - name: Clone llvm-project | |
| shell: bash | |
| run: | | |
| VERSION="${{ inputs.llvm_version || '21.1.8' }}" | |
| echo "Cloning LLVM ${VERSION}..." | |
| git clone --branch "llvmorg-${VERSION}" --depth 1 https://github.com/llvm/llvm-project.git .llvm | |
| - name: Validate distribution components | |
| shell: bash | |
| run: | | |
| python3 scripts/validate-llvm-components.py \ | |
| --llvm-src=.llvm \ | |
| --components-file=scripts/llvm-components.json | |
| - name: Build LLVM (install-distribution) | |
| shell: bash | |
| run: | | |
| EXTRA_ARGS="" | |
| if [[ -n "${{ matrix.target_triple }}" ]]; then | |
| EXTRA_ARGS="--target-triple=${{ matrix.target_triple }}" | |
| fi | |
| pixi run build-llvm \ | |
| --llvm-src=.llvm \ | |
| --mode="${{ matrix.llvm_mode }}" \ | |
| --lto="${{ matrix.lto }}" \ | |
| --build-dir=build \ | |
| ${EXTRA_ARGS} | |
| - name: Build clice using installed LLVM | |
| if: ${{ !matrix.target_triple }} | |
| shell: bash | |
| run: | | |
| cmake -B build -G Ninja \ | |
| -DCMAKE_BUILD_TYPE=${{ matrix.llvm_mode }} \ | |
| -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain.cmake \ | |
| -DCLICE_ENABLE_TEST=ON \ | |
| -DCLICE_CI_ENVIRONMENT=ON \ | |
| -DCLICE_ENABLE_LTO=${{ matrix.lto }} \ | |
| -DLLVM_INSTALL_PATH=".llvm/build-install" | |
| cmake --build build | |
| - name: Run tests | |
| if: ${{ !matrix.target_triple }} | |
| shell: bash | |
| run: | | |
| EXE_EXT="" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| EXE_EXT=".exe" | |
| fi | |
| ./build/bin/unit_tests${EXE_EXT} --test-dir="./tests/data" | |
| pip install uv && uv run --project tests pytest -s --log-cli-level=INFO tests/integration --executable=./build/bin/clice${EXE_EXT} | |
| # Prune is only supported for native builds (requires linking clice to test). | |
| # Cross-compiled targets reuse the native prune manifest of the same OS. | |
| - name: Prune LLVM static libraries (Debug/RelWithDebInfo no LTO) | |
| if: (!matrix.target_triple) && (matrix.llvm_mode == 'Debug' || (matrix.llvm_mode == 'RelWithDebInfo' && matrix.lto == 'OFF')) | |
| shell: bash | |
| run: | | |
| MANIFEST="pruned-libs-${{ matrix.os }}.json" | |
| echo "LLVM_PRUNED_MANIFEST=${MANIFEST}" >> "${GITHUB_ENV}" | |
| python3 scripts/prune-llvm-bin.py \ | |
| --action discover \ | |
| --install-dir ".llvm/build-install/lib" \ | |
| --build-dir "build" \ | |
| --max-attempts 60 \ | |
| --sleep-seconds 60 \ | |
| --manifest "${MANIFEST}" | |
| - name: Upload pruned-libs manifest | |
| if: (!matrix.target_triple) && matrix.llvm_mode == 'RelWithDebInfo' && matrix.lto == 'OFF' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: llvm-pruned-libs-${{ matrix.os }} | |
| path: ${{ env.LLVM_PRUNED_MANIFEST }} | |
| if-no-files-found: error | |
| compression-level: 0 | |
| - name: Apply pruned-libs manifest (RelWithDebInfo + LTO, native only) | |
| if: (!matrix.target_triple) && matrix.llvm_mode == 'RelWithDebInfo' && matrix.lto == 'ON' | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| MANIFEST="pruned-libs-${{ matrix.os }}.json" | |
| python3 scripts/prune-llvm-bin.py \ | |
| --action apply \ | |
| --manifest "${MANIFEST}" \ | |
| --install-dir ".llvm/build-install/lib" \ | |
| --build-dir "build" \ | |
| --gh-run-id "${{ github.run_id }}" \ | |
| --gh-artifact "llvm-pruned-libs-${{ matrix.os }}" \ | |
| --gh-download-dir "artifacts" \ | |
| --max-attempts 60 \ | |
| --sleep-seconds 60 | |
| # For cross-compiled LTO builds, apply the native prune manifest. | |
| # The unused library set is arch-independent (same API surface). | |
| - name: Apply pruned-libs manifest (cross-compile + LTO) | |
| if: matrix.target_triple && matrix.lto == 'ON' | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| MANIFEST="pruned-libs-${{ matrix.os }}.json" | |
| python3 scripts/prune-llvm-bin.py \ | |
| --action apply \ | |
| --manifest "${MANIFEST}" \ | |
| --install-dir ".llvm/build-install/lib" \ | |
| --build-dir "build" \ | |
| --gh-run-id "${{ github.run_id }}" \ | |
| --gh-artifact "llvm-pruned-libs-${{ matrix.os }}" \ | |
| --gh-download-dir "artifacts" \ | |
| --max-attempts 60 \ | |
| --sleep-seconds 60 | |
| - name: Package LLVM install directory | |
| shell: bash | |
| run: | | |
| MODE_TAG="releasedbg" | |
| if [[ "${{ matrix.llvm_mode }}" == "Debug" ]]; then | |
| MODE_TAG="debug" | |
| fi | |
| # Determine arch/platform/toolchain from target triple or runner OS | |
| if [[ -n "${{ matrix.target_triple }}" ]]; then | |
| case "${{ matrix.target_triple }}" in | |
| x86_64-apple-darwin) | |
| ARCH="x64"; PLATFORM="macos"; TOOLCHAIN="clang" ;; | |
| aarch64-linux-gnu) | |
| ARCH="aarch64"; PLATFORM="linux"; TOOLCHAIN="gnu" ;; | |
| aarch64-pc-windows-msvc) | |
| ARCH="aarch64"; PLATFORM="windows"; TOOLCHAIN="msvc" ;; | |
| esac | |
| else | |
| ARCH="x64" | |
| PLATFORM="linux" | |
| TOOLCHAIN="gnu" | |
| if [[ "${{ matrix.os }}" == windows-* ]]; then | |
| PLATFORM="windows" | |
| TOOLCHAIN="msvc" | |
| elif [[ "${{ matrix.os }}" == macos-* ]]; then | |
| ARCH="arm64" | |
| PLATFORM="macos" | |
| TOOLCHAIN="clang" | |
| fi | |
| fi | |
| SUFFIX="" | |
| if [[ "${{ matrix.lto }}" == "ON" ]]; then | |
| SUFFIX="-lto" | |
| fi | |
| if [[ "${{ matrix.llvm_mode }}" == "Debug" && "${{ matrix.os }}" != windows-* ]]; then | |
| SUFFIX="${SUFFIX}-asan" | |
| fi | |
| ARCHIVE="${ARCH}-${PLATFORM}-${TOOLCHAIN}-${MODE_TAG}${SUFFIX}.tar.xz" | |
| set -eo pipefail | |
| tar -C .llvm -cf - build-install | xz -T0 -9 -c > "${ARCHIVE}" | |
| echo "LLVM_INSTALL_ARCHIVE=${ARCHIVE}" >> "${GITHUB_ENV}" | |
| - name: Upload LLVM install artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.LLVM_INSTALL_ARCHIVE }} | |
| path: ${{ env.LLVM_INSTALL_ARCHIVE }} | |
| if-no-files-found: error | |
| # ── Upload to clice-llvm ──────────────────────────────────────────────── | |
| upload: | |
| needs: build | |
| if: ${{ inputs.llvm_version && !inputs.skip_upload }} | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download all build artifacts | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: scripts/download-llvm.sh "${{ github.run_id }}" | |
| - name: Upload to clice-llvm | |
| env: | |
| GH_TOKEN: ${{ secrets.UPLOAD_LLVM }} | |
| TARGET_REPO: clice-io/clice-llvm | |
| run: python3 scripts/upload-llvm.py "${{ inputs.llvm_version }}" "${TARGET_REPO}" "${{ github.run_id }}" | |
| - name: Save manifest for update-clice job | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: llvm-manifest-final | |
| path: artifacts/llvm-manifest.json | |
| if-no-files-found: error | |
| compression-level: 0 | |
| # ── Auto-create PR to update clice LLVM dependency ────────────────────── | |
| update-clice: | |
| needs: upload | |
| if: ${{ !inputs.skip_pr }} | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download manifest | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: llvm-manifest-final | |
| path: . | |
| - name: Update manifest and version | |
| run: | | |
| python3 scripts/update-llvm-version.py \ | |
| --version "${{ inputs.llvm_version }}" \ | |
| --manifest-src llvm-manifest.json \ | |
| --manifest-dest config/llvm-manifest.json \ | |
| --package-cmake cmake/package.cmake | |
| - name: Create or update PR | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| VERSION="${{ inputs.llvm_version }}" | |
| BRANCH="chore/update-llvm-${VERSION}" | |
| RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| RELEASE_URL="https://github.com/clice-io/clice-llvm/releases/tag/${VERSION}" | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git checkout -b "${BRANCH}" | |
| git add config/llvm-manifest.json cmake/package.cmake | |
| git commit -m "chore: update LLVM to ${VERSION}" | |
| git push --force-with-lease origin "${BRANCH}" | |
| # Check if PR already exists for this branch | |
| EXISTING_PR=$(gh pr list --head "${BRANCH}" --json number --jq '.[0].number // empty') | |
| BODY="$(cat <<EOF | |
| ## Summary | |
| - Update LLVM prebuilt binaries to version ${VERSION} | |
| - Updated \`config/llvm-manifest.json\` with new SHA256 hashes | |
| - Updated \`cmake/package.cmake\` version string | |
| **Artifacts:** [clice-llvm release](${RELEASE_URL}) | |
| **Build:** [workflow run](${RUN_URL}) | |
| > Auto-generated by build-llvm workflow | |
| EOF | |
| )" | |
| if [[ -n "${EXISTING_PR}" ]]; then | |
| echo "Updating existing PR #${EXISTING_PR}" | |
| gh pr edit "${EXISTING_PR}" --body "${BODY}" | |
| else | |
| gh pr create \ | |
| --title "chore: update LLVM to ${VERSION}" \ | |
| --body "${BODY}" \ | |
| --base main | |
| fi |