讲师中心 微信公众号

工具推荐

视频效率加速
立刻MV
立刻MV

低成本歌曲 MV、视频生成

AniShort
AniShort

AI短剧协同制作平台

updream

一键生成高质量推广成片

Laper
Laper

剧本策划到成片协作

C++中的动态库与静态库是什么?(如何在构建时进行链接)

千敏姑娘_7186

千敏姑娘_7186

发布时间:2026-02-21 08:23:02

|

887人浏览过

|

来源于php中文网

原创

静态库链接在编译时将.a文件中用到的代码复制进可执行文件,运行时不依赖外部库但体积大、更新难;动态库链接仅在运行时加载.so,需确保LD_LIBRARY_PATH或rpath正确。

c++中的动态库与静态库是什么?(如何在构建时进行链接)

静态库链接:编译时把 .a 文件直接塞进可执行文件

静态库本质是一堆已编译的 .o 目标文件打包成的归档(libxxx.a),链接时会把用到的符号代码“复制”进最终的可执行文件。这意味着运行时不依赖外部库文件,但体积大、更新困难。

实操上,用 g++ 链接静态库要显式指定路径和库名:

g++ main.cpp -L./libs -lmylib -static-libgcc -static-libstdc++

注意几个关键点:

  • -L./libs 告诉链接器去哪找库,不是自动搜 /usr/lib 或当前目录
  • -lmylib 会实际查找 libmylib.a(不是 mylib.a),名字必须匹配前缀规则
  • -static-libgcc 和 -static-libstdc++ 是防止混链动态版系统库——否则即使你用了 libmylib.a,仍可能在运行时报 libstdc++.so.6: version `GLIBCXX_3.4.29' not found
  • 如果 libmylib.a 本身又依赖其他静态库(比如用了 libz.a),得把依赖库也列在命令行里,且顺序不能错:被依赖的库要放在依赖它的库之后(-lmylib -lz,不能反过来)

动态库链接:运行时加载 .so,构建时只记个符号引用

动态库(libxxx.so)不参与编译,链接阶段只检查符号是否存在、签名是否匹配,真正加载发生在程序启动或调用 dlopen() 时。好处是共享内存、便于热更新;坏处是部署时得确保 LD_LIBRARY_PATH 正确,或库在系统默认路径下。

立即学习“C++免费学习笔记(深入)”;

构建命令看着差不多,但行为完全不同:

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
g++ main.cpp -L./libs -lmylib

这里没加 -static,链接器默认优先找 .so。常见陷阱有:

  • 明明放了 libmylib.so 在 ./libs,却报 undefined reference to `xxx':大概率是该 .so 编译时没导出对应符号(没加 -fvisibility=default 或没写 __attribute__((visibility("default"))))
  • 程序编译通过,运行时报 error while loading shared libraries: libmylib.so: cannot open shared object file:说明运行时找不到它。临时解决可用 export LD_LIBRARY_PATH=./libs,但生产环境应改用 rpath:
    g++ main.cpp -L./libs -lmylib -Wl,-rpath,'$ORIGIN/../libs'
    ($ORIGIN 指可执行文件所在目录)
  • 动态库版本升级后崩溃?检查 SONAME 是否变了(用 readelf -d libmylib.so | grep SONAME),DT_SONAME 不一致会导致链接器拒绝加载

nm 和 objdump 是查符号问题的第一工具

链接失败,别急着重装工具链——先确认符号到底存不存在、可见性对不对。静态库和动态库都适用:

  • 看静态库里有没有某函数:
    nm -C libmylib.a | grep 'my_function'
    ,输出带 T(text)表示定义了,U 表示未定义(即只是引用)
  • 看动态库导出的符号(注意是否隐藏):
    nm -C -D libmylib.so | grep 'my_function'
    ,-D 只显示动态符号表里的内容,没输出就说明没导出
  • 进一步确认符号绑定属性:
    objdump -t libmylib.so | grep my_function
    ,如果显示 *UND* 就是未定义,FUNC GLOBAL DEFAULT 才算正常导出

这些命令不依赖构建系统,能快速定位是代码没编译进去、声明没导出,还是链接参数漏写了库。

CMake 中控制动静态链接容易混淆的三个配置点

CMake 默认倾向动态链接,但很多项目需要混合或强制静态。关键不在 find_package(),而在目标属性设置:

  • 让某个 target 强制链接静态版系统库:
    set_target_properties(myapp PROPERTIES LINK_FLAGS "-static-libgcc -static-libstdc++")
  • 指定第三方库用静态方式链接(假设 mylib 同时提供 .a 和 .so):
    find_library(MYLIB_STATIC NAMES mylib PATHS ./libs NO_DEFAULT_PATH)target_link_libraries(myapp ${MYLIB_STATIC})
    ,避免 find_package(mylib) 自动挑 .so
  • 全局禁用动态库搜索(慎用):
    set(CMAKE_FIND_LIBRARY_SUFFIXES ".a${CMAKE_FIND_LIBRARY_SUFFIXES}")
    ,这会让所有 find_library 优先找 .a,但可能破坏 FindXXX.cmake 模块逻辑

最常被忽略的是:CMake 的 IMPORTED 目标(比如用 add_library(mylib IMPORTED))必须手动设置 IMPORTED_LOCATION 指向具体文件,否则 target_link_libraries 会静默失败,连错误都不报。

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

码上飞
码上飞 Hot

一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

相关专题

更多
while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

354

2023.09.25

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1069

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3520

2023.10.25

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

7007

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2888

2023.08.10

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

12385

2023.07.31

网页undefined是什么意思
网页undefined是什么意思

网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

5547

2024.08.14

网页undefined啥意思
网页undefined啥意思

本专题整合了undefined相关内容,阅读下面的文章了解更多详细内容。后续继续更新。

2516

2025.12.25

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

20

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn