在 C 程序中包含标头时,链接器/编译器如何找到相应的代码



我了解在创建 .c 和 .h 文件并将它们添加到我的项目中时链接和编译的工作原理。

但是,当我将像 stdio.h 这样的标头添加到我的项目中时会发生什么?我知道链接器在某些标准目录中搜索 .h 文件,然后将其粘贴到其中,但标头仅包含函数原型,不包含代码。编译器或链接器在哪里可以找到这些函数的代码,以及如何将其添加到我的源文件中?

我问的原因是因为我正在为微控制器编写引导加载程序,我想仔细查看实际发送到编译器的所有 C 代码。我正在为 PIC32 使用非优化的免费版本的 XC32 编译器,所以我不相信它只包括我实际使用的内容。

您需要区分标头和库。

标头声明可用于程序的工具。当您包含诸如 <stdio.h> 的标头(注意:这不是 - 重复不是!——库)时,您可以向编译器提供使用标准 I/O 库中的工具所需的信息。 通常,C 标头不定义实现工具的实际代码。 C++具有"仅标头"库(Boost 的某些部分是"仅标头"库的主要示例)。

图书馆提供设施的实施。 <stdio.h> 标头声明一个函数fopen();某处有一个定义该函数的库。

某些标头(实际上,通常是很多标头)是特权的,它们声明的功能包含在 C 编译器链接程序的标准库中。 您无需执行任何特殊操作即可将函数链接到程序中。 其他标头来自 C 编译器先验不知道的库,对于这些,您必须告诉它在哪里可以找到库(例如,使用 -L /opt/sometool/lib 作为编译器选项)和库名称(例如使用 -lsometool,这可能与 /opt/sometool/lib/libsometool.so/opt/sometool/lib/libsometool.a 链接)。 请注意,SomeTool 的标头可能/opt/sometool/include,您需要添加一个选项-I/opt/sometool/include才能找到sometool.h标头。

链接器不引用标头;编译器本身不引用库。 编译器控制程序确实处理混合(它通常作为单独的程序运行编译过程的多个阶段 - 编译器与链接器分开)。 标头不包含有关库安装位置的信息。

链接器根本不关心头文件。链接器甚至不知道这些存在,因为它只看到已经编译的对象文件,这就是为什么您明确需要指定使用 -l... 选项链接哪些库的原因。链接器隐式链接在标准C库(-lc),这就是标准C函数的找到方式。在许多平台上,这不适用于数学函数,例如 sinpow ,这就是为什么当您想使用这些时需要与-lm链接的原因。

要回答在何处找到指定与-l...链接的库的问题:编译器具有一组它查找的标准目录。它也可能在工作目录中查找。您可以使用-L...编译器选项向库搜索路径添加更多目录。这会告知链接器也在指定的目录中查找库。

相关内容

最新更新