使用gcc / ld,我要使用libfoo.a
,它包含一个符号symbol_foo
(这是一个函数-如果重要的话,请参阅ISR)。 libfoo
中的其他函数显然使用了此函数。我想做的是使用libfoo.a
编译我自己的二进制文件,但是链接到我自己的symbol_foo
版本中。
这可能吗?当前,由于符号的多个定义,我得到ld错误。即它没有声明为“软链接”或原始静态库中的类似内容。
理想情况下,我希望那里存在类似__attribute__((ld_override))
之类的东西,但是我猜那里没有。有什么想法吗?
答案 0 :(得分:5)
这取决于库的设计。对于您而言,答案是“否”,因为该函数未在库中隔离。有关图书馆建设的良好论述,请参阅P J Plauger The Standard C Library1992。是的,它已经相当老了,因此Standard C的版本是C90,但是它所支持的思想仍然有效。
链接器在构建程序时,将处理一系列目标文件和库,以查找不满意的引用(符号名)和跟踪定义。在大多数情况下,它以未定义的符号main
开头。
现在,如果包含symbol_foo
的目标文件仅定义了symbol_foo
,那么如果您在读取库之前已经链接了symbol_foo
,则链接器将忽略{{1} };它已经有一个定义,不需要另一个。但是,symbol_foo
库中包含symbol_foo
的目标文件可能还会定义一些其他符号,而链接器需要这些其他符号,因此它必须链接包含{{ 1}},并且抱怨该符号是双重定义的,即使同一文件中的其他符号不是该符号也是如此。
Plauger提倡(静态)库中的每个目标文件应定义一个外部符号。这样可以最大程度地替代库中的功能。我相信可以假设libfoo.a
的设计者没有做出决定,至少要加上symbol_foo
。
您可以从libfoo.a
中提取目标文件(使用临时目录)并使用symbol_foo
检查其内容;您也许可以直接在库本身上执行此操作。与正确的选项一起使用,将向您显示哪些文件定义和引用了其他符号。
请注意,与共享库链接的规则有些不同。还有“弱”符号会改变行为。您通常还可以从多个目标文件中创建“可重定位”或“可重新链接”的目标文件(通常为libfoo.a
);这样可以为您提供一个更大的目标文件并更改方程式。最后,现在,链接描述文件可以控制哪些符号在库外部可见。因此,这不过是整个主题的掩饰。
答案 1 :(得分:0)
作为一般规则,如果您要覆盖(替换)静态库中的一个非弱全局符号,而仍然使用该库的其余部分,那么您还需要替换所有其他非-静态库中同一编译单元中的弱全局符号。
您可以使用$ python manage.py runserver
在库中找到所有符号-运行
nm
将列出库中的每个对象(编译单元),然后列出所有非弱全局对象该对象中的符号。