有关如何为qmake
创建预构建步骤的SO有几个问题,我可以在我的.pro
文件中执行此操作:
versionTarget.target = ../VersionData/versioning.h
versionTarget.depends = FORCE
win32: versionTarget.commands = cd $$PWD; python.exe ./version_getter.py -p $$TARGET
else: versionTarget.commands = cd $$PWD; python ./version_getter.py -p $$TARGET
PRE_TARGETDEPS += ../VersionData/versioning.h
QMAKE_EXTRA_TARGETS += versionTarget
现在,问题是这种方法本身不是构建步骤而只是另一个构建目标,所以如果我为-j
配置了make
标志,它会在中运行我的脚本与其他构建作业并行。这是非常糟糕的,因为我的脚本创建/更新了一个头文件 - 在编译过程中改变它是不可接受的。
那么,无论如何我可以在运行任何编译之前执行此脚本吗?我知道我可以创建另一个脚本并按顺序调用version_getter.py
和qmake
,但这是不可取的,因为我必须从命令行而不是从Qt Creator中编译。
每个子项目包含的完整.pri
文件如下:
CONFIG += thread
QT += core \
gui
versionTarget.target = ../VersionData/versioning.h
versionTarget.depends = FORCE
win32: versionTarget.commands = cd $$PWD; python.exe ./version_getter.py -p $$TARGET
else: versionTarget.commands = cd $$PWD; python ./version_getter.py -p $$TARGET
PRE_TARGETDEPS += ../VersionData/versioning.h
QMAKE_EXTRA_TARGETS += versionTarget
DEPENDPATH += ../VersionData
INCLUDEPATH += ../VersionData
HEADERS += ../VersionData/versioning.h
UI_HEADERS_DIR = $${_PRO_FILE_PWD_}/include/Qui
DESTDIR = $(SYREN_PATH)
!win32-msvc {
QMAKE_CXXFLAGS += -std=c++0x
}
但这仍然导致相同的并行行为。我认为这可能是由于我使用了ccache
,但将其关闭没有任何区别(当然除了慢得多)。
答案 0 :(得分:13)
另一种选择是从原始问题中的项目文件片段开始,并确保qmake知道versioning.h
是项目文件中其他构建目标的依赖项 -
versioning.h
的完整路径添加到HEADERS
变量。versioning.h
所在的文件夹添加到DEPENDPATH
变量。(警告:如果你在versioning.h
不存在时运行qmake,它会发出“警告:找不到:versioning.h” - the only workaround for that warning is to use the system()
command,正如我在其他答案中所描述的那样。 )
创建包含以下内容的test.pro
:
versionTarget.target = ../versioning.h
versionTarget.depends = FORCE
versionTarget.commands = sleep 5s ; touch ../versioning.h
PRE_TARGETDEPS += ../versioning.h
QMAKE_EXTRA_TARGETS += versionTarget
SOURCES = test.c
HEADERS = ../versioning.h
DEPENDPATH = ..
创建包含以下内容的test.c
:
#include "../versioning.h"
运行qmake
。它将输出WARNING: Failure to find: ../versioning.h
。
运行make -j9
。它将运行versionTarget.commands
(睡眠5秒以夸大任何多处理问题),然后,运行命令编译test.c
。
(如果你检查生成的Makefile
,你会发现test.o
取决于test.c
和../versioning.h
,所以Make应该正确地指出它可以在创建/更新test.c
命令之前运行命令编译../versioning.h
。)
答案 1 :(得分:6)
使用system()
qmake命令 - 它在您运行qmake
make
运行任何构建命令之前运行时运行。
win32: PYTHON=python.exe
else: PYTHON=python
system(cd $$PWD; $$PYTHON ./version_getter.py -p ../VersionData/versioning.h)
答案 2 :(得分:0)
我注意到,如果您检查qmake生成的Makefile,则总是存在第一个名为“ first”的Makefile规则,该规则取决于另一个包含构建说明的规则调试(或发布)。像这样:
...
MAKEFILE = Makefile
first: debug
...
为了创建一个预构建步骤,我们应该修改该规则以依赖于另一个优先级更高的规则。
类似
...
MAKEFILE = Makefile
first: prebuild debug
prebuild:
do_your_instructions
...
这实际上等于以下内容:
...
MAKEFILE = Makefile
first: debug
...
first: prebuild
prebuild:
do_your_instructions
...
通过执行以下操作可以很容易地将其入侵qmake项目中:
# $$PWD/test_prebuild is a batch with the instructions to execute before every build
!build_pass:prebuild.commands = $$PWD/test_prebuild
!build_pass:first.depends = prebuild
QMAKE_EXTRA_TARGETS += prebuild first
请注意,“!build_pass:”可确保仅在Makefile中(而不是在Makefile.Debug或Makefile.Release中)编写此预构建规则,从而防止多次执行test_prebuild。 请注意,这是可能的,因为“ first”未保留(尽管名称为qmake primitive。
就我而言,它运作良好:我希望这个技巧也能对其他人有所帮助。