源文件中的子目录

我有一个使用Makefilebuild立的C ++库。 直到最近,所有的源代码都在一个目录中,Makefile也是这样做的

SOURCES = $(wildcard *.cpp)

哪些工作正常。

现在我已经添加了一些子目录中的源代码,比如subdir 。 我知道我可以做到这一点

SOURCES = $(wildcard *.cpp) $(wildcard subdir/*.cpp)

但我正在寻找一种方法来避免手动指定subdir ,也就是使wildcard查看子目录,或以某种方式生成子目录列表,并用几个wildcard函数来扩展它。 在这一点上,有一个非recursion解决scheme(即只扩展到第一级)就可以了。

我还没有find任何东西 – 我最好的猜测是使用find -type d列出子目录,但感觉像是一个黑客。 有没有内置的方法来做到这一点?

这应该做到这一点:

 SOURCES = $(wildcard *.cpp) $(wildcard */*.cpp) 

如果你改变主意,想要一个recursion的解决scheme(即任何深度),它可以完成,但它涉及一些更强大的Makefunction。 你知道,那些允许你做你真正不应该做的事。

编辑:
杰克·凯利$(wildcard **/*.cpp) Jack Kelly)指出, $(wildcard **/*.cpp)可以使用GNUMake 3.81,至less在某些平台上工作到任何深度。 (他怎么想的,我不知道。)

recursion通配符可以纯粹在Make中完成,而不用调用shell或find命令。 仅使用Make进行search意味着此解决scheme也适用于Windows,而不仅仅是* nix。

 # Make does not offer a recursive wildcard function, so here's one: rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2)) # How to recursively find all files with the same name in a given folder ALL_INDEX_HTMLS := $(call rwildcard,foo/,index.html) # How to recursively find all files that match a pattern ALL_HTMLS := $(call rwildcard,foo/,*.html) 

文件夹名称中的尾部斜杠是必需的。 这个rwildcard函数不像Make的内置通配符函数那样支持多个通配符,但是增加这个支持对于foreach来说更简单一些。

如果你不想使用recursionmakefile,这可能会给你一些想法:

 subdirs := $(wildcard */) sources := $(wildcard $(addsuffix *.cpp,$(subdirs))) objects := $(patsubst %.cpp,%.o,$(sources)) $(objects) : %.o : %.cpp 

通常的做法是将Makefile放入每个具有源代码的子目录中

 all: recursive $(MAKE) -C componentX # stuff for current dir 

要么

 all: recursive cd componentX && $(MAKE) # stuff for current dir recursive: true 

Makefile中的每个Makefile设置放在根源目录中可能是明智的做法。 recursive目标力量进入子目录。 确保它不会在需要recursive的目标中重新编译任何东西。

这是一个附注,不回答你的问题,但有一个文件“recursion考虑有害的”。 这是值得一读的。

链接在这里。 auug97.pdf

如果你可以使用find shell命令,你可以定义一个函数来使用它。

 recurfind = $(shell find $(1) -name '$(2)') SRCS := $(call recurfind,subdir1,*.c) $(call recurfind,subdir2,*.cc) $(call recurfind,subdir2,*.cu) \ ...