Цепочка сборки проектов из исходников

Как и где устанавливаются разные переменные (QT_BUILD_TREE, QMAKE_LIBDIR_QT и т.д. ) для настройки сборки в файлах проектов .pro ? Вопрос наверное один из важнейших для понимания где искать проблемы.

Установка переменных сборки

На самом деле самые первые переменные сборки зашиты прямо внутри в бинарном файле qmake.exe. Это очень своеобразный подход , но наверное у разработчиков Qt были на это причины... Будем называть их переменные 0 уровня.

Далее как продолжается установка переменных . Когда в Qt Creator открывается проект , то Qt Creator уже получает переменные 1 уровня (это мы так будем называть) из файла .qmake.cash , который может лежать на более высоких чем сам проект уровнях.

.qmake.cash генерируется утилитой config.exe , которая сама входит в состав исходников в ветке tools, то есть ее код можно смотреть и ее можно пересобрать заново. Но не об этом речь.

Вот очень простое содержание .qmake.cash :


QMAKE_QT_VERSION_OVERRIDE = 4
OBJECTS_DIR     = tmp/obj/release_shared
MOC_DIR         = tmp/moc/release_shared
RCC_DIR         = tmp/rcc/release_shared
sql-plugins    += sqlite
styles         += windows plastique cleanlooks windowsxp windowsvista motif cde
TMPPATH            = $$quote($$(INCLUDE))
QMAKE_INCDIR_POST += $$split(TMPPATH,";")
TMPPATH            = $$quote($$(LIB))
QMAKE_LIBDIR_POST += $$split(TMPPATH,";")
CONFIG         += minimal-config small-config medium-config large-config full-config release incremental msvc_mp create_prl link_prl depend_includepath QTDIR_build
QT_BUILD_PARTS  = libs tools examples demos docs translations
QMAKESPEC       = C:/QtSDK1.2.1/QtSources/4.8.1/mkspecs/win32-g++
ARCH            = windows
QT_BUILD_TREE   = C:/QtSDK1.2.1/QtSources/4.8.1
QT_SOURCE_TREE  = C:/QtSDK1.2.1/QtSources/4.8.1
QMAKE_MOC       = $$QT_BUILD_TREE/bin/moc.exe
QMAKE_UIC       = $$QT_BUILD_TREE/bin/uic.exe
QMAKE_UIC3      = $$QT_BUILD_TREE/bin/uic3.exe
QMAKE_RCC       = $$QT_BUILD_TREE/bin/rcc.exe
QMAKE_DUMPCPP   = $$QT_BUILD_TREE/bin/dumpcpp.exe
QMAKE_INCDIR_QT = $$QT_BUILD_TREE/include
QMAKE_LIBDIR_QT = $$QT_BUILD_TREE/lib

Основным параметром как видно является QT_BUILD_TREE и QT_SOURCE_TREE, то есть каталог куда будут собираться проект(ы) и где лежат исходники проектов.

Далее все ниже стоящие дополнительные настройки делаются непосредственно в файлах .pro и .pri ваших проектов и их подпроектов. Вот тут как раз и трудно разобраться , но мы попробуем... Как всегда все начинается сначала .... То есть если мы открываем файл проекта всех исходников src.pro , то и читаем всерху вниз все инструкции файла src.pro:

При сборке есть закономерности : например зависимость прокетов реализована специальным образом , так что первым будет собираться bootstrap (начальная загрузка), потом moc.pro , rcc.pro , uic.pro , corelib ,.. Как это так получается?

Src.pro реализует на самом деле набор проектов раскиданных по каталогам , src.pro имеет тип subdirs , то есть :
TEMPLATE = subdirs

ОК , но еще в начале src.pro мы видим конструкцию :
!wince*:!symbian-abld:!symbian-sbsv2:include(tools/tools.pro)

А это значит , что на самом деле сначала будет выполняться сборка проекта tools/tools.pro в буквальном смысле.

То есть смотрим сначала проект tools/tools.pro и видим , что он тоже в свою очередь имеет тип subdirs. И его последовательность сборки задается в переменной TOOLS_SUBDIRS:

TOOLS_SUBDIRS = src_tools_bootstrap src_tools_moc src_tools_rcc
бла бла бла и в конце
SUBDIRS = $$TOOLS_SUBDIRS $$SUBDIRS
то есть TOOLS_SUBDIRS будет собираться ранее SUBDIRS!

И тут есть важный для понимания момент есть переменные TOOLS_SUBDIRS и SRC_SUBDIRS , а есть непосредственно директива SUBDIRS, которую в результате мы и должны сформировать.

Так вот получился SUBDIRS = src_tools_bootstrap src_tools_moc src_tools_rcc src_tools_uic src_corelib .

Вот и все , на самом деле все становится очевидным.... Именно поэтому мы имеем такую последовательность сборки проектов :

Reading C:/QtSDK1.2.1/QtSources/4.8.1/src/tools/bootstrap/bootstrap.pro
Reading C:/QtSDK1.2.1/QtSources/4.8.1/src/tools/moc/moc.pro
Reading C:/QtSDK1.2.1/QtSources/4.8.1/src/tools/rcc/rcc.pro
Reading C:/QtSDK1.2.1/QtSources/4.8.1/src/tools/uic/uic.pro
Reading C:/QtSDK1.2.1/QtSources/4.8.1/src/corelib/corelib.pro

если мы подключим network к сборке , то увидим ниже (именно в этом месте)
Reading C:/QtSDK1.2.1/QtSources/4.8.1/src/network/network.pro

если мы подключим gui к сборке , то увидим ниже (именно в этом месте)
Reading C:/QtSDK1.2.1/QtSources/4.8.1/src/gui/gui.pro

src.pro
   /tools/tools.pro
      /bootstrap/bootstrap.pro // начальный зарузчик, инициализация SRAM и т.д.
      /moc/moc.pro
      /rcc/rcc.pro
      /uic/uic.pro
   /corelib/corelib.pro
      include(../qbase.pri) - это важные по-сути глобальные переменные для ниже стоящих проектов
      include(arch/arch.pri) - зависимости от архитектуры процессоров
      include(concurrent/concurrent.pri)
      include(global/global.pri)
      include(thread/thread.pri)
      include(tools/tools.pri)
      include(io/io.pri)
      include(plugin/plugin.pri)
      include(kernel/kernel.pri) // QObject
      include(codecs/codecs.pri)
      include(statemachine/statemachine.pri)
      include(xml/xml.pri)

Это основа, начало для понимания всего последующего происходящего.

Кстати как изменить каталог сборки для библиотек? В .qmake.cash изменить QMAKE_LIBDIR_QT , и все... Это полезно для чистоты эксперимента , когда собираем библиотеки из исходников , начинаем по минимуму с QtCore и т.д.

Замечания:

При сборке в Qt Creator важно понимать , что нажатие кнопок :

Clear All - очищает все созданные результаты труда , то есть собранные библиотеки *.a (*.dll) . Также очищает все объектные файлы (*.o) , то есть результаты компиляции. Также очищает результаты MOC кодогенератора.

Clean Project .... то же самое только для конкретного проекта , актуально когда открыто в среде несколько проектов.

Rebuild Project ... Полностью делает очистку проекта ка Clean Project и потом собирает все заново.

Build Project ... Тут происходит самый наверное правильный вариант для сборки больших проектов (особенно исходников QT), то есть здесь пересобираются только те файлы , который изменялись , и пересобираются также зависимые от них файлы.
Возможно (но надо проверять) даже если вы сделали заново qmake проекта , то Build Project ... не будет пересобирать проект полностью как Rebuild Project.

Примечание: QT_BUILD_TREE и QT_SOURCE_TREE используются только при сборке из исходников. В обычных проектах по логике вы не должны их увидеть.