如何让qmake额外目标仅在目标过时后才执行?
在qmake中如何判断自定义目标是否过时?
你当前通过QMAKE_EXTRA_TARGETS定义的自定义目标(比如copy_zip)每次执行都会运行,本质是因为这类默认的自定义目标属于伪目标(phony target),构建系统不会检查任何文件的时间戳来判断是否需要重新执行。qmake文档里确实没直接提过时检测的配置方式,但可以通过给自定义目标关联实际输出文件来实现这个需求。
先看你当前的配置代码:
TARGET = demo SOURCES = main.cpp add_resource.commands = mkdir -p $${OUT_PWD}/$${TARGET}.app/Contents/Resources/ $$escape_expand(\n\t) add_resource.commands += cp $$PWD/resource.dat $${OUT_PWD}/$${TARGET}.app/Contents/Resources/ add_resource.depends += first create_zip.commands = zip -r $${OUT_PWD}/$${TARGET}.zip $${OUT_PWD}/$${TARGET}.app create_zip.depends += add_resource copy_zip.commands = cp $${OUT_PWD}/$${TARGET}.zip $${OUT_PWD}/$${TARGET}.zip.dat copy_zip.depends = create_zip QMAKE_EXTRA_TARGETS += add_resource create_zip copy_zip
解决方案:给自定义目标绑定输出文件
要让构建系统自动检测目标是否过时,需要给每个自定义目标添加target属性(指向该目标生成的实际文件/目录),同时明确列出依赖的输入文件。这样构建工具会对比输入文件和输出文件的时间戳,只有当输入更新或输出不存在时,才会执行目标命令。
修改后的配置示例:
TARGET = demo SOURCES = main.cpp # add_resource:绑定输出的resource.dat文件,依赖源文件和first目标 add_resource.target = $${OUT_PWD}/$${TARGET}.app/Contents/Resources/resource.dat add_resource.commands = mkdir -p $$dirname($@) && cp $$PWD/resource.dat $@ add_resource.depends = first $$PWD/resource.dat # create_zip:绑定输出的zip文件,依赖add_resource和app目录 create_zip.target = $${OUT_PWD}/$${TARGET}.zip create_zip.commands = zip -r $@ $${OUT_PWD}/$${TARGET}.app create_zip.depends = add_resource $${OUT_PWD}/$${TARGET}.app # copy_zip:绑定输出的zip.dat文件,依赖create_zip和源zip文件 copy_zip.target = $${OUT_PWD}/$${TARGET}.zip.dat copy_zip.commands = cp $${OUT_PWD}/$${TARGET}.zip $@ copy_zip.depends = create_zip $${OUT_PWD}/$${TARGET}.zip QMAKE_EXTRA_TARGETS += add_resource create_zip copy_zip
关键修改说明:
target:指定该自定义目标最终生成的文件路径,构建系统会以此为基准判断是否过时$@:在命令中指代target定义的输出文件,让命令更简洁且不易出错depends:除了依赖其他目标,还要加上生成输出所需的输入文件(比如resource.dat、demo.app),确保输入更新时目标会重新执行
替代方案:使用QMAKE_EXTRA_COMPILERS
如果你的自定义目标主要是做文件转换(比如从A文件生成B文件),可以用QMAKE_EXTRA_COMPILERS,它天生支持过时检测,配置更规范:
# 定义资源复制的编译器 resource_copier.input = $$PWD/resource.dat resource_copier.output = $${OUT_PWD}/$${TARGET}.app/Contents/Resources/${QMAKE_FILE_IN_BASE}${QMAKE_FILE_EXT} resource_copier.commands = mkdir -p $$dirname(${QMAKE_FILE_OUT}) && cp ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} resource_copier.depends = first QMAKE_EXTRA_COMPILERS += resource_copier # 后续的zip、copy步骤可以类似配置
内容的提问来源于stack exchange,提问作者glennr
相关产品推荐
相关产品推荐

