【发布时间】:2021-07-03 22:37:27
【问题描述】:
在 Windows 上可以这样做(虽然不推荐,因为在不同的 c 库实例之间传递 c 标准库对象可能会出现问题),例如 this:
每个可执行映像(EXE 或 DLL)都可以有自己的静态链接 CRT,也可以动态链接到 CRT。特定图像中静态包含或动态加载的 CRT 版本取决于构建它的工具和库的版本。单个进程可以加载多个 EXE 和 DLL 映像,每个映像都有自己的 CRT
这可以在 Linux 上完成吗?
this 是否意味着错误?但是像Linux这样的通用系统应该没有这样的限制吧?例如,如果代码库 A 和代码库 B 确实需要不同版本的 libc 才能正常工作,并且假设它们都有非常简单的 C 风格 API 供客户端使用(即这些 API 中没有指针参数)怎么办?
如果不可能,则无需阅读以下内容。
作为实现这一目标的第一步,当我尝试使用静态链接 libc 构建共享库时:
g++ -fPIC -Wall -fexceptions -g -c main.cpp -o main.o
g++ -shared -static main.o -o libtestCppSharedLib.so
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginT.o: relocation R_X86_64_32 against hidden symbol `__TMC_END__' can not be used when making a shared object
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
【问题讨论】:
-
静态链接的库包含在生成的二进制文件中,因此两个静态链接到不同库的二进制文件没有问题。有趣的是(当您链接时)这样的静态链接库具有对动态库的引用。 AFAIK 此类引用包括动态库的版本号,以便满足所需的接口。 Linux 系统上可以存在多个版本的动态库。
-
@thebusybee 但是这里考虑的库是一个非常特殊的库:libc。 libc 与加载/初始化/系统调用过程有关系,所以 libc 的问题可能不是小事
-
当然,但是如果存在多个版本的 libc 并在特定系统上运行,为什么引用它们的应用程序不能运行?例如,如果应用程序引用了较新版本的 libc,而静态链接库引用了较旧版本的 libc?
-
我可以想到一些特殊情况,需要应用程序和静态链接库进行特定的系统调用序列,这可能不起作用,因为不同的引用版本的 libc 不兼容。在这种情况下,我认为您需要将应用程序动态链接到库引用的 libc。
-
请说明您为什么要这样做。这与所有常见的 Linux 做法背道而驰。阅读 Drepper 的论文How to write shared libraries
标签: c static-linking dynamic-linking libc crt