添加其他目标文件使用的公共 header/object 文件

Adding a common header/object file that is used by other object files

我创建了一个 http 库,其中包含 2 个目标文件(web.o 和 webssl.o)。这两个文件共享一些共同的常量和函数,每个文件都必须重复这些常量和函数。这也意味着我需要在进行更改时更新这两个文件。

我想要一个 webcommon.o 文件,我可以 link 到 web.o 和 webssl.o 文件。它将包含两个库共享的所有公共代码。

我用共享代码创建了 webcommon.o 文件。我从 web.c 和 webssl.c 中删除了共享代码。当我用这个编译 web.c 和 webssl.c 时:

# gcc -Wall -Werror -O3 -c web.c /my/lib/webcommon.o;
gcc: warning: /my/lib/webcommon.o: linker input file unused because linking not done

通过搜索,-c 选项似乎忽略了目标文件的 linking。

如何创建与 web.o 和 webssl.o 一起使用的 webcommon.o 目标文件?现在看来我只有两个选择:

  1. 保留 web.o 和 webssl.o 中的重复代码,并在需要时更新这两个文件。

  2. 确保我在编译程序时添加了 webcommon.o 文件(使用 web.o 或 webssl.o

  3. 的程序)

-c 告诉 gcc 编译目标文件,因此您需要:

gcc -Wall -Werror -O3 -c web.c -o web.o
gcc -Wall -Werror -O3 -c webssl.c -o webssl.o
...

然后你可以link他们把你最终的可执行文件:

gcc web.o webcommon.o -o web
gcc webssl.o webcommon.o -o webssl

编译时,webcommon 中定义的符号被删除。当您 link 时,您的最终可执行文件具有您的公共库中定义的函数。

因为我认为 web 和 webssl 是库,你可能想创建一个静态库:

ar -c web.a web.o webcommon.o
ar -c webssl.a webssl.o webcommon.o

或者将它们全部放在一个库中:

ar -c weblib.a web.o webcommon.o webssl.o

如果 webssl.o 可以接受 link 对 web.o 的依赖,那么您可以 webssl.o 声明共享变量 extern , 没有定义它们。当你 link 一个带有 webssl.o 和 web.o 的程序时,webssl.o 将共享这些外部变量,并且 webssl.o 将可以访问 [=35= 中的函数].

这种事情通常是通过创建一个 header 来完成的,其中包含所有共享函数的原型和所有共享变量的 extern 声明。共享这些内容的所有源文件都包含 header,但每个共享实体仅在一个源文件中 定义。定义一个 file-scope 变量意味着提供一个带有初始值设定项的声明;定义函数意味着提供函数 body.

如果你采用这种方法,将所有定义放在'web'模块中,那么web.o可以单独使用,但webssl.o只能与[一起使用=35=].

或者,如果你只使用彼此独立的web.o和webssl.o,那么你可以为每个包含webcommon.o 还有。也就是说,

  • 一个库(例如 libweb.a)包含 web.o 和 webcommon.o,以及
  • 一个库(例如 libwebssl.a)包含 webssl.o 和 webcommon.o

然后您 link 将适当的静态库添加到您的程序中,而不是直接 linking web.o 或 webssl.o。

您可能想要查找 ld -r 到 link 个目标文件,然后可以重新link编辑它们。

ld -r -o libweb.o web.o webcommon.o
ld -r -o libwebssl.o webssl.o webcommon.o

然后您可以根据需要 link 和 libweb.olibwebssl.o

或者您可以创建实际的库,libweb.alibwebssl.a(存档库)或 libweb.solibwebssl.so(共享对象)。这是提供图书馆的老式方式;它有很多用处。如果 'web' 和 'webssl' 部分的入口点被明确命名,那么您可以构建一个包含所有三个目标文件的库,并且只需 link 即可。