[LINUX]动静态库:链接方式与路径解析

在软件开发中,动态库(Dynamic Library)和静态库(Static Library)是两种常见的代码组织和链接方式。它们在项目开发和维护中扮演着重要的角色,为了更好地理解它们,让我们深入研究这两种库的使用方法和链接过程。

静态库:libxxx.a
静态库是在编译时被链接到可执行文件中的库。通常以.a为后缀。当使用静态库时,需要在编译时指定头文件的路径和链接库的路径,以下是一些解决方法:
1.使用 -I 选项指定头文件路径:

gcc xxx.c -I ./lib/xxxx/

但这样在链接时可能会报错找不到库。

2.使用 -L 选项指定库文件路径:

gcc xxx.c -I ./lib/xxx/ -L ./lib/xxxxx/

但仍然可能找不到库,因为当前路径下可能有多个.a文件。

3.使用 -l 选项指定库,并去掉前缀和后缀:

gcc xxx.c -I ./lib/xxx/ -L ./lib/xxxxx/ -lxxx

紧跟 -l 后面

演示(创建一个静态库并使用):

  //mymath.h
  1 #pragma once 
  2 
  3 #include <stdio.h>
  4 
  5 
  6 int Add(int a , int b);
  7 int Sub(int a , int b);
                          
  //mymath.c
  1 #include "mymath.h"
  2 
  3 int Add(int a, int b)
  4 {
  5   return a+b;
  6 }
  7 
  8 int Sub(int a ,int b)
  9 {
 10   return a-b;                                                                                             
 11 }
//makefile
  1 static-lib=libmymath.a
  2 
  3 $(static-lib):mymath.o
  4   ar -rc $@ $^
  5 
  6 mymath.o:mymath.c
  7   gcc -c $^                                                                                               
  8 
  9 .PHONY:clean
 10 clean:
 11   rm -rf *.o *.a 
 12 
 13 .PHONY:output
 14 output:
 15   mkdir -p mylib/include
 16   mkdir -p mylib/lib
 17   cp *.h mylib/include
 18   cp *.a mylib/lib

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//main.c
  1 #include "mymath.h"
  2 
  3 int main()
  4 {
  5   printf("3+3=%d\n",Add(3,3));                                                                            
  6 
  7   return 0;
  8 }

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
动态库:libYYY.so
动态库在运行时被加载到内存中。通常以.so为后缀。以下是一些使用动态库的方法:
1.编译产生位置无关码:

gcc -fPIC -c xxx.c

使用 -fPIC 产生位置无关码,直接使用偏移量进行库中函数的编址
2.链接生成动态库

gcc -shared -o libmyfile.so *.o

3.使用 -I、-L 和 -l 选项指定库和路径:

gcc -I lib/include/ -L lib/mylib -lmyfile

如果使用多个库且在同一目录下,只需要 -l 加上去掉前后缀的名称。如果在不同目录下,仍然需要 -I 和 -L 选项,加上路径和文件名。

//mylog.h
  1 #pragma once 
  2 
  3 #include<stdio.h>
  4 
  5 void Print();    
//mylog.c
  1 #include"mylog.h"
  2 
  3 void Print()
  4 {
  5   printf("hello dynamic depot\n");
  6   printf("hello dynamic depot\n");
  7   printf("hello dynamic depot\n");
  8   printf("hello dynamic depot\n");
  9   printf("hello dynamic depot\n");
 10   printf("hello dynamic depot\n");                                                                        
 11 }
//Makefile
  1 static-lib=libmymath.a
  2 dy-lib=libmylog.so
  3 
  4 .PHONY:all
  5 all:$(static-lib) $(dy-lib)                                                                               
  6 
  7 $(static-lib):mymath.o
  8   ar -rc $@ $^
  9 
 10 mymath.o:mymath.c
 11   gcc -c $^
 12 
 13 $(dy-lib):mylog.o
 14   gcc -shared -o $@ $^
 15 
 16 mylog.o:mylog.c
 17   gcc -fPIC -c $^
 18 
 19 .PHONY:clean
 20 clean:
 21   rm -rf *.o *.a 
 22 
 23 .PHONY:output
 24 output:
 25   mkdir -p mylib/include
 26   mkdir -p mylib/lib
 27   cp *.h mylib/include
 28   cp *.a mylib/lib
 29   cp *.so mylib/lib 

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
解决动态库执行时找不到文件的问题
在执行时,动态库可能找不到文件。解决方法包括:
1.将文件拷贝到系统默认的库路径,如 /lib64/ 或 /usr/lib64/ 下。

2.在系统默认的库路径下建立软链接。

ln -s /your/library/path/libmyfile.so /usr/lib64/

3.使用环境变量 LD_LIBRARY_PATH 指定库的路径。

export LD_LIBRARY_PATH=/your/library/path:$LD_LIBRARY_PATH

注意,这种方式在关闭终端后会失效。

4.在 /etc/ld.so.conf.d/ 路径下创建一个文件,将动态库文件路径放到文件中,然后运行 ldconfig 重新加载。

echo "/your/library/path" > /etc/ld.so.conf.d/mylib.conf
ldconfig

这样设置是永久有效的。

通过深入了解动静态库的使用和解决路径问题,我们可以更好地优化代码结构和提高软件的可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值