使用并行构建时 PRE_TARGETDEPS 失败 [英] PRE_TARGETDEPS fails when using parallel builds
问题描述
我正在使用自定义资源管理(代替 qrc)并且我正在尝试将其集成到 QtCreaor.
I'm using a custom ressource management (in replacement to qrc) and I'm trying to integrate it to QtCreaor.
我有一个 Python 脚本,可以生成要编译的源文件.我使用 QMAKE_EXTRA_TARGETS
/PRE_TARGETDEPS
告诉 QMake
这个脚本必须在编译文件之前执行.所以我这样做,在我的专业文件中:
I have a Python script that generates a source file to be compiled. I use QMAKE_EXTRA_TARGETS
/PRE_TARGETDEPS
to tell QMake
that this script must be executed before files are compiled. So I do, in my pro file:
CONFIG += ordered
generated_file.target = my_custom_target
generated_file.commands = echo "Generating..." && d:/dev/vobs_ext_2015/tools_ext/python/Python34_light/python.exe $$PWD/pyc_res_generator.py -o $$PWD/generated/generated.cpp && echo "Generated!"
generated_file.depends = FORCE
QMAKE_EXTRA_TARGETS += generated_file
PRE_TARGETDEPS += my_custom_target
SOURCES += generated/generated.cpp
#DEPENDPATH = ./generated
pyc_res_generator.py
就是:
#! /usr/bin/env python
# -*- coding: utf8 *-*
import argparse
parser = argparse.ArgumentParser(description="", formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument("-o", type=str, help="Output file name")
args = parser.parse_args()
with open(args.o, 'w') as output_file:
output_file.write( "// This is valid C++!" )
为了测试这个,我在generated.cpp中写了一些无效的C++(比如fjkfkfk
).当我编译(目标是Android)时,我在日志中看到:
To test this, I write some invalid C++ in generated.cpp (like fjkfkfk
). When I compile (target is Android), I see in the log:
echo Generating... && python.exe pyc_res_generator.py -o generated/generated.cpp && echo Generated!
Generating...
B:\Android\android-ndk-r11b/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi-g++ -c -Wno-psabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -DANDROID -Wa,--noexecstack -fno-builtin-memmove -std=c++11 -g -g -marm -O0 -fno-omit-frame-pointer -Wall -Wno-psabi -W -D_REENTRANT -fPIC -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I..\TestQt -I. -IB:\QtCreator5_6_1\5.6\android_armv7\include -IB:\QtCreator5_6_1\5.6\android_armv7\include\QtWidgets -IB:\QtCreator5_6_1\5.6\android_armv7\include\QtGui -IB:\QtCreator5_6_1\5.6\android_armv7\include\QtCore -I. -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++\4.9\include -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++\4.9\libs\armeabi-v7a\include -isystem B:\Android\android-ndk-r11b\platforms\android-9\arch-arm\usr\include -IB:\QtCreator5_6_1\5.6\android_armv7\mkspecs\android-g++ -o main.obj ..\TestQt\main.cpp
B:\Android\android-ndk-r11b/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi-g++ -c -Wno-psabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -DANDROID -Wa,--noexecstack -fno-builtin-memmove -std=c++11 -g -g -marm -O0 -fno-omit-frame-pointer -Wall -Wno-psabi -W -D_REENTRANT -fPIC -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I..\TestQt -I. -IB:\QtCreator5_6_1\5.6\android_armv7\include -IB:\QtCreator5_6_1\5.6\android_armv7\include\QtWidgets -IB:\QtCreator5_6_1\5.6\android_armv7\include\QtGui -IB:\QtCreator5_6_1\5.6\android_armv7\include\QtCore -I. -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++\4.9\include -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++\4.9\libs\armeabi-v7a\include -isystem B:\Android\android-ndk-r11b\platforms\android-9\arch-arm\usr\include -IB:\QtCreator5_6_1\5.6\android_armv7\mkspecs\android-g++ -o dialog.obj ..\TestQt\dialog.cpp
B:\Android\android-ndk-r11b/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi-g++ -c -Wno-psabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -DANDROID -Wa,--noexecstack -fno-builtin-memmove -std=c++11 -g -g -marm -O0 -fno-omit-frame-pointer -Wall -Wno-psabi -W -D_REENTRANT -fPIC -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I..\TestQt -I. -IB:\QtCreator5_6_1\5.6\android_armv7\include -IB:\QtCreator5_6_1\5.6\android_armv7\include\QtWidgets -IB:\QtCreator5_6_1\5.6\android_armv7\include\QtGui -IB:\QtCreator5_6_1\5.6\android_armv7\include\QtCore -I. -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++\4.9\include -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++\4.9\libs\armeabi-v7a\include -isystem B:\Android\android-ndk-r11b\platforms\android-9\arch-arm\usr\include -IB:\QtCreator5_6_1\5.6\android_armv7\mkspecs\android-g++ -o generated.obj ..\TestQt\generated\generated.cpp
B:\QtCreator5_6_1\5.6\android_armv7\bin\moc.exe -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -IB:/QtCreator5_6_1/5.6/android_armv7/mkspecs/android-g++ -IC:/Users/jp225611/Documents/TestQt -IB:/QtCreator5_6_1/5.6/android_armv7/include -IB:/QtCreator5_6_1/5.6/android_armv7/include/QtWidgets -IB:/QtCreator5_6_1/5.6/android_armv7/include/QtGui -IB:/QtCreator5_6_1/5.6/android_armv7/include/QtCore -I. -IB:\Android\android-ndk-r11b/sources/cxx-stl/gnu-libstdc++/4.9/include -IB:\Android\android-ndk-r11b/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/include -IB:\Android\android-ndk-r11b/platforms/android-9/arch-arm//usr/include ..\TestQt\dialog.h -o moc_dialog.cpp
..\TestQt\generated\generated.cpp:1:1: error: 'fjkfkfk' does not name a type
// This is valid C++!
^
makefile:670: recipe for target 'generated.obj' failed
mingw32-make: *** [generated.obj] Error 1
mingw32-make: *** Waiting for unfinished jobs....
Generated!
13:59:08: Le processus "B:\QtCreator5_6_1\Tools\mingw492_32\bin\mingw32-make.exe" s'est terminé avec le code 2.
Erreur lors de la compilation/déploiement du projet TestQt (kit : android_armeabi-v7a)
When executing step "Make"
13:59:08: Temps écoulé : 00:03.
并且我看到 generated\generated.cpp
是由 pyc_res_generator.py
正确生成的(它现在包含 //这是有效的 C++!
)...但显然为时已晚,因为编译器看到 fjkfkfk
...如您所见,输出报告:
And I see that generated\generated.cpp
was correctly generated by pyc_res_generator.py
(it now contains // This is valid C++!
)...but apparently too lately as the compiler saw fjkfkfk
...
As you can see, the output reports:
Generating...
B:\Android\android-ndk-r11b/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi-g++ .... ..\TestQt\generated\generated.cpp
Generated...
虽然人们期望:
Generating...
Generated...
B:\Android\android-ndk-r11b/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin/arm-linux-androideabi-g++ .... ..\TestQt\generated\generated.cpp
这仅在启用并行构建时发生(我将 MAKEFLAGS
环境变量设置为-j8")
This only occurs when parallel builds are enabled (I set MAKEFLAGS
environment variable to '-j8`)
看起来我的自定义命令 generated_file
是在编译 generated\generated.cpp
之前启动的,但是系统在实际编译 之前并没有等待它结束>generated\generated.cpp
.
It looks like my custom command generated_file
is started before generated\generated.cpp
is compiled, but the system does not wait for it to end before actually compiling generated\generated.cpp
.
我做错了什么吗?
推荐答案
PRE_TARGETDEPS
(自定义目标)在这里不是好方法,因为 generated_file.target
必须完全匹配Makefile 目标名称可能因不同选项而异:
PRE_TARGETDEPS
(custom targets) is not the good approach here as generated_file.target
must match exactly the Makefile target name which may be vary on different options:
- 启用或不启用影子构建
- 主机平台(使用斜杠或反斜杠作为文件夹分隔符)
- 可能针对编译器/平台
然而,自定义编译器显然效果更好.这就是模拟文件的完成方式.自定义编译器可以生成要编译的新文件(然后系统会在编译之前等待文件生成,即使在执行并行构建时也是如此).
However, custom compiler apparently works much better. That's how moccing files is done. A custom compiler can generate a new file to be compiled (and then the system waits for the file to be generated before compiling it, even when performing parallel builds).
# Set fuiles to be generated in a variable
TO_GENERATE = $$PWD/generated/generated.cpp
# Specify custom command output file:
custom_generator.output = $$PWD/generated/generated.cpp
# Specify custom command:
custom_generator.commands = 'echo "Generating..." && python $$PWD/pyc_res_generator.py -o $$PWD/generated/generated.cpp && echo "Generated..."'
# dependency:
custom_generator.depends = FORCE
# link to input file variable
custom_generator.input = TO_GENERATE
# link to variable to store generated file to
custom_generator.variable_out = SOURCES
# add to qmake:
QMAKE_EXTRA_COMPILERS += custom_generator
然后,您甚至不需要指定SOURCES += $$PWD/generated/generated.cpp
.而且,$$PWD/generated/generated.cpp
在清理时会被删除!
Then, you don't even need to specify SOURCES += $$PWD/generated/generated.cpp
. And also, $$PWD/generated/generated.cpp
gets deleted upon clean!
这完全符合预期!
这篇关于使用并行构建时 PRE_TARGETDEPS 失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!