c++ 和 OpenMP:对 GOMP_loop_dynamic_start 的未定义引用

c++ & OpenMP : undefined reference to GOMP_loop_dynamic_start

我遇到了以下问题:起初我编译了以下文件 cancme.cpp :

void funct()
{
int i,j,k,N;
double s;
#pragma omp parallel for default(none) schedule(dynamic,10) private(i,k,s) shared(j,N)
for(i=j+1;i<N;i++) {}
}

作者:

mingw32-g++.exe -O3 -std=c++11 -mavx -fopenmp -c C:\pathtofile\cancme.cpp -o C:\pathtofile\cancme.o

接下来我构建第二个文件,test.cpp 简单地 link cancme.o 与 :

int main()
{
return(0);
}

作者:

mingw32-g++.exe -O3 -std=c++11 -mavx -fopenmp -c C:\pathtofile\test.cpp -o C:\pathtofile\test.o

当 link 使用 cancme.o 时,由 :

mingw32-g++.exe  -o C:\pathtofile\test.exe C:\pathtofile\test.o  -lgomp  C:\pathtofile\cancme.o

我收到以下错误消息:

C:\pathtofile\cancme.o:cancme.cpp:(.text+0x39): undefined reference to  `GOMP_loop_dynamic_start'
C:\pathtofile\cancme.o:cancme.cpp:(.text+0x49): undefined reference to `GOMP_loop_dynamic_next'
C:\pathtofile\cancme.o:cancme.cpp:(.text+0x52): undefined reference to `GOMP_loop_end_nowait'
C:\pathtofile\cancme.o:cancme.cpp:(.text+0x92): undefined reference to `GOMP_parallel_start'
C:\pathtofile\cancme.o:cancme.cpp:(.text+0x9f): undefined reference to   `GOMP_parallel_end'

有没有人知道那里出了什么问题??? OpenMP 库由 -lgomp 标志正确地 linked,但它好像没有被识别。

注意:我在 windows 7 64 位下使用 MingW 4.8.1 c++ 编译器:

谢谢

雷纳托

你编译命令有误:

mingw32-g++.exe  -o C:\pathtofile\test.exe C:\pathtofile\test.o  -lgomp  C:\pathtofile\cancme.o

如果您使用一些 makefile 生成器,例如 CMake,您不会收到任何链接错误。

不要像这样弄乱编译器参数:object_file_1 linker_flag_1 object_file_2.

正确的编译命令是这样的:

mingw32-g++.exe  -o C:\pathtofile\test.exe C:\pathtofile\test.o   C:\pathtofile\cancme.o -lgomp

GNU linker 是单一的 linker。这意味着它只解析它在到达定义相应符号的目标文件之前看到的符号。这意味着,如果目标文件 foo.o 引用库 libbar.a 中的符号,那么具有 ... foo.o -lbar ... 将导致成功 link,因为在 foo.o 中看到的未定义引用得到满足在处理 libbar.a 期间(只要 -lbar 之后列出的其他对象没有引用库中的符号)。相反,即 ... -lbar foo.o ... 将不起作用,因为一旦 linker 处理了 libbar.a,它将不再在尝试解析 foo.o 中的引用时搜索它。

在支持动态 link 库的 Unix 系统上(例如 Linux、FreeBSD、Solaris 等),通常情况并非如此,因为 -lbar 会首先查找库的动态版本,例如libbar.so,只有在找不到时才会尝试 link 对抗静态 libbar.a。当 link 使用动态库时,顺序无关紧要,因为未解析的引用稍后由运行时 link 编辑器处理。

在 Windows 上,针对动态 link 库 (DLL) 的 link 需要将所谓的导入库静态 link 编辑到可执行文件中。因此,即使外部依赖关系由运行时 linker 处理,仍然需要正确排序静态导入库。 libgomp.a 就是这样一个库。

请注意,此行为特定于属于 MinGW 的 GNU linker。 Microsoft linker 的行为不同:解析引用时,它首先搜索目标文件后面列出的库,然后搜索它前面列出的库。