Skip to content

Commit bfc766c

Browse files
committed
Windows arm64: disable OpenMP so the clang-cl build is self-contained
The clang-cl fix worked (jllama.dll linked for Windows/aarch64), but the next step failed at test discovery: gtest_discover_tests could not launch jllama_test.exe -> exit 0xc0000135 (STATUS_DLL_NOT_FOUND). Root cause: with clang-cl, ggml links LLVM's OpenMP runtime (libomp.lib -> needs libomp140.aarch64.dll at run time). Unlike MSVC's ambient vcomp140.dll on x64, that DLL is not on PATH, so neither the test exe nor a consumer could load the binary. (Upstream llama.cpp works around this by copying libomp140.aarch64.dll next to its arm64 output.) Fix: pass -DGGML_OPENMP=OFF for the arm64 job. ggml falls back to its own std::thread threadpool, so both jllama_test.exe and the shipped arm64 jllama.dll are self-contained with no libomp dependency to ship — cleaner than bundling an LLVM OpenMP DLL into the default JAR. The x86_64/x86 jobs keep OpenMP (MSVC vcomp, which is ambient and already proven). Also updated the job comment + CLAUDE.md to record that VC\Tools\Llvm\ARM64 supplies clang-cl/lld-link (no separate LLVM install needed) and the OpenMP rationale. The getenv/strdup/ctime deprecation messages in the same log are warnings only (clang-cl flagging POSIX names against the MSVC UCRT headers), not the failure. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HL7d4uQ3cKR5HwYFPvZvv7
1 parent d9a6a83 commit bfc766c

2 files changed

Lines changed: 16 additions & 5 deletions

File tree

.github/workflows/publish.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -887,9 +887,14 @@ jobs:
887887
# clang-cl (LLVM's MSVC-compatible driver) satisfies that guard (its compiler id is "Clang")
888888
# while still leaving CMake's MSVC=TRUE, so our static /MT CRT block (CMAKE_MSVC_RUNTIME_LIBRARY
889889
# in CMakeLists.txt) keeps applying and the generator stays Ninja Multi-Config. msvc-dev-cmd
890-
# (arm64) supplies the MSVC headers/libs/linker that clang-cl links against. NOTE: clang-cl must
891-
# be on PATH (the VS "C++ Clang tools" component / LLVM); if a first CI run reports it missing,
892-
# add an LLVM setup step here.
890+
# (arm64) supplies the MSVC headers/libs/linker AND the bundled clang-cl / lld-link under
891+
# VC\Tools\Llvm\ARM64, so no separate LLVM install is needed.
892+
#
893+
# GGML_OPENMP=OFF: with clang-cl, ggml links LLVM's OpenMP (libomp.lib -> needs libomp140.aarch64.dll
894+
# at runtime), which is NOT on PATH like MSVC's ambient vcomp140.dll on x64 — so gtest_discover_tests
895+
# (and any consumer) failed to launch the binary with 0xc0000135 STATUS_DLL_NOT_FOUND. Turning OpenMP
896+
# off makes ggml use its own std::thread threadpool, so the arm64 jllama.dll (and the test exe) are
897+
# self-contained with no libomp dependency to ship. The x86_64/x86 jobs keep OpenMP (MSVC vcomp).
893898
runs-on: windows-11-arm
894899
steps:
895900
- uses: actions/checkout@v7
@@ -909,7 +914,7 @@ jobs:
909914
# explicitly (so the OSInfo-class OS-detection path is skipped) — same as the x86_64 job.
910915
# clang-cl (see the job comment) is required: ggml refuses MSVC cl.exe on ARM.
911916
run: |
912-
.github\build.bat -G "Ninja Multi-Config" -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DOS_NAME=Windows -DOS_ARCH=aarch64 -DBUILD_TESTING=ON
917+
.github\build.bat -G "Ninja Multi-Config" -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DGGML_OPENMP=OFF -DOS_NAME=Windows -DOS_ARCH=aarch64 -DBUILD_TESTING=ON
913918
- name: Run C++ unit tests
914919
run: ctest --test-dir llama/build --output-on-failure
915920
- name: Upload artifacts

CLAUDE.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,13 @@ via `if (MSVC AND NOT CMAKE_C_COMPILER_ID STREQUAL "Clang")`; `clang-cl` (LLVM's
301301
satisfies that guard (compiler id `"Clang"`) while keeping CMake's `MSVC=TRUE`, so the static `/MT` CRT
302302
block still applies and the generator stays Ninja Multi-Config. The job passes
303303
`-DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl`; `msvc-dev-cmd` supplies the MSVC
304-
headers/libs/linker `clang-cl` links against. (Upstream llama.cpp instead cross-compiles arm64 from an
304+
headers/libs/linker **and the bundled clang-cl/lld-link** (`VC\Tools\Llvm\ARM64`), so no separate
305+
LLVM install is needed. It also passes **`-DGGML_OPENMP=OFF`**: with clang-cl, ggml links LLVM's
306+
OpenMP (`libomp.lib``libomp140.aarch64.dll` at runtime), which — unlike MSVC's ambient
307+
`vcomp140.dll` on x64 — is not on `PATH`, so the test exe (and any consumer) failed to launch with
308+
`0xc0000135` (`STATUS_DLL_NOT_FOUND`). Disabling OpenMP makes ggml use its own `std::thread`
309+
threadpool, leaving the arm64 `jllama.dll` self-contained (the x86_64/x86 jobs keep OpenMP via MSVC
310+
`vcomp`). (Upstream llama.cpp instead cross-compiles arm64 from an
305311
x64 runner with `vcvarsall amd64_arm64` + a `clang`/`clang++` toolchain file and no arm64 tests; the
306312
native-runner + `clang-cl` route here keeps the `/MT` CRT and lets `ctest` run on real ARM hardware.)
307313

0 commit comments

Comments
 (0)