Skip to content

Commit 6c400e9

Browse files
committed
[LDC] Set up CI / package generation with GitHub Actions
* Windows x86, x64 & ARM64 * macOS x64 & ARM64 * Linux x64 & AArch64 * Android ARMv7-A & AArch64 2 packages per platform (enabled/disabled assertions), except for cross- compiled Android. Tagged builds are uploaded to the corresponding GitHub release, untagged builds to the GitHub 'CI' release.
1 parent 9eaaa3a commit 6c400e9

5 files changed

Lines changed: 573 additions & 0 deletions

File tree

.github/actions/1-setup/action.yml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
name: Install prerequisites
2+
inputs:
3+
arch:
4+
required: true
5+
clang_major:
6+
required: false
7+
default: 22
8+
runs:
9+
using: composite
10+
steps:
11+
12+
- name: 'Linux: Install required apt packages'
13+
if: runner.os == 'Linux'
14+
shell: bash
15+
run: |
16+
set -eux
17+
cd ..
18+
export DEBIAN_FRONTEND=noninteractive
19+
sudo apt-get -q update
20+
sudo -E apt-get -yq install \
21+
git-core curl g++ python3 pkgconf binutils-dev libzstd-dev zlib1g-dev zstd unzip \
22+
lsb-release wget software-properties-common gnupg # prerequisites of apt.llvm.org install script
23+
24+
- name: 'Linux: Install clang ${{ inputs.clang_major }} from apt.llvm.org'
25+
if: runner.os == 'Linux'
26+
shell: bash
27+
run: |
28+
set -eux
29+
cd ..
30+
major='${{ inputs.clang_major }}'
31+
curl -fL --retry 3 --max-time 30 -O https://apt.llvm.org/llvm.sh
32+
sudo bash llvm.sh $major
33+
34+
# use it as C(++) compiler for future steps
35+
echo "CC=clang-$major" >> $GITHUB_ENV
36+
echo "CXX=clang++-$major" >> $GITHUB_ENV
37+
38+
# make bundled lld the default linker
39+
sudo ln -sf ld.lld-$major /usr/bin/ld
40+
ld --version
41+
42+
- name: 'macOS: Install Homebrew clang ${{ inputs.clang_major }}'
43+
if: runner.os == 'macOS'
44+
shell: bash
45+
run: |
46+
set -eux
47+
major='${{ inputs.clang_major }}'
48+
brew install llvm@$major
49+
50+
if [[ '${{ inputs.arch }}' == arm64 ]]; then
51+
prefix="/opt/homebrew/opt/llvm@$major"
52+
else
53+
prefix="/usr/local/opt/llvm@$major"
54+
fi
55+
56+
# use it as C(++) compiler for future steps
57+
echo "CC=$prefix/bin/clang" >> $GITHUB_ENV
58+
echo "CXX=$prefix/bin/clang++" >> $GITHUB_ENV
59+
60+
# https://github.com/actions/runner-images/issues/10035#issue-2344536514
61+
sudo xcode-select -s /Library/Developer/CommandLineTools
62+
xcrun --show-sdk-path
63+
ls -l /Library/Developer/CommandLineTools/SDKs
64+
65+
# https://github.com/llvm/llvm-project/issues/155531#issuecomment-3229499205
66+
rm -rf "$prefix/include/c++/v1"
67+
68+
- name: 'Windows: Install clang ${{ inputs.clang_major }} from GitHub'
69+
if: runner.os == 'Windows'
70+
shell: bash
71+
run: |
72+
set -eux
73+
cd ..
74+
75+
version='${{ inputs.clang_major }}.1.2'
76+
suffix='win64'
77+
if [[ '${{ inputs.arch }}' == arm64 ]]; then
78+
suffix='woa64'
79+
fi
80+
url="https://github.com/llvm/llvm-project/releases/download/llvmorg-$version/LLVM-$version-$suffix.exe"
81+
82+
curl -fL --retry 3 --max-time 300 -o clang.exe "$url"
83+
./clang.exe //S # double-slash for bash
84+
rm clang.exe
85+
86+
# C:\Program Files\LLVM\bin should already be in PATH
87+
clang-cl --version
88+
89+
# use it as C(++) compiler for future steps
90+
echo 'CC=C:\Program Files\LLVM\bin\clang-cl.exe' >> $GITHUB_ENV
91+
echo 'CXX=C:\Program Files\LLVM\bin\clang-cl.exe' >> $GITHUB_ENV
92+
93+
if [[ '${{ inputs.arch }}' == x86 ]]; then
94+
# make CMake configure 64-bit clang-cl for 32-bit code emission
95+
echo "CFLAGS=-m32" >> $GITHUB_ENV
96+
echo "CXXFLAGS=-m32" >> $GITHUB_ENV
97+
echo "ASMFLAGS=-m32" >> $GITHUB_ENV
98+
fi
99+
100+
- name: 'Windows: Set LDC_VSDIR env variable'
101+
if: runner.os == 'Windows'
102+
shell: bash
103+
run: echo "LDC_VSDIR=$(vswhere -latest -property installationPath)" >> $GITHUB_ENV

.github/actions/2-build/action.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Build & install LLVM incl. LLD, compiler-rt, BOLT
2+
inputs:
3+
arch:
4+
required: false # Windows only
5+
enable_projects:
6+
required: true
7+
targets_to_build:
8+
required: false
9+
default: all
10+
experimental_targets_to_build:
11+
required: false
12+
default: ''
13+
with_asserts:
14+
required: true
15+
extra_cmake_flags:
16+
required: false
17+
default: ''
18+
runs:
19+
using: composite
20+
steps:
21+
22+
- if: runner.os != 'Windows'
23+
shell: bash
24+
run: |
25+
set -eux
26+
cd ..
27+
cmake --version
28+
ninja --version
29+
mkdir build
30+
cd build
31+
cmake -G Ninja ../llvm-project/llvm \
32+
-DCMAKE_BUILD_TYPE=Release \
33+
-DCMAKE_INSTALL_PREFIX=$PWD/../install \
34+
-DLLVM_ENABLE_PROJECTS="${{ inputs.enable_projects }}" \
35+
-DLLVM_TARGETS_TO_BUILD="${{ inputs.targets_to_build }}" \
36+
-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="${{ inputs.experimental_targets_to_build }}" \
37+
-DLLVM_ENABLE_ASSERTIONS=${{ inputs.with_asserts == 'true' && 'ON' || 'OFF' }} \
38+
${{ inputs.extra_cmake_flags }}
39+
ninja install
40+
41+
# Windows: invoke CMake & ninja in MSVC env
42+
- if: runner.os == 'Windows'
43+
shell: cmd
44+
run: |
45+
call "%LDC_VSDIR%\Common7\Tools\VsDevCmd.bat" -arch=${{ inputs.arch }} || exit /b
46+
echo on
47+
cd .. || exit /b
48+
cmake --version || exit /b
49+
ninja --version || exit /b
50+
mkdir build || exit /b
51+
cd build || exit /b
52+
cmake -G Ninja ..\llvm-project\llvm ^
53+
-DCMAKE_BUILD_TYPE=Release ^
54+
"-DCMAKE_INSTALL_PREFIX=%CD%\..\install" ^
55+
"-DLLVM_ENABLE_PROJECTS=${{ inputs.enable_projects }}" ^
56+
"-DLLVM_TARGETS_TO_BUILD=${{ inputs.targets_to_build }}" ^
57+
"-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=${{ inputs.experimental_targets_to_build }}" ^
58+
-DLLVM_ENABLE_ASSERTIONS=${{ inputs.with_asserts == 'true' && 'ON' || 'OFF' }} ^
59+
${{ inputs.extra_cmake_flags }}
60+
if %errorlevel% neq 0 exit /b %errorlevel%
61+
62+
ninja install || exit /b
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
name: Create package & upload artifact(s)
2+
inputs:
3+
arch:
4+
required: true
5+
os:
6+
required: false
7+
default: '' # native
8+
with_asserts:
9+
required: true
10+
runs:
11+
using: composite
12+
steps:
13+
14+
- name: Pack installation dir
15+
shell: bash
16+
run: |
17+
set -euxo pipefail
18+
cd ..
19+
mkdir artifacts
20+
21+
if [[ '${{ github.ref }}' = refs/tags/ldc-v* ]]; then
22+
artifactID='${{ github.ref }}'
23+
artifactID="${artifactID:15}"
24+
else
25+
artifactID='${{ github.sha }}'
26+
artifactID="${artifactID:0:8}"
27+
fi
28+
29+
os='${{ inputs.os }}'
30+
if [[ "$os" == '' ]]; then
31+
if [[ '${{ runner.os }}' == Linux ]]; then
32+
os=linux
33+
elif [[ '${{ runner.os }}' == macOS ]]; then
34+
os=osx
35+
elif [[ '${{ runner.os }}' == Windows ]]; then
36+
os=windows
37+
else
38+
echo "Error: unknown OS '${{ runner.os }}'"
39+
exit 1
40+
fi
41+
fi
42+
43+
if [[ "$os" == windows ]]; then
44+
# on Windows, the lld symlinks are copies
45+
rm install/bin/{ld.lld,ld64.lld*,lld-link,wasm-ld}.exe
46+
mv install/bin/lld.exe install/bin/lld-link.exe
47+
fi
48+
49+
assertsSuffix="${{ inputs.with_asserts == 'true' && '-withAsserts' || '' }}"
50+
51+
artifactName="llvm-$artifactID-$os-${{ inputs.arch }}$assertsSuffix"
52+
mv install $artifactName
53+
if [[ '${{ runner.os }}' == Windows ]]; then
54+
cd $artifactName
55+
7z a -mx=9 ../artifacts/$artifactName.7z * >/dev/null
56+
cd ..
57+
else
58+
chmod -R go=rX $artifactName
59+
if [[ '${{ runner.os }}' == macOS ]]; then
60+
sudo chown -R root:wheel $artifactName
61+
tar -cf - $artifactName | zstd -T0 --ultra -22 -o artifacts/$artifactName.tar.zst
62+
else
63+
tar -cf - --owner=0 --group=0 $artifactName | zstd -T0 --ultra -22 -o artifacts/$artifactName.tar.zst
64+
fi
65+
fi
66+
67+
# export ARTIFACT_{ID,NAME}
68+
echo "ARTIFACT_ID=$artifactID" >> $GITHUB_ENV
69+
echo "ARTIFACT_NAME=$os-${{ inputs.arch }}$assertsSuffix" >> $GITHUB_ENV
70+
71+
- name: 'Linux x86_64: Pack source dir'
72+
if: runner.os == 'Linux' && inputs.os == '' && inputs.arch == 'x86_64' && inputs.with_asserts == 'false'
73+
shell: bash
74+
run: |
75+
set -euxo pipefail
76+
git clean -dffx
77+
artifactName="llvm-$ARTIFACT_ID.src"
78+
mkdir $artifactName
79+
# only keep some subdirs (note: libunwind required by lld, for `mach-o/compact_unwind_encoding.h` include)
80+
for dir in bolt cmake compiler-rt libunwind lld llvm; do
81+
mv $dir $artifactName/
82+
done
83+
mkdir $artifactName/third-party
84+
mv third-party/siphash $artifactName/third-party/
85+
chmod -R go=rX $artifactName
86+
tar -cf - --exclude-vcs --owner=0 --group=0 $artifactName | zstd -T0 --ultra -22 -o ../artifacts/$artifactName.tar.zst
87+
88+
- name: 'Move artifacts dir for uploading'
89+
shell: bash
90+
run: mv ../artifacts ./
91+
92+
- name: Upload artifact(s)
93+
uses: actions/upload-artifact@v6
94+
with:
95+
name: ${{ env.ARTIFACT_NAME }}
96+
path: artifacts/
97+
compression-level: 0
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: Upload to GitHub
2+
runs:
3+
using: composite
4+
steps:
5+
6+
- name: Download all artifacts
7+
uses: actions/download-artifact@v8
8+
with:
9+
path: artifacts/
10+
merge-multiple: true # place all files into artifacts/ directly
11+
12+
- name: Set GITHUB_RELEASE_TAG & ARTIFACT_ID
13+
shell: bash
14+
run: |
15+
set -eux
16+
if [[ '${{ github.ref }}' = refs/tags/ldc-v* ]]; then
17+
tag='${{ github.ref }}'
18+
tag="${tag:10}"
19+
artifactID="${tag:5}"
20+
else
21+
tag=CI
22+
artifactID='${{ github.sha }}'
23+
artifactID="${artifactID:0:8}"
24+
fi
25+
echo "GITHUB_RELEASE_TAG=$tag" >> $GITHUB_ENV
26+
echo "ARTIFACT_ID=$artifactID" >> $GITHUB_ENV
27+
28+
- name: Download existing artifacts from GitHub release
29+
# only enabled for the upstream repo by default - (probably) needs an existing release
30+
if: github.repository == 'ldc-developers/llvm-project'
31+
# don't fail if there are no existing artifacts yet
32+
continue-on-error: true
33+
uses: dsaltares/fetch-gh-release-asset@1.1.2
34+
with:
35+
version: tags/${{ env.GITHUB_RELEASE_TAG }}
36+
regex: true
37+
# only those with matching ARTIFACT_ID
38+
file: ^llvm-${{ env.ARTIFACT_ID }}-
39+
target: existing-artifacts/
40+
41+
- name: Merge existing artifacts & compute hashes
42+
shell: bash
43+
run: |
44+
set -eux
45+
46+
cd artifacts
47+
48+
# Extend by existing release artifacts *missing* from GitHub workflow,
49+
# e.g., artifacts published by Cirrus CI etc.
50+
# (They will be re-uploaded in the next step.)
51+
if [[ -d ../existing-artifacts ]]; then
52+
mv -n ../existing-artifacts/*.* ./
53+
fi
54+
55+
ls -lh
56+
sha256sum * > "llvm-$ARTIFACT_ID.sha256sums.txt"
57+
58+
- name: Upload to GitHub release
59+
uses: ncipollo/release-action@v1
60+
with:
61+
tag: ${{ env.GITHUB_RELEASE_TAG }}
62+
artifacts: artifacts/*
63+
allowUpdates: true
64+
artifactErrorsFailBuild: true
65+
prerelease: false
66+
omitPrereleaseDuringUpdate: true
67+
omitName: true
68+
omitBody: true
69+
omitDraftDuringUpdate: true
70+
# remove existing artifacts for 'CI' release
71+
#removeArtifacts: ${{ env.GITHUB_RELEASE_TAG == 'CI' }}

0 commit comments

Comments
 (0)