【问题标题】:Make target containing subdirectory based on target dependencies根据目标依赖关系制作包含子目录的目标
【发布时间】:2013-12-22 18:00:59
【问题描述】:

假设我有一个源文件列表,每个源文件都将被编译为单独的二进制文件:

SRCS = abcd.c efgh.c ijkl.c

我希望根据文件名在单独的子目录中输出文件,如下所示:

  • 构建/abcd/abcd
  • 构建/efgh/efgh
  • 构建/ijkl/ijkl

我认为静态模式规则是可行的方法。伪make-rule可以是这样的:

$(TARGETS): build/%/%: %.c
    # stuff ...

我首先根据文件名列出子目录:

DIRS = $(SRCS:%.c=build/%)

所以现在我们有了 DIRS = build/abcd build/efgh build/ijkl。我想我现在可以使用以下内容列出目标:

BLDS = $(DIRS:%=%/$(basename %))

但这当然行不通,因为通配符不能在一个模式中多次使用。因此,我现在卡在 BLDS = build/abcd/% build/efgh/% build/ijkl/%。

显然,我完全走错了路。你会怎么做呢?

现在我正在明确地编写每条规则,这开始变得有点乏味:

compile = # command to do stuff
BD = build

all: $(BD)/abcd/abcd $(BD)/efgh/efgh $(BD)/ijkl/ijkl

$(BD)/abcd/abcd: abcd.c
    $(call compile)

$(BD)/efgh/efgh: efgh.c
    $(call compile)

$(BD)/ijkl/ijkl: ijkl.c
    $(call compile)

clean:
    rm -rf build/*

.PHONY: all

【问题讨论】:

    标签: static makefile target rules substitution


    【解决方案1】:

    我相信这可以满足您的需求:

    SRCS:=abcd.c efgh.c ijkl.c
    
    # We could fold NAMES into BLDS's definition if NAMES is not used elsewhere.
    NAMES:=$(SRCS:%.c=%)
    
    BLDS:=$(foreach name,$(NAMES),$(subst foo,$(name),build/foo/foo))
    
    # We don't use DIRS below but the question had this variable.
    DIRS:=$(dir $(BLDS))
    
    TARGETS:=$(BLDS)
    
    .PHONY: all
    all: $(TARGETS)
    
    .SECONDEXPANSION:
    $(TARGETS): $$(notdir $$@).c
        @echo Build $@ from $^
        mkdir -p $(dir $@)
        touch $@
    

    有两个重要的变化。第一个是重新排序变量的创建方式,并使用subst,它允许多次替换匹配的字符串。第二种是使用secondary expansion,以便为每个目标构建规则。你最初的模式有两个%but the docs say

    模式规则看起来像一个普通的规则,除了它的目标包含字符“%”(正好是其中一个)。

    (已添加重点。)

    我已经用假文件 abcd.c efgh.cijkl.c 测试了上述内容,并得到以下输出:

    $ make
    Build build/abcd/abcd from abcd.c
    mkdir -p build/abcd/
    touch build/abcd/abcd
    Build build/efgh/efgh from efgh.c
    mkdir -p build/efgh/
    touch build/efgh/efgh
    Build build/ijkl/ijkl from ijkl.c
    mkdir -p build/ijkl/
    touch build/ijkl/ijkl
    

    【讨论】:

    • 嘿,非常感谢。实际上,我以前从未听说过 make 的二次扩展,所以这真的很有启发性。
    猜你喜欢
    • 2019-01-27
    • 2014-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多