我遇到了以下问题:首先我编译了以下文件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,只需将cancme.o链接到:
int main()
{
return(0);
}
by:
mingw32-g++.exe -O3 -std=c++11 -mavx -fopenmp -c C:\pathtofile\test.cpp -o C:\pathtofile\test.o
将其与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'
有没有人知道那里出了什么问题?
注意:我在Windows 7 64位下使用MingW 4.8.1 c ++编译器:
谢谢
雷纳托
答案 0 :(得分:4)
GNU链接器是单通道链接器。这意味着它只能解析它在到达定义相应符号的目标文件之前所看到的符号。这意味着,如果目标文件foo.o
引用库libbar.a
中的符号,则... foo.o -lbar ...
将导致成功链接,因为在foo.o
中看到的未定义引用在处理期间得到满足libbar.a
(只要在-lbar
之后没有列出其他对象引用库中的符号)。相反,即... -lbar foo.o ...
将不起作用,因为一旦链接器处理libbar.a
,它将在尝试解析foo.o
中的引用时不再搜索它。
在支持动态链接库的Unix系统(例如Linux,FreeBSD,Solaris等)上,情况往往并非如此,因为-lbar
将首先查找库的动态版本,例如: libbar.so
,只有在找不到时才会尝试链接静态libbar.a
。与动态库链接时,顺序无关紧要,因为运行时链接编辑器稍后会处理未解析的引用。
在Windows上,链接动态链接库(DLL)需要将所谓的导入库静态链接到可执行文件中。因此,即使外部依赖项由运行时链接程序处理,仍需要正确地对静态导入库进行排序。 libgomp.a
就是这样一个图书馆。
请注意,此行为特定于作为MinGW一部分的GNU链接器。 Microsoft链接器的行为有所不同:在解析引用时,它首先搜索目标文件之后列出的库,然后搜索之前列出的库。
答案 1 :(得分:1)
你在编译命令中犯了一个错误:
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