From 2e9136e324d014127e01046e135590ce8b5acd7a Mon Sep 17 00:00:00 2001 From: "jinwei.han" Date: Mon, 20 Apr 2026 00:01:44 -0700 Subject: [PATCH] cmake : skip project() when consumed as a subdirectory When llama.cpp or ggml is pulled into a parent CMake project via add_subdirectory / FetchContent / CPM, the unconditional project() calls re-run toolchain detection in the nested scope. For C/CXX this is mostly a no-op, but ggml additionally enables ASM, which triggers an ASM compiler identification pass that can override parent-scope settings (e.g. CMAKE_ASM_COMPILER) and, on cross-compilation toolchains such as iOS or the Android NDK, can pick a different sysroot / architecture than the parent configured. Guard both project() calls behind the standard `CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR` check so they only fire for standalone builds. The existing `LLAMA_STANDALONE` and `GGML_STANDALONE` variables continue to work because they are computed with the same condition. All assembly use in the tree is gated behind `enable_language(ASM)` in the backend that needs it (Metal, Hexagon HTP), so dropping ASM from the embedded project() call is safe. Closes #20415 --- CMakeLists.txt | 10 +++++++++- ggml/CMakeLists.txt | 11 ++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index caea48c5060..a3ef4474ad1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,13 @@ cmake_minimum_required(VERSION 3.14...3.28) # for add_link_options and implicit target directories. -project("llama.cpp" C CXX) + +# Only call project() when llama.cpp is the top-level build. When consumed as +# a subdirectory, a second project() would re-run toolchain detection and can +# override parent-project settings. See: +# https://github.com/ggml-org/llama.cpp/issues/20415 +if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + project("llama.cpp" C CXX) +endif() + include(CheckIncludeFileCXX) #set(CMAKE_WARN_DEPRECATED YES) diff --git a/ggml/CMakeLists.txt b/ggml/CMakeLists.txt index 8454eecde6e..41d568c59d6 100644 --- a/ggml/CMakeLists.txt +++ b/ggml/CMakeLists.txt @@ -6,7 +6,16 @@ cmake_minimum_required(VERSION 3.14...3.28) # for add_link_options and implicit if (POLICY CMP0194) cmake_policy(SET CMP0194 NEW) endif() -project("ggml" C CXX ASM) + +# Only call project() when ggml is the top-level build. When consumed as a +# subdirectory (FetchContent, CPM, etc.), a second project() would re-run +# toolchain detection and can clobber parent-project settings such as +# CMAKE_OSX_ARCHITECTURES, CMAKE_OSX_SYSROOT or CMAKE_ASM_COMPILER during +# cross-compilation (iOS, Android NDK, arm64/x86_64 hosts). +# See: https://github.com/ggml-org/llama.cpp/issues/20415 +if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + project("ggml" C CXX ASM) +endif() ### GGML Version set(GGML_VERSION_MAJOR 0)