• 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.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    翻译一下
    
    如果你的库在链接时安排的顺序是:foo.o -lz bar.o。
    那么gcc的链接器先搜索库foo,然后是z库,然后是bar库。
    这样就带来一个问题,如果库bar调用了库z里面的函数,但是链接器是先搜索的库z,这时候并没有发现库bar调用库z啊,所以就不会把库z中的这部分函数体挑出来进行链接。而是只把库z中,被foo库调用的函数体挑出来。
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    简单使用动态链接库

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

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

    fun.h

    #ifndef _FUN_H
    #define _FUN_H
    
    void fun();
    
    #endif //!_FUN_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    fun.cpp

    #include 
    #include "fun.h"
    
    void fun()
    {
    	std::cout << "fun" << std::endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    编译链接库

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

    main.cpp

    #include "fun.h"
    
    int main()
    {
    	fun();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    编译程序

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

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

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

    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
    
    • 1

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

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

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

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

  • 相关阅读:
    【联通】数据编排技术在联通的应用
    RocketMQ并行消费浅析
    如何才能设计出“好的”测试用例?
    vscode终端显示有错误
    时尚零售企业商品计划管理的数字化之旅
    Java中Map架构简介说明
    域内持久化后门
    打通“隔墙”!浅析低代码超强的整合能力
    全面解析TCP协议(三次握手、四次挥手,头部报文格式)
    力扣:654. 最大二叉树
  • 原文地址:https://blog.csdn.net/qq_40571533/article/details/126791905