美文网首页
linux之动态库和静态库编译

linux之动态库和静态库编译

作者: simbanyan | 来源:发表于2022-05-15 09:52 被阅读0次

    Linux 中 动态库和静态库编译和使用

    为了更好的表述,这里写了一个简单的示例代码 示例代码 源代码链接

    代码目录结构为:

    .
    ├── hello          # 写的一个hello示例库
    │   ├── hello.c
    │   ├── include
    │   │   └── hello.h
    │   └── makefile
    ├── main.c         # 使用main函数去使用上面的库
    └── makefile
    

    其中 hello.c内容:

    #include "include/hello.h"
    void say_hello(char * name){
        printf("Hello, %s!\n", name);
    }
    

    其中 hello.h内容:

    #include<stdio.h>
    void say_hello(char *name);
    

    其中 main.h内容:

    #include<hello.h>
    int main(){
        say_hello("Tom");
    }
    

    静态库编译

    切换目的到hello, 执行一下命令可生成静态库

    gcc -c -o hello.o hello.c -fpic # 编译源文件hello.c 到目标文件hello.o 
    ar -rc  libhello.a hello.o  # ar 打包成一个静态库  
    

    其中gcc的 -fpic 标志含义是:生成使用相对地址无关的目标代码

    注意: 静态库要以lib开头,和.a结束 的方式命名

    动态库的编译

    切换目的到hello, 执行一下命令可生成动态库

    gcc -c -o hello.o hello.c -fpic # 编译源文件hello.c 到目标文件hello.o 
    gcc -shared -fpic -o libhello.so hello.o   # 生成动态库  
    

    注意: 动态库要以lib开头,和.so结束 的方式命名

    如果你下载我提供的代码,也可以直接使用make编译

    静态库的使用

    切换目录回到主目录, 编译main.c 并使用刚才编译好的静态库

    gcc -c -o main.o main.c -Ihello/include # 这里-Ihello/include 指定头文件查找目录为相对路径hello/include 
                            # 这一定要指定头文件查找目录的,不然找不到main.c中使用的hello.h 
    gcc -o main_a  main.o -Lhello -lhello -static 
    # 这里 -Lhello 指定库查找目录为相对路径hello
    # -lhello 指定需要链接的库为hello, 优先链接libhello.so,如何找不到就链接libhello.a  
    # -static 指定要链接静态库, 因为hello目录中同时存在静态库和动态库,所以需要特别指定
    

    最后生成 main_a , 可以直接通过 ./main_a 运行

    动态库的使用

    切换目录回到主目录, 编译main.c 并使用刚才编译好的动态库

    gcc -c -o main.o main.c -Ihello/include 
    gcc -o main_so main.o  -Lhello -lhello -Wl,-rpath=./hello 
    

    相比使用静态库,使用动态库需要指定的查找目录 -Wl,-rpath=./hello
    这里指定的目录,是编译完成的程序运行的时候,去找依赖的动态库的路径,如果你没有指定,程序会
    到系统默认的路径去找,如果没有找到会报错(如下)

    ./main_so: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory
    

    最后生成 main_so , 可以直接通过 ./main_so 运行

    动态库和静态库的区别

    1. 链接时不同
      静态库链接的时候,会把静态库中自己需要的代码复制到自己的程序里面去。
      动态库链接的时候,只会检查一下动态库只是否有自己程序需要的代码,不会复制。
    2. 运行时不同
      静态库因为链接时已经把相关代码复制进程序了,所以运行时不再依赖静态库。
      相反,使用动态的程序在运行时需要去找依赖的动态库,如果找不到会导致无法运行。

    静态库优点

    • 运行效率高些,无需依赖,简单方便。

    动态库的优点

    • 节约内存(主要体现在:因为动态库可多个程序共享一份,当多个程序都在使用这个动态库时,内存中只加载一份)
    • 节约时间(如果库修改代码,只需要重新编译动态库,然后替换掉原先的库。相反静态库需要编译所有使用这个库的程序)


    相关文章

      网友评论

          本文标题:linux之动态库和静态库编译

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