在Makefile中使用多个%s
我必须通过命令(fa2fb)将一组文件(比如fa格式)转换成另一种格式(fb)。每个目标fb仅依赖于一个fa文件 数据结构的格式如下: 资料来源:在Makefile中使用多个%s,makefile,file-conversion,Makefile,File Conversion,我必须通过命令(fa2fb)将一组文件(比如fa格式)转换成另一种格式(fb)。每个目标fb仅依赖于一个fa文件 数据结构的格式如下: 资料来源: ./DATA/L1/fa/L1.fa ./DATA/L2/fa/L2.fa ... ./DATA/Ln/fa/Ln.fa 目标: ./DATA/L1/fb/L1.fb ./DATA/L2/fb/L2.fb ... ./DATA/Ln/fb/Ln.fb 我如何用make实现它 我尝试过这个方法,但它当然不起作用: ./DATA/%/fb/%.fb
./DATA/L1/fa/L1.fa
./DATA/L2/fa/L2.fa
...
./DATA/Ln/fa/Ln.fa
目标:
./DATA/L1/fb/L1.fb
./DATA/L2/fb/L2.fb
...
./DATA/Ln/fb/Ln.fb
我如何用make实现它
我尝试过这个方法,但它当然不起作用:
./DATA/%/fb/%.fb : ./DATA/%/fa/%.fb
@fa2fb $< $@
/DATA/%/fb/%.fb:./DATA/%/fa/%.fb
@fa2fb$<$@
有没有不更改数据目录的简单解决方案
非常感谢 这可能是我写过的最草率的makefile
define template
$(2) : $(1)
echo hi
endef
sources=DATA/L1/fa/L1.fa DATA/L2/fa/L2.fa
$(foreach source,$(sources),$(eval $(call template,$(source),$(subst /fa/,/fb/,$(subst .fa,.fb,$(source))))))
其思想是定义一个宏来生成规则,然后使用foreach
和eval
+call
为每个源调用它一次。源是调用的第一个参数
,因此它在宏中变为$(1)
。第二个参数只是从源文件名到目标文件名的转换;它在宏中变为$(2)
用您自己的规则替换echo hi
,您就可以开始了。并且一定要写一个清晰的评论,否则有一天肯定会有人拿着棒球棒出现在你的门口。使用和创建一个规则,其中先决条件被构造为目标名称的更复杂的函数:
.SECONDEXPANSION:
DATA/%.fb: $$(subst fb,fa,$$@)
@fa2fb $< $@
。第二次扩展:
数据/%.fb:$$(子fb,fa,$$@)
@fa2fb$<$@
注意,这种方法假设
fb
不会出现在文件名的其他任何地方(如果您的所有文件名的格式都是DATA/Ln/fb/Ln.fb
,对于某些整数n
)。这与Nemo的答案基本相同。我只是试图通过创建一个模块列表,简单地包含L1-L2。。。Ln
,而不是源代码全名列表
MODULES := $(notdir $(wildcard ./DATA/L*))
define rule
./DATA/$(1)/fb/$(1).fb: ./DATA/$(1)/fa/$(1).fa
@fa2fb $< $@
endef
$(foreach module, $(MODULES), $(eval $(call rule,$(module))))
MODULES:=$(notdir$(通配符/DATA/L*))
定义规则
/DATA/$(1)/fb/$(1).fb:/DATA/$(1)/fa/$(1).fa
@fa2fb$<$@
恩德夫
$(foreach模块,$(模块),$(eval$(调用规则,$(模块)))
谢谢。对我来说效果很好。我将了解如何检查文件名中是否不存在fa(或fb?)。在实际情况下,它可能会发生。谢谢你的建议。它有点复杂,但可能比另一个更健壮。目前我将坚持第一个建议。关于评论的信息很清楚!