使用来自PGI的main.cpp
编译的我的C ++项目pgcpp
在一个单独的文件cuda()
中调用包含CUDA代码的函数cuda.cu
,并使用nvcc
编译。除非我在函数声明和公共头文件中用cuda()
包装extern "C"
函数,否则我会得到链接错误(未定义的引用)。
没有extern "C"
(符号名称不匹配=>未定义的引用):
$ nm main.o | grep -y cuda
U cuda__FPfPiT2iN32
$ nm cuda.o | grep -y cuda
T _Z13cudaPfPiS0_iS0_S0_S0_
使用extern "C"
(符号名称匹配=>链接工作正常):
$ nm main.o | grep -y cuda
U cuda
$ nm cuda.o | grep -y cuda
T cuda
我的印象是nvcc
使用主机C ++编译器作为主机代码,因此它会像C ++一样破坏符号名称?那我做错了什么?
编辑:这可能是因为nvcc
实际上使用GNU编译器gcc
作为主机代码,而且这个编译器的名称与pgcpp
不同吗?
EDIT2:我的系统有pgcpp 14.9,gcc 4.4.7,nvcc / CUDA 6.5
答案 0 :(得分:2)
nvcc
使用(在linux上)主机gcc / g ++(gnu)工具链。
PGI为编译C ++代码提供了两个稍微不同的工具链。使用pgcpp
工具调用一个工具链。此工具链不 gnu兼容,并且不一定会产生与gnu兼容的名称修改。使用pgc++
工具调用另一个工具链,并将其公布为gnu兼容,并且应该生成与gnu兼容的名称修改。
应使用nvcc
工具解决pgc++
和PGI工具生成的对象之间的此类问题的链接。
另外,使用CUDA 7,现在可以使用PGI编译器(pgc++
)作为nvcc
的主机编译器。然而,这不是问题的症结所在,尽管切换到主机编译器会以类似的方式解决链接问题。
在PGI users guide的当前版本(例如第xv页)和PGI 2015 release notes中引用了pgcpp
和pgc++
之间的差异:
PGI 2015特色与表现
•PGI C ++编译器
◦PGC++(pgc ++)现在是Linux和OS X的默认设置。功能包括支持g ++版本4.2-4.8的GNU兼容名称修改和语言功能。
...
◦pgc++现在也支持Linux上的NVCC主机编译器
请注意pgc++
现在(2015年)被认为是"默认" pgcpp
列为"已弃用。"