web-dev-qa-db-ja.com

コンパイル前のqmakeのプリビルドステップ

SOに関するいくつかの質問があります。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に設定すると、他のビルドジョブと共にparallelでスクリプトが実行されます。これは非常に悪いことです。スクリプトがヘッダーファイルを作成/更新するためです-コンパイル中に途中で変更することは受け入れられません。

それで、とにかくanyコンパイルが実行される前にこのスクリプトを実行させることができますか?別のスクリプトを作成してversion_getter.pyqmakeはそれ以降のシーケンスですが、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を使用したことが原因であると考えましたが、オフにしても違いはありませんでした(もちろん、速度が大幅に低下する以外は)。

24
cmannett85

もう1つのオプションは、元の質問のプロジェクトファイルスニペットから開始し、_versioning.h_がプロジェクトファイルの他のビルドターゲットの依存関係であることをqmakeが認識していることを確認することです—

  • _versioning.h_への完全パスをHEADERS変数に追加します。
  • _versioning.h_が存在するフォルダーをDEPENDPATH変数に追加します。

(警告:_versioning.h_が存在しないときにqmakeを実行すると、「WARNING:Failure to find: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_をコンパイルするコマンドを実行します。)

13
smokris

system() qmakeコマンドを使用します— qmakeを実行すると実行されます。これは、makeがビルドコマンドを実行する前に発生します。

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

Qmakeによって作成されたMakefileを調べると、ビルドの指示を含む別のルールデバッグ(またはリリース)に依存する「first」という名前の最初のMakefileルールが常にあることに気付きました。 Id est、このようなもの:

...
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が複数回実行されるのを防ぐことができます。 「最初の」は予約されていないため、ハッキングが可能であることに注意してください(ただし、名前は qmakeプリミティブ です)。

私の場合はうまくいきました。このトリックが他の人にも役立つことを願っています。

0
pgallir