CMake find_package匹配jsoncpp同版本配置文件失败问题排查
问题根因
版本号完全匹配仍被判定为不兼容的核心原因和版本逻辑无关,报错里的(64bit)标记就是关键提示:这个被扫描到的jsoncpp是64位编译产物,和你当前项目的目标编译架构不匹配。
CMake在Config模式下执行find_package校验时,会在版本匹配判断之外同步校验依赖包的目标架构和当前项目的目标架构是否一致。架构不匹配时会直接判定依赖包不可用,不会单独抛出架构错误,只会在"未被接受的配置文件"列表后标注位宽信息。
这套校验逻辑写在jsoncpp自动生成的jsoncppConfigVersion.cmake文件里:编译jsoncpp时,构建系统会把当时环境的指针大小(64位环境下值为8,对应8字节指针;32位环境下值为4,对应4字节指针)硬编码进版本配置文件,find_package执行时会对比当前项目的CMAKE_SIZEOF_VOID_P变量值和这个硬编码值,二者不一致就直接返回不兼容结果,和版本号是否完全匹配没有关系。
排查步骤
- 确认主项目目标位宽:在项目顶层CMakeLists.txt中加入
message(STATUS "Project target pointer width: ${CMAKE_SIZEOF_VOID_P}"),执行CMake配置,输出值为8代表当前项目是64位构建目标,值为4代表是32位构建目标。 - 确认本地jsoncpp的编译位宽:打开路径
/home/moritz/Schreibtisch/DA/airclipObstacleDetection/lib/jsoncpp/build/CMakeCache.txt,搜索CMAKE_SIZEOF_VOID_P字段,对比它的值和主项目的位宽值,二者必然不相等。
这类问题最常见的触发场景是:主项目开启了32位编译选项(比如全局加了-m32编译flag、使用了32位交叉编译工具链),但lib目录下的jsoncpp是用默认配置编译的64位版本。
解决方法
- 如果主项目目标是64位:检查主项目的编译、链接配置,删除所有强制32位构建的参数(比如全局的
-m32编译选项、针对特定目标的32位编译规则),清空主项目build目录的缓存后重新配置即可。 - 如果主项目目标是32位:清空现有jsoncpp的build目录缓存,重新编译32位版本的jsoncpp,参考配置命令如下:
cd /home/moritz/Schreibtisch/DA/airclipObstacleDetection/lib/jsoncpp rm -rf build/* cd build cmake .. -DCMAKE_C_FLAGS="-m32" -DCMAKE_CXX_FLAGS="-m32" -DCMAKE_INSTALL_PREFIX=../install make -j$(nproc) make install
编译完成后,在主项目的CMake配置中指定jsoncpp的搜索路径为新生成的install目录下的cmake路径,再重新配置主项目即可。
- 注意事项:修改完jsoncpp的编译架构后,必须清空主项目的CMake缓存(直接删除整个build目录是最稳妥的方式),否则CMake会复用之前的错误检测结果,持续触发报错。
内容的提问来源于stack exchange,提问作者Conradict
相关产品推荐
相关产品推荐

