From c1885acd3c94f4b398c24b33980815edb8ad7413 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Mon, 11 May 2026 14:40:11 -0700 Subject: [PATCH] Build clang-tidy with plugin support and publish plugin headers Workerd's JsgLint clang-tidy plugin needs the workerd-tools clang-tidy binary to be built with LLVM_ENABLE_PLUGINS, CLANG_PLUGIN_SUPPORT and LLVM_ENABLE_RTTI enabled so that plugins can be loaded via --load= and resolve symbols against the running binary. Flip those three flags in build/llvm/common.args. Out-of-tree plugins also need a slice of the LLVM source / build tree headers to compile against. Add a packaging step to the LLVM workflow that, when the target contains 'clang-tidy', produces a per-platform llvm---clang-tidy-dev.tar.xz asset containing: - clang/include/{clang,clang-c}/** - llvm/include/{llvm,llvm-c}/** - build/include/** (generated config headers) - build/tools/clang/include/** (generated clang config headers) - clang-tools-extra/clang-tidy/**.h (plugin API) The layout mirrors the LLVM source tree so consumers just need -I clang/include -I llvm/include -I build/include -I build/tools/clang/include -I clang-tools-extra. Generated headers under build/ are platform-specific, hence one tarball per platform. --- .github/workflows/llvm.yml | 50 ++++++++++++++++++++++++++++++++++++++ build/llvm/common.args | 5 ++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/.github/workflows/llvm.yml b/.github/workflows/llvm.yml index f85a832..2e2d86a 100644 --- a/.github/workflows/llvm.yml +++ b/.github/workflows/llvm.yml @@ -124,4 +124,54 @@ jobs: done env: GITHUB_TOKEN: ${{ github.TOKEN }} + # Package the slice of LLVM/Clang/clang-tools-extra headers required to build + # out-of-tree clang-tidy plugins (e.g. workerd's JsgLint). Generated config + # headers under build/ are platform-specific, so we ship one tarball per + # platform. The layout inside the tarball mirrors the LLVM source tree so + # consumers can simply add -I clang/include -I llvm/include -I build/include + # -I build/tools/clang/include -I clang-tools-extra without rewriting paths. + - name: Package clang-tidy plugin development headers + if: contains(inputs.target, 'clang-tidy') + shell: bash + run: | + set -euo pipefail + STAGE_DIR=$PWD/llvm-$LLVM_VERSION-${{ matrix.platform.os }}-clang-tidy-dev + TARBALL=$STAGE_DIR.tar.xz + BASENAME=$(basename "$STAGE_DIR") + mkdir -p "$STAGE_DIR" + + # Copy headers/.def/.inc from src into dst, preserving the relative + # tree. When include_inc is "yes" .def and .inc are included alongside + # .h. Implemented with find for portability across the linux, macOS + # and Windows (Git-bash) runners. + copy_headers() { + local src=$1 + local dst=$2 + local include_inc=${3:-no} + mkdir -p "$dst" + local abs_src + abs_src=$(cd "$src" && pwd) + if [ "$include_inc" = "yes" ]; then + (cd "$abs_src" && find . \( -name '*.h' -o -name '*.def' -o -name '*.inc' \) -print0) + else + (cd "$abs_src" && find . -name '*.h' -print0) + fi | + while IFS= read -r -d '' f; do + mkdir -p "$dst/$(dirname "$f")" + cp "$abs_src/$f" "$dst/$f" + done + } + + copy_headers llvm/clang/include "$STAGE_DIR/clang/include" yes + copy_headers llvm/llvm/include "$STAGE_DIR/llvm/include" yes + copy_headers llvm/build/include "$STAGE_DIR/build/include" yes + copy_headers llvm/build/tools/clang/include "$STAGE_DIR/build/tools/clang/include" yes + # clang-tools-extra/clang-tidy carries the plugin API as plain .h files + # within the source tree (no install target ships them). + copy_headers llvm/clang-tools-extra/clang-tidy "$STAGE_DIR/clang-tools-extra/clang-tidy" + + tar -C "$(dirname "$STAGE_DIR")" -cJf "$TARBALL" "$BASENAME" + gh release upload -R ${{ github.repository }} ${{ inputs.target }}-$LLVM_VERSION "$TARBALL" || true + env: + GITHUB_TOKEN: ${{ github.TOKEN }} diff --git a/build/llvm/common.args b/build/llvm/common.args index 9f613c1..509cfc3 100644 --- a/build/llvm/common.args +++ b/build/llvm/common.args @@ -9,9 +9,10 @@ -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_UTILS=OFF -DLLVM_ENABLE_IDE=ON --DLLVM_ENABLE_PLUGINS=OFF +-DLLVM_ENABLE_PLUGINS=ON -DCLANG_ENABLE_ARCMT=OFF -DCLANG_ENABLE_STATIC_ANALYZER=OFF --DCLANG_PLUGIN_SUPPORT=OFF +-DCLANG_PLUGIN_SUPPORT=ON -DCMAKE_CXX_FLAGS=-g0 -DCMAKE_C_FLAGS=-g0 +-DLLVM_ENABLE_RTTI=ON