Skip to content

Commit 51f37cb

Browse files
committed
feat: add bootstrap-macos workflow (xmake + xlings LLVM)
Standalone workflow_dispatch to produce the first macOS ARM64 mcpp binary via xmake. References the proven xlings release pattern: xlings install → LLVM → xmake build → package. Once this produces a working binary, it can be uploaded as a release asset and used for subsequent self-host builds.
1 parent 2fd68dd commit 51f37cb

1 file changed

Lines changed: 138 additions & 0 deletions

File tree

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
name: bootstrap-macos
2+
3+
# One-shot workflow to produce the first macOS mcpp binary.
4+
# Uses xmake + xlings LLVM to compile mcpp from source.
5+
# Once a macOS binary exists, mcpp can self-host for future releases.
6+
7+
on:
8+
workflow_dispatch:
9+
10+
jobs:
11+
bootstrap:
12+
name: Bootstrap mcpp (macOS ARM64)
13+
runs-on: macos-15
14+
timeout-minutes: 30
15+
env:
16+
XLINGS_NON_INTERACTIVE: '1'
17+
XLINGS_VERSION: '0.4.30'
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- name: System info
22+
run: |
23+
uname -a
24+
sw_vers
25+
xcrun --show-sdk-path
26+
27+
- name: Install xlings
28+
run: |
29+
WORK=$(mktemp -d)
30+
tarball="xlings-${XLINGS_VERSION}-macosx-arm64.tar.gz"
31+
curl -fsSL -o "${WORK}/${tarball}" \
32+
"https://github.com/d2learn/xlings/releases/download/v${XLINGS_VERSION}/${tarball}"
33+
tar -xzf "${WORK}/${tarball}" -C "${WORK}"
34+
"${WORK}/xlings-${XLINGS_VERSION}-macosx-arm64/subos/default/bin/xlings" self install
35+
echo "$HOME/.xlings/subos/default/bin" >> "$GITHUB_PATH"
36+
echo "$HOME/.xlings/bin" >> "$GITHUB_PATH"
37+
38+
- name: Install LLVM + xmake
39+
run: |
40+
xlings install llvm -y || xlings install llvm@20.1.7 -y
41+
brew install xmake
42+
LLVM_ROOT=$(find "$HOME/.xlings" -path "*/xpkgs/xim-x-llvm/*/bin/clang++" | head -1 | xargs dirname | xargs dirname)
43+
echo "LLVM_ROOT=$LLVM_ROOT" >> "$GITHUB_ENV"
44+
"$LLVM_ROOT/bin/clang++" --version
45+
xmake --version
46+
47+
- name: Build mcpp with xmake
48+
run: |
49+
# Generate xmake.lua if not present
50+
if [ ! -f xmake.lua ]; then
51+
cat > xmake.lua << 'EOF'
52+
add_rules("mode.release")
53+
set_languages("c++23")
54+
55+
package("cmdline")
56+
set_homepage("https://github.com/mcpplibs/cmdline")
57+
set_description("Modern C++ command-line parsing library")
58+
set_license("Apache-2.0")
59+
add_urls("https://github.com/mcpplibs/cmdline/archive/refs/tags/$(version).tar.gz")
60+
add_versions("0.0.1", "3fb2f5495c1a144485b3cbb2e43e27059151633460f702af0f3851cbff387ef0")
61+
on_install(function (package)
62+
import("package.tools.xmake").install(package)
63+
end)
64+
package_end()
65+
66+
add_requires("cmdline 0.0.1")
67+
68+
target("mcpp")
69+
set_kind("binary")
70+
add_files("src/main.cpp")
71+
add_files("src/**.cppm")
72+
add_packages("cmdline")
73+
add_includedirs("src/libs/json")
74+
set_policy("build.c++.modules", true)
75+
EOF
76+
fi
77+
78+
# Configure with xlings LLVM
79+
xmake f -y -m release --toolchain=llvm --sdk="$LLVM_ROOT"
80+
# Build
81+
xmake build -y mcpp
82+
83+
- name: Verify built binary
84+
run: |
85+
MCPP=$(find build -name mcpp -type f -perm +111 | head -1)
86+
test -x "$MCPP"
87+
file "$MCPP"
88+
"$MCPP" --version
89+
echo "MCPP=$MCPP" >> "$GITHUB_ENV"
90+
91+
- name: Package
92+
id: package
93+
run: |
94+
VERSION=$(awk -F '"' '/^version[[:space:]]*=/{print $2; exit}' mcpp.toml)
95+
TARBALL="mcpp-${VERSION}-darwin-arm64.tar.gz"
96+
WRAPPER="mcpp-${VERSION}-darwin-arm64"
97+
98+
mkdir -p "dist/$WRAPPER/bin"
99+
cp "$MCPP" "dist/$WRAPPER/bin/mcpp"
100+
strip "dist/$WRAPPER/bin/mcpp" 2>/dev/null || true
101+
cp LICENSE "dist/$WRAPPER/" 2>/dev/null || true
102+
cp README.md "dist/$WRAPPER/" 2>/dev/null || true
103+
104+
cat > "dist/$WRAPPER/mcpp" << 'LAUNCHER'
105+
#!/bin/sh
106+
exec "$(dirname "$0")/bin/mcpp" "$@"
107+
LAUNCHER
108+
chmod +x "dist/$WRAPPER/mcpp"
109+
110+
# Bundle xlings
111+
XLINGS_BIN="$HOME/.xlings/subos/default/bin/xlings"
112+
if [ -x "$XLINGS_BIN" ]; then
113+
mkdir -p "dist/$WRAPPER/registry/bin"
114+
cp "$XLINGS_BIN" "dist/$WRAPPER/registry/bin/xlings"
115+
fi
116+
117+
(cd dist && tar -czf "$TARBALL" "$WRAPPER")
118+
(cd dist && shasum -a 256 "$TARBALL" > "$TARBALL.sha256")
119+
120+
echo "tarball=dist/$TARBALL" >> "$GITHUB_OUTPUT"
121+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
122+
ls -la dist/
123+
124+
- name: Smoke test
125+
run: |
126+
SMOKE=$(mktemp -d)
127+
tar -xzf "${{ steps.package.outputs.tarball }}" -C "$SMOKE"
128+
VERSION="${{ steps.package.outputs.version }}"
129+
"$SMOKE/mcpp-${VERSION}-darwin-arm64/bin/mcpp" --version
130+
"$SMOKE/mcpp-${VERSION}-darwin-arm64/mcpp" --version
131+
132+
- name: Upload artifact
133+
uses: actions/upload-artifact@v4
134+
with:
135+
name: mcpp-darwin-arm64
136+
path: |
137+
dist/mcpp-*-darwin-arm64.tar.gz
138+
dist/mcpp-*-darwin-arm64.tar.gz.sha256

0 commit comments

Comments
 (0)