函数在.cu中声明的.h中定义

时间:2017-12-17 16:31:32

标签: c++ reference cuda undefined

我将项目拆分为三个文件夹:src,include,obj 我正在使用CImg.h和cuda.h库。 我在convolve.h中声明void convolve(cimg_library::CImg<float>&, cimg_library::CImg<float> const &); 并在convolve.cu中定义它。

我的档案:

main.cpp:

#include "CImg.h"
#include "../include/convolve.h" 
using namespace cimg_library;

int main(){
CImg<float> var1("/*path*/");
CImg<float> var2("/*path2*/");
convolve(var1,var2);
//some code
}

convolve.h:

  1 #ifndef CONVOLVE_H
  2 #define CONVOLVE_H
  //some define
  10 void convolve(cimg_library::CImg<float>&, cimg_library::CImg<float> const &);
  11 #endif //CONVOLVE_H

convolve.cu:

1 void convolve(CImg<float>& img, const CImg<float>& kernel){
//some code
24     kernel<<<dimGrid,dimBlocks>>>(/*some arg*/);
}

和我的新makefile:

1 CC=nvcc
2 CX=g++
3 IDIR =../include
4 special_IDIR = /usr/local/cuda-9.0/include
5 LDIR = /usr/local/cuda-9.0/lib64
6 CFLAGS=-I$(special_IDIR) -L$(LDIR)
7 
8 LIBS = -lX11 -lpthread -lcudart
9 ODIR = ../obj
10 
11 
12 _DEPS = convolve.h kernel.cuh
13 DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
14 
15 _OBJ = main.o convolve.o kernel.o
16 OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
17 
18 $(ODIR)/%.o: %.cpp $(DEPS)
19         $(CX) -x c++ -o $@ $< $(CFLAGS) $(LIBS)
20 
21 $(ODIR)/%.o: %.cu $(DEPS)
22         $(CC) -cu -o $@ $< $(CFLAGS)
23 
24 all: $(OBJ)
25         $(CC) -o $@ $^ $(CFLAGS) 
26 
27 
28 .PHONY: clean
29 
30 clean:
31         rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 

以下是我的问题:它表示对void convolve(cimg_library::CImg<float>&, cimg_library::CImg<float> const &)的引用未定义。

我认为这是因为我从未明确地告诉编译器卷积的定义是在convolve.cu中。但是我没有找到如何正确地建立这个链接。

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

  1. 请不要使用行号发布代码(或Makefile内容)。它通常会妨碍它。
  2. 此处的编译过程遵循编译...链接过程。第一阶段是编译阶段,您应该在此阶段对-cg++使用nvcc(即两种类型的Makefile目标)
  3. nvcc没有-cu选项。我想也许你的意思是-x cu
  4. 我还删除了函数调用中的&符号。

    以下是基于您展示的内容的简化示例,主要删除了CImg内容以及其他一些不必要的内容:

    $ cat main.cpp
    #include "convolve.h"
    
    int main(){
    
    int var1 = 0;
    int var2 = 1;
    convolve(var1, var2);
    }
    $ cat convolve.h
    void convolve(int &, int &);
    $ cat convolve.cu
    #include "convolve.h"
    
    __global__ void kernel(){};
    
    void convolve(int & i1, int & i2){
    
    kernel<<<1,1>>>();
    }
    $ cat Makefile
    CC=nvcc
    CX=g++
    IDIR = .
    special_IDIR = /usr/local/cuda-9.1/include
    LDIR = /usr/local/cuda-9.1/lib64
    CFLAGS=-I$(special_IDIR) -L$(LDIR)
    LIBS =
    ODIR = .
    _DEPS = convolve.h
    DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
    _OBJ = main.o convolve.o
    OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
    $(ODIR)/%.o: %.cu $(DEPS)
            $(CC) -c -x cu -o $@ $< $(CFLAGS)
    $(ODIR)/%.o: %.cpp $(DEPS)
            $(CX) -c -x c++ -o $@ $< $(CFLAGS) $(LIBS)
    all: $(OBJ)
            $(CC) -o $@ $^ $(CFLAGS)
    .PHONY: clean
    clean:
            rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
    $ make clean
    rm -f ./*.o *~ core /*~
    $ make
    g++ -c -x c++ -o main.o main.cpp -I/usr/local/cuda-9.1/include -L/usr/local/cuda-9.1/lib64
    nvcc -c -x cu -o convolve.o convolve.cu -I/usr/local/cuda-9.1/include -L/usr/local/cuda-9.1/lib64
    nvcc -o all main.o convolve.o -I/usr/local/cuda-9.1/include -L/usr/local/cuda-9.1/lib64
    $
    
    如果您的设置中有CUDA 9.0,则

    将上述Makefile中的cuda-9.1的实例更改为cuda-9.0。但是,编译命令并不真正需要链接器libs(-L)。当我们在此处与nvcc进行关联时,也无需通过引用CUDA包含的-I-L开关以及属于此类的CUDA库工具包。 nvcc已经知道如何找到这些。

    Makefile可能会有任意数量的建议或调整,例如-x cu-x c++开关可能是不必要的(至少它们对于我的简化示例来说是不必要的)但我的目标在这里不是要创建完美的Makefile,而是为您提供一个路线图来解决您目前正在目睹的问题。

相关问题