zoukankan      html  css  js  c++  java
  • c/c++ 之静态库

    静态库

    静态库的链接过程

    #include <cstdio>
    void foo();
    extern int b; //foo函数和b的定义都在libh.a里
    int main() {
    	foo();
    	int a = b;
    	foo();
    	return b;
    }
    

    编译成目标文件:g++ a.cc -g -c -o a.o

    反汇编查看汇编代码:objdump -dS a.o

    0000000000000000 <main>:
    #include <cstdio>
    void foo();
    extern int b;
    int main() {
       0:	f3 0f 1e fa          	endbr64 
       4:	55                   	push   %rbp
       5:	48 89 e5             	mov    %rsp,%rbp
       8:	48 83 ec 10          	sub    $0x10,%rsp
    	foo();
       c:	e8 00 00 00 00       	callq  11 <main+0x11>
    	int a = b;
      11:	8b 05 00 00 00 00    	mov    0x0(%rip),%eax        # 17 <main+0x17>
      17:	89 45 fc             	mov    %eax,-0x4(%rbp)
    	foo();
      1a:	e8 00 00 00 00       	callq  1f <main+0x1f>
    	return b;
      1f:	8b 05 00 00 00 00    	mov    0x0(%rip),%eax        # 25 <main+0x25>
    }
      25:	c9                   	leaveq 
      26:	c3                   	retq 
    

    先看两次调用foo()函数,汇编代码地址0xc的位置:callq 110x11callq 11的下一行位置。再看地址0x1acallq 1f0x1f也是下一行位置。因为这时不知函数foo()的定义在哪,所以暂时用callq指令的下一个指令的位置代替。

    再看引用变量b的时候:mov 0x0(%rip),也是用下一个指令的地址代替还没有找到定义的b

    再看与库链接后的汇编代码:

    0000000000001189 <main>:
    #include <cstdio>
    void foo();
    extern int b;
    int main() {
        1189:	f3 0f 1e fa          	endbr64 
        118d:	55                   	push   %rbp
        118e:	48 89 e5             	mov    %rsp,%rbp
        1191:	48 83 ec 10          	sub    $0x10,%rsp
    	foo();
        1195:	e8 16 00 00 00       	callq  11b0 <_Z3foov>
    	int a = b;
        119a:	8b 05 70 2e 00 00    	mov    0x2e70(%rip),%eax        # 4010 <b>
        11a0:	89 45 fc             	mov    %eax,-0x4(%rbp)
    	foo();
        11a3:	e8 08 00 00 00       	callq  11b0 <_Z3foov>
    	return b;
        11a8:	8b 05 62 2e 00 00    	mov    0x2e62(%rip),%eax        # 4010 <b>
    }
        11ae:	c9                   	leaveq 
        11af:	c3                   	retq   
    
    00000000000011b0 <_Z3foov>:
        11b0:	f3 0f 1e fa          	endbr64 
        11b4:	55                   	push   %rbp
        11b5:	48 89 e5             	mov    %rsp,%rbp
        11b8:	48 8d 35 46 0e 00 00 	lea    0xe46(%rip),%rsi
    

    看地址0x11950x119a就知道,链接后函数foo()的地址在0x11b0,变量b的地址在0x4010的位置。

    编译成目标文件(未链接)

    g++ -c a.cc b.cc c.cc d.cc
    #生成 a.o b.o c.o d.o
    

    将目标文件打包为静态库

    ar rs libxxx.a a.o b.o c.o d.o
    #选项'r'表示将后边的文件列表添加到文件包,如果不存在就创建它,如果文件包中已有同名文件就替换成新的。
    #选项's'是专用于生成静态库的,表示为静态库创建索引,这个索引被链接器使用。
    #库名以lib开头
    

    将库和主程序编译链接在一起

    g++ main.cc -L. -lxxx -I. -o main
    #'-L' 后接静态库的目录
    #'-l' 后接静态库名称(去掉lib和.a。如:libxxx.a就写xxx)
    #'-I' 后接头文件目录
    

    查找路径

    g++ -print-search-dirs #查看
    install: /usr/lib/gcc/i486-linux-gnu/4.3.2/
    programs: =/usr/lib/gcc/i486-linux-gnu/4.3.2/:/usr/lib/gcc/i486-linux-gnu/4.3.2/
    libraries: =/usr/lib/gcc/i486-linux-gnu/4.3.2/:/usr/lib/gcc/i486-linux-gnu/4.3.2/
    

    编译器会在这些路径和-L指定的路径中查找-l指定的库,比如-lxxx编译器会先查找有没有libxxx.so,如果有就链接它,如果没有就查找静态库。所以编译器是优先考虑共享库的,如果希望只链接静态库,可以指定-static选项。

  • 相关阅读:
    数组定义和使用
    跳转语句—break,continue,goto
    案例 天线抬不起头来
    int是几位;short是几位;long是几位 负数怎么表示
    Python3的类注意事项
    用usb线配置直流电机驱动器不能配置成功
    案例 电源灯亮,但是就是不闪灯,而且也下载不了程序
    关于ai算法的一个点子
    进程 并发 线程 032
    ftp功能深度剖析 + 线程 031
  • 原文地址:https://www.cnblogs.com/rookiezjz/p/14423702.html
Copyright © 2011-2022 走看看