简体   繁体   中英

CUDA and C++ with folders structure - generic makefile

I'd like to write generic makefile that compiles and links all my modules.

Folders structure:

\include
----+Common.h
----+Graph.h
----+GraphColoringCPU.h
----+GraphColoringGPU.cuh
----+LogCreate.h
\obj <- initially empty, all .o files
---- ...
\src
----+Common.cu
----+Graph.cpp
----+GraphColoringCPU.cpp
----+GraphColoringGPU.cu
----+LogCreate.cpp
----+main.cu
+Makefile
+main <- target, missing before 'make'

Makefile:

CUDA_INSTALL_PATH ?= /usr/local/cuda

# Compilers
CXX := g++
LINK := g++ -fPIC
NVCC  := nvcc -ccbin /usr/bin

# Includes
INCLUDES = -I. -I$(CUDA_INSTALL_PATH)/include

# Common flags
COMMONFLAGS += $(INCLUDES)
NVCCFLAGS := $(COMMONFLAGS) -gencode arch=compute_20,code=sm_20
CXXFLAGS += $(COMMONFLAGS)
CFLAGS += $(COMMONFLAGS)

# Compiler flags
DLINKFLAGS      := -lcublas_device -lcudadevrt -lcublas -lcudart

# Debug mode
NVCCFLAGS += --compiler-options -Wall -G

#-arch=sm_35

# Libraries
LIB_CUDA := -L$(CUDA_INSTALL_PATH)/lib64 -lcudart

# Folder structure
OBJ = obj
SRC = src
INC = include

# Options
OBJS_CU = $(OBJ)/Common.ch.o $(OBJ)/GraphColoringGPU.cuh.o $(OBJ)/kernel.cu.o 
OBJS = $(OBJ)/Graph.cpp.o $(OBJ)/LogCreate.cpp.o $(OBJ)/GraphColoringCPU.cpp.o $(OBJ)/link.o 
TARGET = main
LINKLINE = $(LINK) -o $(TARGET) $(OBJS_CU) $(OBJS) $(LIB_CUDA)

.SUFFIXES: .c .cpp .h .cu .cuh .o

$(OBJ)/%.cuh.o: $(SRC)/%.cu $(INC)/%.cuh
    $(NVCC) $(NVCCFLAGS) -dc $< -o $@

$(OBJ)/%.ch.o: $(SRC)/%.cu $(INC)/%.h
    $(NVCC) $(NVCCFLAGS) -dc $< -o $@

$(OBJ)/%.cu.o: $(SRC)/%.cu
    $(NVCC) $(NVCCFLAGS) -dc $< -o $@

$(OBJ)/link.o:
    $(NVCC) -dlink $(NVCCFLAGS) $(DLINKFLAGS) $(OBJS_CU) -o $@  

$(OBJ)/%.cpp.o: $(SRC)/%.cpp $(INC)/%.h
    $(CXX) $(CXXFLAGS) -c $< -o $@

$(TARGET): $(OBJS_CU) $(OBJS) Makefile
    $(LINKLINE)

# all:
    # $(NVCC) $(NVCCFLAGS) -dc $(SRC)Common.cu $(SRC)GraphColoringGPU.cu $(SRC)kernel.cu 
    # $(NVCC) $(NVCCFLAGS) -dlink $(OBJ)Common.o $(OBJ)GraphColoringGPU.o $(OBJ)kernel.o -o $(OBJ)link.o
    # $(CXX) $(CXXFLAGS) -c $(SRC)Graph.cpp -o $(OBJ)graph.o
    # $(CXX) $(CXXFLAGS) -c $(SRC)LogCreate.cpp -o $(OBJ)logcreate.o
    # $(CXX) $(CXXFLAGS) -c $(SRC)GraphColoringCPU.cpp -o $(OBJ)GraphColoringCPU.o
    # $(LINK) -o main $(OBJ)Common.o $(OBJ)GraphColoringGPU.o $(OBJ)kernel.o $(OBJ)link.o $(OBJ)graph.o $(OBJ)logcreate.o $(OBJ)GraphColoringCPU.o $(LIB_CUDA)

clean: 
    rm -rf *.o log.txt

As you can see at the bottom there is some commented code. This code works fine without folders structure (all files in main dir).

Output of commented code:

nvcc -ccbin /usr/bin -I. -I/usr/local/cuda/include -gencode arch=compute_20,code=sm_20 --compiler-options -Wall -G -dc Common.cu GraphColoringGPU.cu kernel.cu
nvcc -ccbin /usr/bin -I. -I/usr/local/cuda/include -gencode arch=compute_20,code=sm_20 --compiler-options -Wall -G -dlink Common.o GraphColoringGPU.o kernel.o -o link.o
g++ -I. -I/usr/local/cuda/include -c Graph.cpp -o graph.o
g++ -I. -I/usr/local/cuda/include -c LogCreate.cpp -o logcreate.o
g++ -I. -I/usr/local/cuda/include -c GraphColoringCPU.cpp -o GraphColoringCPU.o
g++ -fPIC -o main Common.o GraphColoringGPU.o kernel.o link.o graph.o logcreate.o GraphColoringCPU.o -L/usr/local/cuda/lib64 -lcudart

Actual makefile produces output:

nvcc -ccbin /usr/bin -dlink -I. -I/usr/local/cuda/include -gencode arch=compute_20,code=sm_20 --compiler-options -Wall -G -lcublas_device -lcudadevrt -lcublas -lcudart obj/Common.ch.o obj/GraphColoringGPU.cuh.o obj/kernel.cu.o  -o obj/link.o
nvlink fatal   : Could not open input file 'obj/Common.ch.o'
make: *** [obj/link.o] Error 255

I know that it tries to compile with no proper order but I don't know how to change it.

Proper order rules:

1) Compile all '.cu' files using 'nvcc -dc' and places suitable '.o' files into \obj folder 
2) Link all '.o' files (where sources are .cu files) using 'nvcc -dlink' into 'link.o' file (and place it into \obj folder) 
3) Compile all '.cpp' files using 'g++ -c' and places suitable '.o' files into \obj folder 
4) Links all '.o' files into target 'main' (and place it in main folder)

Thanks for advices.

I knew I had been pretty close to write correct make. I've tried command 'make main' and it... worked (some little changes was needed).

Here is working Makefile (unchanged code omitted):

# Options
OBJS_CU = $(OBJ)/Common.ch.o $(OBJ)/GraphColoringGPU.cuh.o $(OBJ)/main.cu.o 
OBJS = $(OBJ)/Graph.cpp.o $(OBJ)/LogCreate.cpp.o $(OBJ)/GraphColoringCPU.cpp.o $(OBJ)/link.o 
TARGET = main
LINKLINE = $(LINK) -o $(TARGET) $(OBJS_CU) $(OBJS) $(LIB_CUDA)

.SUFFIXES: .c .cpp .h .cu .cuh .o

$(OBJ)/%.cuh.o: $(SRC)/%.cu $(INC)/%.cuh
    $(NVCC) $(NVCCFLAGS) -dc $< -o $@

$(OBJ)/%.ch.o: $(SRC)/%.cu $(INC)/%.h
    $(NVCC) $(NVCCFLAGS) -dc $< -o $@

$(OBJ)/%.cu.o: $(SRC)/%.cu
    $(NVCC) $(NVCCFLAGS) -dc $< -o $@

$(OBJ)/link.o:
    $(NVCC) $(NVCCFLAGS) -dlink $(OBJS_CU) -o $@    

$(OBJ)/%.cpp.o: $(SRC)/%.cpp $(INC)/%.h
    $(CXX) $(CXXFLAGS) -c $< -o $@

$(TARGET): $(OBJS_CU) $(OBJS) Makefile
    $(LINKLINE)

Also, if rule for $(TARGET) will be first rule, simple 'make' will be enough for working correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM