任何编译之前的 qmake 预构建步骤

问题描述 投票:0回答:4

关于如何为

qmake
创建预构建步骤有几个问题,我可以在我的
.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
标志,它会与其他构建作业并行 运行我的脚本。 这非常糟糕,因为我的脚本创建/更新了一个头文件 - 在编译过程中对其进行部分更改是不可接受的。

那么,我是否可以在运行 any 编译之前执行此脚本? 我知道我可以创建另一个脚本并依次调用

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
,但将其关闭并没有什么区别(当然除了速度慢得多)。

qt qmake
4个回答
14
投票

另一种选择是从原始问题中的项目文件片段开始,并确保 qmake 知道

versioning.h
是项目文件中其他构建目标的依赖项 -

  • versioning.h
    的完整路径添加到
    HEADERS
    变量中。
  • versioning.h
    所在的文件夹添加到您的
    DEPENDPATH
    变量中。

(警告:如果在

versioning.h
不存在时运行 qmake,它将发出“警告:找不到:versioning.h” - 该警告的唯一解决方法是使用
system()
命令
,如我在另一个答案中描述过。)

示例

创建

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
。)


8
投票

使用

system()
qmake 命令 — 它会在您运行
qmake
时运行,这会在
make
运行任何构建命令之前发生。

win32: PYTHON=python.exe
else:  PYTHON=python
system(cd $$PWD; $$PYTHON ./version_getter.py -p ../VersionData/versioning.h)

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 原语

就我而言,效果很好:我希望这个技巧也能帮助其他人。


0
投票

对此有更好的解决方案! 您可以利用

QMAKE_EXTRA_COMPILERS
强制同步预构建操作,这在使用 parallel 编译(make -j 标志)时有效!我不能相信这个解决方案,我在这个帖子中找到了它:https://stackoverflow.com/a/50619989/3220983

© www.soinside.com 2019 - 2024. All rights reserved.