c++ - GCC/LD 仅针对直接依赖关系进行链接

标签 c++ linux g++ ld

我有一个场景,我有一个依赖于库 A 的二进制文件,而库 A 又依赖于库 B。

我已经针对库 B 构建了库 A,但是库 B:s 符号都没有从库 A 中泄漏,所有内容都包含在 cpp 文件中。

现在我只想将二进制文件链接到库 A,因为库 A 可以满足二进制文件中找到的所有符号。这可能吗?

在实际应用程序中,库 B 是网络协议(protocol)的实现,我有很多链接到中间库的二进制文件。而且我不希望二进制文件知道所使用的不同网络协议(protocol)。

平台:Linux/GCC

代码:

liba/liba.h:

#ifndef LIBA_H
#define LIBA_H

int getANumber();

#endif

liba/liba.cpp:

#include "liba.h"
#include "../libb/libb.h"

int getANumber(){ return getBNumber(); }

libb/libb.h:

#ifndef LIBB_H
#define LIBB_H

int getBNumber();

#endif

libb/libb.cpp:

#include "libb.h"

int getBNumber(){ return 42; }

main.cpp:

#include "liba/liba.h"
#include <iostream>

int main(int argc, char** argv) {
  std::cout << getANumber() << std::endl;
  return 0;
}

命令:

~/libb/ $ g++ -shared -o libb.so libb.cpp
~/liba/ $ g++ -shared -o liba.so liba.cpp -L../libb -lb

~/ $ g++ -o main main.cpp -Lliba -la # fails

~/ # These two work, but I don't want to specify libb here.
~/ $ g++ -o main main.cpp -Lliba -la -Wl,-rpath-link,libb 
~/ $ LD_LIBRARY_PATH=libb g++ -o main main.cpp -Lliba -la

解决这个问题的最佳方法是什么?我必须将其创建为插件吗?

最诚挚的问候, 丹尼尔

最佳答案

如果您想更改在运行时使用的库,那么您不能直接链接它,而是使用“手动”加载。换句话说,调用dlopendlsym

这可能也意味着您在“liba”中需要稍微不同的架构,因为“libb”中的每个函数都变成了函数指针,所以沿着这些思路:

int (*getBNumber)() = NULL;

void initialize()
{
   void *handle = dlopen("libb", RTLD_NOW); 
   getBNumber = (int (*)())dlsym(handle, "getBNumber"); 
}

int getANumber(){ return getBNumber(); }

您需要进行一些设置,以便在某个时刻调用初始化 - 或者在每个函数中都有一个 if (!initialized)initialize();

关于c++ - GCC/LD 仅针对直接依赖关系进行链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18076739/

相关文章:

c++ - 内存映射和排序文件后字节下落不明

c++ - 函数和数组

linux - 用于查找该目录中保留过去 7 天内创建的文件的空间有多少的命令。不使用 `find`

Cmake 不使用 add_compile_options 应用编译选项

c++ - 迁移到 Xcode,现在有很多 "is not member of std"和一些其他 header 问题

c++ - 如何迭代字符串 vector 的 vector ? (c++)

c++ - 从模板中使用的结构类型中查找类型(可能是底层的)

linux - Bash 将大文件拆分为较小的文件

c++ - volatile sig_atomic_t 的内存安全

c++ - 如何让 G++ 找到导入文件