用gcc链接静态库和动态库生成可执行文件


一、用gcc生成静态库和动态库

1.准备

(1)创建目录并编写函数

hello.h

hello.c

main.c

(2)将hello.c 编译成.o文件

输入gcc -c hello.c 再运行ls命令可看到生成了hello.o文件
在这里插入图片描述

2.静态库的使用

(1)由.o文件创建静态库

输入ar -crv libmyhello.a hello.o可看到生成了libmyhello.a文件
在这里插入图片描述

(2)在程序中使用静态库

方法一:gcc -o hello main.c -L. -lmyhello
在这里插入图片描述
方法二:gcc main.c libmyhello.a -o hello

方法三:先输入gcc -c main.c 生成main.o,再输入gcc -o hello main.c libmyhello.a生成可执行文件
在这里插入图片描述

(3)静态库特点验证

在程序编译时其会被连接到目标代码中,程序运行是则不需要静态库的存在。在删掉静态库的情况下,运行可执行文件,发现程序仍旧正常运行,表明静态库跟程序执行没有联系。同时,也表明静态库是在程序编译的时候被连接到代码中的。
在这里插入图片描述

3.动态库的使用

(1) 创建动态库

gcc -shared -fPIC -o libmyhello.so hello.o
shared:表示指定生成动态链接库,不可省略
-fPIC:表示编译为位置独立的代码,不可省略
可以看到动态库文件生成
在这里插入图片描述

(2)在程序中使用动态库

gcc -o hello main.c -L. -lmyhello
再运行可执行文件hello,会出现错误
在这里插入图片描述
错误是因为程序在运行时,会在/usr/lib的目录查找需要的动态文件,所以需把libmyhello.so复制到目录下
在这里插入图片描述

4.静态库和动态库对比

先删除除.c和.h外的所有文件
在这里插入图片描述
再创建静态库文件和动态库文件
在这里插入图片描述
在这里插入图片描述
发现静态库和动态库同时存在时,优先使用动态库,这里同上把libmyhello.so复制到目录下即可成功运行
在这里插入图片描述

二、库的使用实战

在第一次作业的程序代码基础进行改编,除了x2x函数之外,再扩展写一个x2y函数(功能自定),main函数代码将调用x2x和x2y;将这3个函数分别写成单独的3个 .c文件,并用gcc分别编译为3个.o 目标文件;将x2x、x2y目标文件用 ar工具生成1个 .a 静态库文件, 然后用 gcc将 main函数的目标文件与此静态库文件进行链接,生成最终的可执行程序,记录文件的大小。将x2x、x2y目标文件用 ar工具生成1个 .so 动态库文件, 然后用 gcc将 main函数的目标文件与此动态库文件进行链接,生成最终的可执行程序,记录文件的大小,并与之前做对比。

1.准备

创建如下文件
在这里插入图片描述
main.c

#include"sub1.h"
#include"sub2.h"
#include<stdio.h>

int main()
{
    int a,b;    
    printf("please input a");//输入a的值    
    scanf("%d",&a);     
    printf("please input b");//输入b的值    
    scanf("%d",&b);    
    printf("%d/%d=%.2f\n",b,a,x2x(a,b));    
    printf("%d*%d=%d\n",a,b,x2y(a,b));    
    return 0;
}

sub1.h

#ifndef __SUB1_H
#define __SUB1_H

float x2x(int a,int b);        //计算b除以a

#endif

sub1.c

#include "sub1.h"
float x2x(int a,int b)
{
    float ans;
    ans=(float)b/a;
    return ans;
}

sub2.h

#ifndef __SUB2_H
#define __SUB2_H

int x2y(int a,int b);    //计算a*b

#endif

sub2.c

#include "sub2.h"
int x2y(int a,int b)
{
    return a*b;
}

2.静态库的生成与使用

(1)将这3个函数分别写成单独的3个 .c文件,并用gcc分别编译为3个.o 目标文件,将x2x、x2y目标文件用 ar工具生成 .a 静态库文件

·编译.o目标文件
输入命令gcc -c main.c sub1.c sub2.c编译得到main.o、sub1.o、sub2.o三个目标文件
·编译libxx.a静态库文件
输入命令ar -crv libsub1.a sub1.o 和ar -crv libsub2.a sub2.o编译生成libsub1.a和libsub2.a静态库文件
在这里插入图片描述

(2)用 gcc将 main函数的目标文件与此静态库文件进行链接,生成最终的可执行程序,记录文件的大小

·使用命令gcc main.o libx2.a -o main链接main.o和libx2.a文件生成可执行文件main
在这里插入图片描述
·执行可执行文件main
使用命令./main执行该可执行文件
在这里插入图片描述
·测试是否真的静态库链接成功
删除静态库libx2.a目标文件,再次执行该可执行文件
在这里插入图片描述

以上说明静态库链接生成的可执行文件运行时不需要该静态库,因为该静态库已经被编译到可执行文件中了。
·main1文件大小
在这里插入图片描述
可以看到使用静态库的文件大小为8.4k

3.使用动态库

(1)编译动态库文件libx2.so

·.o目标文件已经在上面编译静态库文件时生成了,因此这里直接编译动态库文件。使用命令gcc -shared -o libx2.so sub1.o sub2.o生成libx2.so

在这里插入图片描述

(2)链接为可执行文件

·使用命令gcc main1.o -L. -lx2 -o main2链接两个目标文件生成可执行文件main2
在这里插入图片描述

·执行生成的可执行文件main
使用命令./main2执行该可执行文件main2
发现报错如下:

在这里插入图片描述

原因:
程序在运行时, 会在/usr/lib 和/lib 等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提示类似上述错误而终止程序运行。
解决方法:
将libx2.so 复制到目录/usr/lib 中,再次执行./main运行(若提示权限不够则以使用sudo mv libx2.so /usr/lib该命令)
在这里插入图片描述
·main2文件大小
在这里插入图片描述

发现动态库的文件大小为8.3k,比静态库的小

总结

通过使用静态库和动态库分别链接生成可执行文件main,我深入的了解到了不同库函数的链接的作用是不一样的。静态库链接是直接在程序编译时就将其组装到一起,可以不依赖于静态库就能运行;而动态库链接是在程序运行时才将其载入内存运行且不能够缺少,否则不能运行。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值