如何将项目链接到同一C静态库的两个不同版本? [英] How to link a project to two different versions of the same C static library?

查看:83
本文介绍了如何将项目链接到同一C静态库的两个不同版本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on a complex C ecosystem where different packages/libraries are developed by different people.

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

I would like to create a new project named foobar. This project uses two libraries, the library foo and the library bar.

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

Unfortunately, bar does not require the same version that foo requires. Both use say so there is a conflict.

如果所有软件包都在带有子模块的Git上,则递归克隆时无法构建 foobar 项目,因为两个 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. So the submodule strategy doesn't work.

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

My question is: how is it possible to manage one project that uses two different version of the same static library (*.a)?

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

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

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.

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

foo

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

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

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

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

foobar

// 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.

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

For example, the GCC linker ld has a -r switch that allows this. 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. 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.

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

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.

这篇关于如何将项目链接到同一C静态库的两个不同版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆