在 Makefile 中使用多个 %

发布于 2024-11-24 03:22:53 字数 465 浏览 1 评论 0原文

我必须通过命令(fa2fb)将一组文件(假设格式fa)转换为另一种格式(fb)。每个目标fb仅依赖于一个fa文件。

数据结构的格式如下:

source:

./DATA/L1/fa/L1.fa
./DATA/L2/fa/L2.fa
...
./DATA/Ln/fa/Ln.fa

target:

./DATA/L1/fb/L1.fb
./DATA/L2/fb/L2.fb
...
./DATA/Ln/fb/Ln.fb

如何用make实现?

我已经尝试过这个,但当然它不起作用:

./DATA/%/fb/%.fb :  ./DATA/%/fa/%.fb

    @fa2fb $< $@

是否有任何简单的解决方案而不更改数据目录?

非常感谢!

I have to convert a set of file (let's say format fa) into another format (fb) by a command (fa2fb). Each target fb depends only on one fa file.

Data structure is in a format like this:

source:

./DATA/L1/fa/L1.fa
./DATA/L2/fa/L2.fa
...
./DATA/Ln/fa/Ln.fa

target:

./DATA/L1/fb/L1.fb
./DATA/L2/fb/L2.fb
...
./DATA/Ln/fb/Ln.fb

How can I implement it with make?

I have tried this but of course it did not work:

./DATA/%/fb/%.fb :  ./DATA/%/fa/%.fb

    @fa2fb 
lt; $@

Is there any simple solution without changing the data directories?

Many thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

回忆凄美了谁 2024-12-01 03:22:56

这可能是我写过的最草率的 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 为每个源调用一次。源是调用的第一个参数,因此它在宏中变成$(1)。第二个参数只是从源文件名到目标文件名的转换;它在宏中变成$(2)

echo hi 替换为您自己的规则,您应该可以开始了。一定要写一个漂亮的大而清晰的评论,否则有一天肯定会有人拿着棒球棒出现在你家门口。

This may be the sloppiest makefile I have ever written.

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))))))

The idea is to define a macro to generate your rules, then use foreach and eval+call to invoke it once for each source. The source is the first argument to the call, so it becomes $(1) in the macro. The second argument is just the transformation from a source file name to a destination file name; it becomes $(2) in the macro.

Replace echo hi with your own rule and you should be good to go. And be sure to write a nice big clear comment or someday someone will surely show up at your door with a baseball bat.

心不设防 2024-12-01 03:22:56

这与尼莫的回答基本相同。我只是试图通过创建一个模块列表来使 foreach 调用更具可读性,其中仅包含 L1 L2 ... Ln,而不是完整源代码列表名称。

MODULES := $(notdir $(wildcard ./DATA/L*))

define rule
./DATA/$(1)/fb/$(1).fb: ./DATA/$(1)/fa/$(1).fa
    @fa2fb 
lt; $@
endef

$(foreach module, $(MODULES), $(eval $(call rule,$(module))))

This is basically the same as Nemo's answer. I just tried to make the foreach call a bit more readable, by creating a list of modules, containing simply L1 L2 ... Ln, instead of the list of full source names.

MODULES := $(notdir $(wildcard ./DATA/L*))

define rule
./DATA/$(1)/fb/$(1).fb: ./DATA/$(1)/fa/$(1).fa
    @fa2fb 
lt; $@
endef

$(foreach module, $(MODULES), $(eval $(call rule,$(module))))
汐鸠 2024-12-01 03:22:55

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

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

请注意,此方法假设 fb 不会出现在文件名中的其他任何位置(如果所有文件名的格式为 DATA/Ln/fb/,则该结论成立) Ln.fb,对于某个整数n)。

Use secondary expansion and the subst function to create a rule where the prerequisites are constructed as a more complex function of the target name:

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

Note that this approach assumes that fb will not occur anywhere else in the filename (which holds true if all of your filenames are of the form DATA/Ln/fb/Ln.fb, for some integer n).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文