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

Posted 10km

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

以上是关于cmake编译cJSON,使用时找不到cjson-static target(静态库) 的问题的主要内容,如果未能解决你的问题,请参考以下文章

Linux(程序设计):30---cJSON库(C语言操作JSON)

我的MAC编译LUA-CJSON模块时报如下错误,求大神解答~~!

JSON解析器json-c

C语言调用cJSON库解析json

C语言调用cJSON库解析json

C语言调用cJSON库解析json