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

时间:2015-04-10 18:15:13

标签: c static-linking object-files

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

我想有一个webcommon.o文件,我可以链接到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选项忽略了目标文件的链接。

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

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

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

3 个答案:

答案 0 :(得分:0)

-c告诉gcc编译一个目标文件,所以你需要:

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

然后你可以链接它们以放置你的最终可执行文件:

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

编译时,webcommon中定义的符号被删除。链接时,最终的可执行文件具有公共库中定义的功能。

由于我认为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

答案 1 :(得分:0)

如果webssl.o可以接受web.o上的链接依赖,那么你可以让webssl.o声明共享变量extern,而无需定义它们。当您将程序与webssl.o和web.o链接时,webssl.o将共享这些外部变量,而webssl.o将可以访问web.o中的函数。

通常通过创建包含所有共享函数原型和所有共享变量的extern声明的标头来完成此类操作。共享这些内容的所有源文件都包含标头,但每个共享实体仅在一个源文件中定义。定义文件范围变量意味着使用初始化程序提供声明;定义函数意味着提供函数体。

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

或者,如果您只使用web.o和webssl.o彼此独立,那么您也可以为包含webcommon.o的每个人构建一个静态库。也就是说,

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

然后将相应的静态库链接到您的程序,而不是直接链接web.o或webssl.o。

答案 2 :(得分:0)

您可能希望查找ld -r以链接可以重新链接的目标文件。

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

然后,您可以根据需要与libweb.olibwebssl.o进行关联。

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