【发布时间】:2015-03-02 07:57:40
【问题描述】:
我的 C++ 项目 main.cpp,使用来自 PGI 的 pgcpp 编译,调用了一个函数 cuda(),该函数在单独的文件 cuda.cu 中包含 CUDA 代码,使用 nvcc 编译。除非我在函数声明和公共头文件中用extern "C" 包装cuda() 函数,否则会出现链接错误(未定义的引用)。
没有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
【问题讨论】:
-
nvcc 在 CUDA 6.5 及之前版本将使用主机 gnu 编译器。 PGI 工具同时具有 PGI“本机”工具链和 PGI gnu 兼容工具链。您可以切换到与 PGI gnu 兼容的工具链(即使用
pgc++而不是pgcpp),或者您可以切换到可以使用 PGI 工具链作为主机编译器的 CUDA 7。您可能想研究PGI documentation。 -
确实这是我的第一反应。 PGI 用户指南没有指出
pgc++和pgcpp之间的任何区别。在使用pgc++而不是pgcpp编译纯C++ 代码时,符号名称确实被同样地损坏了。谢谢! -
关于此声明:“PGI 用户指南并未指出 pgc++ 和 pgcpp 之间有任何区别”,请尝试查看 PGI user guide 的页面 xv。
-
你是对的。我收到了 2014 版的用户指南。
标签: c++ cuda nvcc name-mangling pgi