头文件
查看系统下安装了哪些头文件:
$ ls /usr/include/
用vim打开其中的头文件 stdio.h ,发现其包含若干库函数的声明(比如 printf)。
库文件
查找系统下安装的库文件:
ll /usr/lib64
如果说头文件提供函数的声明,那么库文件则提供函数的实现。函数的实现就在库文件中,库文件就是把原文件经过一定的翻译,然后打包为一个文件提供给用户,这样就无需提供过多源文件,也可以达到隐藏源文件的目的。
动态库&静态库
Linux下默认只安装动态库,没有安装静态库。
C静态库安装指令如下:
$ (sudo)yum install -y glibc-static
动态库
在运行时被加载到内存中,占用空间较小,需要确保运行时能够找到正确的库文件。
ldd指令:
ldd[文件名]-检测可执行程序形成的时候都依赖了哪些动态库
//l:list(列出)
//d:dynamic(动态的)
//d:dependencies(依赖关系)
Linux下,以 .so 为后缀的是动态库。Windows下,以 .dll为后缀的是动态库。
创建动态库:
gcc -shared -fPIC -o liblibrary.so library.c
//-shared: 生成一个共享库(动态库)。
//-fPIC: 生成位置无关的代码,这是为了确保生成的库可以在不同的内存位置加载,通常在动态库中使用。
//-o liblibrary.so: 指定输出文件的名称为 liblibrary.so,这是一个动态库的命名约定。
//library.c: 输入的源代码文件,用于构建动态库。
//这个指令的作用是将 library.c 编译成一个动态库 liblibrary.so。
链接时使用动态库:
gcc -o my_program main.c -L. -llibrary
//-o my_program: 指定输出文件的名称为 my_program。
//main.c: 输入的源代码文件,用于构建可执行程序。
//-L.: 指定在当前目录查找库文件。
//-llibrary: 指定链接名为 library 的库文件。这里的 -l 选项告诉编译器链接一个名为 library 的库,而实际的库文件是 liblibrary.so。
//这个指令的作用是将 main.c 编译成一个名为 my_program 的可执行程序,并在链接阶段将动态库 liblibrary.so 链接到可执行程序中。
运行时环境变量设置:
在运行程序之前,确保动态库路径被正确设置,可以通过" LD_LIBRARY_PATH " 环境变量来实现。
export LD_LIBRARY_PATH=/path/to/library:$LD_LIBRARY_PATH
./my_program
//export: 用于设置环境变量。
//LD_LIBRARY_PATH: 环境变量,指示运行时动态链接器在哪里查找共享库文件。
///path/to/library: 具体的路径,这里是你希望运行时动态链接器查找库文件的路径。
//$LD_LIBRARY_PATH: 用于在设置新的路径时保留原有的 LD_LIBRARY_PATH 的值
//这个指令的作用是将 /path/to/library 添加到 LD_LIBRARY_PATH 环境变量中,以确保运行时能够找到 liblibrary.so。
静态库
静态库在编译时被链接到可执行文件中,独立性强,但可能导致程序体积较大。
Linux下,以 .a为后缀是静态库。Windows下,以 .lib 为后缀的是静态库。
创建静态库:
gcc -c library.c -o library.o
//编译源文件生成目标文件
ar rcs liblibrary.a library.o
//ar: 用于创建和维护静态库的工具。
//rcs: 选项用于创建库(r),替换已存在的同名库中的文件(c),以及创建索引(s)。
//liblibrary.a: 指定输出的静态库的名称。
//library.o: 包含在静态库中的目标文件。
//这个指令的作用是使用 ar 工具将目标文件 library.o 打包成一个名为 liblibrary.a 的静态库。
链接时使用静态库:
gcc -o my_program main.c -L. -llibrary
//-o my_program: 指定输出文件的名称为 my_program。
//main.c: 输入的源代码文件,用于构建可执行程序。
//-L.: 指定在当前目录查找库文件。
//-llibrary: 指定链接名为 library 的库文件。这里的 -l 选项告诉编译器链接一个名为 library 的库,而实际的库文件是 liblibrary.a。
//这个指令的作用是将 main.c 编译成一个名为 my_program 的可执行程序,并在链接阶段将静态库 liblibrary.a 链接到可执行程序中。
动态链接&静态链接
GCC默认为动态链接,若想静态链接,得加上 -static 选项,改变优先级。
动态链接
在程序执行时进行链接。动态链接的主要目的就是将程序所需要的库函数和外部模块代码保留在独立的库文件中,在程序执行时再加载。在执行过程中去找要链接的函数,生成的可执行文件中没有函数代码,只包含函数重定位信息。当删除动态库时,可执行程序就不能运行。
动态链接的优点是占用空间较小,并且更新方便,只需要替换相应的库文件即可。然而,动态链接的缺点是执行速度相对较慢,因为在执行时需要额外的加载过程。
静态链接
静态链接是在形成可执行程序之前进行的链接。静态链接的主要目的就是将程序所需要的所有库函数和外部模块的代码都合并到最终的可执行文件中。这样,在程序运行时就不再需要加载额外的库文件。就算把静态库删除也不会影响可执行的程序。
静态链接的优点是执行速度相对较快,因为所有代码都在一个文件中,不需要额外的加载过程。然而静态链接的缺点就是占用空间较大,并且更新困难,因为每次更新都需要重新编译整个程序。