在C语言中链接文件/标题
假设我有以下程序(在C语言中链接文件/标题,c,linux,compilation,linker,clang,C,Linux,Compilation,Linker,Clang,假设我有以下程序(hello.c): 编译:将代码转换为汇编代码 生成的文件:hello.s 汇编:将汇编代码转换为目标代码 生成的文件:hello.o 链接:将目标文件合并到一个我们将执行的文件中 clang hello.o -lm 或者(假设我也想链接hello2.o) 因此,问题来了: 描述的过程是否正确 在链接阶段,我们将.o(目标代码)文件链接在一起。我知道math.h位于/usr/include目录中。哪里是math.o?链接器是如何找到它的 Linux中的.a(静态库)和.
hello.c
):
clang hello.o -lm
或者(假设我也想链接hello2.o)
因此,问题来了:
.o
(目标代码)文件链接在一起。我知道math.h
位于/usr/include
目录中。哪里是math.o
?链接器是如何找到它的.a
(静态库)和.so
(动态库)是什么?它们与.o
文件和链接阶段有何关系mylib.c
文件,其中声明并实现了我的函数。我将如何分享这些信息,以便人们通过执行\include
或\include“mylib.h”
将其包含在项目中-lm
开关链接到libm.so(共享对象,因此:.so),其中定义了math.h中声明的数学函数所需的所有符号注意:在您发布的代码中,有些事情不会发生,因为您没有使用math.h中的任何内容,因此链接到libm.so完全没有必要。编译器还试图优化生成的代码,在您的情况下,该程序相当于世界上最简单的Hello。但问题的其余部分是有效的,回答起来确实有意义。您上面描述的过程是正确的。然而,在绝大多数情况下,C代码在一个步骤中进行预处理和组装,如下所示:
clang -c hello.c
执行单独的预处理通常仅用于调试。除非您打算进行一些很少需要的手动装配级优化,否则几乎永远不会进行到装配的转换
关于链接,-l
选项告诉链接器查找“lib{name}.so”形式的共享库。在您的示例中,-lm
告诉链接器链接libm.so。默认情况下,它将在/usr/lib中查找,但是您可以使用-L
选项为它提供一个目录列表以搜索库
您可以使用-B
标志在与静态库或动态库的链接之间切换:
clang hello.o -lm -Bstatic -lstaticlib -B dynamic -ldynamiclib
这将与libm.so、libstaticlib.a和libdynamiclib.so链接
静态库与.o文件一样直接链接到可执行文件。相反,动态库与可执行文件分开保存,并在运行时加载
clang
)的LLVM位代码、优化等math.h
只定义标准数学库libm.a
(您可以链接到-lm
)的原型。函数本身存在于libm.a中存档的对象文件中(见下文)ar
操作这些库(例如ar-t
列出库中的目标文件)。输出二进制文件中不包括动态(或共享)库。相反,代码所需的符号将在运行时加载extern
ed原型创建一个头文件:
#ifndef MYLIB_H
#define MYLIB_H
extern int mylib_something(char *foo, int baz);
#endif
并将其与您的库一起发送。当然,开发人员还必须(友好地)链接到您的库clang hello.o -lm
clang hello.o hello2.o
clang -c hello.c
clang hello.o -lm -Bstatic -lstaticlib -B dynamic -ldynamiclib
#ifndef MYLIB_H
#define MYLIB_H
extern int mylib_something(char *foo, int baz);
#endif