运行时库本身就是动态库吗?

时间:2015-11-03 15:01:31

标签: c openmp libraries

我正在为具有OpenMP并行化程序的系统进行交叉编译,但是当我在目标上运行时,我收到错误:

无法加载库' libgomp.so.1'

环顾四周后,我发现它是一个OpenMP运行时库。有没有在编译器主机上静态链接库,还是需要在目标机器上存在?如果它可以静态链接,那么是什么使运行时库与动态库不同?如果环境正确,可以静态或动态地链接任何库吗?

3 个答案:

答案 0 :(得分:1)

术语"运行时库"通常用于运行程序所需的标准库和环境。对于C程序,它是C标准库,可能是一些特定于编译器的库,以及一些链接到程序的目标文件,用于设置标准C环境。

A"运行时库" 可以是动态库,甚至是多个动态库的集合。但它也可以是一个或多个静态库。

答案 1 :(得分:1)

动态库是提供运行时库的便捷方式,因为许多程序可能希望链接到这样的库。这就是动态链接和动态库在那里的原因 - 第一个需要特定动态库的进程将导致它被加载到内存中。之后,这个动态库实例可以被许多进程重用。

想象一下,如果你有几十个进程正在运行,并且每个进程都与说{{1}}库静态链接。我假设与每个进程链接单个DLL的情况相比,内存消耗会显着增长。

在我看来,如果库将被许多不同的进程使用(例如DirectX可能是这样的库),那么将它作为动态库提供可能更有效。否则,最好使用静态链接。

答案 2 :(得分:1)

您可以通过提供某些链接器选项来选择性地静态链接某些库。对于libgomp,它将类似于:

gcc -o executable foo.o bar.o -Wl,-static -lgomp -Wl,-Bdynamic -lpthread -lother -llibs

-Wl,-static-Wl,-Bdynamic之间列出的所有库都将以静态方式链接。 -fopenmp不应出现在链接命令中,因为它扩展为在用户提供的选项后附加的链接器标志,因此应明确列出libpthread。这也意味着即使是简单的OpenMP程序也必须在两个单独的步骤中进行编译和链接,以便静态链接起作用。

示例:

// foo.c
#include <stdio.h>
#include <omp.h>

int main(void)
{
   #pragma omp parallel
   printf("Hello world from thread %d\n", omp_get_thread_num());
   return 0;
}

传统编译:

$ gcc -fopenmp -o foo foo.c
$ ldd foo
     linux-vdso.so.1 =>  (0x00007ffff5661000)
     libgomp.so.1 => /usr/lib64/libgomp.so.1 (0x0000003bcfa00000)
     libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003bc2600000)
     libc.so.6 => /lib64/libc.so.6 (0x0000003bc1e00000)
     librt.so.1 => /lib64/librt.so.1 (0x0000003bc3200000)
     /lib64/ld-linux-x86-64.so.2 (0x0000003bc1a00000)

该计划与libgomp的DSO版本相关联。

完全静态链接:

$ gcc -fopenmp -static -o foo foo.c
$ ldd foo
     not a dynamic executable

使用-static所有库都静态链接到可执行文件中。

仅静态链接libgomp

$ gcc -fopenmp -c foo.c
$ gcc -o foo foo.o -Wl,-static -lgomp -Wl,-Bdynamic -lpthread
$ ldd foo
     linux-vdso.so.1 =>  (0x00007ffdaaf61000)
     libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003bc2600000)
     libc.so.6 => /lib64/libc.so.6 (0x0000003bc1e00000)
     /lib64/ld-linux-x86-64.so.2 (0x0000003bc1a00000)

在这种情况下,保持静态链接对象的正确顺序非常重要。如果在foo.o之后放置-lgomp,则会出现链接错误:

$ gcc -o foo -Wl,-static -lgomp -Wl,-Bdynamic foo.o -lpthread
foo.o: In function `main':
foo.c:(.text+0x14): undefined reference to `GOMP_parallel_start'
foo.c:(.text+0x23): undefined reference to `GOMP_parallel_end'
foo.o: In function `main.omp_fn.0':
foo.c:(.text+0x3b): undefined reference to `omp_get_thread_num'
collect2: ld returned 1 exit status

包含OpenMP结构的源代码生成的任何目标文件都应放在 -lgomp之前