如何将项目链接到同一个C静态库的两个不同版本?

时间:2018-02-20 08:47:30

标签: c linker package static-libraries

我正在开发一个复杂的C生态系统,其中不同的人开发了不同的包/库。

我想创建一个名为foobar的新项目。该项目使用两个库,即库foo和库bar

不幸的是,bar不需要foo所需的相同版本。两者都使用say因此存在冲突。

如果所有软件包都在带有子模块的Git上,则在递归克隆时无法构建foobar项目,因为在不同的翻译单元中存在两个say函数。因此submodule策略不起作用。

我的问题是:如何管理使用两个不同版本的相同静态库的一个项目({{1 }})?

结构

*.a

项目foobar需要库 foobar | .----'----. <---- (require) v v foo bar (v1.0) | | (v2.0) '-> say <-' 和库foo,这两个库都使用bar包:say需要版本1和foo需要版本2.

bar

FOO

// say.h
void say(char *);

// foo.c
#include "say.h"

void foo(void) {
    say("I am foo");
}

foobar的

// bar.c
#include "say.h"

void bar(void) {
    say("I am bar");
}

1 个答案:

答案 0 :(得分:2)

链接器通常具有一种模式,在该模式下,它们执行部分链接,该链接解析当前可以解析的引用,并生成准备好进一步链接的对象模块,而不是已完成的可执行文件。

例如,GCC链接器ld有一个-r开关允许这样做。使用此开关以及可能的其他人,您可以将foo.o与一个库关联以生成foo.partial.o,并将bar.o与另一个库单独链接以生成bar.partial.o。然后,您可以将foo.partial.obar.partial.o相互链接,主程序以及所需的任何其他库和对象模块。

这适用于静态库,其中每个库的代码都包含在生成的可执行文件或目标文件中,并且完全解析了对其符号的引用。对于共享动态库,可能存在问题,因为动态库需要在运行时解析引用,并且链接器和可执行文件格式可能支持也可能不支持在一个库的不同版本中区分同名符号的功能。