【问题标题】:How do I avoid these repetitions when using recursive make?使用递归make时如何避免这些重复?
【发布时间】:2011-08-27 19:18:24
【问题描述】:

假设我有一个包含两个或多个子文件夹foobar 等的项目。我在项目的根目录以及每个子目录中都有一个Makefile

我想让某些目标(例如allclean 等)在每个子目录中递归运行。我的顶级Makefile 看起来像这样:

all:
    $(MAKE) -C foo all
    $(MAKE) -C bar all

clean:
    $(MAKE) -C foo clean
    $(MAKE) -C bar clean

在我看来这里有很多重复。 有什么方法可以避免在我的 Makefile 中进行这种繁琐的重复吗?

【问题讨论】:

  • 不使用automake有什么原因吗?
  • @awoodland 不一定,有什么好处?
  • 好处是你得到了所有为你写的东西:)

标签: makefile dry


【解决方案1】:

这个怎么样:

SUBDIRS=foo bar
all clean:
        for dir in $(SUBDIRS) ; do \
            $(MAKE) -C $$dir $@ ; \
        done

【讨论】:

  • @reprogrammer:问题不在于递归 make 的概念,而是递归 make 的通常实现,例如 GNU make 中的递归。相比之下,Electric Make 使用 non-blocking recursive make 来解决递归 make 的性能问题,并使用 conflict detection and correction 来确保正确性。最终结果是您获得了递归制作的便利非递归的性能/正确性。
【解决方案2】:

有点吓人:

SUBDIRS=foo bar
SUBDIR_TARGETS=all clean

define subdir_rule
$(2): $(1)-$(2)
$(1)-$(2):
    make -C $(1) $(2)
endef

$(foreach targ,$(SUBDIR_TARGETS),\
    $(foreach dir,$(SUBDIRS),\
        $(eval $(call subdir_rule,$(dir),$(targ)))))

【讨论】:

    【解决方案3】:

    我会这样做:

    SUBDIRS=foo bar baz
    
    TARGETS = clean all whatever
    .PHONY:$(TARGETS)
    
    # There really should be a way to do this as "$(TARGETS):%:TARG=%" or something...
    all: TARG=all
    clean: TARG=clean
    whatever: TARG=whatever
    
    $(TARGETS): $(SUBDIRS)
        @echo $@ done
    
    .PHONY: $(SUBDIRS)
    $(SUBDIRS):
        @$(MAKE) -s -C $@ $(TARG)
    

    【讨论】:

      猜你喜欢
      • 2017-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多