【问题标题】:Using multiple % in Makefile在 Makefile 中使用多个 %
【发布时间】:2011-10-04 04:17:24
【问题描述】:

我必须通过命令(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 $< $@

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

非常感谢!

【问题讨论】:

    标签: makefile file-conversion


    【解决方案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 为每个源调用一次。源是call 的第一个参数,因此它在宏中变为$(1)。第二个参数只是从源文件名到目标文件名的转换;它在宏中变为$(2)

    用你自己的规则替换echo hi,你应该很高兴。并且一定要写一个漂亮的大而清晰的评论,否则总有一天会有人拿着棒球棒出现在你家门口。

    【讨论】:

    • 感谢您的建议。它有点复杂,但可能比另一个更强大。目前我会坚持第一个建议。关于 cmets 的信息很明确!
    【解决方案2】:

    使用secondary expansionsubst function 创建一个规则,其中先决条件被构造为目标名称的更复杂函数:

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

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

    【讨论】:

    • 谢谢。在我的情况下它工作正常。我将了解如何检查文件名中是否不存在 fa(或 fb?)。在实际情况下,它可能会发生。
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-10
      • 2013-08-16
      • 1970-01-01
      相关资源
      最近更新 更多