cmake编译cJSON,使用时找不到cjson-static target(静态库) 的问题

cJSON是基于ANSI C的跨平台JSON解析开源库,支持cmake跨平台编译.
使用cmake也不复杂,以gcc编译为例以下是编译过程。

build cJSON

# 从github下载cJSON代码
git clone https://github.com/DaveGamble/cJSON.git
cd cJSON
# 当前文件夹下生成编译工程文件
# BUILD_SHARED_AND_STATIC_LIBS=ON 指定生成静态库和动态库,默认只生成动态库
cmake . -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=RELEASE \
	-DCMAKE_INSTALL_PREFIX=release\cJSON_$(gcc -dumpmachine) \
	-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
	-DBUILD_SHARED_AND_STATIC_LIBS=ON \
   	-DENABLE_CJSON_TEST=OFf \
	-DENABLE_TARGET_EXPORT=ON 
# 编译安装
cmake --build . --target install

上面的脚本编译cJSON生成了动态库和静态库,并安装到release/cJSON_x86_64-linux-gnu

quote cjson-static import target

下面是cmake脚本中引用cJSON静态库的代码示例:
CMakeLists.txt

cmake_minimum_required( VERSION 3.0 )
project(test LANGUAGES C)
## 指定cJSON安装路径
set(CMAKE_PREFIX_PATH cJSON/release/cJSON_x86_64-linux-gnu)
# 创建测试target
add_executable(cjson_test cjson_test.c)
find_package(cJSON CONFIG REQUIRED)
if(TARGET cjson-static)
	# 添加cJSON静态库的import target到 
	target_link_libraries(cjson_test cjson-static)
else()
	# 没找到报错退出
	message(FATAL_ERROR "NOT FOUND cjson-static target ")
endif()

然而在执行上面的代码时出错了。提示NOT FOUND cjson-static target,也就是说find_package能在cJSON/release/cJSON_x86_64-linux-gnu下正常找到cJSON这个package,但cJSON package中却没有名为cjson-static的target。

问题溯源

这是为什么?
我检查了cJSON的CMakeLists.txt脚本,确实创建了cjson-static import target,而且release/cJSON_x86_64-linux-gnu/lib下也确实生成了静态库libcjson.a.但是find_package就是没找到cjson-static import target.

再仔细研究cJSON的CMakeLists.txt脚本,发现了问题,问题出下面这段在安装cjson-static target的代码上,这是cJSON的BUG.

if (BUILD_SHARED_AND_STATIC_LIBS)
    install(TARGETS "${CJSON_LIB}-static" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}")
endif()
## 没有正确指定安装位置

修复

修改如下,再编译cJSON,就可以了。

if (BUILD_SHARED_AND_STATIC_LIBS)
    install(TARGETS "${CJSON_LIB}-static"
    EXPORT "${CJSON_LIB}" 
    ARCHIVE DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}"
    INCLUDES DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}"
)
endif()

进一步检查发现cjson_utils-static(cjson_utils静态)也存在同样的问题

    if (BUILD_SHARED_AND_STATIC_LIBS)
        install(TARGETS "${CJSON_UTILS_LIB}-static" DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}")
    endif()

改为

    if (BUILD_SHARED_AND_STATIC_LIBS)
        install(TARGETS "${CJSON_UTILS_LIB}-static" 
        EXPORT "${CJSON_UTILS_LIB}" 
        ARCHIVE DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}"
        INCLUDES DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}"
        )
    endif()

以上修改我已经向DaveGamble/cJSON提交了Pull Request,

https://github.com/DaveGamble/cJSON/pull/625

但目前为止还没有被批准合并,所以如果你下载cJSON官方的代码这个问题还没有被修复。
你可以我fork的仓库 https://github.com/10km/cJSON.git下载修复此问题的代码。也可以从我的这个码云镜像仓库下载 https://gitee.com/l0km/cJSON.git

猜你喜欢

转载自blog.csdn.net/10km/article/details/121224151