[英]Makefile for cuda/c++, Cannot successfully compile
我花了很多時間嘗試編寫一個makefile來編譯一些c ++文件以及一些.cu文件。 當前無法獲得輸出時,我無法成功編譯目標,這不是正確的二進制文件。
因此,基本上,我的所有源文件都位於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規則。
它不是正確的二進制文件
最接近的原因是您將設備鏈接指定為最終構建(即鏈接階段)操作:
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 $<
^^
因為您已經指定了鏈接階段應該立即完成,並且使用nvcc
,我們可以對您的makefile進行一些相對簡單的更改 ,以實現可以進行rdc鏈接的makefile。 這是一個完全可行的示例,源於您的示例:
$ 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!
$
請注意,如果您實際上不希望生成RDC代碼,則可以在上面的Makefile中將-dc
更改回-c
。 但是,出於演示目的,我的特定代碼示例取決於CUDA RDC。
比直接回答更多的是建議:
您做錯的是嘗試重新發明輪子。 使用更高級別的構建系統,不要麻煩自己編寫Makefile。 周圍有不止一種; 我個人使用CMake並對此感到滿意。 CMake有一個模塊,用於為CUDA設置事物路徑和其他變量。 這是一個簡短的教程,您可以簽出:
現在,這並不是說您永遠不會遇到任何問題,而是:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.