LilyPond项目Makefile多层级包含文件的依赖项最佳实践
LilyPond项目Makefile依赖管理方案
你的空规则问题分析
你写的空规则parts/piano.ly: notes/piano.ily会导致make报错。因为make会认为parts/piano.ly是需要构建生成的目标,当notes/piano.ily更新后,make发现目标文件比依赖旧,就会尝试执行规则的命令,但空规则没有命令,make会抛出"没有规则可以生成目标"的错误——而实际上parts/piano.ly是你手动编写的静态文件,不是生成的,所以这个思路不成立。
最优解决方案:自动追踪LilyPond依赖
LilyPond本身支持生成依赖文件,能自动识别.ly文件中\include的所有.ily或其他文件,完全不需要手动维护依赖列表。具体实现步骤如下:
1. 定义生成依赖文件的规则
添加规则让LilyPond为每个parts/*.ly生成对应的.dep依赖文件:
# 为每个parts目录下的.ly文件生成依赖文件 parts/%.dep: parts/%.ly lilypond -dwrite-dep-file=$@ $<
这个命令会让LilyPond解析目标.ly文件,把所有被\include的文件路径写入到对应的.dep文件中。
2. 包含所有依赖文件
在Makefile中加入以下语句,让make自动加载生成的依赖文件:
# 自动加载所有parts目录下的.dep文件,-include避免首次构建时文件不存在报错 -include parts/*.dep
3. 保持PDF生成规则简洁
PDF的生成规则不需要手动添加任何.ily依赖,make会通过.dep文件自动识别所有间接依赖:
# 生成pdf目录下的PDF文件 pdf/%.pdf: parts/%.ly # 确保pdf目录存在 mkdir -p pdf # 调用LilyPond生成PDF,指定输出目录和文件名前缀 lilypond -o pdf/$* $<
效果说明
- 当你修改
notes/piano.ily或者parts/piano.ly本身时,make会通过.dep文件检测到依赖变化,自动触发pdf/piano.pdf的重建。 - 如果后续
parts/piano.ly新增或修改了\include的文件,LilyPond会自动更新.dep文件,不需要你手动修改Makefile,维护性极强。
不推荐的折中方案(仅作参考)
如果暂时不想用依赖文件生成,也可以给parts/piano.ly的规则加一个touch命令,但这个方法有明显缺点:
parts/piano.ly: notes/piano.ily touch $@
它会修改parts/piano.ly的修改时间戳,强制触发PDF重建,但如果该文件在版本控制系统中,touch会导致它被标记为已修改,容易造成混淆,因此不推荐使用。
内容的提问来源于stack exchange,提问作者Rusty
相关产品推荐
相关产品推荐

