• Linux 创建静态库(.a)和动态库(.so)


    0. 回顾一下 gcc 选项

    ==============================================

    -E : 仅做预处理,例如去注释,宏展开,include 展开等

    -S : 将源程序编译为汇编代码 *.s

    -c :  预处理,汇编,生成目标文件 *.o

    -o :  预处理,汇编,链接,生成可执行 ELF 文件

    ==============================================

    -g :  编译时加入调试信息

    -Wall : 编译时显示所有告警

    -std=c99 : 编译时支持 c99 语法

    -I directory : (i) 加入头文件搜索目录

    -lxxx : (L) 链接静态库或动态库

    ==============================================

    1. 创建和使用静态库

    - 库文件 arithmetic.c

    int add(int a, int b) { return a + b; }
    int sub(int a, int b) { return a - b; }
    int mul(int a, int b) { return a * b; }
    int div(int a, int b) { return a / b; }

    - 头文件 arithmetic.h

    #ifndef ARITHMETIC_H_
    #define ARITHMETIC_H_
    
    extern int add(int, int);
    extern int sub(int, int);
    extern int mul(int, int);
    extern int div(int, int);
    
    #endif

    - 主测试文件 use_arithmetic_lib.c

    #include "arithmetic.h"
    #include <stdio.h>
    
    int main(void)
    {
        int x, y;
        printf("Enter two integers: ");
        scanf("%d%d", &x, &y);
    
        printf("add is: %d
    ", add(x, y));
        printf("sub is: %d
    ", sub(x, y));
        printf("mul is: %d
    ", mul(x, y));
        printf("div is: %d
    ", div(x, y));
    
        return 0;
    }

    生成静态库步骤:

    1)编译 arithmetic.c 为目标文件,生成 arithmetic.o

    $ gcc -c arithmetic.c

    2)将 arithmetic.o 转换为静态库文件(注意,库文件命名规则,libxxx.a)

    $ ar rcs libarithmetic.a arithmetic.o

     

    使用静态库:

    方法1:$ gcc use_arithmetic_lib.c -static ./libarithmetic.a -o use_arithmetic_lib

    方法2:$ gcc use_arithmetic_lib.c -L. -larithmetic -o use_arithmetic_lib               # -L 指定静态库文件路径

    正规使用静态库到方式: $ gcc use_arithmetic_lib.c  -static  -L.  -larithmetic  -o  use_arithmetic_lib

     

    对于静态库,编译完成后,可执行文件可以脱离静态库运行。但是设想一下,如果一个静态库被调用很多次,则在内存中有这个库很多重复的加载,这是引入动态库的原因之一。以下介绍动态库。

     

    2. 创建和使用动态库

    (使用和上述静态库同样的c代码)

     

    生成动态库步骤:

    1)编译 arithmetic.c 为目标文件,生成 arithmetic.o

    $ gcc -c arithmetic.c

    2)将目标文件转换成动态库文件 (注意动态库文件的命名规则 libxxx.so.major.minor)

    $ gcc -fPIC -shared -o libarithmetic.so.0.1 arithmetic.o

    以上两步可以合在一起,

    $ gcc -fPIC -shared -o libarithmetic.so.0.1 arithmetic.c

    使用动态库文件:

    $ gcc use_arithmetic_lib.c  -L.  -larithmetic  -o  use_arithmetic_lib

    要使编译后的可执行文件能找到动态库文件,则,

    1) 将动态库文件拷贝到 /usr/local/lib(建议自己生成的动态库文件放在此目录。默认动态库文件搜索路径是 /usr/lib, /lib, /usr/local/lib)

    $ sudo cp libarithmetic.so.0.1 /usr/local/lib

    2)创建一个软链接

    $ sudo ln -sf libarithmetic.so.0.1 libarithmetic.so

    3) 更新 ld 缓存

    $ sudo ldconfig

    使用可执行文件时,不能脱离动态库环境(例如,可执行文件不能放到其它机器上跑), run 结果如下,

    =====================================================================================

    有时编译完成后,执行时报错: cannot open shared object file: No such file or directory 解决方法有以下两种:

    种: 在 .bashrc 中添加 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib  (假定动态链接文件.so 安装在 /usr/local/lib 下)

    种: $ sudo vim /etc/ld.so.conf  添加 /usr/local/lib 然后执行 $ sudo ldconfig

    =====================================================================================

    动态库文件的好处是,可以动态更新库文件,不用重复编译可执行文件。如下,

    更改 arithmetic.c 为 arithmetic_modify.c 为,

    int add(int a, int b) { return a + b; }
    int sub(int a, int b) { return a - b; }
    int mul(int a, int b) { return a * b; }
    int div(int a, int b) { return a / b + 100; }

    编译生成目标文件:

    $ gcc -c arithmetic_modify.c

    生成动态库文件:

    $ gcc -fPIC -shared -o libarithmetic.so.0.2 arithmetic.o

    拷贝动态库文件到 /usr/local/lib

    $ sudo cp libarithmetic.so.0.2 /usr/local/lib

    更新软连接

    $ sudo ln -sf libarithmetic.so.0.2 libarithmetic.so

    再执行一下 use_arithmetic_lib

    最后,使用命令 ldd 可以查看可执行文件的动态库依赖关系,如下,

    $ ldd use_arithmetic_lib

    完。

  • 相关阅读:
    luogu2253 好一个一中腰鼓!
    luogu2948 滑雪课
    luogu1556 幸福的路
    luogu1900 自我数
    luogu1632 点的移动
    luogu1999 高维正方体
    树状数组模板
    杜教筛
    [比赛|考试] 9月第一周的考试
    历年NOIP真题总结
  • 原文地址:https://www.cnblogs.com/gaowengang/p/6164461.html
Copyright © 2020-2023  润新知