[TOC]

形式

一般来说,Windows的静态库文件扩展名是 .lib,动态库文件扩展名是 .dll (Dynamic-Link Libraries);Linux的静态库扩展名是 .a,动态库扩展名是 .so (Shared Object)

Linux系统存储的库的位置一般在:/lib 和 /usr/lib。 在 64 位的系统上有些库也可能被存储在/usr/lib64 下。库的头文件一般会被存储在 /usr/include 下或其子目录下。
Linux库有两种,一种是静态库,其命令规则为 libxxx.a;一种是共享库,其命令规则为 libxxx.so

生成

静态库生成

step1 编译生成.o文件

1
gcc -c hello.c

此时将会生成一个hello.o文件

-c 和含义:只编译,不链接

step2 使用.o文件生成 .a静态库

1
ar -crv libhello.a hello.o

-crv是ar命令的选项:c,r,v分别代表crate,replace,verbose

  1. -c (create):
    • 表示创建一个新的静态库文件(即 libhello.a)。
    • 如果库文件已经存在,-c 不会报错,而是继续执行操作。
    • 如果没有此选项,ar 在库文件不存在时可能会提示错误。
  2. -r (replace):
    • 将一个或多个目标文件(如 hello.o)添加到静态库中。
    • 如果静态库中已经存在同名文件,则替换它。
    • 如果静态库中不存在该文件,则会新增该文件。
  3. -v (verbose):
    • 显示详细信息。
    • 在执行操作时,会列出具体处理了哪些目标文件。

动态库生成

1
gcc -shared -fPIC -o libhyhello.so hello.o
1
gcc -o hello main.c libhyhello.so 

-shared

  • 指定生成一个共享库(动态库,.so 文件)
  • 共享库是运行时动态加载的,适用于多进程共享代码,减少内存占用

-fPIC

  • 生成位置无关代码(Position-Independent Code)
  • 作用: 共享库在内存中加载到任何地址都能正常运行,这对于动态库至关重要
  • hello.o 必须是通过 -fPIC 编译生成的,确保目标代码是位置无关的

-o libhyhello.so

  • 指定输出文件名为 libhyhello.so,这是动态库的标准命名格式
  • Linux 系统中,动态库通常以 lib 开头,扩展名为 .so(shared object)

hello.o

  • 输入文件,是先前用 gcc 编译生成的目标文件

使用

方法一

1
gcc -o hello main.c -L. -lhello

-L.

  • 指定库的搜索路径为当前目录 (.)。
  • 链接器在查找静态库或动态库时,除了默认的路径(如 /usr/lib/usr/local/lib),也会在当前目录中查找。
  • 作用: 如果静态库文件 libhello.a 或动态库文件 libhello.so 位于当前目录,这个选项确保它们能够被正确找到。

-lhello

  • 表示链接名为 hello 的库。
  • 工作原理:
    • 链接器会自动寻找以下文件:
      • 静态库:libhello.a
      • 动态库:libhello.so
    • 搜索路径包括默认路径和通过 -L 指定的路径(这里是当前目录 .)。

方法二

1
gcc main.c libhyhello.a -o hello

方法三

1
2
gcc -c main.c
gcc -o hello main.o libmyhello.a

GCC命令相同时,会先执行.a文件,还是会先执行.so文件?

先删除除.c和.h文件外的所有文件,然后再编译形成.o文件,生成.o文件后,再由.o文件分别生成.a文件和.so文件。
执行程序后,发现当静态库和动态库同名时,gcc 命令将优先使用动态库,默认去连/usr/lib 和/lib 等目录中的动态库。

静态库与动态库的区别

每一个程序在使用静态库时,都会将静态库文件拷贝一份添加到自身。如果有多个程序都要使用该静态库文件时,都会给自身添加一份拷贝,这就导致会产生空间浪费。在源文件较少时不明显,但如果在一个项目中,静态库文件本身就比较大,并且使用该静态库文件的源程序很多,这就会造成大量内存浪费。
而动态库文件在被使用时,会对所有想使用该动态库的源程序添加一个标记,在程序执行时再链接动态库文件使用。这就是动态库的优点,也是动态库被称为共享库的原因。

参考资料【C++】静态库和动态库文件的生成和使用_c++ .a文件-CSDN博客