简体   繁体   English

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

[英]How to link a project to two different versions of the same C static library?

I am working on a complex C ecosystem where different packages/libraries are developed by different people. 我正在一个复杂的C生态系统中,由不同的人开发不同的包/库。

I would like to create a new project named foobar . 我想创建一个名为foobar的新项目。 This project uses two libraries, the library foo and the library bar . 该项目使用两个库,库foo和库bar

Unfortunately, bar does not require the same version that foo requires. 不幸的是, bar不需要与foo所需的版本相同。 Both use say so there is a conflict. 两者say所以存在冲突。

If all the packages are on Git with submodules, the foobar project cannot be built when cloned recursively because two say functions exist in different translation units. 如果所有软件包都在带有子模块的Git上,则在递归克隆时无法构建foobar项目,因为在不同的翻译单元中存在两个say函数。 So the submodule strategy doesn't work. 因此, submodule策略不起作用。

My question is: how is it possible to manage one project that uses two different version of the same static library ( *.a )? 我的问题是:如何管理一个使用同一静态库( *.a )的两个不同版本的项目?

Structure 结构体

          foobar
            |
       .----'----.           <---- (require)
       v         v
      foo       bar
(v1.0) |         | (v2.0)
       '-> say <-' 

The project foobar require the library foo and the library bar , both of these libraries uses the say package: foo requires version 1 and bar requires version 2. 项目foobar需要库foo和库bar ,这两个库都使用say包: foo需要版本1, bar需要版本2。

Packages 配套

say

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

foo

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

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

bar 酒吧

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

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

foobar foob​​ar

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

int main() {
    foo();
    bar();
    return EXIT_SUCCESS;
}

Linkers typically have a mode in which they perform a partial link, which resolves references that can be currently resolved and produces an object module ready for further linking instead of a finished executable file. 链接器通常具有执行部分链接的模式,该模式可以解析当前可以解析的引用,并生成准备用于进一步链接的对象模块,而不是已完成的可执行文件。

For example, the GCC linker ld has a -r switch that allows this. 例如,GCC链接程序ld具有允许该操作的-r开关。 Using this switch, and possibly others, you could link foo.o with one library to make foo.partial.o and separately link bar.o with another library to make bar.partial.o . 使用此开关(可能还有其他开关),可以将foo.o与一个库链接成foo.partial.o并分别将bar.o与另一个库链接成bar.partial.o Then you could link foo.partial.o and bar.partial.o with each other, the main program, and any other libraries and object modules needed. 然后,您可以将foo.partial.obar.partial.o相互链接,链接foo.partial.o以及bar.partial.o任何其他库和对象模块。

This can work for static libraries, where the code for each library is included in the resulting executable or object file, and the references to its symbols are fully resolved. 这可以用于静态库,其中每个库的代码都包含在生成的可执行文件或目标文件中,并且对其符号的引用已完全解析。 For shared dynamic libraries, there may be problems, since dynamic libraries require references to be resolved at run time, and the linker and executable file format might or might not support the ability to distinguish symbols of the same name in different versions of one library. 对于共享动态库,可能会出现问题,因为动态库需要在运行时解析引用,并且链接器和可执行文件格式可能支持也可能不支持在一个库的不同版本中区分相同名称的符号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM