GCC动态库和头文件的搜索顺序

静态库链接时搜索路径顺序:
1.ld会去找GCC命令中的参数-L
2.再找gcc的环境变量LIBRARY_PATH
3.再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的
 
动态链接时、执行时搜索路径顺序:
1.编译目标代码时指定的动态库搜索路径;
2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;
4.默认的动态库搜索路径/lib;
5.默认的动态库搜索路径/usr/lib。
Linux下,库文件一般放在/usr/lib /lib下,
如果安装在/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作。
如果安装在其他目录,需要将其添加到/etc/ld.so.cache文件中,步骤如下
1.编辑/etc/ld.so.conf文件,加入库文件所在目录的路径
2.运行ldconfig,该命令会重建/etc/ld.so.cache文件
有关环境变量:
LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径
LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径
链接过程
 建立静态库方法(包括静态内部库和动态外部库)
gcc -c fun.c
ar cqs libfun.a fun.o
 编译中使用静态库方法
gcc call.c -static -L. -lfun -o fun_static_call
 建立动态库(包括动态内部库和动态外部库)
gcc fun.c -fPIC -shared -o libfun.so
 编译中使用动态库方法
gcc call.c -L. -lfun -o fun_dyn_call
编译器会先在path文件夹下搜索libxxx.so文件,如果没有找到,继续搜索libxxx.a(静态库)。
执行过程
 无论是使用动态库还是外部库链接时都是使用的ld连接器;
 使用动态库的程序执行时使用动态加载器。在Linux 下,加载器是/lib/ld-Linux.so.X(X是版本号)。然后加载器搜索、加载程序所要使用的动态链接库。搜索顺序见上。
 
Linux程序GCC编译基本过程
一个程式从原始码到可执行文件(或共享库文件),一般都要经过预处理、编译、汇编和链接这四个步骤。
编译过程扫描头文件的搜索路径顺序
gcc 在编译时如何去寻找所需要的头文件 :
※所以header file的搜寻会从-I开始
※然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH
 
※再找内定目录
/usr/include
/usr/local/include
/usr/lib/gcc-lib/i386-linux/2.95.2/include
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../include/g++-3
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../i386-linux/include
库文件但是如果装gcc的时候,是有给定的prefix的话,那么就是
/usr/include
prefix/include
prefix/xxx-xxx-xxx-gnulibc/include
prefix/lib/gcc-lib/xxxx-xxx-xxx-gnulibc/2.8.1/include
### GCC动态库的使用方法 在Linux环境下,GCC支持两种类型的库:静态库(`.a` 文件)动态库(`.so` 文件)。动态库允许程序运行时加载共享对象文件,从而减少内存占用并提高效率。 #### 创建动态库 要创建一个动态库,可以按照以下过程完成: 1. 编写源代码文件 `calc.c` 头文件 `calc.h`。 2. 将 `.c` 文件编译为目标文件: ```bash gcc -fPIC -c calc.c -o calc.o ``` 这里 `-fPIC` 参数用于生成位置无关代码 (Position Independent Code),这是构建动态库所必需的[^2]。 3. 使用目标文件生成动态库: ```bash gcc -shared -o libcalc.so calc.o ``` #### 链接动态库 当需要将动态库链接到应用程序时,可以通过如下命令实现: ```bash gcc main.c -o main -L./ -lcalc ``` 其中: - `-L./` 表示指定当前目录作为查找路径; - `-lcalc` 告诉链接器寻找名为 `libcalc.so` 的动态库[^1]。 如果遇到找不到动态库的情况,在执行阶段可能需要设置环境变量 `LD_LIBRARY_PATH` 来告知操作系统动态库的位置: ```bash export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ``` 或者永久修改 `/etc/ld.so.conf` 并更新缓存: ```bash echo "/path/to/library" | sudo tee -a /etc/ld.so.conf sudo ldconfig ``` 对于更复杂的项目结构,比如包含多个子模块的情况下,则需明确指明 include 路径以及 library 存储路径。例如: ```bash gcc mytest.c -I ./myadd/include -L ./myadd/lib -lmyadd ``` 这里 `-I` 定义了头文件所在目录而 `-L` 则定义了库文件所在的目录[^3]。 #### 动态库常见问题解决方案 1. **无法找到符号错误** 如果出现未定义引用错误,可能是由于缺少必要的依赖项或者是链接顺序不正确引起的。确保所有的依赖都已正确定位并且按正确的次序传递给链接器。 2. **运行时报错 'No such file or directory' 或者 'cannot open shared object file'** 此类问题是因系统未能定位到所需的 .so 文件所致。确认已经设置了合适的 `LD_LIBRARY_PATH` 或者调整了系统的全局配置使得能够识别新增加的库地址。 3. **版本冲突** 当存在不同版本的相同名称的库时可能会引发兼容性问题。务必验证使用的具体版本号是否满足需求,并考虑采用显式的版本控制机制来规避此类风险。 ```python import ctypes # 加载动态库 lib = ctypes.CDLL('./libcalc.so') # 调用函数前先设定参数类型与返回值类型(假设有一个 add 函数接受两个整数) lib.add.argtypes = [ctypes.c_int, ctypes.c_int] lib.add.restype = ctypes.c_int result = lib.add(5, 3) print(result) # 输出8 ``` 上述 Python 示例展示了如何利用 `ctypes` 库调用 C/C++ 中定义的功能接口。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值