星云点击:星空遥控器
120.47M · 2026-02-04
本次编译核心实现基于 CMake FetchContent 自动拉取第三方依赖(Abseil/Protobuf)+ 编译生成 Android 动态库 libnativesdk.so,全程适配 NDK25/CMake3.22,最终实现无报错编译成功。
注:CMakeLists.txt完整文件在文章末尾
基于现有业务代码(core/jni 目录)+ Protobuf 生成代码,通过 CMake 实现:
FetchContent,为自动化拉取 Git 仓库依赖做准备。,锁定稳定 Tag 20240116.0;,升级版本至 v3.25.3(稳定版);GIT_SUBMODULES "",禁止拉取 gtest/benchmark 子模块,彻底解决网络 SSL 拉取错误;set(protobuf_INSTALL OFF CACHE BOOL "" FORCE),禁用 Protobuf 内置的安装 / 导出逻辑,从根源规避导出依赖链错误;执行 FetchContent_MakeAvailable(abseil-cpp protobuf),CMake 自动完成:
${protobuf_SOURCE_DIR}/third_party/utf8_range;include_directories 暴露头文件路径,保证业务代码可正常 #include "utf8_range.h";file(GLOB) 递归获取核心业务代码(core/ .cpp、jni/ .cpp)和 Protobuf 编译生成的代码(proto/generated/*.pb.cc);ALL_SRC,作为后续编译动态库的输入。add_library(nativesdk SHARED ${ALL_SRC}),指定编译为 Android 动态库;PROTOBUF_USE_LITE_RUNTIME 等核心宏,匹配 Protobuf Lite 版本使用规范;build/intermediates/cmake/[Debug/Release]/obj/[架构(如arm64-v8a)]/ 生成最终产物 libnativesdk.so。akrylysov/utf8_range.git 报 404,Google 官方无独立 utf8_range 仓库;utf8_range.h,CMake 报语言识别失败;protobuf_INSTALL OFF 禁用 Protobuf 所有 install/export 逻辑,从根源解决问题。GIT_SUBMODULES "",禁止 Protobuf 拉取任何子模块,仅拉取核心源码。项目根目录/.cxx/[构建类型]/[随机标识]/[架构]/_deps/,后续构建不重复拉取;如需更新依赖版本(修改 GIT_TAG),必须彻底删除项目根目录的 build/ 和 .cxx/ 文件夹,否则会使用旧缓存;git config --global https.proxy ,替换为自身代理地址);CMAKE_ANDROID_STL_TYPE c++_static 仅对 Android 生效,迁移至 Visual Studio 时会被自动忽略,无需修改;protobuf_INSTALL OFF、GIT_SUBMODULES "" 等均为官方提供的配置开关,非自定义 hack,稳定性高,无需额外调整。file(GLOB) 的路径;#include "utf8_range.h",引用 Protobuf 头文件按生成路径写,无需添加绝对路径;build/ 和 .cxx/ 文件夹(彻底清除缓存),可解决 90% 以上的配置冲突问题;项目根目录/.vs/CMakeFiles/_deps/,与 Android 环境缓存独立,互不干扰。当前 CMakeLists.txt 已实现零手动依赖、零配置冲突、跨平台兼容,核心能力:
FetchContent_Declare 中的 GIT_TAG,删除缓存后重新构建即可。build/ 和 .cxx/ 文件夹,避免缓存文件过多占用磁盘空间;cmake_minimum_required(VERSION 3.10.2)
project(nativesdk)
# 基础编译配置(适配NDK25/CMake3.22,无冗余)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "" FORCE)
set(CMAKE_ANDROID_STL_TYPE c++_static CACHE STRING "" FORCE)
# ================================= 全依赖自动化拉取 =================================
include(FetchContent)
# 1. Abseil:官方正确Tag 20240116.0,关闭浅克隆
FetchContent_Declare(
abseil-cpp
GIT_REPOSITORY
GIT_TAG 20240116.0
GIT_SHALLOW OFF
GIT_PROGRESS ON
)
set(ABSL_BUILD_TESTING OFF CACHE BOOL "" FORCE)
set(ABSL_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(ABSL_BUILD_BENCHMARKS OFF CACHE BOOL "" FORCE)
# 2. Protobuf:3.25.3 Lite版 + 核心修复:禁止拉取任何子模块(解决SSL错误)
FetchContent_Declare(
protobuf
GIT_REPOSITORY
GIT_TAG v3.25.3 # 已改为3.25.3稳定版
GIT_SHALLOW OFF
GIT_PROGRESS ON
GIT_SUBMODULES "" # 关键!禁止拉取gtest/benchmark子模块,彻底避免SSL错误
)
set(protobuf_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(protobuf_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(protobuf_USE_LITE_RUNTIME ON CACHE BOOL "" FORCE)
set(protobuf_BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
set(protobuf_INSTALL OFF CACHE BOOL "" FORCE) # 核心新增!禁用Protobuf的安装/导出逻辑,从根源避免错误
# 一次性初始化Abseil+Protobuf(Protobuf 3.25.3会自动构建内置的utf8_range库,无需手动处理)
FetchContent_MakeAvailable(abseil-cpp protobuf)
# ================================= 核心优化:复用Protobuf自动构建的utf8_range库(无命名冲突) =================================
# 定位protobuf 3.25.3内置的utf8_range头文件目录(仅暴露头文件,无需重新编译)
set(UTF8_RANGE_SRC_DIR "${protobuf_SOURCE_DIR}/third_party/utf8_range")
# 暴露utf8_range头文件路径,确保业务代码可正常#include "utf8_range.h"
include_directories(${UTF8_RANGE_SRC_DIR})
# ================================= 对接本地业务代码=================================
file(GLOB YOUR_BUSINESS_SRC
${CMAKE_CURRENT_SOURCE_DIR}/core/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/jni/*.cpp
)
file(GLOB PROTO_GEN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/proto/generated/*.pb.cc)
set(ALL_SRC ${YOUR_BUSINESS_SRC} ${PROTO_GEN_SRC})
# ================================= 编译SO + 头文件 + 链接(一键对接,无任何修改) =================================
add_library(nativesdk SHARED ${ALL_SRC})
target_include_directories(nativesdk PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/proto/generated
${abseil-cpp_SOURCE_DIR}
${protobuf_SOURCE_DIR}
${UTF8_RANGE_SRC_DIR} # 保留utf8_range头文件路径
)
target_compile_definitions(nativesdk PRIVATE
PROTOBUF_USE_LITE_RUNTIME
GOOGLE_PROTOBUF_NO_RTTI
PROTOBUF_DISABLE_JSON=1
)
# 链接配置(直接使用Protobuf自动构建的utf8_range库,无命名冲突)
target_link_libraries(nativesdk PRIVATE
absl::base absl::strings absl::hash absl::synchronization absl::time absl::status
protobuf::libprotobuf-lite
utf8_range # 直接链接Protobuf内置的utf8_range库(无需::别名,原生支持)
log z atomic m
)