如何使用GNUMake指定依赖于目标的先决条件? [英] How do I specify target dependant prerequisits with GNUMake?
问题描述
说我有一个这样的源文件列表:
Say I have a list of source files like this:
SOURCE=aaa.src bbb.src ccc.src
我想创建一个规则,以在其自己的文件夹中构建每个相应的目标,其名称取决于soruce文件。
I want to create a rule to build each corresponding target in its own folder, the name of which depends on the soruce file.
源文件---->相应的输出文件/目标
Sourcefile ----> Corresponding output file / target
aaa.src -------------------> aaa / aaa.out
aaa.src -------------------> aaa/aaa.out
bbb.src -------------------> bbb / bbb.out
bbb.src -------------------> bbb/bbb.out
ccc.src -------------------> ccc / ccc.out
ccc.src -------------------> ccc/ccc.out
如何使用GNUMake为此编写规则?我的最大努力是下面的Makefile:
How do I write a rule for this using GNUMake? My best effort was the following Makefile:
.PHONY: all clean
CC=somecompiler
SOURCE := aaa.src bbb.src ccc.src
RTARGS := $(SOURCE:%.src=%.out)
TDIRS := $(addsuffix /,$(basename $(SOURCE)))
TARGS := $(join $(TDIRS), $(RTARGS))
all:$(TARGS)
%.out: $(SOURCE) # Better source specification?
@[ ! -d "$(dir $*)" ] && mkdir "$(dir $*)"
$(CC) "$(patsubst %/,%,$(dir $*)).src" "$@"
clean:
rm -f $(TARGS)
rmdir --ignore-fail-on-non-empty $(TDIRS)
这里的问题是,任何一个目标(即 .out
文件)都取决于 源(即 .src
文件),而不只是具有相同基名的文件。我可以将注释行更改为%。out:%.src
,但是源文件必须与输出文件位于同一目录中。我也可以像这样编译它:
The problem here is, that any one target (i.e. .out
file) depends on every source (i.e. .src
file), instead of just the one that has the same basename. I could change the commented line to %.out: %.src
but than the source file would have to be in the same directory as the output file. I could also compile it something like this:
%.out: %.src
$(CC) "$>" -o "$*/$@"
但是,make会始终编译每个目标,无论它是否已经存在。
But then make would always compile every target regardless of whether it already exists or not.
我如何仅使用适当的源文件。 在通用规则中分别为每个目标指定依赖项的正确方法是什么?
How do I get make to use the appropriate source file only. What is the proper way of specifying dependences for each target separately in a generic rule?
推荐答案
在GNU使您可以独立于配方指定先决条件,并且仍然对所有 .out
文件具有通用/模式规则:
In GNU Make you can specify prerequisites separately from recipes and still have a generic / pattern rule for all .out
files:
.PHONY: all clean
all :
SOURCES := aaa.src bbb.src ccc.src
OUTPUTS := $(foreach src,${SOURCES},$(basename ${src})/${src:%.src=%.out})
# Build dependencies in the form of x/x.out : x.src | x
define ESTABLISH_DEPENDENCY =
$(basename ${1})/${1:%.src=%.out} : ${1} | $(basename ${1}) # Also depend on the output directory.
$(basename ${1}) : # Rule to create the output directory.
mkdir $$@
endef
$(foreach src,${SOURCES},$(eval $(call ESTABLISH_DEPENDENCY,${src})))
all : ${OUTPUTS}
# Generice rule for all .out files.
%.out :
@echo "build $@ from $^"
touch $@
%.src : # For debugging only.
touch $@
.PHONY: all
输出:
$ make
touch aaa.src
mkdir aaa
build aaa/aaa.out from aaa.src
touch aaa/aaa.out
touch bbb.src
mkdir bbb
build bbb/bbb.out from bbb.src
touch bbb/bbb.out
touch ccc.src
mkdir ccc
build ccc/ccc.out from ccc.src
touch ccc/ccc.out
请注意,对目录具有仅顺序的依赖关系并让它们创建它们比让每个配方先检查目录是否存在更为有效和优雅
Note that it is more efficient and elegant to have order-only dependencies on directories and let make create them, than to have each recipe checking directory existence first.
这篇关于如何使用GNUMake指定依赖于目标的先决条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!