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

now*_*wox 2 c linker package static-libraries

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

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

不幸的是,bar不需要与foo需要的版本相同的版本。两者都使用say所以有冲突。

如果所有包都位于带有子模块的 Git 上,则foobar递归克隆时无法构建项目,因为两个say函数存在于不同的翻译单元中。所以这个submodule策略行不通。

我的问题是:如何管理一个使用同一静态库()的两个不同版本的项目?*.a

结构

          foobar
            |
       .----'----.           <---- (require)
       v         v
      foo       bar
(v1.0) |         | (v2.0)
       '-> say <-' 
Run Code Online (Sandbox Code Playgroud)

项目 foobar 需要 库foo和 库bar,这两个库都使用say包:foo需要版本 1 和bar需要版本 2。

套餐

// say.h
void say(char *);
Run Code Online (Sandbox Code Playgroud)

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

void foo(void) {
    say("I am foo");
}
Run Code Online (Sandbox Code Playgroud)

酒吧

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

void bar(void) {
    say("I am bar");
}
Run Code Online (Sandbox Code Playgroud)

富巴

// main.c
#include <stdlib.h>
#include "foo"
#include "bar"

int main() {
    foo();
    bar();
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*hil 5

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

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

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