业务目标概述
我们的目标是将 ChatSDK 变成Linux 静态库(
.a),最终交付的产品包括头文件和静态库文件。借助
make install命令,将库和头文件安装到系统目录/usr/local,这样其他项目就能直接引用。SDK的目录结构如下:
sdk ├─ CMakeLists.txt # SDK的构建脚本 ├─ include # 外部头文件 │ ├─ util │ ├─ ChatGPTProvider.h │ ├─ ChatSDK.h │ ├─ common.h │ ├─ DataManager.h │ ├─ DeepSeekProvider.h │ ├─ GeminiProvider.h │ ├─ LLMManager.h │ ├─ LLMProvider.h │ ├─ OllamaLLMProvider.h │ └─ SessionManager.h └─ src # 源文件 ├─ util ├─ ChatGPTProvider.cpp ├─ ChatSDK.cpp ├─ DataManager.cpp ├─ DeepSeekProvider.cpp ├─ GeminiProvider.cpp ├─ LLMManager.cpp ├─ OllamaLLMProvider.cpp └─ SessionManager.cpp
源文件管理方式
手动枚举源文件
原理:在
add_executable / add_library中明确列出所有.cpp源文件。优点:编译文件清单简单明了。
缺点:如果有新的
.cpp文件,必须手动更新CMakeLists.txt,否则会漏掉。
add_executable(testLLM testLLM.cpp ../sdk/src/util/myLog.cpp ../sdk/src/DeepSeekProvider.cpp ../sdk/src/ChatGPTProvider.cpp ../sdk/src/GeminiProvider.cpp ../sdk/src/OllamaLLMProvider.cpp ../sdk/src/DataManager.cpp ../sdk/src/SessionManager.cpp ../sdk/src/LLMManager.cpp ../sdk/src/ChatSDK.cpp )
自动收集源码
原理:使用递归遍历特定目录,通配符匹配文件后缀并存入 CMake 变量中。
小提醒:使用 GLOB 的时候,新增的文件不会被自动检索,记得重新执行
cmake ..才能识别新文件。
# 递归收集src目录中的所有cpp文件 file(GLOB_RECURSE SDK_SOURCES "src/*.cpp") # 递归收集include目录中的所有h文件 file(GLOB_RECURSE SDK_HEADERS "include/*.h")
完整的 CMakeLists.txt 代码示例
# CMake最低版本要求,放在最开头
cmake_minimum_required(VERSION 3.10)
# 项目定义
project(ai_chat_sdk)
# SDK名称变量
set(SDK_NAME "ai_chat_sdk")
# C++标准配置
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 构建类型设为:发布版本
set(CMAKE_BUILD_TYPE Release)
# 自动收集源码与头文件
file(GLOB_RECURSE SDK_SOURCES "src/*.cpp")
file(GLOB_RECURSE SDK_HEADERS "include/*.h")
# 生成静态库
add_library(${SDK_NAME} STATIC
${SDK_SOURCES}
${SDK_HEADERS}
)
# 设置编译产物输出目录
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/build)
# 头文件搜索路径
target_include_directories(${SDK_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
)
# 启用HTTPS支持
target_compile_definitions(${SDK_NAME} PUBLIC
CPPHTTPLIB_OPENSSL_SUPPORT
)
# 查找OpenSSL依赖
find_package(OpenSSL REQUIRED)
# 第三方库搜索路径
link_directories(/usr/local/lib)
# 链接依赖库
target_link_libraries(${SDK_NAME}
jsoncpp
fmt
spdlog
sqlite3
OpenSSL::SSL
OpenSSL::Crypto
)
# 安装规则
install(TARGETS ${SDK_NAME}
ARCHIVE DESTINATION lib
)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
DESTINATION include/ai_chat_sdk
FILES_MATCHING PATTERN "*.h"
)关键字说明:
add_library(xxx STATIC):构建静态库,生成lib${SDK_NAME}.a。target_include_directories PUBLIC:这个路径在本库和任何链接它的项目中都有效。target_compile_definitions PUBLIC:宏定义会传递给上层项目。install TARGETS ... ARCHIVE DESTINATION lib:将静态库安装到${CMAKE_INSTALL_PREFIX}/lib。install DIRECTORY:批量复制头文件到系统的 include 子目录。
编译与安装流程
# 进入sdk源码目录 cd sdk # 创建构建目录 mkdir build cd build # cmake解析构建脚本 cmake .. # 编译生成静态库libai_chat_sdk.a make # 安装到系统目录(需要root权限) sudo make install
安装后产物位置:
静态库:
/usr/local/lib/libai_chat_sdk.a头文件:
/usr/local/include/ai_chat_sdk/
常见错误及解决方案
错误:OpenSSL::SSL target was not found
原因:
find_package(OpenSSL REQUIRED)缺失,导致无法找到OpenSSL::SSL。解决:在 CMake 脚本中添加
find_package(OpenSSL REQUIRED),确保放在使用OpenSSL::SSL之前。
警告:cmake_minimum_required should be called prior to project()
原因:
cmake_minimum_required()放在了project()之后。解决:确保把
cmake_minimum_required放在文件第一行。
权限拒绝:Permission denied
现象:直接
make install无权限失败。解决方案:使用
sudo make install提升权限。
GLOB_RECURSE 新增源码不编译
原因:
file(GLOB_RECURSE只在CMake解析阶段扫描一次,后续新增文件不会自动检测。解决:新增文件后重新运行
cmake ..,再执行make。
如何使用SDK
其他开发者想使用这个 ChatSDK,可以:
获取 SDK 源码。
创建构建目录,执行
cmake .. && make && sudo make install。在自己的项目中直接
#include <ai_chat_sdk/ChatSDK.h>,然后链接ai_chat_sdk。
一些核心概念
PUBLIC / PRIVATE / INTERFACE
| 属性 | 作用域 |
|---|---|
| PRIVATE | 此库编译时有效,不传递给其他链接者 |
| PUBLIC | 当前库和所有链接该库的上层项目都有效 |
| INTERFACE | 仅链接该库的上层项目有效,本库编译时不生效 |
install 参数解析
ARCHIVE DESTINATION lib:专门针对静态库(.a)。LIBRARY DESTINATION lib:专门针对动态库(.so/.dylib)。RUNTIME DESTINATION bin:可执行程序、Windows下的dll。CMAKE_INSTALL_PREFIX:默认安装根目录为/usr/local,可以使用-DCMAKE_INSTALL_PREFIX=xxx来修改。
静态库的本质
Linux静态库
.a其实是.o目标文件的集合;链接时会将库内的代码完整复制到最终的可执行文件中。优点是部署简单,运行时不依赖外部库;缺点是可执行文件较大,库更新需要重新编译链接。
结束语
感谢各位的阅读,希望这些内容对你们有帮助!
