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