我在我的应用的“lib”目录主目录,其中包含的子目录的任意数量,每一个具有其自身的生成文件。

我想在主目录的单个Makefile文件,调用每个子目录的Makefile。我知道这是可能的,如果我手动列出子目录,但我想有它自动完成的。

我在想的东西像下面,但它显然是行不通的。请注意,我也有干净的,试验等指标,所以%的可能不是一个好主意。

LIBS=lib/*

all: $(LIBS)

%:
  (cd $@; $(MAKE))

任何帮助理解!

有帮助吗?

解决方案

下面将与GNU make工作:

LIBS=$(wildcard lib/*)
all: $(LIBS)
.PHONY: force
$(LIBS): force
  cd $@ && pwd

如果有可能比lib目录以外的东西,你可以选择使用:

LIBS=$(shell find lib -type d)

要解决多目标的问题,您可以建立特殊的目标,为每个目录,然后剥离的前缀子编译:

LIBS=$(wildcard lib/*)
clean_LIBS=$(addprefix clean_,$(LIBS))
all: $(LIBS)
clean: $(clean_LIBS)
.PHONY: force
$(LIBS): force
  echo make -C $@
$(clean_LIBS): force
  echo make -C $(patsubst clean_%,%,$@) clean

其他提示

还有列出子目录的gmake仅命令,而无需使用任何外壳命令的方法:

test:
  @echo $(filter %/, $(wildcard lib/*/))

此将列出所有子目录尾随'/'。删除它可以使用替代的模式:

subdirs = $(filter %/, $(wildcard lib/*/))
test:
  @echo $(subdirs:%/=%)

然后到实际创建你可以使用一个小窍门每个子目录执行的makefile规则 - 假目标在一个不存在的目录。我认为在这种情况下一个例子将告诉比任何解释更多:

FULL_DIRS =$(filter %/, $(wildcard lib/*/))
LIB_DIRS  =$(FULL_DIRS:%/=%)
DIRS_CMD  =$(foreach subdir, $(LIB_DIRS), make-rule/$(subdir))

make-rule/%:
  cd $* && $(MAKE)

all: DIRS_CMD

基本上,目标'all'列出所有子目录作为先决条件。例如,如果包含LIB_DIRS然后lib/folder1 lib/folder2扩大看起来像这样:

all: make-rule/lib/folder1 make-rule/lib/folder2

然后“使”,以执行规则'all',尝试将每个先决条件与现有的目标相匹配。在这种情况下,目标是'make-rule/%:',它使用'$*'提取'make-rule/'后的字符串,并使用它作为在配方参数。例如,第一个先决条件将被匹配和扩大这样的:

make-rule/lib/folder1:
  cd lib/folder1 && $(MAKE)

如果你想调用比所有不同的目标,在一个未知的一些子目录是什么?

在下面的Makefile使用宏所以创建转发伪目标为多个子目录,以在命令行应用给定的目标,以它们中的每:

# all direct directories of this dir. uses "-printf" to get rid of the "./"
DIRS=$(shell find . -maxdepth 1 -mindepth 1 -type d -not -name ".*" -printf '%P\n')
# "all" target is there by default, same logic as via the macro
all: $(DIRS)

$(DIRS):
    $(MAKE) -C $@
.PHONY: $(DIRS)

# if explcit targets where given: use them in the macro down below. each target will be delivered to each subdirectory contained in $(DIRS).
EXTRA_TARGETS=$(MAKECMDGOALS)

define RECURSIVE_MAKE_WITH_TARGET
# create new variable, with the name of the target as prefix. it holds all
# subdirectories with the target as suffix
$(1)_DIRS=$$(addprefix $(1)_,$$(DIRS))

# create new target with the variable holding all the subdirectories+suffix as
# prerequisite
$(1): $$($1_DIRS)

# use list to create target to fullfill prerequisite. the rule is to call
# recursive make into the subdir with the target
$$($(1)_DIRS):
      $$(MAKE) -C $$(patsubst $(1)_%,%,$$@) $(1)

# and make all targets .PHONY
.PHONY: $$($(1)_DIRS)
endef

# evaluate the macro for all given list of targets
$(foreach t,$(EXTRA_TARGETS),$(eval $(call RECURSIVE_MAKE_WITH_TARGET,$(t))))

希望这有助于。真的paralelism处理乐于助人的时候:让-j12清洁所有的树具有的makefile这些目标......一如往常:用make打是危险的,节目的不同元水平太接近, - )

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top