Skip to content

Commit 970d2bc

Browse files
committed
Adding mac release
1 parent 0c6fb33 commit 970d2bc

5 files changed

Lines changed: 761 additions & 588 deletions

File tree

.github/workflows/release.yml

Lines changed: 118 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -162,27 +162,114 @@ jobs:
162162
path: dist/
163163
if-no-files-found: error
164164

165+
macos:
166+
name: Build tarball (macOS ${{ matrix.arch }})
167+
needs: stage
168+
runs-on: ${{ matrix.runner }}
169+
timeout-minutes: 90
170+
strategy:
171+
fail-fast: false
172+
matrix:
173+
include:
174+
- arch: arm64
175+
runner: macos-15
176+
steps:
177+
- name: Checkout (with submodules)
178+
uses: actions/checkout@v4
179+
with:
180+
submodules: recursive
181+
182+
- name: Install LLVM 22
183+
# Homebrew's current `llvm` is the locked major; the configure-time
184+
# major check fails loudly if that ever stops being true, so this does
185+
# not silently build against the wrong one.
186+
run: |
187+
set -euo pipefail
188+
brew install llvm ninja
189+
echo "LLVM_PREFIX=$(brew --prefix llvm)" >> "$GITHUB_ENV"
190+
191+
- name: Configure, build, and package
192+
# LLVMDSDL_VENDOR_LLVM on macOS installs the self-contained bundle rather
193+
# than the raw targets: without it the tarball's binaries reference
194+
# /opt/homebrew and run only on a machine that already has Homebrew LLVM.
195+
run: |
196+
set -euo pipefail
197+
cmake -S . -B out -G Ninja \
198+
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
199+
-DLLVM_DIR="${LLVM_PREFIX}/lib/cmake/llvm" \
200+
-DMLIR_DIR="${LLVM_PREFIX}/lib/cmake/mlir" \
201+
-DLLVMDSDL_VENDOR_LLVM=ON
202+
cmake --build out
203+
cd out && cpack -G TGZ
204+
205+
- name: Collect tarball
206+
run: |
207+
set -euo pipefail
208+
mkdir -p dist
209+
cp out/*.tar.gz dist/
210+
cd dist
211+
shasum -a 256 -- *.tar.gz > SHA256SUMS
212+
ls -la
213+
214+
- name: Verify the tarball is self-contained
215+
# There is no pristine container to install into, and this runner is the
216+
# worst possible judge -- it has Homebrew LLVM at exactly the paths a
217+
# non-relocated binary would reference. So the check asserts linkage,
218+
# not just behaviour.
219+
run: |
220+
python3 packaging/verify/smoke_macos.py \
221+
--tarball "dist/llvm-dsdl-${{ needs.stage.outputs.version }}-darwin-${{ matrix.arch }}.tar.gz" \
222+
--expect-version "${{ needs.stage.outputs.version }}"
223+
224+
- name: Upload tarball
225+
uses: actions/upload-artifact@v4
226+
with:
227+
name: macos-${{ matrix.arch }}
228+
path: dist/
229+
if-no-files-found: error
230+
165231
publish:
166232
name: Publish release
167-
needs: [stage, build]
233+
needs: [stage, build, macos]
168234
if: needs.stage.outputs.publish == 'true'
169235
runs-on: ubuntu-latest
170236
permissions:
171237
contents: write # create the release
172238
id-token: write # provenance attestation
173239
attestations: write
174240
steps:
175-
- name: Download packages
241+
# Two steps rather than one brace pattern, and into per-artifact
242+
# subdirectories rather than merged: every build job writes its own
243+
# SHA256SUMS, and merging would silently leave one overwriting the others.
244+
- name: Download Linux artifacts
176245
uses: actions/download-artifact@v4
177246
with:
178247
pattern: deb-*
179-
path: dist
180-
merge-multiple: true
248+
path: staging
249+
250+
- name: Download macOS artifacts
251+
uses: actions/download-artifact@v4
252+
with:
253+
pattern: macos-*
254+
path: staging
255+
256+
- name: Combine artifacts
257+
run: |
258+
set -euo pipefail
259+
mkdir -p dist
260+
find staging -type f ! -name SHA256SUMS -exec cp {} dist/ \;
261+
# One checksum file covering everything, rebuilt from the artifacts
262+
# themselves rather than concatenated, so it cannot disagree with what
263+
# is actually attached.
264+
cd dist && sha256sum -- * > SHA256SUMS
265+
cat SHA256SUMS
181266
182267
- name: Attest build provenance
183268
uses: actions/attest-build-provenance@v2
184269
with:
185-
subject-path: dist/*.deb
270+
subject-path: |
271+
dist/*.deb
272+
dist/*.tar.gz
186273
187274
- name: Create the release
188275
uses: softprops/action-gh-release@v2
@@ -192,9 +279,10 @@ jobs:
192279
draft: true
193280
files: |
194281
dist/*.deb
282+
dist/*.tar.gz
195283
dist/SHA256SUMS
196284
body: |
197-
## Install — Ubuntu 22.04, 24.04, or 26.04
285+
## Ubuntu 22.04, 24.04, or 26.04
198286
199287
Pick the package matching your architecture (`dpkg --print-architecture`):
200288
@@ -203,12 +291,32 @@ jobs:
203291
sudo apt install ./llvm-dsdl_${{ needs.stage.outputs.version }}_arm64.deb
204292
```
205293
206-
No repository to add: the package bundles the LLVM 22 runtime it needs,
207-
because no Ubuntu release carries it. Everything else it depends on comes
208-
from the stock Ubuntu archive.
209-
210294
`llvm-dsdl-dev` is also attached, for linking against the frontend,
211295
MLIR dialect, and emitter libraries.
212296
297+
## macOS (Apple silicon)
298+
299+
Extract with `tar`, not by double-clicking:
300+
301+
```
302+
tar -xzf llvm-dsdl-${{ needs.stage.outputs.version }}-darwin-arm64.tar.gz
303+
./llvm-dsdl-${{ needs.stage.outputs.version }}-darwin-arm64/bin/dsdlc --version
304+
```
305+
306+
The binaries are ad-hoc signed rather than notarized. Extracting with
307+
`tar` keeps them runnable; opening the archive in Finder marks them
308+
with macOS's quarantine attribute and Gatekeeper will refuse to run
309+
them. Move the extracted directory wherever you like — it is
310+
relocatable — and add its `bin/` to your `PATH`.
311+
312+
## Both platforms
313+
314+
No repository or package manager to configure: each package bundles the
315+
LLVM 22 runtime it needs, because neither Ubuntu nor a stock macOS
316+
carries it. Everything else comes from the platform.
317+
318+
Verify downloads against `SHA256SUMS`, or check build provenance with
319+
`gh attestation verify <file> --repo ${{ github.repository }}`.
320+
213321
Verify the download against `SHA256SUMS`, or check build provenance with
214322
`gh attestation verify <file> --repo ${{ github.repository }}`.

CMakeLists.txt

Lines changed: 79 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,17 @@ set(LLVMDSDL_INSTALLABLE_LIBRARIES
518518

519519
set(LLVMDSDL_INSTALL_COMPONENT_BIN "bin")
520520
set(LLVMDSDL_INSTALL_COMPONENT_DEV "dev")
521+
set(LLVMDSDL_SELF_CONTAINED_TOOL_BUNDLE_DEFAULT OFF)
522+
if(APPLE OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
523+
set(LLVMDSDL_SELF_CONTAINED_TOOL_BUNDLE_DEFAULT ON)
524+
endif()
525+
526+
option(LLVMDSDL_ENABLE_SELF_CONTAINED_TOOL_BUNDLE
527+
"Enable self-contained tool bundle target (copies the tools with runtime deps)"
528+
${LLVMDSDL_SELF_CONTAINED_TOOL_BUNDLE_DEFAULT})
529+
530+
set(LLVMDSDL_SELF_CONTAINED_TOOLS_DIR "${LLVMDSDL_BINARY_DIR}/self-contained-tools")
531+
521532

522533
# Vendoring libLLVM into the package.
523534
#
@@ -527,23 +538,35 @@ set(LLVMDSDL_INSTALL_COMPONENT_DEV "dev")
527538
# the library inside the package is what makes `apt install ./llvm-dsdl_*.deb` work
528539
# on a machine that has never heard of apt.llvm.org.
529540
#
530-
# Off by default: a developer's `cmake --install` should not copy a ~100 MB library
541+
# The same reasoning applies to the macOS tarball: a bare download has no
542+
# dependency resolver either, and a tree whose binaries reference
543+
# /opt/homebrew/opt/llvm only runs on a machine that already has Homebrew LLVM.
544+
#
545+
# Off by default: a developer's `cmake --install` should not copy a ~150 MB library
531546
# into the install tree. The release build turns it on explicitly.
532547
#
533548
# LLVM is Apache-2.0-WITH-LLVM-exception, so redistribution is fine with
534549
# attribution -- packaging/deb/copyright carries the licence paragraph, and its
535550
# Files: stanza must be activated when this is enabled for a published package.
536551
option(LLVMDSDL_VENDOR_LLVM
537-
"Ship libLLVM inside the install tree and point the tools at it via RPATH."
552+
"Ship libLLVM inside the install tree so the package runs without a system LLVM."
538553
OFF)
539554

540-
if(LLVMDSDL_VENDOR_LLVM)
541-
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
542-
message(FATAL_ERROR
543-
"LLVMDSDL_VENDOR_LLVM is implemented for Linux only (it relies on ELF RPATH). "
544-
"macOS distribution goes through Homebrew, which depends on llvm@22 instead.")
545-
endif()
555+
# Linux and macOS reach the same outcome by different mechanisms: ELF RPATH set
556+
# on the installed binaries, versus Mach-O install names rewritten by the bundle
557+
# target. The flag means "self-contained" on both; only the plumbing differs.
558+
set(LLVMDSDL_VENDOR_LLVM_VIA_BUNDLE OFF)
559+
if(LLVMDSDL_VENDOR_LLVM AND APPLE)
560+
set(LLVMDSDL_VENDOR_LLVM_VIA_BUNDLE ON)
561+
endif()
562+
563+
if(LLVMDSDL_VENDOR_LLVM AND NOT CMAKE_SYSTEM_NAME STREQUAL "Linux" AND NOT APPLE)
564+
message(FATAL_ERROR
565+
"LLVMDSDL_VENDOR_LLVM is implemented for Linux (ELF RPATH) and macOS "
566+
"(Mach-O install names) only.")
567+
endif()
546568

569+
if(LLVMDSDL_VENDOR_LLVM AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
547570
# A private directory rather than ${CMAKE_INSTALL_LIBDIR}: this is our copy of
548571
# someone else's library, and it must never satisfy anything but our own tools.
549572
set(LLVMDSDL_VENDOR_LLVM_SUBDIR "${CMAKE_INSTALL_LIBDIR}/llvm-dsdl")
@@ -625,10 +648,39 @@ if(LLVMDSDL_VENDOR_LLVM)
625648
BUILD_WITH_INSTALL_RPATH OFF)
626649
endif()
627650

628-
install(
629-
TARGETS ${LLVMDSDL_INSTALLABLE_TOOLS}
630-
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
631-
COMPONENT ${LLVMDSDL_INSTALL_COMPONENT_BIN})
651+
if(LLVMDSDL_VENDOR_LLVM_VIA_BUNDLE)
652+
# macOS gets its self-contained tree from the bundle target, which rewrites
653+
# Mach-O install names in place. Installing the bundle rather than the raw
654+
# targets is the whole point: the raw binaries reference
655+
# /opt/homebrew/opt/llvm and only run where Homebrew LLVM is already present,
656+
# which is exactly the trap a downloadable tarball must not contain.
657+
#
658+
# The bundle's layout is bin/ + lib/ and its install names are
659+
# @executable_path/../lib, so it must land at the prefix root unchanged --
660+
# relocating lib/ elsewhere would break every reference in it.
661+
if(NOT LLVMDSDL_ENABLE_SELF_CONTAINED_TOOL_BUNDLE)
662+
message(FATAL_ERROR
663+
"LLVMDSDL_VENDOR_LLVM on macOS is implemented via the self-contained bundle, "
664+
"but LLVMDSDL_ENABLE_SELF_CONTAINED_TOOL_BUNDLE is OFF.")
665+
endif()
666+
667+
install(
668+
DIRECTORY "${LLVMDSDL_SELF_CONTAINED_TOOLS_DIR}/bin/"
669+
DESTINATION "${CMAKE_INSTALL_BINDIR}"
670+
COMPONENT ${LLVMDSDL_INSTALL_COMPONENT_BIN}
671+
USE_SOURCE_PERMISSIONS)
672+
673+
install(
674+
DIRECTORY "${LLVMDSDL_SELF_CONTAINED_TOOLS_DIR}/lib/"
675+
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
676+
COMPONENT ${LLVMDSDL_INSTALL_COMPONENT_BIN}
677+
USE_SOURCE_PERMISSIONS)
678+
else()
679+
install(
680+
TARGETS ${LLVMDSDL_INSTALLABLE_TOOLS}
681+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
682+
COMPONENT ${LLVMDSDL_INSTALL_COMPONENT_BIN})
683+
endif()
632684

633685
install(
634686
TARGETS ${LLVMDSDL_INSTALLABLE_LIBRARIES}
@@ -921,27 +973,27 @@ if(LLVMDSDL_ENABLE_PYTHON_ACCELERATOR)
921973
)
922974
endif()
923975

924-
set(LLVMDSDL_SELF_CONTAINED_TOOL_BUNDLE_DEFAULT OFF)
925-
if(APPLE OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
926-
set(LLVMDSDL_SELF_CONTAINED_TOOL_BUNDLE_DEFAULT ON)
927-
endif()
928-
929-
option(LLVMDSDL_ENABLE_SELF_CONTAINED_TOOL_BUNDLE
930-
"Enable self-contained tool bundle target (copies dsdlc/dsdl-opt with runtime deps)"
931-
${LLVMDSDL_SELF_CONTAINED_TOOL_BUNDLE_DEFAULT})
932-
933976
if(LLVMDSDL_ENABLE_SELF_CONTAINED_TOOL_BUNDLE)
934-
set(LLVMDSDL_SELF_CONTAINED_TOOLS_DIR
935-
"${LLVMDSDL_BINARY_DIR}/self-contained-tools")
936-
add_custom_target(bundle-tools-self-contained
977+
# All three tools, not just the two that generate code: the macOS release
978+
# tarball ships this tree, and a package missing the language server would be
979+
# a strange thing to hand someone.
980+
#
981+
# Part of ALL only when the install rules consume it (macOS vendoring), because
982+
# then `cmake --install` must find it already built. Otherwise it stays opt-in:
983+
# it copies and re-signs ~150 MB of LLVM, which no ordinary build should pay for.
984+
set(LLVMDSDL_BUNDLE_IN_ALL "")
985+
if(LLVMDSDL_VENDOR_LLVM_VIA_BUNDLE)
986+
set(LLVMDSDL_BUNDLE_IN_ALL ALL)
987+
endif()
988+
989+
add_custom_target(bundle-tools-self-contained ${LLVMDSDL_BUNDLE_IN_ALL}
937990
COMMAND
938991
${CMAKE_COMMAND}
939-
-DTOOL_DSDLC=$<TARGET_FILE:dsdlc>
940-
-DTOOL_DSDLOPT=$<TARGET_FILE:dsdl-opt>
992+
"-DTOOLS=$<TARGET_FILE:dsdlc>;$<TARGET_FILE:dsdl-opt>;$<TARGET_FILE:dsdld>"
941993
-DOUTPUT_DIR=${LLVMDSDL_SELF_CONTAINED_TOOLS_DIR}
942994
-DLLVMDSDL_SOURCE_DIR=${LLVMDSDL_SOURCE_DIR}
943995
-P ${LLVMDSDL_SOURCE_DIR}/cmake/BundleSelfContainedTools.cmake
944-
DEPENDS dsdlc dsdl-opt
996+
DEPENDS ${LLVMDSDL_INSTALLABLE_TOOLS}
945997
USES_TERMINAL
946998
VERBATIM
947999
COMMENT

0 commit comments

Comments
 (0)