在共享对象链接期间指定整个存档包含

Posted

技术标签:

【中文标题】在共享对象链接期间指定整个存档包含【英文标题】:specify whole archive inclusion during shared object link 【发布时间】:2015-03-03 20:31:31 【问题描述】:

我有一个共享对象库(C++ 中的 python 扩展),其中包括来自共享代码库的其他几个档案,这些档案在我们以前的家庭烘焙版本 makefiles 中包装在 -Wl,whole-archive arhive1.a archive2.a ... -Wl,no-whole-archive 中。每个存档都包含在其自己的子目录中,并且是作为此 python 扩展最终目标的一部分而构建的。我正在将我们的构建环境移植到使用 autoconf 和 automake。

在与 python 扩展相关的Makefile.am 中,我有这个(去掉了无关的东西):

pyexc_LTLIBRARIES = pyextension.la
ARCHIVE1_PATH = ../Path/to/.libs/   # built from another Makefile.am
ARCHIVE2_PATH = ../Path2/to/.libs/

pyextension_la_SOURCES = ...

pyextension_la_LDFLAGS = -lz -lrt -module ...
pyextension_la_LIBADD = $(ARCHIVE1_PATH)/archive1.a $(ARCHIVE2_PATH)/archive2.a
pyextension_la_CXXFLAGS = -std=c++0x -fPIC

所有这些东西都出现在命令行上,但没有正确打包,因为当我导入我的 pyextension 模块时,我从它正在寻找的档案中得到未定义的符号错误。原来,我对pyextension_LDFLAGS 有这样的东西:

pyextension_la_LDFLAGS = -Wl,whole-archive $(ARCHIVE1_PATH)/archive1.a $(ARCHIVE2_PATH)/archive2.a -Wl,no-whole-archive -lz -lrt -module 

然而,令我惊讶的是,当最后的Makefile 由make 处理时,在运行./configure 之后,选项-Wl,whole-archive-Wl,no-whole-archive 出现在命令行中,但什么都没有在它们之间(??)和其他地方列出的存档文件。所以,我想我应该尝试pyextension_la_LIBADD 的路线与档案,魔法会奏效。

我不知道从这里去哪里。顺便说一句,这些其他存档库将作为我们部署的一部分与其余的存档库​​一起安装,但在构建期间,它们显然还没有安装。因此,非常感谢有关如何实现这一点的任何指示。我仍然是 automakeautoconf 新手。

【问题讨论】:

您不应该将 any 库或控制特定库如何链接的选项放在LDFLAGS:而不是-lz -lrt 等。 LDFLAGS 用于控制整个链接器的选项。属于LDFLAGS 的选项的典型示例是-L 选项。所有-l 选项,所有取决于标志顺序的选项等都属于LIBADD。另外,我假设您需要-Wl,--whole-archive,而不是-Wl,whole-archive,对吗?还是前端给你加了-- 请记住,链接器对命令行上的选项排序高度敏感。如果您为共享库发布了链接行的剪切/粘贴,将会很有帮助,以便我们可以看到它。 doh,我知道,但是,正如我所说,我是新手,忘记了。我已经改成这个pyextension_la_LIBADD = -lz ...。我试图在那里添加我的-Wl,--whole-archive,但收到来自 libtool 的“为你感到羞耻”的消息,这样的选项应该放在_LDFLAGS 中。所以,我把它移回了那里,再一次,我在-Wl,--whole-archive -Wl,--no-whole-archive 之间看不到任何东西,即使我已经把它们放在Makefile.am 那里。 您确定该消息来自 libtool 吗?无论如何,这些标志不得出现在LDFLAGS 中。时期。不管 libtool (或 automake )说什么,把它们放在那里是行不通的。它们必须出现在LIBADD 中。这些工具只需要把它吸起来。 所以我似乎陷入了第 22 条问题的僵局。 LDFLAGS 不是应该列出我的档案的地方,但这些档案必须列在--whole-archive--no-whole-archive 选项之间。但是,automake 有一个 conniption 并说我不应该在 _LIBADD 中使用-Wl,...。那么,我究竟应该如何让它发挥作用呢? 【参考方案1】:

你可能会从帮助我的同一件事中得到帮助here:

-Wl,--whole-archive,$(ARCHIVE1_PATH)/archive1.a,$(ARCHIVE2_PATH)/archive2.a,--no-whole-archive

用逗号为一个-Wl 选项指定多个参数将使Automake 将它们视为一个单元,并且不会移动它们。缺点是 Automake 无法确定这些目标文件是您的库的依赖项,因此您可能还必须指定 _DEPENDENCIES

【讨论】:

以上是关于在共享对象链接期间指定整个存档包含的主要内容,如果未能解决你的问题,请参考以下文章

linux environment parameter

linux environment parameter

将共享对象链接到其他共享对象 C++ 项目

linux上动态链接期间符号的替代实现

链接到显示所有帖子的存档页面

如何在交叉编译期间强制链接到未安装的库