当前位置: 首页 > article >正文

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

1. 前言

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

/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 中,原先有这样的链接语句:

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 中,把原先的

target_link_libraries(
    ${PROJECT_NAME}
    jsoncpp.a
    ${OpenCV_LIBS}
    ${Boost_SYSTEM_LIBRARY}
)

改成:

target_link_libraries(
    ${PROJECT_NAME}
    jsoncpp.so
    ${OpenCV_LIBS}
    ${Boost_SYSTEM_LIBRARY}
)

或者:

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


http://www.kler.cn/a/464771.html

相关文章:

  • 从configure.ac到构建环境:解析Mellanox OFED内核模块构建脚本
  • SQL使用游标
  • GPT分区 使用parted标准分区划分,以及相邻分区扩容
  • SpringBoot Maven 项目 pom 中的 plugin 插件用法整理
  • 联邦学习中LLM分割的主流方法
  • 五类推理(逻辑推理、概率推理、图推理、基于深度学习的推理)的开源库 (一)
  • 第二十六天 自然语言处理(NLP)词嵌入(Word2Vec、GloVe)
  • TTL 传输中过期问题定位
  • 【网络协议】路由信息协议 (RIP)
  • 【PyTorch][chapter 28][李宏毅深度学习][Diffusion Model-2]
  • C# 设计模式(结构型模式):装饰器模式
  • 【51单片机-零基础chapter1】
  • MySQL/Oracle集群
  • 操作系统论文导读(八):Schedulability analysis of sporadic tasks with multiple criticality specifications——具有多个
  • 8086汇编(16位汇编)学习笔记10.寄存器总结
  • 数据的高级处理——pandas模块进阶——使用Python进行数据分析
  • 六十二:HTTP/3: QUIC 协议格式
  • 爬虫在分析网站结构时的注意事项及代码示例
  • 活动预告 |【Part2】 Azure 在线技术公开课:迁移和保护 Windows Server 和 SQL Server 工作负载
  • 【数字电路一】逻辑代数基础
  • TLS: WebRTC中ThreadManager的线程局部存储
  • 【2024华为OD-E卷-100分-传递悄悄话】(题目+思路+JavaC++Python解析)
  • 【ShuQiHere】使用 SCP 进行安全文件传输
  • 音视频入门基础:MPEG2-PS专题(2)——使用FFmpeg命令生成ps文件
  • docker compose模式下,volumes中的${HOSTNAME}识别不了
  • (ICLR-2023)ADALORA:自适应预算分配,实现参数高效微调