3

我必须通过命令(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/%/fa/%.fb

    @fa2fb $< $@

有没有不改变数据目录的简单解决方案?

非常感谢!

4

3 回答 3

2

使用二次扩展subst函数创建一个规则,其中先决条件被构造为目标名称的更复杂函数:

.SECONDEXPANSION:
DATA/%.fb: $$(subst fb,fa,$$@)
    @fa2fb $< $@

请注意,此方法假定fb不会出现在文件名中的其他任何地方(如果所有文件名的格式均为DATA/Ln/fb/Ln.fb, 对于某些整数,则适用n)。

于 2011-07-13T05:10:35.663 回答
1

这可能是我写过的最草率的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))))))

这个想法是定义一个宏来生成您的规则,然后使用foreacheval+call为每个源调用一次。source 是 的第一个参数call,所以它$(1)在宏中。第二个参数只是从源文件名到目标文件名的转换;它变成$(2)了宏。

替换echo hi为您自己的规则,您应该一切顺利。一定要写一个很好的清晰的评论,否则总有一天有人会拿着棒球棒出现在你家门口。

于 2011-07-13T04:41:36.847 回答
0

这与尼莫的回答基本相同。我只是试图通过创建一个包含简单的模块列表而不是完整的源名称列表来使foreach调用更具可读性。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))))
于 2011-07-13T12:43:43.290 回答