Reputation: 337
My project has the following directory structure:
Where *.extension means a bunch of files with that extension. I can't seem to get the makefile to work correctly. The error I'm getting is:
FA_kernels/FA_SFD.cu:2:20: fatal error: FA_SFD.h: No such file or directory
#include "FA_SFD.h"
^
My intent was for -I headers to be specified to the compiler, thereby making the headers directory available for searching. Clearly this has not worked. Here is the makefile:
CC := nvcc
LD := nvcc
MODULES := FA_kernels FD_kernels MEM_kernels MOD_kernels .
SRC_DIR := $(MODULES)
BUILD_DIR := $(addprefix build/,$(MODULES))
SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.cu))
OBJ := $(patsubst src/%.cu,build/%.o,$(SRC))
INCLUDES := $(addprefix -I,headers)
vpath %.cu $(SRC_DIR)
define make-goal
$1/%.o: %.cu
$(CC) $(INCLUDES) -c $$< -o $$@
endef
.PHONY: all checkdirs clean
all: checkdirs build/lem
build/lem: $(OBJ)
$(LD) $^ -o $@
checkdirs: $(BUILD_DIR)
$(BUILD_DIR):
@mkdir -p $@
clean:
@rm -rf build
$(foreach bdir,$(BUILD_DIR),$(eval $(call make-goal,$(bdir))))
Any ideas?
UPDATE: Here is the full console output from running make
nvcc FA_kernels/FA_SFD.cu FA_kernels/partition.cu FA_kernels/contribA.cu FA_kernels/parallel-SFD-List.cu FD_kernels/SFD.cu FD_kernels/flow_routines.cu FD_kernels/floodingDriver.cu FD_kernels/watershed.cu MEM_kernels/memory_dev.cu MEM_kernels/Data.cu MEM_kernels/MapInfo.cu MEM_kernels/memory.cu MOD_kernels/erosion.cu MOD_kernels/eroincidep.cu MOD_kernels/updates.cu MOD_kernels/runoffweight.cu MOD_kernels/depo-List.cu lem.cu -o build/lem
FA_kernels/FA_SFD.cu:2:20: fatal error: FA_SFD.h: No such file or directory
#include "FA_SFD.h"
^
compilation terminated.
Makefile:24: recipe for target 'build/lem' failed
make: *** [build/lem] Error 1
Upvotes: 0
Views: 3098
Reputation: 943
From your output, apparently patsubst
in OBJ
was not successful at all. From the way you define SRC, I assume makefile
is directly under src/
, then you should change src/%.cu
to %.cu
in the definition of OBJ
as such:
OBJ := $(patsubst %.cu,build/%.o,$(SRC))
Also, if I understand you correctly, you were trying to create a folder structure under build/
that is identical to the folder structure under src/
. So, for instance, /src/abc.cu
will generate /src/build/abc.o
, then you don't need to define functions to get these rules, simply do:
build/%.o: %.cu
$(CC) $(INCLUDES) -c $< -o $@
and you are good to go.
If instead you wish to create build/
on the same level as src/
. i.e. XXX/src/abc.cu
-> XXX/build/abc.o
. Then simply replace all occurrences of build
in your makefile with ../build
.
If you would rather put makefile at the same level as src/
, then you should edit SRC
to reflect that:
SRC := $(foreach sdir,$(SRC_DIR),$(wildcard src/$(sdir)/*.cpp))
and change the target to:
build/%.o: src/%.cpp
$(CC) $(INCLUDES) -c $< -o $@
Now you can safely remove vapth ...
and the last line $foreach
in your makefile.
EDIT: This is what your makefile will look like. I can't test it right now so there may be some mistakes in it, but hopefully it makes you understand the general idea.
CC := nvcc
LD := nvcc
MODULES := FA_kernels FD_kernels MEM_kernels MOD_kernels .
SRC_DIR := $(MODULES)
BUILD_DIR := $(addprefix build/,$(MODULES))
SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.cu))
OBJ := $(patsubst %.cu,build/%.o,$(SRC))
INCLUDES := $(addprefix -I,headers)
# vpath %.cu $(SRC_DIR)
#define make-goal
build/%.o: %.cu
$(CC) $(INCLUDES) -c $< -o $@
#endef
.PHONY: all checkdirs clean
all: checkdirs build/lem
build/lem: $(OBJ)
$(LD) $^ -o $@
checkdirs: $(BUILD_DIR)
$(BUILD_DIR):
@mkdir -p $@
clean:
@rm -rf build
#$(foreach bdir,$(BUILD_DIR),$(eval $(call make-goal,$(bdir))))
Upvotes: 3