link 静态库到共享库(例如 openmp)是个好主意吗
Is it a good idea to link a static library to a shared library (for example openmp)
我正在 linux 系统上构建共享库,该系统旨在用于将部署在服务器上 Docker 中的项目。这个共享库使用 openmp。因此,我想知道
是否更好(或更便携)
- openmp 静态链接到我的共享库
- 我应该在 Docker 中正确安装 gcc 以便找到 openmp
- 将 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 运行时共享库的副本。
我正在 linux 系统上构建共享库,该系统旨在用于将部署在服务器上 Docker 中的项目。这个共享库使用 openmp。因此,我想知道
是否更好(或更便携)- openmp 静态链接到我的共享库
- 我应该在 Docker 中正确安装 gcc 以便找到 openmp
- 将 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 运行时共享库的副本。