cuda/c++的Makefile无法成功编译 我花了相当多的时间尝试编写一个Mag文件来编译一些C++文件以及一些Cu文件。我无法成功编译目标,而我目前确实获得了一个输出,它不是一个正确的二进制文件

cuda/c++的Makefile无法成功编译 我花了相当多的时间尝试编写一个Mag文件来编译一些C++文件以及一些Cu文件。我无法成功编译目标,而我目前确实获得了一个输出,它不是一个正确的二进制文件,c++,makefile,compilation,cuda,C++,Makefile,Compilation,Cuda,所以,基本上我所有的源文件都在一个src目录中,我的makefile在主项目文件夹中,src上的一个目录。我有一个main.cpp、一个hostDeviceCom.cu、一个myKernel.cu和一个cudaErrorCheck.cu,这是我在上一个项目中用nvcc一步手工编译过的。其概念是在.out所在的位置有一个单独的构建文件夹 所以我的问题是:我在下面的makefile中做错了什么 TARGET_EXEC ?= cudaNestim.out T_CUDA_O ?= cudaTMp.

所以,基本上我所有的源文件都在一个src目录中,我的makefile在主项目文件夹中,src上的一个目录。我有一个main.cpp、一个hostDeviceCom.cu、一个myKernel.cu和一个cudaErrorCheck.cu,这是我在上一个项目中用nvcc一步手工编译过的。其概念是在.out所在的位置有一个单独的构建文件夹

所以我的问题是:我在下面的makefile中做错了什么

TARGET_EXEC ?= cudaNestim.out
T_CUDA_O    ?= cudaTMp.o
NVCC        ?= nvcc
BUILD_DIR   ?= ./build
SRC_DIRS    ?= ./src
CUDA_ARCH   ?= -arch=sm_52
NVCCFLAGS   ?= $(CUDA_ARCH) 
NVCCFLNK    ?= $(CUDA_ARCH) --device-link
CXXFLAGS    ?= --std=c++11 -MM -MT
CXXOPTS     ?= -MM -MT
# System Libraries -------------------------------------------------------------------------------
OCV_DIR     ?= -L/user/local/lib
OCV_LIB     ?= -lopencv_core -lopencv_viz -lopencv_highgui -lopencv_features2d -lopencv_imgproc
OCV_INC     ?= -I/usr/include
OCV_LINK    ?= $(OCV_DIR) $(OCV_LIB)

CUDA_DIR    ?= -L/user/local/cuda-8.0/lib64
CUDA_LIB    ?= -lcutil -lcudpp -lcuda -lcudart 
CUDA_INC    ?= -I/usr/local/cuda-8.0/include
CUDA_LINK   ?= $(CUDA_DIR) $(CUDA_LIB)
#--------------------------------------------------------------------------------------------------

# find all the source files
SRCS := $(shell find $(SRC_DIRS) -name *.cu -or -name *.cpp -or -name *.c -or -name *.s) 
#go to build directory and create a .o file for each src file found
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)
# create a .d file from each .o file. SO one .d for each .source
DEPS := $(OBJS:.o=.d)


LIB_DIRS := $(OCV_LINK) $(CUDA_LINK)
INCS     := $(CUDA_INC) $(OCV_INC)

$(BUILD_DIR)/$(TARGET_EXEC): $(OBJS) 
    $(NVCC) $(NVCCFLNK) $(OBJS) $(LIB_DIRS)  -o $@ 

$(BUILD_DIR)/%.cu.o: %.cu
    $(MKDIR_P) $(dir $@)
    $(NVCC) $(NVCCFLAGS) -o $@ -c $< 

    #echo ".cu.o rule:" $(NVCCFLAGS) -o $@ -c $< $(OCV_INC) $(CUDA_INC)
    #$(NVCC) $(NVCCFLAGS) -o $@ -c $< $(OCV_INC) $(CUDA_INC)

$(BUILD_DIR)/%.cpp.o: %.cpp
    $(MKDIR_P) $(dir $@)
    $(CXX) $(CXXFLAGS) $(INCS) -o $@ -c $< 

# Phony rules -------------------------------------------------------------------------------

.PHONY: clean
clean:
    $(RM) -r $(BUILD_DIR)

MKDIR_P ?= mkdir -p

-include $(DEPS)

我知道,我没有使用任何.d规则,我正在努力使这一点起作用,并在以后找出如何将.d规则用于更复杂的内容。

与其说是直接的回答,不如说是一个建议:

你做错的是试图重新发明轮子。使用更高级别的构建系统,不要麻烦自己编写Makefile。这里有不止一个这样的地方;我个人使用它,并对它感到满意。CMake有一个模块,用于为CUDA设置内容路径和其他变量。以下是您可以查看的简短教程:

现在,并不是说你永远不会遇到任何问题,而是:

他们会少一些 他们可能更容易调试,看看这里的一些。 它不是一个正确的二进制文件

原因是您将设备链接指定为最终生成ie链接阶段操作:

NVCCFLNK    ?= $(CUDA_ARCH) --device-link
                              ^^^^^^^^^^^
...

$(BUILD_DIR)/$(TARGET_EXEC): $(OBJS) 
    $(NVCC) $(NVCCFLNK) $(OBJS) $(LIB_DIRS)  -o $@ 
              ^^^^^^^^
因此,您执行的最后一个构建步骤是一个设备链接,它是。您的Makefile通常也没有正确设置设备链接,因为在将编译与链接分离时,如果您想要设备链接,即生成,则必须在编译期间指定-dc,而不是-c:

$(BUILD_DIR)/%.cu.o: %.cu
    $(MKDIR_P) $(dir $@)
    $(NVCC) $(NVCCFLAGS) -o $@ -c $< 
                               ^^

注意,如果您实际上不想生成RDC代码,可以在上面的Makefile中将-dc改回-c。但是,出于演示目的,我的特定代码示例取决于CUDA RDC。

发布shell中显示的最终链接命令。详细说明它不是一个合适的二进制文件。另外,当您尝试分两步构建二进制文件时会发生什么情况?首先是对象,然后是cudaNestim.out,不使用Make?要解释JWZ,请改用CMake。现在您有两个问题。@Talonmes:CMake将为OP自动发现CUDA相关路径。因此,不,现在OP将有0或1个问题。
$ cat Makefile
TARGET_EXEC ?= cudaNestim.out
NVCC        ?= nvcc
BUILD_DIR   ?= ./bld
SRC_DIRS    ?= ./src
CUDA_ARCH   ?= -arch=sm_61
NVCCFLAGS   ?= $(CUDA_ARCH)
#NVCCFLNK    ?= $(CUDA_ARCH) --device-link
NVCCFLNK    ?= $(CUDA_ARCH)
CXXFLAGS    ?= --std=c++11 -MM -MT
CXXOPTS     ?= -MM -MT
# System Libraries -------------------------------------------------------------------------------
OCV_DIR     ?= -L/user/local/lib
#OCV_LIB     ?= -lopencv_core -lopencv_viz -lopencv_highgui -lopencv_features2d -lopencv_imgproc
OCV_LIB     ?=
OCV_INC     ?= -I/usr/include
OCV_LINK    ?= $(OCV_DIR) $(OCV_LIB)

CUDA_DIR    ?= -L/usr/local/cuda-8.0/lib64
#CUDA_LIB    ?= -lcutil -lcudpp -lcuda -lcudart
CUDA_LIB    ?= -lcuda -lcudart
CUDA_INC    ?= -I/usr/local/cuda-8.0/include
CUDA_LINK   ?= $(CUDA_DIR) $(CUDA_LIB)
#--------------------------------------------------------------------------------------------------
MKDIR_P ?= mkdir -p
# find all the source files
SRCS := $(shell find $(SRC_DIRS) -name *.cu -or -name *.cpp -or -name *.c -or -name *.s)
#go to build directory and create a .o file for each src file found
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)
# create a .d file from each .o file. SO one .d for each .source
DEPS := $(OBJS:.o=.d)


LIB_DIRS := $(OCV_LINK) $(CUDA_LINK)
INCS     := $(CUDA_INC) $(OCV_INC)

$(BUILD_DIR)/$(TARGET_EXEC): $(OBJS)
        $(NVCC) $(NVCCFLNK) $(OBJS) $(LIB_DIRS)  -o $@

$(BUILD_DIR)/%.cu.o: %.cu
        $(MKDIR_P) $(dir $@)
        $(NVCC) $(NVCCFLAGS) -o $@ -dc $<

    #echo ".cu.o rule:" $(NVCCFLAGS) -o $@ -c $< $(OCV_INC) $(CUDA_INC)
    #$(NVCC) $(NVCCFLAGS) -o $@ -c $< $(OCV_INC) $(CUDA_INC)

$(BUILD_DIR)/%.cpp.o: %.cpp
        $(MKDIR_P) $(dir $@)
        $(CXX) $(CXXFLAGS) $(INCS) -o $@ -c $<

# Phony rules -------------------------------------------------------------------------------

.PHONY: clean
clean:
        $(RM) -r $(BUILD_DIR)
$ ls
bld  Makefile  src
$ cat src/hello.cu
#include <stdio.h>

__device__ void hello(){

  printf("hello!\n");
}
$ cat src/test.cu
#include <stdio.h>

__device__ void hello();

__global__ void my_hello(){

  hello();
}

int main(){

  my_hello<<<1,1>>>();
  cudaDeviceSynchronize();

}
$ make clean
rm -f -r ./bld
$ make
mkdir -p bld/./src/
nvcc -arch=sm_61  -o bld/./src/hello.cu.o -dc src/hello.cu
mkdir -p bld/./src/
nvcc -arch=sm_61  -o bld/./src/test.cu.o -dc src/test.cu
nvcc -arch=sm_61 ./bld/./src/hello.cu.o ./bld/./src/test.cu.o -L/user/local/lib  -L/usr/local/cuda-8.0/lib64 -lcuda -lcudart   -o bld/cudaNestim.out
$ bld/cudaNestim.out
hello!
$