美文网首页
静态库、动态库编译原理

静态库、动态库编译原理

作者: xinayida | 来源:发表于2021-01-09 21:57 被阅读0次

    编译过程

    预处理 -> 编译 -> 汇编 -> 链接

    预处理

    1. 完成宏替换、文件引入,去除空行、注释等。
    2. 针对预处理命令进行处理,头文件包含、宏定义扩展、条件编译的选择等。
    # test.c
    #include <stdio.h> 
    int main(){
        printf("hello world!\n");
        return 0;
    }
    ------------------------------------------------
    $ gcc -E test.c -o test.i
    
    • -E: 让gcc在预处理结束后停止编译,test.i文件为预处理后的文件
    • -o: 指定输出文件

    编译

    这里的编译不是指程序从源文件到二进制程序的全部过程,而是指将经过预处理之后的程序转换成特定汇编代码(assembly code)的过程。

    $ gcc -S test.i -o test.s
    

    汇编

    将上一步的汇编代码转换成机器码(machine code),这一步产生的文件叫做目标文件,是二进制格式。

    $ gcc -c test.s -o test.o
    

    链接

    链接过程将多个目标文以及所需的库文件(.so等)链接成最终的可执行文件

    $ gcc test.o -o test
    $ ./test
    

    更详细的内容可以参考:https://www.cnblogs.com/CarpenterLee/p/5994681.html#top

    生成静态库

    • 首先生成test.o目标文件
    • 使用ar命令将test.o打包成libtest.a静态库
    # 首先生成目标文件
    $ gcc -c test.c -o test.o
    # 使用ar命令将目标文件打包成静态库
    $ ar rcs libtest.a test.o
    # 使用ar t libtest.a 查看静态库内容
    $ ar t libtest.a
    test.o
    

    生成动态库

    • 首先生成test.o目标文件。
    • 使用-shared和-fPIC参数生成动态库
    # 首先生成目标文件
    $ gcc -c test.c
    # 使用-fPIC和-shared生成动态库
    $ gcc -shared -fPIC -o libtest.so test.o
    

    例子

    tool.h

    int find_max(int arr[], int n);
    

    tool.c

    #include "tool.h"
    
    int find_max(int arr[], int n){
        int max = arr[0];
        int i;
        for(i = 0; i < n; i++){
            if(arr[i] > max){
                max = arr[i];
            }
        }
        return max;
    }
    

    main.c

    #include <stdio.h>
    #include "tool.h"
    int main(){
        int arr[] = {1,3,5,8,2};
        int max = find_max(arr, 5);
        printf(" max = %d\n", max);
        return 0;
    }
    

    编译静态库

    • 编译目标文件 $ gcc -c tool.c,省略-o默认生成同名文件
    • 编译静态库文件 ar rcs libtool.a tool.o
    • 编译可执行文件&链接静态库 gcc -o main main.c -L. -ltool
      -L: 查询库路径
      -l: 需要链接的库
    • 执行 ./main

    编译动态库

    $ gcc -shared -fPIC -o libtool.so tool.c
    $ gcc -o main -L. -ltool main.c
    $ ./main
    

    ps

    • 静态库和动态库同名时,系统会优先链接动态库。
    • 查看文件详情ls -lh
    • 查看链接库详情
      linuxldd main
      macOx 动态库:otool -L main ,静态库 nm main

    静态库与动态库区别

    • 静态库在程序编译时会链接到目标代码中,程序运行时不在需要静态库,因此体积较大。每次编译都需要载入静态代码,因此内存开销大。
    • 动态库在程序编译时不会被链接到目标代码中,而是在程序运行时才被载入,程序运行时需要动态库存在,因此体积较小。而且系统只需载入一次动态库,不同程序可以得到内存中相同的动态库副本,因此内存开销小。

    相关文章

      网友评论

          本文标题:静态库、动态库编译原理

          本文链接:https://www.haomeiwen.com/subject/fzacaktx.html