gcc/g++链接时候库的顺序

简介

记录一个以前遇到一个问题,代码没问题,但是g++编译出现了问题。
这边先说结果:

g++ ... obj($?) -l(上层逻辑lib) -l(中间封装lib) -l(基础lib) -l(系统lib) -o $@

gcc -l 官方解释如下:
       -l library
           Search the library named library when linking.  (The second alter-
           native with the library as a separate argument is only for POSIX
           compliance and is not recommended.)

           It makes a difference where in the command you write this option;
           the linker searches and processes libraries and object files in the
           order they are specified.  Thus, foo.o -lz bar.o searches library z
           after file foo.o but before bar.o.  If bar.o refers to functions in
           z, those functions may not be loaded.
翻译一下

如果你的库在链接时安排的顺序是:foo.o -lz bar.o。
那么gcc的链接器先搜索库foo,然后是z库,然后是bar库。
这样就带来一个问题,如果库bar调用了库z里面的函数,但是链接器是先搜索的库z,这时候并没有发现库bar调用库z啊,所以就不会把库z中的这部分函数体挑出来进行链接。而是只把库z中,被foo库调用的函数体挑出来。

所以要把最基础实现的库放在最后,这样左边的lib就可以调用右边的lib中的代码。

简单使用动态链接库

查看一个可执行文件或动态库依赖哪些动态库
readelf -d
ldd

文件结构:
在这里插入图片描述

fun.h

#ifndef _FUN_H
#define _FUN_H

void fun();

#endif //!_FUN_H

fun.cpp

#include <iostream>
#include "fun.h"

void fun()
{
	std::cout << "fun" << std::endl;
}

编译链接库

g++ -c -fpic fun.cpp -I./include/
g++ -shared *.o -o ./lib/libFun.so

main.cpp

#include "fun.h"

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

编译程序

g++ main.cpp -o main -I./include/ -L./lib/ -lFun

运行发现报错
在这里插入图片描述
发现在系统默认路径里面找不到我们的动态链接库
在这里插入图片描述

去网上找了一下默认查找路径:

  1. gcc 编译时指定的运行时库路径 -Wl,-rpath
  2. 环境变量 LD_LIBRARY_PATH
  3. ldconfig 缓存 /etc/ld.so.cache
  4. 系统默认库位置 /lib /usr/lib

这边就使用第一个吧

g++ main.cpp -o main -Wl,--rpath=./lib/ -I./include/ -L./lib/ -lFun

运行没问题了
在这里插入图片描述

现在的问题我们编译的时候命令会不会写成下面这种:

g++ -o main -Wl,--rpath=./lib/ -I./include/ -L./lib/ -lFun main.cpp

在这里插入图片描述
编译直接报错,找不到库,我们把动态链接库放到了.o文件前面,因为解析的时候是从右往左,所以解析.o文件的时候找不到动态链接库了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值