使用 nvcc 编译依赖的 .c 和 .cu 文件
Compiling dependent .c and .cu files with nvcc
我希望将一些用常规旧 C 语言编写的主机辅助函数包含在 .cu 文件中,该文件运行一些主机代码并定义和调用内核函数。我对 makefile 一无所知,对一般的多文件项目也没有很好的感觉,并且无法理解为什么以下内容适用于 .c 扩展名但无法使用 .cu 扩展名。
A.h
void sayhello();
A.c:
#include "A.h"
#include <stdio.h>
void sayhello() {
printf("Hello from A\n");
}
B.c:
#include "A.h"
int main(int argc, char * argv) {
sayhello();
return 0;
}
B.cu
#include "A.h"
int main(int argc, char * argv[]) {
sayhello();
return 0;
}
当我编译 A.c 时一切正常:
$ nvcc -arch compute_30 -code sm_30 -o test B.c A.c
$ ./test
Hello from A
但是当试图编译 B.cu 链接器找不到 sayhello()
$ nvcc -o test B.cu A.c
/tmp/tmpxft_000017bb_00000000-16_B.o: In function 'main':
tmpxft_000017bb_00000000-4_B.cudafe1.cpp:(.text+0x26): undefined reference to 'sayhello()'
collect2: error: ld returned 1 exit status
为什么找不到sayhello(),这些编译有什么区别,有没有办法编译这种结构的代码?
您需要在 sayhello 函数上使用 __host__ __device__
修饰。
此外,在 A.h
中包含 cuda_runtime.h
CUDA 使用 C++ 编译器编译 .cu
文件。因此,它期望 .cu
文件中引用的所有函数都具有 C++ 链接,除非另有明确说明。在您的情况下,您必须明确指示 C++ 编译器。
您应该发现像这样修改您的代码:
extern "C" {
#include "A.h"
}
int main(int argc, char * argv[]) {
sayhello();
return 0;
}
将解决问题,因为它会指示编译器期望 C 函数的 C 链接,而不是 C++ 链接。
我希望将一些用常规旧 C 语言编写的主机辅助函数包含在 .cu 文件中,该文件运行一些主机代码并定义和调用内核函数。我对 makefile 一无所知,对一般的多文件项目也没有很好的感觉,并且无法理解为什么以下内容适用于 .c 扩展名但无法使用 .cu 扩展名。
A.h
void sayhello();
A.c:
#include "A.h"
#include <stdio.h>
void sayhello() {
printf("Hello from A\n");
}
B.c:
#include "A.h"
int main(int argc, char * argv) {
sayhello();
return 0;
}
B.cu
#include "A.h"
int main(int argc, char * argv[]) {
sayhello();
return 0;
}
当我编译 A.c 时一切正常:
$ nvcc -arch compute_30 -code sm_30 -o test B.c A.c
$ ./test
Hello from A
但是当试图编译 B.cu 链接器找不到 sayhello()
$ nvcc -o test B.cu A.c
/tmp/tmpxft_000017bb_00000000-16_B.o: In function 'main':
tmpxft_000017bb_00000000-4_B.cudafe1.cpp:(.text+0x26): undefined reference to 'sayhello()'
collect2: error: ld returned 1 exit status
为什么找不到sayhello(),这些编译有什么区别,有没有办法编译这种结构的代码?
您需要在 sayhello 函数上使用 __host__ __device__
修饰。
此外,在 A.h
中包含 cuda_runtime.hCUDA 使用 C++ 编译器编译 .cu
文件。因此,它期望 .cu
文件中引用的所有函数都具有 C++ 链接,除非另有明确说明。在您的情况下,您必须明确指示 C++ 编译器。
您应该发现像这样修改您的代码:
extern "C" {
#include "A.h"
}
int main(int argc, char * argv[]) {
sayhello();
return 0;
}
将解决问题,因为它会指示编译器期望 C 函数的 C 链接,而不是 C++ 链接。