make:模式规则先决条件中的自动变量

时间:2019-05-01 09:50:02

标签: makefile

我在Arch Linux上使用GNU Make从LilyPond源文件生成PDF。我的目录结构如下:

scores/
├── makefile
├── out
│   ├── others-songs
│   │   ├── ...
│   │   ├── ...
│   │   └── 失恋阵线联盟
│   │       ├── 失恋阵线联盟.edition.log
│   │       ├── 失恋阵线联盟.oll.log
│   │       └── 失恋阵线联盟.pdf
│   └── ...
├── src
│   ├── others-songs
│   │   ├── ...
│   │   ├── ...
│   │   └── 失恋阵线联盟
│   │       ├── chorus.ily
│   │       ├── verse.ily
│   │       ├── words.ily
│   │       └── 失恋阵线联盟.ly
│   └── ...

out目录中的PDF取决于.ily中相应目录中的.lysrc文件。如果修改了.ly文件,则以下隐式模式规则将起作用,但如果其他文件中的任何一个被修改,则该规则不起作用:

LY = $(shell find src -iname '*.ly')
PDF = $(subst src,out,$(LY:.ly=.pdf))

pdf: $(PDF)
out/%.pdf: src/%.ly
    @mkdir -p $(dir $@)
    @lilypond --include=$(lib) \
             -dpoint-and-click=\#f \
             -o $(basename $@) $<

我尝试做一些不同的事情,例如将$(<D)*.ily附加到先决条件上,但是没有成功。我已经在在线GNU make manual上寻求帮助,但是我没有想出可以应用于我的特殊情况的任何东西。

如何编写一个模式规则,使每个PDF都依赖于相应的相应源目录中的所有文件?

编辑

我的第一个问题可能还不够清楚。我想要的行为是如果源目录中的任何文件被更改,则相应的PDF被更新。例如,如果更改了chorus.ily,则创建失恋阵线联盟.ly

1 个答案:

答案 0 :(得分:0)

一个工作示例:

LY := $(shell find src -iname '*.ly')
PDF := ${LY:src/%.ly=out/%.pdf}
pdf: $(PDF)

define pdf_deps
$(1:src/%.ly=out/%.pdf) : $(wildcard $(dir ${1})*)
endef

# Make each pdf depend on all the files in its src directory.
$(foreach ly,${LY},$(eval $(call pdf_deps,${ly})))

out/%.pdf:
    @echo "making $@ from $^"

用法:

$ ls -1R
.:
Makefile
out
src

./out:

./src:
A
B

./src/A:
a.ly

./src/B:
b.1
b.ly

$ make
making out/B/b.pdf from src/B/b.ly src/B/b.1
mkdir -p out/B
touch out/B/b.pdf
making out/A/a.pdf from src/A/a.ly
mkdir -p out/A
touch out/A/a.pdf

$ make
make: Nothing to be done for 'pdf'.

$ touch src/B/b.ly
$ make
making out/B/b.pdf from src/B/b.ly src/B/b.1
mkdir -p out/B
touch out/B/b.pdf

$ make
make: Nothing to be done for 'pdf'.

$ touch src/B/b.1
$ make
making out/B/b.pdf from src/B/b.ly src/B/b.1
mkdir -p out/B
touch out/B/b.pdf

$ make
make: Nothing to be done for 'pdf'.