PRE_TARGETDEPS 使用并行构建时失败
PRE_TARGETDEPS fails when using parallel builds
我正在使用自定义资源管理(替代 qrc)并且我正在尝试将它集成到 QtCreaor。
我有一个 Python 脚本可以生成要编译的源文件。我使用 QMAKE_EXTRA_TARGETS
/PRE_TARGETDEPS
来告诉 QMake
这个脚本必须在编译文件之前执行。所以我这样做了,在我的 pro 文件中:
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),我在日志中看到:
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.6\android_armv7\include -IB:\QtCreator5_6_1.6\android_armv7\include\QtWidgets -IB:\QtCreator5_6_1.6\android_armv7\include\QtGui -IB:\QtCreator5_6_1.6\android_armv7\include\QtCore -I. -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++.9\include -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++.9\libs\armeabi-v7a\include -isystem B:\Android\android-ndk-r11b\platforms\android-9\arch-arm\usr\include -IB:\QtCreator5_6_1.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.6\android_armv7\include -IB:\QtCreator5_6_1.6\android_armv7\include\QtWidgets -IB:\QtCreator5_6_1.6\android_armv7\include\QtGui -IB:\QtCreator5_6_1.6\android_armv7\include\QtCore -I. -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++.9\include -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++.9\libs\armeabi-v7a\include -isystem B:\Android\android-ndk-r11b\platforms\android-9\arch-arm\usr\include -IB:\QtCreator5_6_1.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.6\android_armv7\include -IB:\QtCreator5_6_1.6\android_armv7\include\QtWidgets -IB:\QtCreator5_6_1.6\android_armv7\include\QtGui -IB:\QtCreator5_6_1.6\android_armv7\include\QtCore -I. -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++.9\include -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++.9\libs\armeabi-v7a\include -isystem B:\Android\android-ndk-r11b\platforms\android-9\arch-arm\usr\include -IB:\QtCreator5_6_1.6\android_armv7\mkspecs\android-g++ -o generated.obj ..\TestQt\generated\generated.cpp
B:\QtCreator5_6_1.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
正确生成的(它现在包含 // This is valid C++!
)...但是编译器看到 fjkfkfk
显然太晚了。 ..
如您所见,输出报告:
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”)
看起来我的自定义命令generated_file
在编译generated\generated.cpp
之前就开始了,但是系统没有等它结束才真正编译generated\generated.cpp
。
我是不是做错了什么?
您需要将目标的名称设置为其生成的文件的名称。这是一个适合我的完整项目文件(qmake 3.1,Qt 5.10.1):
# Filename relative to the *build* directory.
generated_file.target = generated/generated.cpp
generated_file.commands = 'echo "Generating..." && mkdir -p generated && echo "int main() {}" > generated/generated.cpp'
generated_file.depends = FORCE
QMAKE_EXTRA_TARGETS += generated_file
# Filename relative to the *source* directory.
SOURCES += $$OUT_PWD/generated/generated.cpp
原因是generated_file.target
成为Makefile
中目标的名称,所以当需要generated.cpp
时,将执行您的自定义规则来创建文件。
您也可以从 PRE_TARGETDEPS
中删除它,因为您已经将生成的文件添加到 SOURCES instead
,这会创建适当的依赖关系。
请注意,此方法会在 build 目录中生成文件,而不是 source 目录中。这就是为什么在添加到 SOURCES
时需要指定 $$OUT_PWD
的原因:默认情况下,qmake 似乎假定 SOURCES
是相对于源目录的。
如果你想在 source 目录中生成它,你可能会认为你只是在每个地方加上前缀 $$PWD
,但是 qmake 有时使用绝对路径,有时相对的,一切都失败了。您可能可以使用 $$absolute_path($$PWD)
来解决这个问题,但我还没有尝试过。
生成的 Makefile
中的相关部分(评论是我的):
# How to create generated/generated.cpp.
# Depending on FORCE to make it always stale (fails if you create a file named FORCE :)).
generated/generated.cpp: FORCE
echo "Generating..." && mkdir -p generated && echo "int main() {}" > generated/generated.cpp
# generated.o depends on generated/generated.cpp.
# Note that it's not in the same directory; we don't care.
generated.o: generated/generated.cpp
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o generated.o generated/generated.cpp
# The final executable depends on the compiled generated.o.
OBJECTS = generated.o
$(TARGET): $(OBJECTS)
$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)
qmake documentation 对此很含糊,只说 target
应该是 "The name of the custom build target."。但是,示例显示他们将其设置为输出文件的名称。 (作为奖励,它还展示了如何在 commands
中不重复该名称。)
PRE_TARGETDEPS
(自定义目标)在这里不是好方法,因为 generated_file.target
必须与 Makefile 目标名称完全匹配,该名称可能因不同的选项而异:
- 影子构建是否启用
- 主机平台(使用斜杠或反斜杠作为文件夹分隔符)
- 可能是目标 compiler/platform
但是,自定义编译器显然工作得更好。移动文件就是这样完成的。自定义编译器可以生成要编译的新文件(然后系统在编译之前等待文件生成,即使在执行并行构建时也是如此)。
# 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
在清除后被删除!
这完全符合预期!
另一种方法依赖于 TEMPLATE=subdirs,以在并行构建环境中实现 libname.depends。每个应用程序文件夹中需要两个 .pro 文件。还有一个在共享库文件夹中。您的开发区域中使用 TEMPLATE=subdirs 的任何其他文件夹都需要兼容。
例如使用 LibLarry 的 TestApp。
文件夹 TestApp 有
bld.pro 和 TestApp.pro。
TestApp.pro:
#This is a TEMPLATE=subdirs, which gmake will interpret;
# making sure the build dependencies are respected
TEMPLATE = subdirs
SUBDIRS += bld mylib
bld.file = bld.pro
bld.depends = mylib # force library to be built first.
mylib.file = $${PATH_TO_LIB_LARRY}/liblarry.pro
bld.pro:
TARGET=TestApp
SOURCES+=TestApp.cpp
PRE_TARGETDEPS+=$${PATH_TO_LIB_LARRY}/liblarry.a
#boilerplate...
QT -= gui
CONFIG = ...
include ($${PATH_TO_LIB_LARRY}/liblarry.pri) # contains include file info
CONFIG += link_prl # allow lib larry to specify its position in the linker input command.
文件夹 LibLarry 有
LibLarry.pro
含
LibLarry.pro:
TARGET=larry
TEMPLATE=lib
CONFIG+=staticlib
CONFIG+=create_prl # export information, so apps can link correctly
SOURCES+=my_shared_function.cpp
include (liblarry.pri)
liblarry.pri:
HEADERS += $$PWD/my_shared_function.h
INCLUDEPATH += $$PWD
我正在使用自定义资源管理(替代 qrc)并且我正在尝试将它集成到 QtCreaor。
我有一个 Python 脚本可以生成要编译的源文件。我使用 QMAKE_EXTRA_TARGETS
/PRE_TARGETDEPS
来告诉 QMake
这个脚本必须在编译文件之前执行。所以我这样做了,在我的 pro 文件中:
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),我在日志中看到:
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.6\android_armv7\include -IB:\QtCreator5_6_1.6\android_armv7\include\QtWidgets -IB:\QtCreator5_6_1.6\android_armv7\include\QtGui -IB:\QtCreator5_6_1.6\android_armv7\include\QtCore -I. -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++.9\include -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++.9\libs\armeabi-v7a\include -isystem B:\Android\android-ndk-r11b\platforms\android-9\arch-arm\usr\include -IB:\QtCreator5_6_1.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.6\android_armv7\include -IB:\QtCreator5_6_1.6\android_armv7\include\QtWidgets -IB:\QtCreator5_6_1.6\android_armv7\include\QtGui -IB:\QtCreator5_6_1.6\android_armv7\include\QtCore -I. -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++.9\include -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++.9\libs\armeabi-v7a\include -isystem B:\Android\android-ndk-r11b\platforms\android-9\arch-arm\usr\include -IB:\QtCreator5_6_1.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.6\android_armv7\include -IB:\QtCreator5_6_1.6\android_armv7\include\QtWidgets -IB:\QtCreator5_6_1.6\android_armv7\include\QtGui -IB:\QtCreator5_6_1.6\android_armv7\include\QtCore -I. -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++.9\include -isystem B:\Android\android-ndk-r11b\sources\cxx-stl\gnu-libstdc++.9\libs\armeabi-v7a\include -isystem B:\Android\android-ndk-r11b\platforms\android-9\arch-arm\usr\include -IB:\QtCreator5_6_1.6\android_armv7\mkspecs\android-g++ -o generated.obj ..\TestQt\generated\generated.cpp
B:\QtCreator5_6_1.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
正确生成的(它现在包含 // This is valid C++!
)...但是编译器看到 fjkfkfk
显然太晚了。 ..
如您所见,输出报告:
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”)
看起来我的自定义命令generated_file
在编译generated\generated.cpp
之前就开始了,但是系统没有等它结束才真正编译generated\generated.cpp
。
我是不是做错了什么?
您需要将目标的名称设置为其生成的文件的名称。这是一个适合我的完整项目文件(qmake 3.1,Qt 5.10.1):
# Filename relative to the *build* directory.
generated_file.target = generated/generated.cpp
generated_file.commands = 'echo "Generating..." && mkdir -p generated && echo "int main() {}" > generated/generated.cpp'
generated_file.depends = FORCE
QMAKE_EXTRA_TARGETS += generated_file
# Filename relative to the *source* directory.
SOURCES += $$OUT_PWD/generated/generated.cpp
原因是generated_file.target
成为Makefile
中目标的名称,所以当需要generated.cpp
时,将执行您的自定义规则来创建文件。
您也可以从 PRE_TARGETDEPS
中删除它,因为您已经将生成的文件添加到 SOURCES instead
,这会创建适当的依赖关系。
请注意,此方法会在 build 目录中生成文件,而不是 source 目录中。这就是为什么在添加到 SOURCES
时需要指定 $$OUT_PWD
的原因:默认情况下,qmake 似乎假定 SOURCES
是相对于源目录的。
如果你想在 source 目录中生成它,你可能会认为你只是在每个地方加上前缀 $$PWD
,但是 qmake 有时使用绝对路径,有时相对的,一切都失败了。您可能可以使用 $$absolute_path($$PWD)
来解决这个问题,但我还没有尝试过。
生成的 Makefile
中的相关部分(评论是我的):
# How to create generated/generated.cpp.
# Depending on FORCE to make it always stale (fails if you create a file named FORCE :)).
generated/generated.cpp: FORCE
echo "Generating..." && mkdir -p generated && echo "int main() {}" > generated/generated.cpp
# generated.o depends on generated/generated.cpp.
# Note that it's not in the same directory; we don't care.
generated.o: generated/generated.cpp
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o generated.o generated/generated.cpp
# The final executable depends on the compiled generated.o.
OBJECTS = generated.o
$(TARGET): $(OBJECTS)
$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)
qmake documentation 对此很含糊,只说 target
应该是 "The name of the custom build target."。但是,示例显示他们将其设置为输出文件的名称。 (作为奖励,它还展示了如何在 commands
中不重复该名称。)
PRE_TARGETDEPS
(自定义目标)在这里不是好方法,因为 generated_file.target
必须与 Makefile 目标名称完全匹配,该名称可能因不同的选项而异:
- 影子构建是否启用
- 主机平台(使用斜杠或反斜杠作为文件夹分隔符)
- 可能是目标 compiler/platform
但是,自定义编译器显然工作得更好。移动文件就是这样完成的。自定义编译器可以生成要编译的新文件(然后系统在编译之前等待文件生成,即使在执行并行构建时也是如此)。
# 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
在清除后被删除!
这完全符合预期!
另一种方法依赖于 TEMPLATE=subdirs,以在并行构建环境中实现 libname.depends。每个应用程序文件夹中需要两个 .pro 文件。还有一个在共享库文件夹中。您的开发区域中使用 TEMPLATE=subdirs 的任何其他文件夹都需要兼容。
例如使用 LibLarry 的 TestApp。
文件夹 TestApp 有 bld.pro 和 TestApp.pro。
TestApp.pro:
#This is a TEMPLATE=subdirs, which gmake will interpret;
# making sure the build dependencies are respected
TEMPLATE = subdirs
SUBDIRS += bld mylib
bld.file = bld.pro
bld.depends = mylib # force library to be built first.
mylib.file = $${PATH_TO_LIB_LARRY}/liblarry.pro
bld.pro:
TARGET=TestApp
SOURCES+=TestApp.cpp
PRE_TARGETDEPS+=$${PATH_TO_LIB_LARRY}/liblarry.a
#boilerplate...
QT -= gui
CONFIG = ...
include ($${PATH_TO_LIB_LARRY}/liblarry.pri) # contains include file info
CONFIG += link_prl # allow lib larry to specify its position in the linker input command.
文件夹 LibLarry 有 LibLarry.pro 含
LibLarry.pro:
TARGET=larry
TEMPLATE=lib
CONFIG+=staticlib
CONFIG+=create_prl # export information, so apps can link correctly
SOURCES+=my_shared_function.cpp
include (liblarry.pri)
liblarry.pri:
HEADERS += $$PWD/my_shared_function.h
INCLUDEPATH += $$PWD