2016-03-01 151 views
0

我明白如何链接和编译时创建.c和.h文件并将其添加到我的项目。在C程序中包含头文件时,链接器/编译器如何找到相应的代码?

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

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

+1

它在图书馆里。标准的或明确链接的(看链接器设置) –

+0

可能的重复问题? https://stackoverflow.com/questions/3368121/how-does-acc-compiler-find-the-definitions-of-prototypes-in-header-files – user3303504

回答

4

您需要区分标题和库。

标题声明程序可用的工具。如果包含一个标头,如<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标头。

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

4

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

要找到库指定与-l...进行链接的问题:编译器有一组标准目录,它也可能在工作目录中查找。您可以使用-L...编译器选项将更多目录添加到库搜索路径中。这告诉链接器也查看库的指定目录。

+0

一些编译器允许在代码中指定'#pragma'指令,它们指定要链接的库的名称。 (根据您的看法,这可能是有用的或意大利面条!) –

+0

@ M.M是的。如果我记得正确,此功能在Plan 9中引入。他们围绕这个想法构建了他们的整个编译器工具链,你不应该为编译器提供'-L'选项,因为你可以用这样的指令消除它们。 – fuz

相关问题