LInux下生成静态库和动态库

文章目录

    • 库是什么
    • 库的种类
    • 库的意义
    • 库的命名
  • 静态库与动态库生成实例
    • 编译多个源文件
    • 静态库
    • 动态库
  • Linux下库浅谈
    • 查看一个可执行程序依赖哪些库
    • 可执行程序在执行时定位共享库文件
    • 如何让系统找到新库
  • 编译参数分析

库是什么

  • 在所有平台下都存在着大量的库。库本质上是一种可执行的二进制代码,可以被操作系统载入内存执行。(以下内容只限于Linux平台)

库的种类

  • Linux下的库有俩种:静态库和共享库(动态库)。
静态库 动态库
在编译过程中已经被载入可执行程序,所以体积较大 在可执行程序运行时才载入内存,在编译过程中只是简单的引用,所以代码体积较小

库的意义

  • 库是大佬们编好的可以直接复用的代码,但要遵守许可协议。
  • 实际写代码时每个程序都要依赖底层的库,不可能每行代码都自己写。
  • 不同的程序调用共享库,只需要一份内存被该库占用。

库的命名

  • 在Linux下,库一般存放在/user/lib和/lib目录下
  • 静态库的名字一般为libxxxx.a(xxxx为该库的名称)
  • 动态库的名字一般为libxxxx.so.major.minor(xxxx为该库的名称,major为主版本号,minor为副版本号)

静态库与动态库生成实例

  1. 准备好测试工作,写好测试代码test.h 、test.c、 main.c
  • test.h
#ifndef TEST_H
#define TEST_H

void print(const char *str);

#endif

  • test.c
#include

void print(const char *str)
{
    printf("%s\n",str);
}

  • main.c
#include"test.h"

int main()
{
    print("hello world");
    return 0;
}

  1. 思考:在测试代码中我们的test.c是可以通过gcc -o编译吗?
    在这里插入图片描述
  • 这是肯定无法编译成功的。因为hello.c是一个无main函数的不完整程序。
  • 无论是静态库还是动态库都是由.o创建的,因此必须将.c文件通过gcc编译成.o文件。
  • 此时由三种方法可以完成:
    1. 通过编译多个源文件,直接将目标代码合成一个.o文件
    2. 通过创建静态库,使main函数调用print函数时可调用静态库
    3. 通过创建动态库,使main函数调用print函数时可调用动态库

编译多个源文件

  1. gcc -c test.c //生成test.o文件
  2. gcc -c main.c //main.o文件
  3. gcc -o print main.o test.o //将main.o文件和test.o编译成一个可执行文件print
  4. ./print //可正常执行!
    LInux下生成静态库和动态库_第1张图片

静态库

  1. ar rcs libmyprint.a test.o //生成静态库
  2. gcc -o print main.c -static -L. -lmyprint //生成可执行文件print
  3. ./print
  4. 此时可以删除静态库文件再执行print会发现依然可以执行。
    LInux下生成静态库和动态库_第2张图片

动态库

  1. gcc -fPIC -c *c //(此时的test.o文件和main.c需重新编译)
  2. gcc -shared -o libmyprint.so main.o test.o //生成动态库
  3. gcc -o print main.c -L. -lmyprint //生成可执行文件print
  4. ./print
  5. 此时可以删除动态库文件再执行print发现会报错
    LInux下生成静态库和动态库_第3张图片

Linux下库浅谈

查看一个可执行程序依赖哪些库

  • ldd命令可查看一个可执行程序依赖的共享库
ldd print

在这里插入图片描述

可执行程序在执行时定位共享库文件

  • 当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。
    此时就需要系统动态载入器
  • 对于 elf 格式的可执行程序,是由 ld-linux .so*来完成的,它先后搜索 elf 文件的 DT_RPATH段—环境变量 LD_LIBRARY_PATH—/etc/ld.so.cache 文件列表—/lib/,/usr/lib 目录找到库文件后将其载入内存
export LD_LIBRARY_PATH='pwd' //将当前目录添加为共享目录

如何让系统找到新库

  1. 安装在/lib或/usr/lib下,ld默认能找到
  2. 安装在其他目录,需要添加到/etc/ld.so.cashe
  • 编辑/etc/ld.so.conf文件,加入库文件所在目录的路径
  • 运行ldconfig,会自动重建/etc/ld.so.cache文件

编译参数分析

  • -shared 指定生成动态库
  • -fPIC 编译为位置独立的代码。不用此参数的代码是位置相关的所以动态载入时通过代码拷贝,不能达到代码共享的目的
  • -L. 要连接的库在当前目录中
  • LD_LIBRARY_PATH 指示动态连接器可以装载动态库的路径

你可能感兴趣的:(Linux)