运行库本身就是动态库吗?
Are runtime libraries inherently dynamic libraries?
我正在为一个带有 OpenMP 并行化程序的系统进行交叉编译,但是当我 运行 在目标上时,我得到错误:
无法加载库'libgomp.so.1'
环顾四周后,我发现它是一个 OpenMP 运行时间库。是否有任何静态 link 编译器主机上的库,或者它是否需要存在于目标机器上?如果可以静态 linked,那么 运行time 库与动态库有何不同?如果环境正确,是否可以静态或动态 link 任何库?
术语 "runtime library" 通常用于 运行 您的程序所需的标准库和环境。对于 C 程序,它是 C 标准库,可能还有一些其他特定于您的编译器的库,以及一些链接到您的程序以设置标准 C 环境的目标文件。
一个"runtime library"可以是一个动态库,甚至是多个动态库的集合。但也可以是一个或多个静态库。
Dynamic 库是提供 runtime 库的便捷方式,因为许多程序可能希望 link 反对这种图书馆。这就是动态 linking 和动态库在那里的原因 - 需要特定动态库的第一个进程将导致它被加载到内存中。以后这个动态库实例可以被很多进程复用
想象一下,如果您有数十个进程 运行,并且每个进程都静态地 link 反对说 C runtime
库。我认为与每个进程对单个 DLL link 的情况相比,内存消耗会显着增加。
在我看来,如果库将被许多不同的进程使用(例如 DirectX 可能是这样的库),那么将其作为动态库提供可能会更有效。否则,最好使用 static linking。
您可以通过提供某些 link 其他选项来选择性地静态 link 某些库。对于 libgomp
它将类似于:
gcc -o executable foo.o bar.o -Wl,-static -lgomp -Wl,-Bdynamic -lpthread -lother -llibs
-Wl,-static
和 -Wl,-Bdynamic
之间列出的任何库都将被静态 linked。 -fopenmp
不应出现在 linking 命令中,因为它扩展为 linker 标志,这些标志附加在用户提供的选项之后,因此 libpthread
应该明确列出。这也意味着即使是简单的 OpenMP 程序也必须在两个单独的步骤中编译和 linked 才能使静态 linking 工作。
示例:
// 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 版本link编辑的。
完全静态 linking:
$ gcc -fopenmp -static -o foo foo.c
$ ldd foo
not a dynamic executable
使用 -static
所有库都 link 静态地输入到可执行文件中。
仅 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)
在这种情况下,保持静态 linked 对象的正确顺序很重要。如果 foo.o
放在 -lgomp
之后,将导致 link 错误结果:
$ 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
.
我正在为一个带有 OpenMP 并行化程序的系统进行交叉编译,但是当我 运行 在目标上时,我得到错误:
无法加载库'libgomp.so.1'
环顾四周后,我发现它是一个 OpenMP 运行时间库。是否有任何静态 link 编译器主机上的库,或者它是否需要存在于目标机器上?如果可以静态 linked,那么 运行time 库与动态库有何不同?如果环境正确,是否可以静态或动态 link 任何库?
术语 "runtime library" 通常用于 运行 您的程序所需的标准库和环境。对于 C 程序,它是 C 标准库,可能还有一些其他特定于您的编译器的库,以及一些链接到您的程序以设置标准 C 环境的目标文件。
一个"runtime library"可以是一个动态库,甚至是多个动态库的集合。但也可以是一个或多个静态库。
Dynamic 库是提供 runtime 库的便捷方式,因为许多程序可能希望 link 反对这种图书馆。这就是动态 linking 和动态库在那里的原因 - 需要特定动态库的第一个进程将导致它被加载到内存中。以后这个动态库实例可以被很多进程复用
想象一下,如果您有数十个进程 运行,并且每个进程都静态地 link 反对说 C runtime
库。我认为与每个进程对单个 DLL link 的情况相比,内存消耗会显着增加。
在我看来,如果库将被许多不同的进程使用(例如 DirectX 可能是这样的库),那么将其作为动态库提供可能会更有效。否则,最好使用 static linking。
您可以通过提供某些 link 其他选项来选择性地静态 link 某些库。对于 libgomp
它将类似于:
gcc -o executable foo.o bar.o -Wl,-static -lgomp -Wl,-Bdynamic -lpthread -lother -llibs
-Wl,-static
和 -Wl,-Bdynamic
之间列出的任何库都将被静态 linked。 -fopenmp
不应出现在 linking 命令中,因为它扩展为 linker 标志,这些标志附加在用户提供的选项之后,因此 libpthread
应该明确列出。这也意味着即使是简单的 OpenMP 程序也必须在两个单独的步骤中编译和 linked 才能使静态 linking 工作。
示例:
// 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 版本link编辑的。
完全静态 linking:
$ gcc -fopenmp -static -o foo foo.c
$ ldd foo
not a dynamic executable
使用 -static
所有库都 link 静态地输入到可执行文件中。
仅 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)
在这种情况下,保持静态 linked 对象的正确顺序很重要。如果 foo.o
放在 -lgomp
之后,将导致 link 错误结果:
$ 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
.