link 静态库到共享库(例如 openmp)是个好主意吗

Is it a good idea to link a static library to a shared library (for example openmp)

我正在 linux 系统上构建共享库,该系统旨在用于将部署在服务器上 Docker 中的项目。这个共享库使用 openmp。因此,我想知道

是否更好(或更便携)
  1. openmp 静态链接到我的共享库
  2. 我应该在 Docker 中正确安装 gcc 以便找到 openmp
  3. 将 openmp 的 .so 与我的库一起分发

如果选项 1 最好,有人可以提供使用 cmake 执行此操作的正确方法吗?

我在下面添加了一些关于该主题的文档:

您通常不能 link 将静态库转换为共享库。

因为静态库 (lib*.a) 不包含 position-independent code (PIC),但共享库需要 PIC(实际上)。

(理论上,非 PIC 共享库是可能的;但它们会在各种进程的不同地址包含如此多的 relocation that the "shared" aspect is lost and the dynamic linker would have a lot of work. So in practice, every shared library needs to be PIC to permit its code segment[s] to be mmap(2)-ed,并且仍然保持共享)

阅读 Drepper 的 How To Write Shared Libraries 论文。

但是,您可以 link 一个共享库(例如 libopenmp.so)到另一个共享库(您的共享库,参见 this)。然后使用您的共享库的程序将需要 libopenmp.so.

因此您可以执行 2 或 3,甚至将您的库打包为适当的 .deb 包(这将 依赖于 libopenmpi2 Debian 包) .

你可能想了解一下package management

你应该了解更多 virtual address space of your process. For that, use proc(5) and pmap(1). For first examples, try cat /proc/self/maps and cat /proc/$$/maps. Then, if your process has pid 1234, try cat /proc/1234/maps and/or pmap 1234. You'll then understand how shared libraries are mmap(2)-ed.

将 OpenMP 运行时静态链接到另一个共享库是一个坏主意,即使您可以实现它。如果最终代码的某些其他组件也使用 OpenMP,您将在此过程中得到两个不同的 OpenMP 运行时。当每个运行时创建自己的线程池并因此性能不佳时,这会迅速导致 over-subscription。 (如果您的代码假设 OpenMP 关键部分将保护它免受其他并行代码的影响,还有潜在的正确性失败...)

最简单的答案可能是您的第 3 个答案:随您的代码一起提供相关 OpenMP 运行时共享库​​的副本。