Linux 下静态链接库.a 和动态链接库.so 的生成

1、库

所谓的库就是一种可执行代码的二进制形式,可以被操作系统载入内存执行。

2、静态库和动态库 

静态库 .a

文件的命名方式:“libxxx.a”,库名前加“lib”,后缀是“.a”,库名是“xxx”

链接时间:静态库的代码是在编译过程中被载入到程序中的

链接方式:静态库的链接是将整个函数库的所有数据都合成进了目标代码,优点是编译后的执行程序不需要外部的函数库支持,因为所使用的函数已经被编进去了;缺点是如果所使用的静态库发生更新改变,则需要重新编译生成静态库。

动态库 .so

文件命名方式:“libxxx.so”,库名前加“lib”,后缀是“.so”,库名是“xxx”

链接时间:动态库在编译时并没有被编译进目标代码,而是当你的程序执行到相关函数的时候才调用该函数库里的相应函数。缺点是函数库并没有整合进程序,所以程序的运行环境必须提供相应的库;优点是动态库的改变不影响程序。

二者的区别:同一个程序分别使用静态库和动态库生成两个可执行文件时,静态库链接所生成的那个可执行文件要比动态库链接所生成的可执行文件占用的空间大。

3、静态链接库和动态链接库的生成

(1)生成一个可执行文件

hello.c 

//hello.c 函数库的源程序,打印hello world!
#include <stdio.h>

int main()
{
        printf("hello world!\n");
        return 0;
}

生成一个hello.o文件,该文件是将源文件编译生成的汇编文件,在链接之前该文件是不可执行的,生成.o文件的命令为:

gcc -c hello.c

生成一个hello的可执行文件,格式为ELF

gcc -o hello hello.c

此时,hello为一个可执行文件,执行结果如下

 

 

(2)静态库

 准备三个文件 hello.c hello.h test.c

//hello.c 打印hello world
#inlcude "hello.h"

void hello()
{
    printf("hello world!\n");
}
//hello.h

#include <sdtio.h>

void hello();

 

//test.c 测试程序,调用hello函数打印hello world

#include "hello.h"

int main()
{
    hello();
    return 0;
}

使用如下命令,将hello.c生成hello.o的汇编文件

gcc -c hello.c

由.o文件生成.a的静态库文件,静态库的名字问libhello.a

ar rc libhello.a hello.o

使用静态库进行静态链接,生成可执行文件hello

gcc -o test test.c -L. -lhello

-L 是指定加载库文件的路径

-l 指定加载的库文件

生成的可执行文件是test,运行一下

 

(3)动态库

还是用上面的三个文件

生成.o文件

gcc -c hello.c

生成动态库

gcc -fPIC -shared -o libhello.so hello.c

链接生成可执行文件

gcc -o test test.c -L. libhello.so

生成的可执行文件是test,./test执行可执行文件时报如下错

 

因为执行程序找不到libhello.so

用:ldd test命令查看libhello.so库,发现其找不到

原因是在 /etc/ld.so.conf 文件中设置了动态链接库了寻找路径

 

可以看到有很多路径设置文件,在ld.so.conf文件中添加libhello.so的路径

然后执行:ldconfig命令

此时执行可执行文件test就能成功了。

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值