Make: *.h 没有那个文件或目录

Make: *.h no such file or directory

我的项目有以下目录结构:

其中 *.extension 表示一堆具有该扩展名的文件。我似乎无法让 makefile 正常工作。我得到的错误是:

 FA_kernels/FA_SFD.cu:2:20: fatal error: FA_SFD.h: No such file or directory
 #include "FA_SFD.h"
                    ^

我的意图是将 -I headers 指定给编译器,从而使 headers 目录可用于搜索。显然这没有奏效。这是生成文件:

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
/%.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))))

有什么想法吗?

更新: 这是 运行 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

从您的输出来看,显然 OBJ 中的 patsubst 根本没有成功。从你定义SRC的方式来看,我假设makefile直接在src/之下,那么你应该在OBJ的定义中将src/%.cu更改为%.cu

OBJ       := $(patsubst %.cu,build/%.o,$(SRC))

此外,如果我理解正确的话,您试图在 build/ 下创建一个与 src/ 下的文件夹结构相同的文件夹结构。因此,例如,/src/abc.cu 将生成 /src/build/abc.o,那么您无需定义函数来获取这些规则,只需执行:

build/%.o: %.cu
    $(CC) $(INCLUDES) -c $< -o $@

一切顺利。

如果您希望在与 src/ 相同的级别上创建 build/。即 XXX/src/abc.cu -> XXX/build/abc.o。然后只需将 makefile 中所有出现的 build 替换为 ../build.

如果您希望将 makefile 放在与 src/ 相同的级别,那么您应该编辑 SRC 以反映这一点:

SRC       := $(foreach sdir,$(SRC_DIR),$(wildcard src/$(sdir)/*.cpp))

并将目标更改为:

build/%.o: src/%.cpp
    $(CC) $(INCLUDES) -c $< -o $@

现在您可以安全地删除 vapth ... 和 makefile 中的最后一行 $foreach

编辑:这就是您的 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 %.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))))