Linux动静态库

Linux动静态库

静态库

核心特性:

  • 链接时机:在编译时将库代码直接嵌入到可执行文件中。
  • 文件格式:.a(Linux)、.lib(Windows)。
  • 内存占用:每个使用该库的可执行文件都会包含一份完整的库代码副本。

创建静态库(.a文件)

  1. 编写源代码:首先,编写你需要的库函数的源代码文件,例如mylib.c
  2. 编译为目标文件:使用gcc/g++编译源码为目标文件(.o文件)
bash 复制代码
g++ -c mylib.cpp -o mylib.o
  1. 创建静态库:使用ar工具将目标文件打包为静态库(.a文件)
bash 复制代码
ar rcs libmylib.a mylib.o
  • rcs:替换旧文件(r)、创建新库(c)、生成索引(s)

动态库

核心特性:

  • 链接时机:在运行时由操作系统动态加载到内存(映射到地址空间的共享区)。
  • 文件格式:.so(Linux)、.dll(Windows)。
  • 内存占用:多个进程可共享同一份库的内存实例。

创建动态库(.so文件)

  1. 编写源代码:首先编写库函数的源代码文件,例如mylib.c
  2. 编译并生成位置无关代码(PIC):在编译为目标文件时,需要添加-fPIC选项以生成位置无关代码
bash 复制代码
g++ -c -fPIC mylib.cpp -o mylib.o
  1. 创建动态库:使用gcc/g++的-shared选项将目标文件链接为动态库(.so文件)
bash 复制代码
g++ -shared mylib.o -o libmylib.so

库的链接

在gcc/g++的编译和链接过程中,-I(大写i)、-L、-l(小写L)是三个常用的选项,它们分别用于指定头文件的搜索路径库文件的搜索路径 以及要链接的库的名称

bash 复制代码
gcc -I /home/user/include -L /home/user/lib -lmylib my_program.c -o my_program


-I/home/user/include 告诉编译器在 /home/user/include目录下查找头文件。
-L/home/user/lib 告诉链接器在 /home/user/lib目录下查找库文件。
-Imylib告诉链接器链接名为mylib的库 (即查找libmylib.a或libmylib.so文件)。

】:

  • 库就是功能性代码块的包装,也是包含:头文件 和 源文件(所谓的:库文件),头文件和库文件一般都是存储在各自的目录下,所以需要分别链接。
  • 链接库名时要去掉前后缀,前缀lib,后缀 .a / .so。

上述操作是让编译器知道了文件路径,但链接完成后的程序运行时动态库还需要加载,加载器还不知道所使用的第三方动态库的路径。

五种方法解决:

  1. 将动态库文件拷贝到系统默认的库路径 /lib64/ 或 /usr/lib64/;
  2. 建立系统默认的库路径下的软链接指向第三方库;
  3. 将库的路径添加进环境变量 LD_LIBRARY_PATH 中
bash 复制代码
//临时追加
export LD_LIBRARY_PATH=/path/to/your/lib:$LD_LIBRARY_PATH
./your_program
  1. 编译时指定 rpath(硬编码路径到可执行文件)
bash 复制代码
g++ main.cpp -L./mylib -lmylib -Wl,-rpath='$ORIGIN/mylib' -o main

//-Wl,-rpath=...:将 rpath 写入可执行文件,$ORIGIN 表示可执行文件所在目录。
  1. 配置/etc/ld.so.conf.d/,ldconfig更新
    在/etc/ld.so.conf.d/路径下创建一个 .conf文件,把动态库所在的路径放到这个.conf文件中,然后ldconfig 重新加载一份即可。
bash 复制代码
cd  /etc/ld.so.conf.d/
touch  myname.conf
vim myname.conf  //打开后把路径复制粘贴进去就行

怎么简化链接库的命令呢?

  1. 如果自己创建的头文件和库文件 分别放在系统中存储库的文件的目录中时,就不需要-I和-L了,仅需链接指定库文件即可(就像使用C语言库直接编译那样,还是需要指定库名称)。
  2. 建立系统标准库目录下的软链接
    eg:
c 复制代码
#include "myinc/mymath.h"
gcc main.c -o main -lmymath

//在系统头文件和库文件的标准库目录下 分别创建指向自己创建的库的头文件和库文件的软链接

动态库在系统中加载之后,会被所有链接了该库的进程共享,这是如何被共享的?

答:动态库从磁盘加载到物理内存,然后这一份动态库文件可以与所有链接该库的进程建立映射,映射到每个进程的进程地址空间的共享区中。

相关推荐
Xena_Networks7 分钟前
SierraNet协议分析使用指导[RDMA]| 如何设置 NVMe QP 端口以进行正确解码
linux·服务器·网络
purrrew23 分钟前
【Java ee初阶】网络原理
java·运维·服务器·网络·网络协议·udp·java-ee
python算法(魔法师版)39 分钟前
数据库故障排查指南:从连接问题和性能优化
服务器·网络·数据库·性能优化
滴水之功1 小时前
Ubuntu22.04怎么退出Emergency Mode(紧急模式)
linux·运维·服务器
小馬佩德罗2 小时前
Linux/AndroidOS中进程间的通信&线程间的同步 - 信号量
linux·信号量
又逢乱世2 小时前
Ubuntu 安装 HAProxy
服务器·网络·数据库
明仔丶2 小时前
开启docker中mysql的binlog日志
运维·docker·容器·binlog
wqqqianqian2 小时前
国产linux系统(银河麒麟,统信uos)使用 PageOffice 在线打开Word文件,并用前端对话框实现填空填表
linux·前端·word·pageoffice
清风来点灯2 小时前
Ubuntu22.04安装显卡驱动/卸载显卡驱动
linux·笔记·ubuntu
qrh_yogurt3 小时前
搭建spark伪分布集群
大数据·服务器·spark