将目标文件与 GCC 链接时,您能否创建独立的抽象层?

Can you create independent layers of abstraction when linking object files with GCC?

我有一些文件,例如:

a.c a.h
b.c b.h
c.c c.h
d.c d.h

其中 a 使用 b,b 使用 c,c 使用 d。

在编译的时候,有什么方法可以只linka直接到b,而不是把它们都包含在我的编译语句中吗?

以某种方式使用:

gcc a.o b.o

而不是:

gcc a.o b.o c.o d.o

我想这样做是为了让 a 不必担心 b 或 c 或 d 是否使用任何其他文件实现,而是可以直接将其自身指向 b.o

附带问题,有没有一种方法也可以执行像这样的通配符对象命令也递归地进入文件:

gcc *.o

我很好奇,以防万一上述最佳情况不可能发生

您似乎对编译和链接的工作方式有一点误解。

假设文件如下所示:

//a.h
// nothing in particular

//a.c
#include "b.h"
int main()
{
  bravo();
  return 0;
}

//b.h
void bravo();

//b.c
#include "c.h"
void bravo()
{
  charlie();
}

//c.h
void charlie();

//c.c
#include "d.h"
void charlie()
{
  delta();
}

等等。

如您所见,a.c中的代码是指declared in b.h and defined中的代码在 b.c。它不涉及 cd.

中的任何内容

您可以通过编译构建a.o [1]:

gcc -c a.c    

“-c”表示 "build the binary object file and stop, don't try to build an executable"。编译器注意到行

#include "b.h"

并将 "b.h" 拉入代码。它不会查看 b.c,因为没有人告诉它要查看。它看到这段代码使用了尚未定义的 bravo(),它相信在构建可执行文件时有人会提供此功能。编译器既不知道也不关心 b.ccharlie()delta() 或任何 cd 文件。

构建可执行文件时,链接器 发挥作用 [2]:

gcc a.o b.o c.o d.o

链接器可以从这些文件构建可执行文件,因为所有被调用的函数都已定义,因此它可以解决所有未解决的问题。这个:

gcc a.o b.o

将不起作用。 链接器说 "hold on, I can't build a complete program out of this, you call charlie(), but I see no definition of charlie()!"

[1] 对于应该叫 "compiling a.c" 还是 "compiling a.o" 存在一些分歧,但这在这里并不重要。

[2] 请注意,gcc 包含编译器和链接器,以及其他东西。就像一把瑞士军刀。