aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/nightly-build.yml9
-rw-r--r--AGENTS/ARCH.md14
-rw-r--r--cmake/NativeCompiler.cmake13
-rw-r--r--doc/build.md17
-rw-r--r--tools/build-static-lld.sh51
5 files changed, 87 insertions, 17 deletions
diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml
index 1f21821..048133d 100644
--- a/.github/workflows/nightly-build.yml
+++ b/.github/workflows/nightly-build.yml
@@ -123,13 +123,16 @@ jobs:
- name: Install LLVM 23 and packaging dependencies
run: |
test "$(uname -m)" = arm64
- brew install llvm@23 lld pandoc zlib zstd ncurses python
+ brew install llvm@23 pandoc zlib zstd ncurses python
test -x "$(brew --prefix llvm@23)/bin/clang++"
+ - name: Build matching static LLD libraries
+ run: |
+ sh tools/build-static-lld.sh "$(brew --prefix llvm@23)" "$PWD/build" 3
+
- name: Build the embedded release package
run: |
llvm_prefix=$(brew --prefix llvm@23)
- lld_prefix=$(brew --prefix lld)
zlib_prefix=$(brew --prefix zlib)
zstd_prefix=$(brew --prefix zstd)
ncurses_prefix=$(brew --prefix ncurses)
@@ -139,7 +142,7 @@ jobs:
-DCMAKE_C_COMPILER="$llvm_prefix/bin/clang" \
-DCMAKE_CXX_COMPILER="$llvm_prefix/bin/clang++" \
-DLLVM_DIR="$llvm_prefix/lib/cmake/llvm" \
- -DCMAKE_PREFIX_PATH="$llvm_prefix;$lld_prefix;$zlib_prefix;$zstd_prefix;$ncurses_prefix"
+ -DCMAKE_PREFIX_PATH="$llvm_prefix;$zlib_prefix;$zstd_prefix;$ncurses_prefix"
cmake --build build --target release --parallel 3
- name: Smoke test the packaged compiler
diff --git a/AGENTS/ARCH.md b/AGENTS/ARCH.md
index 30e4f90..e78d872 100644
--- a/AGENTS/ARCH.md
+++ b/AGENTS/ARCH.md
@@ -67,8 +67,8 @@ selected executable changes.
Platform modules relocate package paths only inside the extraction directory;
Homebrew bottles also receive local Cellar/opt links and Mach-O relocation/signing.
Package hashes skip unchanged extractions; a changed package set rebuilds the
-managed root. Downloads belong to the package-manager commands in `doc/build.md`,
-not to CMake. The Windows Pandoc ZIP is downloaded directly from its official
+managed root. Downloads belong to the explicit dependency commands and static LLD
+helper in `doc/build.md`, not to CMake. The Windows Pandoc ZIP is downloaded directly from its official
release because MSYS2 has no Pandoc package. Only the Linux build is verified.
Generated IR uses the C++ exception ABI; native compilation links its runtime
@@ -143,6 +143,14 @@ headers or system runtime dylibs. No user development toolchain is required.
Linux statically links non-system runtimes but dynamically links glibc; do not use
global `-static` there. Generated binaries require a compatible host system runtime.
+Homebrew's LLD package contains shared libraries. Run `tools/build-static-lld.sh`
+with the selected LLVM prefix and cpsc build directory before configuring on macOS.
+It builds matching LLD sources, installs static archives and tools into the build
+prefix, and leaves LLVM itself installed. Source and build caches are versioned;
+the resulting local `lib/cmake/lld` takes precedence over shared system packages.
+The helper's build-time linker can use the installed LLVM dylib; cpsc still links
+the LLD archives and static LLVM components.
+
Windows build instructions retain MSYS2 MINGW64. Its LLVM/Clang package names
and compiler executable names are unversioned; CMake still requires major 23.
The build guide explicitly selects `/mingw64/bin/clang.exe` and `clang++.exe`
@@ -218,7 +226,7 @@ job uses a macOS 15 arm64 runner, and Windows uses Windows Server 2025 x86_64.
All four check out the push SHA and run independently after cleanup. All three
compiler jobs use LLVM/Clang/LLD 23, Python, Release and EMBEDDED settings, Pandoc, and the
existing `release` target. Linux obtains its toolchain from apt.llvm.org; macOS
-uses Homebrew's LLVM 23. Windows uses `msys2/setup-msys2@v2` with MINGW64,
+uses Homebrew's LLVM 23 and builds matching static LLD with the helper above. Windows uses `msys2/setup-msys2@v2` with MINGW64,
MSYS2 LLVM/Clang packages, explicit native compiler and LLVM paths, and the
MinGW Makefiles generator. It downloads the official Pandoc 3.12.1 Windows
x86_64 ZIP into `build/deps/packages/` for CMake to extract. Each compiler job
diff --git a/cmake/NativeCompiler.cmake b/cmake/NativeCompiler.cmake
index 29682ec..35c7f41 100644
--- a/cmake/NativeCompiler.cmake
+++ b/cmake/NativeCompiler.cmake
@@ -18,6 +18,13 @@ else()
set(cpsc_linker_libraries lldELF)
endif()
+foreach(cpsc_native_library clangDriver ${cpsc_linker_libraries})
+ get_target_property(cpsc_native_type ${cpsc_native_library} TYPE)
+ if(NOT cpsc_native_type STREQUAL "STATIC_LIBRARY")
+ message(FATAL_ERROR "Native output requires static ${cpsc_native_library}; found ${cpsc_native_type}. See doc/build.md for static dependency setup.")
+ endif()
+endforeach()
+
set(cpsc_native_flags)
get_filename_component(cpsc_lld_prefix "${LLD_DIR}/../../.." ABSOLUTE)
if(APPLE)
@@ -105,9 +112,3 @@ foreach(cpsc_import IN LISTS CLANG_EXPORTED_TARGETS LLD_EXPORTED_TARGETS LLVM_AV
set_property(TARGET ${cpsc_import} PROPERTY INTERFACE_LINK_LIBRARIES "${cpsc_interface}")
endif()
endforeach()
-foreach(cpsc_native_library clangDriver ${cpsc_linker_libraries})
- get_target_property(cpsc_native_type ${cpsc_native_library} TYPE)
- if(NOT cpsc_native_type STREQUAL "STATIC_LIBRARY")
- message(FATAL_ERROR "Native output requires static ${cpsc_native_library}")
- endif()
-endforeach()
diff --git a/doc/build.md b/doc/build.md
index a3b9cc3..7f702d3 100644
--- a/doc/build.md
+++ b/doc/build.md
@@ -133,10 +133,10 @@ The `clang-tools-extra` package is required because MSYS2's `ClangTargets.cmake`
Install the Xcode Command Line Tools for the macOS SDK, make and package
relocation tools with `xcode-select --install` if needed. The LLVM bottle below
-provides Clang 23. Install CMake with Homebrew:
+provides Clang 23. Install the build tools and LLVM SDK with Homebrew:
```bash
-brew install cmake python
+brew install cmake python llvm@23
```
Recommended binary-bottle downloads to the build directory:
@@ -144,16 +144,23 @@ Recommended binary-bottle downloads to the build directory:
```bash
mkdir -p build/deps/packages
HOMEBREW_CACHE="$PWD/build/deps/packages" brew fetch --force-bottle \
- llvm lld zlib zstd ncurses lz4 xz
+ llvm zlib zstd ncurses lz4 xz
```
[Homebrew's `llvm` formula](https://formulae.brew.sh/formula/llvm) currently
provides 23; verify the downloaded version before configuring. This requires
-binary bottles available for your macOS version and CPU; source
-archives are not used. CMake extracts the bottles into a local `Cellar/`, creates
+binary bottles available for your macOS version and CPU. CMake extracts the bottles into a local `Cellar/`, creates
local `opt/` links and relocates their CMake and dynamic-library paths using the
Command Line Tools. The macOS build has only been reviewed statically.
+Homebrew's `lld` formula builds shared libraries, which cannot be embedded in the single-file compiler. Before configuring cpsc, build static LLD against the LLVM version selected for the compiler:
+
+```bash
+sh tools/build-static-lld.sh "$(brew --prefix llvm@23)" "$PWD/build" 3
+```
+
+The helper downloads the matching official LLVM source release, extracts LLD, its common CMake utilities and libunwind's Mach-O headers, and builds LLD using the installed LLVM SDK. It installs static LLD libraries, headers, tools and CMake configuration into `build/`, where cpsc's local dependency lookup finds them before system packages. It does not rebuild LLVM or libunwind. Use the same build directory for the helper and cpsc. For an already-extracted LLVM bottle, pass its `build/deps/root/opt/llvm` prefix instead; the LLVM versions must match. The helper uses the host architecture and defaults to a macOS 15.0 deployment target; set `MACOSX_DEPLOYMENT_TARGET` to override that target for both builds.
+
## Build
You must explicitly choose `-DCPSC_RUN_MODE=PATH`, `EMBEDDED`, or `NONE` on
diff --git a/tools/build-static-lld.sh b/tools/build-static-lld.sh
new file mode 100644
index 0000000..407e814
--- /dev/null
+++ b/tools/build-static-lld.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+# Build LLD against an installed LLVM SDK; install it in cpsc's build prefix.
+set -eu
+
+if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then
+ echo "Usage: sh tools/build-static-lld.sh LLVM_PREFIX BUILD_DIRECTORY [JOBS]" >&2
+ exit 1
+fi
+
+llvm_prefix=$(cd "$1" && pwd)
+mkdir -p "$2"
+build_root=$(cd "$2" && pwd)
+jobs=${3:-3}
+llvm_version=$("$llvm_prefix/bin/llvm-config" --version)
+case "$llvm_version" in
+ 23.*) ;;
+ *) echo "Static LLD requires LLVM 23; found $llvm_version" >&2; exit 1 ;;
+esac
+
+work="$build_root/static-lld-$llvm_version"
+archive="$work/llvm-project-$llvm_version.src.tar.xz"
+mkdir -p "$work/src/llvm"
+if [ ! -f "$archive" ]; then
+ curl -fL --retry 3 \
+ "https://github.com/llvm/llvm-project/releases/download/llvmorg-$llvm_version/llvm-project-$llvm_version.src.tar.xz" \
+ -o "$archive.part"
+ mv "$archive.part" "$archive"
+fi
+if [ ! -f "$work/src/.extracted" ]; then
+ tar -xJf "$archive" -C "$work/src" --strip-components=1 \
+ "llvm-project-$llvm_version.src/lld" "llvm-project-$llvm_version.src/cmake" \
+ "llvm-project-$llvm_version.src/libunwind/include"
+ touch "$work/src/.extracted"
+fi
+
+set --
+if [ "$(uname -s)" = Darwin ]; then
+ set -- "-DCMAKE_OSX_ARCHITECTURES=$(uname -m)" \
+ "-DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-15.0}"
+fi
+cmake -S "$work/src/lld" -B "$work/build" \
+ -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF \
+ -DLLVM_INCLUDE_TESTS=OFF -DLLVM_LINK_LLVM_DYLIB=ON \
+ "-DLLVM_DIR=$llvm_prefix/lib/cmake/llvm" \
+ "-DLLVM_MAIN_SRC_DIR=$work/src/llvm" \
+ "-DCMAKE_C_COMPILER=$llvm_prefix/bin/clang" \
+ "-DCMAKE_CXX_COMPILER=$llvm_prefix/bin/clang++" \
+ "-DCMAKE_INSTALL_RPATH=$llvm_prefix/lib" \
+ "-DCMAKE_INSTALL_PREFIX=$build_root" -DCMAKE_INSTALL_LIBDIR=lib "$@"
+cmake --build "$work/build" --parallel "$jobs"
+cmake --install "$work/build"