为多个目标编写一个包含一条规则的生成文件?

Posted

技术标签:

【中文标题】为多个目标编写一个包含一条规则的生成文件?【英文标题】:Write a makefile with one rule for many targets? 【发布时间】:2013-04-05 08:47:34 【问题描述】:

这似乎是一个非常简单的问题,但我找不到任何方法来解决它。

我的意图是通过调用 pyuic4 命令(来自PyQt)将每个“.ui”文件转换为“.py”文件。我试图用一个非常短的 makefile 来管理它:

%.py: %.ui
    pyuic4 $< --output $@

这就是我目前所需要的。

makefile 名为“Makefile”,位于调用“make”的文件夹中,“.ui”文件也是如此。 “pyuic4(.bat)”在系统路径中(Windows 7),Unix Utilities 也是,其中“make”是其中的一部分。

当从 Windows 控制台运行“make”时,它会说:

make: *** No targets.  Stop.

使用显式文件名从命令行调用 pyuic4 有效。

我知道我可以单独指定任何目标文件,但如果可能的话,我想避免这种情况。

有什么想法吗?

【问题讨论】:

您的示例适用于我在 linux 上。也许尝试使用 -d 选项来看看出了什么问题? 谢谢@suvayu 据说它正在为一个名为“Makefile”的文件寻找一个隐式规则,我无法理解。我正在使用 make 3.80。 您定义的规则要求您使用命令“make .py”,其中 是您要生成的文件的名称。 Make 不会自动假定您要将所有 ui 文件转换为 py 文件。 @ChristophJüngling 我忽略了你只是打电话给make。正如@kasterma 所说,您必须使用当前的 Makefile 键入 make filename @suvayu ...因为我没有指定一个目标,它将所有动作集中到这一点?好的,那么最好使用一个简单的 shell 脚本,就像 eriktous 写的那样。 【参考方案1】:

根据 kasterma 的评论,您需要告诉 make 要构建哪个目标,但您只提供了一个模式规则。这可以通过以下方式完成。

UIFILES := $(wildcard *.ui)
PYFILES := $(UIFILES:.ui=.py)

.PHONY: all
all: $(PYFILES)

%.py: %.ui
    pyuic4 $< --output $@

【讨论】:

【参考方案2】:

由于您显然使用的是 GNU Makefile 语法,我建议您这样编写规则:

UIFILES = $(wildcard *.ui)

.PHONY: ui2py

ui2py: $(UIFILES)
        @for uifile in $(UIFILES); do \
                pyuic4 $$(uifile) --output $$uifile%.ui.py; \
        done

【讨论】:

现在我得到另一个错误:程序异常终止 C:\Users\...\Temp\make9642.sh: fork failed: no error [1] make: *** [ui2py] Error 1 嗯,你真的信任你的硬件还是你的系统?因为,看起来问题不在于 Makefile,而在于较低级别。 不,我不知道,这是 Windows :-) 我会在旧的 XP 机器上试试这个,在这个机器上一个更大的 makefile 可以正常工作。 这只是一个伪装的shell脚本。如果您要这样做,几乎不需要使用 make(这可能是 OP 的正确方法)。【参考方案3】:

虽然问题可以通过 perror 或 eriktous 的解决方案来解决,但我现在将采用 eriktous 提到的第三种方式,只需使用 shell 脚本调用 pyuic4 命令。它的运行速度非常快,即使输出会产生相同的文件,也不会对源代码控制造成伤害。

我遇到了第二点,这可能让我分心了。 pyuic4命令真正命名为pyuic4.bat,在Windows中是一个“批处理文件”,类似于Linux/Unix环境下的shell脚本;相似,但不相同。如果从另一个批处理文件调用批处理文件,则应使用前导“调用”语句调用它,以防止在第一次调用后终止批处理。

如果我有三个文件(@符号是为了防止命令在执行过程中被列出)

D:\Projekte\test>type main.cmd
@sub1
@sub2

D:\Projekte\test>type sub1.cmd
@echo This is sub 1

D:\Projekte\test>type sub2.cmd
@echo This is sub 2

...结果只是

D:\Projekte\test>main
This is sub 1

所以我对这个非常小的东西的“解决方案”是一个名为“update.cmd”的简单批处理文件,可以通过以下行的副本进行扩展:

call pyuic4 mainwindow.ui --output mainwindow.py

这不是我最初想要的,但它对我有用。

但无论如何,谢谢你的帮助:-)

【讨论】:

以上是关于为多个目标编写一个包含一条规则的生成文件?的主要内容,如果未能解决你的问题,请参考以下文章

Makefile文件的基本单元 —— 规则

初识makefile

makefile编写

跟我一起写Makefile

从源文件生成目标文件的通用“make”规则

通用生成文件显示没有生成目标错误的规则