← All tasks
cppggml-org/llama.cpp #27834Repaired task

Build fails when GGML_CPU=OFF: tests, examples and POCs link against CPU-only symbols

envgap__ggml-org__llama.cpp-27834

01 / FAILURE SIGNATURE

Captured in a clean container

/work/pocs/vdot/q8dot.cpp:13:10: fatal error: ggml.h: No such file or directory

02 / ENVIRONMENT RECIPE

Base commit
b49650adb31f2e49a0d76113aeb1792134fd8413
Manifest
pocs/CMakeLists.txt
Reproduce
cmake -S pocs -B build -DBUILD_TESTING=OFF && cmake --build build -j4
Run under trace
cmake --build build -j4
Reference environment fix used for admission
diff --git a/examples/convert-llama2c-to-ggml/CMakeLists.txt b/examples/convert-llama2c-to-ggml/CMakeLists.txt
index 2162da4fd..d921af9a4 100644
--- a/examples/convert-llama2c-to-ggml/CMakeLists.txt
+++ b/examples/convert-llama2c-to-ggml/CMakeLists.txt
@@ -1,5 +1,7 @@
-set(TARGET llama-convert-llama2c-to-ggml)
-add_executable(${TARGET} convert-llama2c-to-ggml.cpp)
-install(TARGETS ${TARGET} RUNTIME)
-target_link_libraries(${TARGET} PRIVATE llama-common llama ${CMAKE_THREAD_LIBS_INIT})
-target_compile_features(${TARGET} PRIVATE cxx_std_17)
+if (GGML_CPU)
+    set(TARGET llama-convert-llama2c-to-ggml)
+    add_executable(${TARGET} convert-llama2c-to-ggml.cpp)
+    install(TARGETS ${TARGET} RUNTIME)
+    target_link_libraries(${TARGET} PRIVATE llama-common llama ${CMAKE_THREAD_LIBS_INIT})
+    target_compile_features(${TARGET} PRIVATE cxx_std_17)
+endif()
diff --git a/pocs/CMakeLists.txt b/pocs/CMakeLists.txt
index d49d14dee..93c76d609 100644
--- a/pocs/CMakeLists.txt
+++ b/pocs/CMakeLists.txt
@@ -8,7 +8,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 
 if (EMSCRIPTEN)
 else()
-    if (NOT GGML_BACKEND_DL)
+    if (NOT GGML_BACKEND_DL AND GGML_CPU)
         add_subdirectory(vdot)
     endif()
 endif()
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index a398344c8..9b3a4fcc4 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -322,7 +322,7 @@ if (APPLE)
     llama_build(test-rset-release.cpp)
 endif()
 
-if (NOT GGML_BACKEND_DL)
+if (NOT GGML_BACKEND_DL AND GGML_CPU)
     # these tests use the backends directly and cannot be built with dynamic loading
     llama_build_and_test(test-barrier.cpp)
     llama_build_and_test(test-quantize-fns.cpp)

03 / ORIGINAL ISSUE TEXT

ggml-org/llama.cpp #27834 · read the original issue
## Description

Building with `-DGGML_CPU=OFF -DGGML_CUDA=ON` (as done in the [CI CUDA Windows workflow](https://github.com/ggml-org/llama.cpp/blob/master/.github/workflows/build-cuda-windows.yml)) fails at link time because several targets reference CPU backend symbols that don't exist when `GGML_CPU=OFF`.

## Reproduction

```bat
cmake -B build -G "Ninja Multi-Config" -DGGML_CUDA=ON -DGGML_CPU=OFF
cmake --build build --config Release -j
```

## Failing targets and unresolved symbols

### Tests

| Target | Unresolved symbols |
|--------|-------------------|
| `test-barrier` | `ggml_threadpool_new`, `ggml_threadpool_free`, `ggml_graph_plan`, `ggml_graph_compute` |
| `test-quantize-fns` | `ggml_get_type_traits_cpu`, `ggml_cpu_init` |
| `test-quantize-perf` | `ggml_get_type_traits_cpu`, `ggml_cpu_init` |
| `test-rope` | `ggml_graph_plan`, `ggml_graph_compute` |
| `test-col2im-1d` | `ggml_graph_compute_with_ctx` |

### Examples / POCs

| Target | Unresolved symbols |
|--------|-------------------|
| `llama-convert-llama2c-to-ggml` | `ggml_set_f32_nd` |
| `llama-vdot` | `ggml_get_type_traits_cpu` |
| `llama-q8dot` | `ggml_get_type_traits_cpu` |

## Expected behavior

Targets that depend on the CPU backend should be excluded from the build when `GGML_CPU=OFF`.

## Suggested fix

Guard the affected targets in `tests/CMakeLists.txt`, `examples/`, and `pocs/` with `if(GGML_CPU)`, similar to how other conditional targets are handled.

## Workaround

Pass `-DLLAMA_BUILD_TESTS=OFF -DLLAMA_BUILD_EXAMPLES=OFF` to skip tests, examples, and POCs.
Continue on GitHub ↗

04 / LABELS

Labels checked by running the task · needs human review

misspecificationunderspecification
Label rules and the text that matched
[
  {
    "category": "underspecification",
    "rule": "signature.missing_system_requirement",
    "source": "failure_signature",
    "excerpt": "/work/pocs/vdot/q8dot.cpp:13:10: fatal error: ggml.h: No such file or directory"
  },
  {
    "category": "misspecification",
    "rule": "diff.changes_existing_manifest_line",
    "source": "manifest_diff:pocs/CMakeLists.txt",
    "excerpt": "-    if (NOT GGML_BACKEND_DL)\n+    if (NOT GGML_BACKEND_DL AND GGML_CPU)"
  }
]

Mined from a merged pull request linked to the issue whose changed files are all environment files.

The base commit is the pull request's base, not the dated default-branch commit; the registry is pinned to the merge date so the pull request's own pins resolve.

Default commands from envgap default-recipe synthesizer v1; gold_files are the pull request's environment diff.

Preparation uses current registries. Historical package availability is not enforced here; execution metadata records this limitation separately from the oracle's date-bounding policy.