使用CMake构建多Android NDK目标报错:could not load cache 求调试方法
问题描述
尝试使用NDK构建多个ABI目标时,始终出现**"could not load cache"**错误,使用的是docker-android-ndk镜像,以及Monocypher提供的C源码。
错误信息
CMake Error: Could not load cache.
CMake Error: Error processing file: /app/CMakeLists.txt
ninja: error: rebuilding 'build.ninja': subcommand failed
构建脚本
#!/bin/bash cd /app cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=$NDK_ROOT/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=android-21 /app cmake --build /app -v
CMakeLists.txt
cmake_minimum_required(VERSION 3.16) project(monocypher) set(MONOCYPHER_SRC_FOLDER "Monocypher/src") set(MONOCYPHER_SOURCES "${MONOCYPHER_SRC_FOLDER}/monocypher.h" "${MONOCYPHER_SRC_FOLDER}/monocypher.c" "${MONOCYPHER_SRC_FOLDER}/optional/monocypher-ed25519.h" "${MONOCYPHER_SRC_FOLDER}/optional/monocypher-ed25519.c" ) include_directories(${MONOCYPHER_SRC_FOLDER}) include(ExternalProject) file(TO_CMAKE_PATH "${CMAKE_TOOLCHAIN_FILE}" toolchain_file) macro (setup_library library_name android_abi) ExternalProject_Add(${library_name}-builder SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" BUILD_ALWAYS YES DOWNLOAD_COMMAND "" INSTALL_COMMAND "" UPDATE_COMMAND "" PATCH_COMMAND "" CMAKE_ARGS -DLIBNAME=${library_name} -DANDROID_ABI=${android_abi} -DCMAKE_FIND_ROOT_PATH=${CMAKE_FIND_ROOT_PATH} -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DCMAKE_TOOLCHAIN_FILE=${toolchain_file} -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_BINARY_DIR}/android-build/libs/${android_abi} -D${PROJECT_NAME}-MultiBuild=ON BUILD_COMMAND ${CMAKE_COMMAND} --build . --config Release ) #add_library(monocypher_native SHARED ${MONOCYPHER_SOURCES}) #set_property(TARGET monocypher_native PROPERTY ENABLE_EXPORTS 1) endmacro() setup_library(${PROJECT_NAME}-v8a arm64-v8a ${CMAKE_PREFIX_PATH}) add_library(monocypher_native SHARED ${MONOCYPHER_SOURCES}) set_property(TARGET monocypher_native PROPERTY ENABLE_EXPORTS 1)
调试与解决方法
1. 解决ExternalProject缓存冲突
你用ExternalProject_Add直接将源码目录作为SOURCE_DIR,主CMake进程已在该目录生成CMakeCache.txt,子构建进程读取同一缓存时会引发冲突。
修改setup_library宏,给每个ABI指定独立构建目录:
macro (setup_library library_name android_abi) set(BUILD_DIR "${CMAKE_BINARY_DIR}/build-${android_abi}") ExternalProject_Add(${library_name}-builder SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" BUILD_DIR "${BUILD_DIR}" # 新增独立构建目录 BUILD_ALWAYS YES DOWNLOAD_COMMAND "" INSTALL_COMMAND "" UPDATE_COMMAND "" PATCH_COMMAND "" CMAKE_ARGS -DLIBNAME=${library_name} -DANDROID_ABI=${android_abi} -DCMAKE_FIND_ROOT_PATH=${CMAKE_FIND_ROOT_PATH} -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DCMAKE_TOOLCHAIN_FILE=${toolchain_file} -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_BINARY_DIR}/android-build/libs/${android_abi} -D${PROJECT_NAME}-MultiBuild=ON BUILD_COMMAND ${CMAKE_COMMAND} --build "${BUILD_DIR}" --config Release ) endmacro()
2. 改用外部构建模式
原脚本直接在源码目录生成缓存,既污染源码也易引发冲突,改用Out-of-Source Build:
#!/bin/bash mkdir -p /app/build && cd /app/build cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=$NDK_ROOT/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=android-21 .. cmake --build . -v
3. 验证CMake与NDK版本兼容性
docker镜像中的CMake版本可能不符合NDK要求,运行以下命令确认:
cmake --version echo $NDK_ROOT && ls $NDK_ROOT/build/cmake/
例如NDK r25+要求CMake 3.22以上版本,版本不匹配时需更换镜像或升级CMake。
4. 清理残留缓存文件
每次构建前清理旧缓存,避免干扰:
rm -rf /app/CMakeCache.txt /app/CMakeFiles /app/build.ninja /app/build
5. 简化配置排查基础问题
暂时注释ExternalProject_Add相关代码,先验证单个ABI构建是否正常:
# include(ExternalProject) # ... # setup_library(...) add_library(monocypher_native SHARED ${MONOCYPHER_SOURCES}) set_property(TARGET monocypher_native PROPERTY ENABLE_EXPORTS 1)
若单个ABI构建正常,再逐步定位ExternalProject的配置问题。
内容的提问来源于stack exchange,提问作者AlbertK
相关产品推荐
相关产品推荐

