具有多个 .h 和 .cu 文件的静态库无法解析函数

Static library with multiple .h and .cu files can't resolve functions

提问人:Sean 提问时间:11/30/2012 最后编辑:Sean 更新时间:11/30/2012 访问量:2669

问:

当使用 multiple.h 和 .cu 文件编译静态库时,我得到一个未解析的 extern 函数。下面是一个复制错误的简短示例。

看来我无法先让 Nsight Eclipse Edition 编译 extrafunctions.cu。在我的完整项目中,首先编译了具有额外函数的文件,但它仍然抛出无法解决外部函数错误。

下面是此示例的输出:Here's the output for this sample:

**** Build of configuration Debug for project linkerror ****

make all 
Building file: ../cudatest.cu
Invoking: NVCC Compiler
nvcc -I/usr/local/cuda/include -G -g -O0 -gencode arch=compute_30,code=sm_30 -odir "" -M -o "cudatest.d" "../cudatest.cu"
nvcc --compile -G -I/usr/local/cuda/include -O0 -g -gencode arch=compute_30,code=compute_30 -gencode arch=compute_30,code=sm_30  -x cu -o  "cudatest.o" "../cudatest.cu"
../cudatest.cu(19): warning: variable "devInts" is used before its value is set

../cudatest.cu(19): warning: variable "devInts" is used before its value is set

ptxas fatal   : Unresolved extern function '_Z9incrementi'
make: *** [cudatest.o] Error 255

**** Build Finished ****

cudatest.h:

#ifndef CUDAPATH_H_
#define CUDAPATH_H_

#include <cuda.h>
#include <cuda_runtime.h>
#include "extrafunctions.h"

void test();


#endif /* CUDAPATH_H_ */

cudatest.cu:

#include <cuda.h>
#include <cuda_runtime.h>
#include "extrafunctions.h"

__global__ void kernel(int* devInts){
    int tid = threadIdx.x + (blockDim.x*blockIdx.x);

    if (tid == 0){
        for(int i = 0; i < NUMINTS; i++){
            devInts[i] = increment(devInts[i]);
        }
    }
}

void test(){

    int* myInts = (int*)malloc(NUMINTS * sizeof(int));
    int* devInts;
    cudaMemcpy((void**)devInts, myInts, NUMINTS*sizeof(int), cudaMemcpyHostToDevice);
    kernel<<<1,1>>>(devInts);
    int* outInts = (int*)malloc(NUMINTS * sizeof(int));
    cudaFree(devInts);
    free(myInts);
    free(outInts);
}

extrafunctions.h:

#ifndef EXTRAFUNCTIONS_H_
#define EXTRAFUNCTIONS_H_

#include <cuda.h>
#include <cuda_runtime.h>

#define NUMINTS 4

int __device__ increment(int i);

#endif /* EXTRAFUNCTIONS_H_ */

extrafunctions.cu:

#include <cuda.h>
#include <cuda_runtime.h>
#include "extrafunctions.h"


int __device__ increment(int i){
    return i+1;
}
C++ CUDA 静态库 头文件 unresolved-external

评论

1赞 Robert Crovella 11/30/2012
如果你能创建一个简单的复制器,那会有所帮助。这可能是 c/c++ 链接问题。无论如何,对我来说,你的帖子中没有足够的信息来猜测发生了什么。即使您发布了编译命令行,它可能会有所帮助。
0赞 Sean 11/30/2012
@RobertCrovella,我重新编写了它,以包含一个复制问题和编译命令行和输出的简短示例。
1赞 Robert Crovella 11/30/2012
不知何故,我们需要让 nsight EE 发出此命令,而不是您发布的第二个编译命令:这个项目究竟是如何在 nsight EE 中设置的?您指定了什么类型的项目?--compile 开关告诉编译器生成不可重定位的设备代码,这些代码必须修复其所有链接点。-dc 创建可重定位(基本上是未链接的)代码。nvcc -dc -G -I/usr/local/cuda/include -O0 -g -gencode arch=compute_30,code=compute_30 -gencode arch=compute_30,code=sm_30 -x cu -o "cudatest.o" "../cudatest.cu"
0赞 Sean 11/30/2012
@RobertCrovella 没有通过项目属性中的复选框启用设备编译 (-dc) 的选项,但我将命令行模式编辑为 ${COMMAND} -dc ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX} ${OUTPUT} ${INPUTS},它同时获取示例和我的原始项目进行编译。
0赞 Sean 11/30/2012
但是我现在无法编译使用该库的 g++ 链接项目。我收到错误“undefined reference to '__cudaRegisterLinkedBinary_43...'。我的库包含顺序是 -lm、-lcudapath、-lcuda -lcudart -lbz2(-lcudapath 是我的静态库)

答:

5赞 Eugene 11/30/2012 #1

您需要显式启用单独的编译才能正常工作。右键单击您的项目,“属性”,Build->CUDA,然后选择“单独编译”链接器模式。

请注意,单独编译仅适用于 SM 2.0+ GPU,并且只能发出 SASS(例如,无法发出与未来 CUDA 设备兼容的 PTX)。有关更多信息,请阅读NVCC手册中的“在CUDA中使用单独编译”。

更新您需要使用 NVCC 链接器来链接设备代码,这就是 GCC 链接器失败的原因。在Nsight中,您可以使用NVCC链接整个应用程序,也可以设置一个包含所有CUDA代码并使用NVCC收费链构建的静态库项目,以及使用GCC并与第一个项目生成的静态库链接的常规C / C++项目。