静态编译:在编译时,将所有依赖的库文件直接链接到最终的可执行文件中。生成的可执行文件较大,但不需要依赖外部的库文件即可运行。
动态库(共享库):在编译时,不将库文件直接链接到可执行文件中,而是在运行时动态加载库文件。生成的程序较小,但运行时需要依赖外部的库文件。
.a
文件形式存在(如 libexample.a
)。.so
文件形式存在(如 libexample.so
)。假设我们有一个简单的库 libexample.a
和一个使用该库的应用程序 app.c
。
// example.c
int add(int a, int b) {
return a + b;
}
// app.c
#include <stdio.h>
extern int add(int a, int b);
int main() {
printf("Result: %d\n", add(3, 4));
return 0;
}
编译静态库:
gcc -c example.c -o example.o
ar rcs libexample.a example.o
静态编译应用程序:
gcc app.c -L. -lexample -o app_static
编译动态库:
gcc -shared -fPIC example.c -o libexample.so
动态编译应用程序:
gcc app.c -L. -lexample -o app_dynamic
运行时需要设置 LD_LIBRARY_PATH
环境变量,以便找到动态库:
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./app_dynamic
原因:运行时系统找不到所需的 .so
文件。
解决方法:
.so
文件存在于 LD_LIBRARY_PATH
指定的路径中。ldconfig
更新缓存(适用于系统库)。sudo ldconfig /path/to/library
原因:链接时找不到库中的符号定义。
解决方法:
gcc app.c -L. -lexample -o app_dynamic
通过以上步骤,可以有效管理和使用 Linux 下的静态库和动态库,解决常见的编译和运行问题。
领取专属 10元无门槛券
手把手带您无忧上云