有没有办法在 .pro 文件中指定要添加到{{1>}生成的 Makefile 中的标准目标的额外命令?例如,考虑qmake
,可能需要额外的命令:
我想使用普通目标而不是自定义目标,因为我希望它在我的工作流程中完全透明。那是(再次以distclean
为例),我不想......
distclean
。distclean
已经well-known且直观†。 我找到了How to add custom targets in a qmake generated Makefile?,但这描述了添加自定义目标(already documented,甚至是back in 4.6),而不是向现有目标添加规则。虽然它确实包含一些提示,但它们都需要添加新的自定义目标,因为在 Makefile 中多次指定同一目标会替换(不添加)来自前一目标的命令。
我唯一能想到的尝试是将distclean
添加到 .pro 文件中作为一个疯狂的猜测(例如target.commands += new commands
)。这没有效果。
如何使用distclean.commands += rm \"*~\"
透明地向现有目标添加自定义命令?
† 对于qmake
示例:虽然distclean
也在"标准目标"列表,在实践中我发现它很少使用,并且在任何情况下maintainer-clean
默认情况下都不会生成它;我认为它不合适。
答案 0 :(得分:22)
有两种直接的方法可以实现这一点,具体取决于您希望解决方案的自包含/可移植性以及您希望对命令执行顺序的宽松程度。
第一个选项是在 .pro 文件中为新命令创建自定义目标,然后将该目标添加为要修改的标准目标的先决条件。回到distclean
示例,假设您要添加一个命令来删除所有 *〜文件:
在 .pro 文件中创建自定义目标。请注意,您必须在 .pro 文件中转义引号和斜杠。例如,添加:
extraclean.commands = find . -name \"*~\" -exec rm -v {} \\;
将此目标添加为您要修改的目标的依赖项:
distclean.depends = extraclean
这实际上不会修改distclean
规则,因为此方法不能用于修改现有规则。然而...
将新目标和要修改的目标添加为额外目标:
QMAKE_EXTRA_TARGETS += distclean extraclean
这会向distclean
添加Makefile
的第二个规范,但这可行,因为you can add dependencies to existing targets in make
in separate rules, even though you can't add commands that way。如果您还要在 .pro 文件中指定distclean.commands
,则可以通过替换其默认配方来中断现有distclean
。
所以,把它们放在一起,放在 .pro 文件中:
extraclean.commands = find . -name \"*~\" -exec rm -v {} \\;
distclean.depends = extraclean
QMAKE_EXTRA_TARGETS += distclean extraclean
其中extraclean
是包含您要添加的命令的自定义目标,distclean
是您要修改的现有目标。
优点:
qmake
。缺点:
distclean
示例中,使用我正在使用的qmake
版本,这会将命令放在源树清理之后,但在 Makefile 本身被删除之前(这是只有默认配方采取的行动)。对于此示例,这不是问题,但可能是您的问题。第二个选项是更改qmake
生成的 Makefile 的名称,并创建自己的 Makefile 推迟 >生成的,而不是包括+覆盖它。这也是一个简单的选择;虽然不像选项1那样自包含,但它使您能够在默认生成的配方之前和之后执行命令。
您不希望包含+覆盖现有的 Makefile ,因为您不想替换默认配方。如果这样做,则必须重新实现默认值,但这可能是一个问题,因为默认值可能会更改(并且您必须跟上更改)。最好让qmake
做尽可能多的工作,而不是重复它的工作。
要做到这一点:
首先,更改qmake
生成的文件的名称。这可以通过在 .pro 文件中添加这样的行来实现:
MAKEFILE = RealMakefile
这将导致qmake
输出 RealMakefile 而不是 Makefile 。
下一步是使用自定义命令创建自己的Makefile
。但是,这里有一些警告。首先,再次使用distclean
的完整示例。在名为Makefile
的文件中:
.DEFAULT_GOAL := all
%:
@$(MAKE) -f RealMakefile $@
distclean:
@$(MAKE) -f RealMakefile $@
@find . -name "*~" -exec rm -v {} \;
关于此的一些注意事项:
.DEFAULT_GOAL
,否则distclean
将成为默认值。如果您对.DEFAULT_GOAL
不满意,可以选择使用all
作为配方来指定@$(MAKE) -f RealMakefile $@
规则。 %
目标匹配此 Makefile 中未另行定义的任何目标。它只是将处理委托给 RealMakefile 。distclean
目标是我们添加命令的地方。我们仍然需要委托 RealMakefile ,但可以在发生之前和之后添加其他命令。优点:
缺点:
qmake
,而且我实际上也不确定哪些部分特定于GNU make
(欢迎评论)。所以,虽然这个答案可能有点长,但这两种方法都非常简单。除非命令执行顺序是个问题,否则我更喜欢选项1。
答案 1 :(得分:0)
另一种解决方案是将要删除的文件添加到 QMAKE_CLEAN
和 QMAKE_DISTCLEAN
qmake 变量中。
build_tests {
TINYORM_SQLITE_DATABASE = $$quote($$TINYORM_BUILD_TREE/tests/q_tinyorm_test_1.sqlite3)
QMAKE_CLEAN = $$TINYORM_SQLITE_DATABASE
QMAKE_DISTCLEAN = $$TINYORM_SQLITE_DATABASE
}
这只是相关的,您什么时候知道要删除的文件,因此在这种情况下,您不能使用 rm
命令或某种通配符。