【C++/CMake】从静态库到动态库:一行改动解决 “找不到 -ljsoncpp” 链接报错

1. 前言

在使用 CMake 构建 C++ 项目时,链接第三方库往往会碰到一些"链接失败"的问题,尤其在 Linux 环境下比较常见。最近我在编译一个涉及 JSON 解析功能的项目时,遇到如下错误:

bash 复制代码
/usr/bin/ld: 找不到 -ljsoncpp: 没有那个文件或目录
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/run_intrinsic_calibration.dir/build.make:113: ../bin/run_intrinsic_calibration] 错误 1
make[1]: *** [CMakeFiles/Makefile2:111: CMakeFiles/run_intrinsic_calibration.dir/all] 错误 2
make: *** [Makefile:91: all] 错误 2

很明显,链接器找不到 jsoncpp 相关的库文件。通过在 CMakeLists.txt 中把对 jsoncpp.a 的静态库链接改成链接 jsoncpp.so(动态库),最终成功解决了问题。本文就把这个过程分享给大家,供遇到类似问题的同学参考。


2. 问题背景

在项目的 CMakeLists.txt 中,原先有这样的链接语句:

cmake 复制代码
target_link_libraries(
    ${PROJECT_NAME}
    jsoncpp.a
    ${OpenCV_LIBS}
    ${Boost_SYSTEM_LIBRARY}
)

这表示显式地去链接名为 jsoncpp.a 的静态库。但是在实际环境中,系统安装的只是 libjsoncpp.so(动态库),并不存在对应的 jsoncpp.a(静态库)。因此,链接器自然找不到 jsoncpp.a 文件,就会报类似 "找不到 -ljsoncpp" 或 "无法打开 jsoncpp.a" 这样的错误。

2.1 为什么只安装了 .so 而没有 .a?

在大多数 Linux 发行版上,默认安装的 libjsoncpp-dev(或同名开发包)只会提供共享库(libjsoncpp.so)和头文件,而不一定会提供静态库(libjsoncpp.a)。这是因为静态库往往需要额外维护,并且在普通场景中使用动态库更方便、可维护性更高。


3. 解决思路

要想解决这个报错,无非两种方案:

  1. 改用动态库:如果只是想让项目能正常编译和运行,直接链接动态库就可以了。
  2. 自行安装/编译静态库 :如果明确需要静态链接(比如某些嵌入式场景、需要单文件发布等),就得手动编译并安装 jsoncpp.a。

在这里,我的需求只是能让程序正常编译、运行,不依赖完全的静态链接。因此,选择了 最简单的 方案 ------ 把 ".a" 改成 ".so" ,或者更常见的是 直接写 "jsoncpp" 让 CMake 自动去查找共享库和头文件。


4. 改动一行,链接成功

我只需要在 CMakeLists.txt 中,把原先的

cmake 复制代码
target_link_libraries(
    ${PROJECT_NAME}
    jsoncpp.a
    ${OpenCV_LIBS}
    ${Boost_SYSTEM_LIBRARY}
)

改成:

cmake 复制代码
target_link_libraries(
    ${PROJECT_NAME}
    jsoncpp.so
    ${OpenCV_LIBS}
    ${Boost_SYSTEM_LIBRARY}
)

或者:

cmake 复制代码
target_link_libraries(
    ${PROJECT_NAME}
    jsoncpp
    ${OpenCV_LIBS}
    ${Boost_SYSTEM_LIBRARY}
)

然后重新 cmake .. && make -j,就可以看到编译顺利通过。因为系统在 /usr/lib/x86_64-linux-gnu/ (不同发行版可能略有差异)下找到了 libjsoncpp.so 这个文件,满足了链接要求。


5. 动态库与静态库的区别

简单科普一下:

  • 动态库(.so) :程序运行时需要依赖外部的共享库文件,升级库时不需要重新编译所有应用,发布体积小,但需要在环境中保留 .so 文件。
  • 静态库(.a):编译时将第三方库的代码直接打包进可执行文件,发布时无需再携带库文件,更独立,但是体积变大,且若库有更新,需要重新编译可执行文件。

常见情况下,如果你没有特殊需求,使用动态库更方便。


6. 总结

  • 问题核心 :CMake 链接阶段找不到 jsoncpp.a,因为系统并没有安装静态库。
  • 解决方法 :直接改用已经安装的动态库 jsoncpp.so,或者在链接指令里只写 jsoncpp 让 CMake 自动匹配到共享库。
  • 经验教训 :
    1. 安装 libjsoncpp-dev 一类的开发包后,大多数情况下只会得到 .so 文件而不是 .a 文件。
    2. 如果想要静态库 .a,通常要自己编译或者额外安装静态库包。
    3. 若非必要,动态库 .so 更常用。

希望这篇文章对同样遇到 "找不到 -ljsoncpp" 链接错误的朋友有所帮助。如果对你有用,欢迎点赞、收藏或关注。我们下篇文章再见!

参考gpt share:https://chatgpt.com/share/67760c04-d638-8010-84a6-9bcaa52e5144

相关推荐
昵称画5 小时前
交接班记录电子化:三班之间的信息不漏
开发语言·数据库·人工智能·低代码·php
“AI国潮设计-小江”5 小时前
【AIGC实战】Python+SDXL批量生成“潮汕英歌舞不倒翁”IP | 角色一致性与多场景融合方案,附完整代码
开发语言·人工智能·python·prompt·aigc
传奇开心果编程5 小时前
【Rust入门练中学】第6课:结构体与方法
开发语言·rust·结构体·编程语言理论·结构体方法·编程通用语言
code tsunami5 小时前
【无标题】
开发语言·python
CodeGL6 小时前
10、Python基础之进程和线程
开发语言·python
hetao17338377 小时前
2026-10-22~23 hetao1733837 的刷题记录
c++·算法
TechWayfarer7 小时前
PHP漏洞被利用,怎么揪出攻击IP?
开发语言·python·tcp/ip·网络安全·php
王老师青少年编程7 小时前
2025年6月GESP真题及题解(C++三级): 选择题和判断题(题解)
c++·真题·gesp·答案·csp·三级·信奥赛
卡卡~~8 小时前
“101计划”核心课程实践教材《数据实验结构指导-C++语言版》题目集
开发语言·c++·学习·算法
qq_406981038 小时前
大白话rust系列09 函数调用两次有什么错?
开发语言·python·rust