Ошибка PRE_TARGETDEPS при использовании параллельных сборок - PullRequest
0 голосов
/ 29 мая 2018

Я использую пользовательское управление ресурсами (вместо qrc) и пытаюсь интегрировать его в QtCreaor.

У меня есть скрипт Python, который генерирует исходный файл для компиляции.Я использую QMAKE_EXTRA_TARGETS / PRE_TARGETDEPS, чтобы сообщить QMake, что этот сценарий должен быть выполнен до компиляции файлов.Итак, я делаю, в моем профессиональном файле:

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++!" )

Чтобы проверить это, я пишу недопустимый C ++ в генерируемом.cpp (например, 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\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 (теперь он содержит // 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.

Я что-то не так делаю?

Ответы [ 3 ]

0 голосов
/ 31 мая 2018

PRE_TARGETDEPS (пользовательские цели) здесь не очень подходит, так как generated_file.target должно точно соответствовать имени цели Makefile, которое может варьироваться в зависимости от параметров:

  • построение теней включено или нет
  • хост-платформа (используя косую черту или обратную косую черту в качестве разделителя папок)
  • возможно, целевой компилятор / платформа

Однако, пользовательский компилятор, очевидно, работает намного лучше.Вот так делаются моховые файлы.Пользовательский компилятор может сгенерировать новый файл для компиляции (и затем система ждет, пока файл будет сгенерирован, прежде чем компилировать его, даже при выполнении параллельных сборок).

# 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 удаляется после очистки!

Это работает отлично, как и ожидалось!

0 голосов
/ 06 августа 2019

Альтернатива опирается на подкаталоги TEMPLATE =, чтобы учитывать libname.depends в среде параллельной сборки.Вам потребуется два .pro-файла в каждой папке приложения.И один в папке общей библиотеки.Любые другие папки в вашей области разработки, использующие TEMPLATE = subdirs, должны быть совместимы.

например, TestApp с использованием LibLarry.

Папка 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
0 голосов
/ 29 мая 2018

Вам необходимо установить имя цели на имя файла, который она генерирует.Вот полный файл проекта, который работает для меня (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 .Вот почему вам нужно указать $$OUT_PWD при добавлении его в SOURCES: по умолчанию qmake, похоже, предполагает, что SOURCES относительно исходного каталога.

Если вы хотите сгенерировать его вВместо этого source directory, вы можете подумать, что вы просто префикс $$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 довольно расплывчата по этому поводу, только заявляя, что target должно быть "Имя цели пользовательской сборки."Тем не менее, пример показывает, что они устанавливают имя выходного файла.(В качестве бонуса также показано, как не повторять это имя в commands.)

...