如何在不同目录中指定makefile的目标?

6
我正在尝试弄清楚为什么我无法将目标指定为不同的目录。
我正在尝试从json文件生成一些php类,但是我已经将生成php的那一行改成了一个虚拟的echo语句,这样其他人就可以复制粘贴并测试,如果他们感到非常慷慨的话。
有两件事情需要添加到包含makefile的目录中:
- 一个名为PatientDbPath.json的虚拟依赖文件。 - 一个名为out的目录。
如果我有一个包含以下内容的makefile:
.SUFFIXES: .php .json
.json.php:
    echo "HelloMe" > PatientDbPath.php

PatientDbPath.php: PatientDbPath.json

clean:
    $(RM) PatientDbPath.php

当我运行make时,一切都正常;PatientDbPath.php被正确创建,并且下次运行make时,我会收到消息make:'PatientDbPath.php'已经是最新的

但是,我想在一个单独的目录中生成php文件,因此我更新了我的makefile如下:

.SUFFIXES: .php .json
.json.php:
    echo "HelloMe" > out/PatientDbPath.php

out/PatientDbPath.php: PatientDbPath.json

clean:
    $(RM) out/PatientDbPath.php

当我这样做时,Make告诉我make: Nothing to be done for 'out/PatientDbPath.php',尽管在out目录中没有PatientDbPath.php文件。

所以我想也许是后缀规则的问题,于是我创建了第三个makefile。

out/PatientDbPath.php: PatientDbPath.json
    echo "Whatever" > out/PatientDbPath.php

clean:
    rm out/PatientDbPath.php

这个很好,像第一个一样有效。有人能看出我第二个 makefile 做错了什么吗?
谢谢。
2个回答

5

还有一种更优雅的方法来完成相同的事情:

$(JSON_FILES): out/%.php: %.json
    action

这将为在JSON_FILES列表中列出的每个文件创建一个规则。因此,如果定义了JSON_FILES= foo.json bar.json,则这相当于:

out/foo.php: foo.json
    action

out/bar.php: bar.json
    action

你可以使用$(wildcard *.json)来设置该值,如果你真的想要所有的.json文件,或者如果该规则仅适用于少数文件,则可以手动设置。

4

您的通配符规则(.json -> .php)存在两个错误,一个是概念上的错误,另一个是实际上的错误。

概念上的错误在于这是一条将任意json文件(比如foo.json)转换为任意同名.php文件(比如json.php)的规则。然而,您的规则是专门用于生成PatientDbPth.php的。更好的规则应该是:

.json.php:
    echo "HelloMe" > $@

其中$@是一个变量,用于命名输出文件。

这也展示了实际问题:这些规则真的只适用于同名文件。如果您有一个将.json转换为.php的规则,并且您有foo.php和bar.php,但您想要out/PatientDbPath.php,那么通配符规则将无法匹配。匹配涉及整个文件名,因此通配符规则在请求out/PatientDbPath.php时不匹配。这使您得到没有操作的规则,因此make推断不需要执行任何操作。

如果这是您想要转换的唯一文件,则最好像第三个文件中所做的那样编写它。如果您有许多json文件,并且都想将它们转换为out/*.php,并且您正在使用GNU make,则可以使用GNU make的广义通配符规则:

out/%.php:    %.json
    action

谢谢回复,我将尝试更改我的真实makefile以使用建议的符号表示法。我很快会跟进或标记它已回答。关于概念上的问题,我在这里发布的只是一个显示问题的示例makefile,并非我的真实makefile。 - Ruan Mendes
好的,我测试了一下,你说得对,将我的 makefile 更改为使用 out/%.php : %.json 就解决了问题。我有一个后续问题。我需要为该目录中的每个 .json 文件创建单独的规则吗? - Ruan Mendes
我找到了我想要的解决方案,基本上我需要添加以下行:all:: $(patsubst %.json, out/%.php, $(wildcard *.json)) 这将为从该目录中的每个 .json 生成的每个 php 文件添加依赖关系。 - Ruan Mendes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接