ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

llama.cpp 外部安装与 CMake 包消费验证:详解 examples/test-cmake 的最小可运行示例

llama.cpp 外部安装与 CMake 包消费验证:详解 examples/test-cmake 的最小可运行示例 llama.cpp 外部安装与 CMake 包消费验证详解 examples/test-cmake 的最小可运行示例【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cppexamples/test-cmake是 llama.cpp 仓库中一个专门用于手动验证本机安装结果的最小工程先把 llama.cpp 本身配置、构建并安装到一个本地目录再把这个目录当作一个标准的 CMake 依赖包用find_package(llama)的方式编译并链接一个独立的 C 程序。读完后你将掌握如何把一个已安装的 llama.cpp 作为第三方库接入自己的项目并能通过两个脚本build-install.sh/build.sh快速排查安装配置install layout、共享库、动态后端加载是否正确。这个示例解决什么问题README 对它的定位非常明确This is just for manually testing/developing of a llama.cpp installation to enable troubleshooting issues and exploration. The idea is that this can be used after making changes to llama.cpp installation cmake configuration and then verify it locally.也就是说当你修改了 llama.cpp 的安装相关 CMake 配置例如库安装目录、共享/静态库开关、后端动态加载方式之后可以用这个工程在本地“自测”安装产物是否完整、CMake config 文件是否能被下游find_package正确找到、运行期能否从自定义目录加载动态后端。整个示例由 5 个文件组成README.md用法说明build-install.sh以“被依赖库”的身份构建并安装 llama.cppbuild.sh以“下游消费者”的身份配置、编译、运行 test-cmakeCMakeLists.txt消费者工程的最小 CMake 脚本test-cmake.cpp只做版本打印与后端初始化的最小 C 程序.gitignore忽略install、build、llama-build-install三个本地产物目录。第一步构建并安装 llama.cpp 到本地目录build-install.sh 的完整内容只有三行核心逻辑清目录、配置、构建、安装#!/bin/bash set -e rm -rf llama-build-install install cmake --fresh -S ../../. -B llama-build-install -DCMAKE_BUILD_TYPERelease \ -DBUILD_SHARED_LIBSON \ -DGGML_BACKEND_DLON \ -DGGML_CPU_ALL_VARIANTSON \ -DLLAMA_TESTS_INSTALLOFF \ -DCMAKE_INSTALL_PREFIX${PWD}/install \ -DGGML_BACKEND_DIR${PWD}/install/lib/llama.cpp \ -DGGML_LIB_INSTALL_DIR${PWD}/install/lib/llama.cpp \ -DLLAMA_LIB_INSTALL_DIR${PWD}/install/lib/llama.cpp \ -DLLAMA_TOOLS_INSTALLOFF cmake --build llama-build-install --parallel 12 cmake --install llama-build-install注意它的-S ../../.指向的是 llama.cpp 仓库根目录即“先把自己安装成一个库”。逐个参数解释如下这些开关在仓库的 CMake 源码中都可以找到定义参数作用源码依据CMAKE_BUILD_TYPERelease以 Release 模式构建被安装的主库CMake 常规BUILD_SHARED_LIBSON构建共享库.so/.dylib/.dll是下游动态链接的前提cmake/llama-config.cmake.in中LLAMA_SHARED_LIB即取自该开关GGML_BACKEND_DLON将 ggml 各计算后端CPU、CUDA、Metal 等构建成可动态加载的.so运行期再加载而非静态编入主库ggml/CMakeLists.txtoption(GGML_BACKEND_DL ggml: build backends as dynamic libraries (requires BUILD_SHARED_LIBS) OFF)且 ggml/src/CMakeLists.txt 明确GGML_BACKEND_DL依赖BUILD_SHARED_LIBSGGML_CPU_ALL_VARIANTSON一次构建所有 CPU 微架构变体如libggml-cpu-alderlake.so、haswell等运行期按机器能力挑选加载ggml/CMakeLists.txtoption(GGML_CPU_ALL_VARIANTS ggml: build all variants of the CPU backend (requires GGML_BACKEND_DL) OFF)GGML_BACKEND_DIR指定动态后端.so的安装目标目录ggml/CMakeLists.txt 定义为CACHE PATHggml/src/CMakeLists.txt 会在GGML_BACKEND_DL开启时把它编进ggml的宏定义GGML_BACKEND_DIR...并在 ggml/src/CMakeLists.txt 把各后端install(TARGETS ... LIBRARY DESTINATION ${GGML_BACKEND_DIR})GGML_LIB_INSTALL_DIR/LLAMA_LIB_INSTALL_DIRggml 与 llama 两层库的安装目录ggml/CMakeLists.txt 与 CMakeLists.txt 中均定义为CACHE PATHCMAKE_INSTALL_PREFIX整个安装的根前缀这里落到当前目录下的install/CMake 常规LLAMA_TESTS_INSTALLOFF/LLAMA_TOOLS_INSTALLOFF只安装库与头文件不安装测试程序和 CLI 工具缩小安装产物CMakeLists.txt 中两个option(...)的定义安装完成后install/lib/下的产物在 README 中给出了一个真实示例不同平台文件名会不同(venv) $ ls install/lib/ cmake libggml.so libllama-common.so.0 libllama.so.0.1.0 llama.cpp libggml-base.so libggml.so.0 libllama-common.so.0.1.0 libmtmd.so pkgconfig libggml-base.so.0 libggml.so.0.19.0 libllama.so libmtmd.so.0 libggml-base.so.0.19.0 libllama-common.so libllama.so.0 libmtmd.so.0.1.0可以观察到三个关键点出现了libggml、libggml-base、libllama、libllama-common、libmtmd多组“无版本主链 带版本实体 带版本符号链接”的组合说明主库确实按共享库方式安装且 soname 机制完整cmake/子目录存放的是供下游find_package使用的 CMake package config 文件即由 cmake/llama-config.cmake.in 生成的产物llama.cpp/子目录是GGML_BACKEND_DIR/GGML_LIB_INSTALL_DIR/LLAMA_LIB_INSTALL_DIR指向的目标位置动态后端.so会落在里面——这解释了为什么运行期需要把install/lib/llama.cpp加进LD_LIBRARY_PATH。第二步把安装目录当作 CMake 包来消费build.sh 只有三行但完整演示了“下游消费者”的标准流程#!/bin/bash set -e cmake -S . -B build -DCMAKE_PREFIX_PATH${PWD}/install cmake --build build LD_LIBRARY_PATH${PWD}/install/lib/llama.cpp:${PWD}/install/lib${LD_LIBRARY_PATH::$LD_LIBRARY_PATH} ./build/test-cmake三步分别对应配置-DCMAKE_PREFIX_PATH${PWD}/install告诉 CMake 到本地安装前缀里找find_package需要的 config 文件构建正常cmake --build运行把install/lib/llama.cpp动态后端目录与install/lib共享库目录前置注入LD_LIBRARY_PATH保证动态链接器能在运行期找到libllama.so、libggml.so以及libggml-cpu-*.so等动态后端。消费者工程 examples/test-cmake/CMakeLists.txt 是接入 llama.cpp 安装的最小模板全文如下cmake_minimum_required(VERSION 3.14) project(llama-simple) set(CMAKE_CXX_STANDARD 17) find_package(llama 0.1.0 REQUIRED) add_executable(test-cmake test-cmake.cpp) target_link_libraries(test-cmake PRIVATE llama) target_compile_definitions(test-cmake PRIVATE LLAMA_BUILD_NUMBER${LLAMA_BUILD_NUMBER} LLAMA_BUILD_COMMIT${LLAMA_BUILD_COMMIT} )这里有两点值得展开。find_package(llama)背后发生了什么llama.cpp 通过 cmake/llama-config.cmake.in 提供标准 CMake package config其关键片段是set(LLAMA_VERSION LLAMA_VERSION) set(LLAMA_BUILD_COMMIT LLAMA_BUILD_COMMIT) set(LLAMA_BUILD_NUMBER LLAMA_BUILD_NUMBER) set(LLAMA_SHARED_LIB BUILD_SHARED_LIBS) PACKAGE_INIT set_and_check(LLAMA_INCLUDE_DIR PACKAGE_LLAMA_INCLUDE_INSTALL_DIR) set_and_check(LLAMA_LIB_DIR PACKAGE_LLAMA_LIB_INSTALL_DIR) find_package(ggml REQUIRED HINTS ${LLAMA_LIB_DIR}/cmake) find_library(llama_LIBRARY llama REQUIRED HINTS ${LLAMA_LIB_DIR} NO_CMAKE_FIND_ROOT_PATH) add_library(llama UNKNOWN IMPORTED) set_target_properties(llama PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${LLAMA_INCLUDE_DIR} INTERFACE_LINK_LIBRARIES ggml::ggml;ggml::ggml-base; IMPORTED_LINK_INTERFACE_LANGUAGES CXX IMPORTED_LOCATION ${llama_LIBRARY} INTERFACE_COMPILE_FEATURES c_std_90 POSITION_INDEPENDENT_CODE ON)由此可以确认config 文件本身把LLAMA_VERSION、LLAMA_BUILD_COMMIT、LLAMA_BUILD_NUMBER暴露为普通 CMake 变量——这就是 examples/test-cmake/CMakeLists.txt 里能直接引用${LLAMA_BUILD_NUMBER}/${LLAMA_BUILD_COMMIT}的原因它们并不是find_package自动生成的而是llama-config.cmake显式set出来的该 config 又通过find_package(ggml REQUIRED HINTS ${LLAMA_LIB_DIR}/cmake)级联找到 ggml 的 package config并把导入目标llama的INTERFACE_LINK_LIBRARIES指向ggml::ggml;ggml::ggml-base所以下游只需要target_link_libraries(... PRIVATE llama)就能同时拿到 llama 与 ggml 两套符号INTERFACE_INCLUDE_DIRECTORIES指向安装前缀里的头文件目录因此消费者不需要再手工include_directories。这也解释了为什么build-install.sh中必须显式指定GGML_LIB_INSTALL_DIR与LLAMA_LIB_INSTALL_DIRconfig 文件里HINTS ${LLAMA_LIB_DIR}/cmake与HINTS ${LLAMA_LIB_DIR}都依赖这个路径才能找到 ggml 的 cmake 子目录和libllama.so实体。test-cmake.cpp只做“初始化即成功”test-cmake.cpp 的完整源码#include llama.h #include cstdio int main(void) { printf([test-cmake] version: %s, build: %d (%s)\n, llama_version(), LLAMA_BUILD_NUMBER, LLAMA_BUILD_COMMIT); printf([test-cmake] Initializing backend...\n); llama_backend_init(); printf([test-cmake] Backend initialized.\n); llama_backend_free(); return 0; }它只验证四件事头文件llama.h能被编译器找到include 目录配置正确llama_version()、LLAMA_BUILD_NUMBER、LLAMA_BUILD_COMMIT这些运行期/编译期版本信息可读config 文件变量传递正确llama_backend_init()能成功加载后端——在GGML_BACKEND_DLONGGML_CPU_ALL_VARIANTSON下这一步会真正从GGML_BACKEND_DIR指向的目录 dlopen 具体的libggml-cpu-variant.sollama_backend_free()能正常释放无运行期崩溃。完整流程与预期输出在examples/test-cmake/目录内按 README 顺序执行./build-install.sh会创建install/目录并在其lib/下生成上节列出的共享库与cmake/、pkgconfig/子目录。然后./build.shREADME 给出的实际运行输出是-- Configuring done (0.0s) -- Generating done (0.0s) -- Build files have been written to: /path/to/llama.cpp/examples/test-cmake/build [100%] Built target test-cmake [test-cmake] Using llama.cpp version 0.1.0-dev-b10335 [test-cmake] Initializing backend... load_backend: loaded CPU backend from /path/to/llama.cpp/examples/test-cmake/install/lib/llama.cpp/libggml-cpu-alderlake.so [test-cmake] Backend initialized.其中load_backend: loaded CPU backend from .../install/lib/llama.cpp/libggml-cpu-alderlake.so这一行是判断GGML_BACKEND_DL与GGML_BACKEND_DIR是否配置成功的直接证据它明确说明运行期是动态加载了位于install/lib/llama.cpp/的 alderlake 变体 CPU 后端而不是静态链接进libggml.so。适用前提与排查要点在使用这个示例前需要明确的限制依赖平台示例脚本使用LD_LIBRARY_PATH注入动态库路径属于 Linux/macOS 风格Windows 用户需要改用 PATH 或将.dll放入可执行文件目录脚本需自行调整。依赖共享库GGML_BACKEND_DLON在 ggml/src/CMakeLists.txt 中要求BUILD_SHARED_LIBSON两者必须同时开启CPU 变体与 native 互斥ggml/src/ggml-cpu/CMakeLists.txt 明确GGML_NATIVE与GGML_BACKEND_DL不兼容需要改用GGML_CPU_ALL_VARIANTS这也正是build-install.sh的选法安装前缀CMAKE_INSTALL_PREFIX硬编码为${PWD}/install若仓库不允许写入如根目录只读需先修改脚本里的路径产物目录install/、build/、llama-build-install/均已被 .gitignore 忽略可放心在本地重复执行。当你的项目修改了安装相关 CMake 配置例如调整LLAMA_LIB_INSTALL_DIR、切换GGML_BACKEND_DL后最直接的验证路径就是本示例的“安装 →find_package→llama_backend_init”闭环build-install.sh验证安装 layoutbuild.sh验证下游可发现性与运行期后端加载两者合起来即等价于一次轻量化的集成回归。【免费下载链接】llama.cppLLM inference in C/C项目地址: https://gitcode.com/GitHub_Trending/ll/llama.cpp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表