static - 根据目标依赖关系使目标包含子目录

标签 static makefile target rules substitution

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

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

最佳答案

我相信这符合您的要求:

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这样 make 就会为每个目标构建规则。您最初的模式有两个 %, but the docs say :

A pattern rule looks like an ordinary rule, except that its target contains the character `%' (exactly one of them).

(强调已添加。)

我已经使用假文件 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

关于static - 根据目标依赖关系使目标包含子目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20732357/

相关文章:

java - Java public/private 和 static 修饰符如何影响一行中声明的多个变量?

java - 这个静态方法有什么作用?

linux - Node osrm 设置失败

Eclipse CDT 创建的 makefile 在 Windows 上无法 "clean"

xcode - 你如何改变发展目标?

c - 关于 C 中局部静态变量的不同行为的问题

asp.net-mvc - ASP.NET MVC Controller 静态方法

makefile - Makefiles是如何重新制作的——看不懂官方文档

iphone:使用具有不同构建目标的不同图标?

javascript - 首次单击时不执行多个设置超时功能