编辑:
我能够大大减少问题。只有三个文件,一个 .cpp、一个 .cu 和一个 heather,在尝试链接它们时出现与原始消息相同的错误。
示例文件的代码非常非常简单:
示例.cpp
#include "example.h"
extern "C" void launch_kernels();
void example::launch()
{
launch_kernels();
}
example_kernel.cu
#include <iostream>
__global__ void Find()
{}
extern "C" void launch_kernels() {
std::cout << "Hello\n" << std::endl;
}
示例.h
class example {
public:
void launch();
};
正在编译...
g++ -shared -fPIC -Wall -O3 -c example.cpp -o example.o
nvcc -shared -c -O3 example_kernel.cu -o example_kernel.o --expt-relaxed-constexpr --extended-lambda
我得到了两个 .o 文件,没有任何问题。但是,在最后一步:
nvcc -Xcompiler -fPIC -shared example_kernel.o example.o -o example.a
我收到致命的原始错误:
/usr/bin/ld: example_kernel.o: warning: relocation against `_ZNKSt5ctypeIcE8do_widenEc' in read-only section `.text'
/usr/bin/ld: example_kernel.o: relocation R_X86_64_PC32 against symbol `_Z4Findv' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
原文:
我有一个用C++编写的大型共享库,现在,我想将一部分代码传递给CUDA,情况是:
我有四个
.cpp
文件和一个 .cu
文件。我在一个 extern “C” void launch_kernels()
文件和 CUDA 文件中都有 .cpp
行,以便链接它们。.cu
文件可以使用 nvcc 毫无问题地编译为 .o
文件,与使用以下参数单独的 .cpp
文件相同:
g++ -std=c++14 -m64 -pthread -DWM_DP -DWM_LABEL_SIZE=32 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -Wno-attributes -Wno-unknown-pragmas -O3 -DNoRepository -ftemplate-depth-100 -fPIC -Wno-old-style-cast -Wno-unused-local-typedefs -Wno-array-bounds -Wno-deprecated-declarations -fpermissive -I/usr/include -fPIC -c file1.c -o file1.o
然后,我用这四个
.so
构建了一个共享库.o
,没有任何问题:
g++ -std=c++14 -m64 -pthread -DWM_DP -DWM_LABEL_SIZE=32 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -Wno-attributes -Wno-unknown-pragmas -O3 -DNoRepository -ftemplate-depth-100 -fPIC -Wno-old-style-cast -Wno-unused-local-typedefs -Wno-array-bounds -Wno-deprecated-declarations -fpermissive -I/usr/include -fPIC -shared -Xlinker --add-needed -Xlinker --no-as-needed file1.o file2.o file3.o file4.o -o finallib.so
问题出在最后一步,当我想将我的cuda文件与此
finallib.so
链接时。我尝试使用 nvcc:
nvcc --shared -Xcompiler -fPIC finallib.so filecuda.cu -o finallibcuda.so --expt-relaxed-constexpr --extended-lambda
我只得到一个非常小的文件,无法正常工作。然后我尝试使用 g++:
g++ -std=c++14 -m64 -pthread -DWM_DP -DWM_LABEL_SIZE=32 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -Wno-attributes -Wno-unknown-pragmas -O3 -DNoRepository -ftemplate-depth-100 -fPIC -Wno-old-style-cast -Wno-unused-local-typedefs -Wno-array-bounds -Wno-deprecated-declarations -fpermissive -fPIC -shared -Xlinker --add-needed -Xlinker --no-as-needed finallib.so filecuda.o -L/usr/local/cuda/lib64 -lcudart -o finallibcuda.so
我收到此错误:
/usr/bin/ld: filecuda.o: warning: relocation against _Z4Findv' in read-only section .text.startup’ /usr/bin/ld: filecuda.o: relocation R_X86_64_PC32 against symbol `_Z4Findv’ can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
我还尝试在创建最终的
.o
文件之前链接 .cu
和 .so
,并且此链接很好,但是当我尝试创建最终的 .so
时,我遇到了相同的错误。
有什么想法吗?
这个命令:
nvcc -shared -c -O3 example_kernel.cu -o example_kernel.o --expt-relaxed-constexpr --extended-lambda
是否不将
-fPIC
传递给编译器。它还传递无用的 -shared
标志(仅在链接期间使用,但此处没有发生链接)。
正确的命令应该类似于:
nvcc -Xcompiler -fPIC -c -O3 example_kernel.cu -o example_kernel.o --expt-relaxed-constexpr --extended-lambda