我在非平面目录结构中有几百个文件。我的Makefile列出了每个源文件,考虑到项目的大小以及项目中有多个开发人员的事实,当我们忘记放入新文件或删除旧文件时,可能会产生烦恼。我想概括我的Makefile,以便make可以简单地构建所有.cpp和.h文件,而不必指定所有文件名,给出了不同类型文件的一些通用规则。
我的问题:如果目录中包含大量子文件夹中的大量文件,我如何告诉make构建它们而不必将每个子文件夹指定为路径的一部分?我如何制作它,以便我只能在根目录中使用一个Makefile?
编辑:this几乎回答了我的问题,但它要求您指定所有文件名:\
答案 0 :(得分:1)
我确信可以使用pure-gmake解决方案,但是使用外部命令来修改makefile,或者生成一个外部命令(你的makefile中include
)可能要简单得多。
有些事情:
all: myprog
find_sources:
zsh -c 'for x in **/*.cpp; echo "myprog: ${x/.cpp/.o}" >> deps.mk'
include deps.mk
并运行
make find_sources && make
注意:确切的zsh行可能需要一些转义才能在make文件中工作,例如: $$而不是$。它也可以用bash + find替换。
答案 1 :(得分:1)
与平台无关的一种方式(我的意思是独立于Windows或Linux中的shell)是:
DIRS = relative/path1\
relative/path2
dd = absolute/path/to/subdirectories
all:
@$(foreach dir, $(DIRS), $(MAKE) -C $(dd)$(dir) build -f ../../Makefile ;)
build:
... build here
请注意空格和分号在这里很重要,同样重要的是指定绝对路径,并在末尾指定相应Makefile的路径(在这种情况下,我在祖父文件夹中只使用一个Makefile)
但是有更好的方法涉及PHONY目标,它更好地显示进度和错误,并在一个文件夹出现问题而不是继续执行其他目标时停止构建:
.PHONY: subdirs $(DIRS)
subdirs: $(DIRS)
$(DIRS):
$(MAKE) -C $@ build -f ../../Makefile
all : prepare subdirs
...
build :
... build here
我再次在这里只使用一个Makefile,它应该适用于所有子项目。对于孙子文件夹中的每个子项目,使用根目录中的一个Makefile创建目标“build”。
答案 2 :(得分:0)
我首先使用通配符函数的组合: http://www.gnu.org/software/make/manual/make.html#Wildcard-Function
VPATH / VPATH http://www.gnu.org/software/make/manual/make.html#Selective-Search
和文件功能 http://www.gnu.org/software/make/manual/make.html#File-Name-Functions
对于排除(即:备份,如Jonathan Leffler所述),使用不在vpath中的单独文件夹进行备份,并使用良好的隐式规则。
您仍然需要定义要处理的文件夹,但不能定义其中的每个文件。
答案 3 :(得分:0)
我对这个有两个想法。一方面,如果你的Make系统编译并链接它找到的所有内容,你会发现有人在源目录中留下了相互冲突的垃圾。另一方面,非冲突的垃圾将会激增,你将无法轻易将其与实时代码区分开来......
我认为这取决于您的商店特定的许多内容,例如源代码源控制系统以及您是否计划拥有另一个具有重叠代码库的项目。也就是说,如果确实想要编译给定目录下的每个源文件然后将它们全部链接起来,我建议简单的递归:创建对象,在这里编译所有源文件,添加结果对象(使用完整路径)到顶部源目录中的列表,递归到此处的所有目录。要链接,请使用列表。