Первая попытка собрать из исходников libQtCore.a

Это первая попытка с ходу разобраться как собираюются библиотеки Qt (в минимальном варианте). Тут конечно все дедается не правильно, но для истории решили оставить как есть.

Что мы понимаем изначально: есть исходники, есть компилятор cl.exe (от Майкрософт), есть линковщик link.exe , есть какой-то Qt Creator...

На самом деле еще мы еще не знаем о роли начальной конфигурации среды через config.exe. configure.exe практическое использование.

Но тем не менее оставим все как было у нас на практике.

Итак после продолжительного отсутствия в мире программирования приложений Windows под Qt пришлось вернуться и озадачится по взрослому - можно ли собрать Qt 4.8.1 тот , что устанавливается в C:\QtSDK1.2.1 (когда Qt принадлежал еще Nokia).

На дворе 2021г. У нас Windows 10-64. Qt 4.8.1. Поехали.

Очень помогает опыт, полученный в других областях программирования, например опыт программирования контроллеров, где для нас открываются знания, что существуют бесплатные инcтрументарии сборки проектов под GNU gсс и т.д.

То есть речь о том, что можно все собирать на открытом исходном коде.

Итак все начинается с головы : имеем исходники в каталоге C:\QtSDK1.2.1\QtSources\4.8.1\src.
Тут лежит тот самый главный projects.pro. Он содержит подпроекты src.pro, tools.pro и др.

Для того чтобы начать хоть что-то компилировать надо по идеалогии Qt воспользоваться утилитой qmake, которая по файлам .pro cоздает в соответствующих каталогах создает файлы makefiles , которые в свою очередь уже будут использоваться при компиляции и сборке.

Вот примерно такая иерархия каталогов (дерево) реализовано. То есть там все исходники Qt раскиданы по каталогам.


projects.pro   // лежит в C:\QtSDK1.2.1\QtSources\4.8.1
\src\src.pro
\src\gui\gui.pro
\src\gui\kernel\kernel.pri
   ......
\src\corelib\corelib.pro
\src\corelib\io\io.pri
   ......

Примечание : если projects.pro не совсем корявый, то при открытие его в qt Creator должно сразу правильно разворачиваться дерево зависимых проектов. Если этого не происходит значит надо искать проблему...

Итак пытаемся вызвать qmake из Qt creator для project.pro - процесс начинается , но затыкается много раз , пока мы не настроим не достающие переменные для зависимых проектов.

Вызов у нас такой (в логе посмотрели) :

"c:\qtsdk1.2.1\desktop\qt\4.8.1\mingw\bin\qmake.exe" C:\QtSDK1.2.1\QtSources\4.8.1\projects.pro -r -spec win32-g++ "CONFIG+=release"

-r - это рекурсивно, то есть по всем внутренним каталогам проходим.

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

Первый затык связан переменной $$QT_SOURCE_TREE

Очень часто в файлах .pro в дереве каталогов встречается переменная $$QT_SOURCE_TREE, которая должная содержать путь самого верхнего каталога, то есть где лежит projects.pro. Но почему-то она пустая?... Это видно если в файле .pro сделать massage ($$QT_SOURCE_TREE). Это именно не переменная из среды окружения , так как тогда она бы применялась в коде так : $$(QT_SOURCE_TREE).

Самый верхний каталог это тот где мы запускаем qmake , то есть если открыт projects.pro в Qt и для него мы вызываем qmake в qt , то получится верхний каталог C:\QtSDK1.2.1\QtSources\4.8.1 .

Выясняется что , $$QT_SOURCE_TREE можно определить в .qmake.cache, который должен быть расположен на один каталог выше нашего projects.pro .

Второй затык связан с QT_BUILD_TREE

Также выясняется , что переменная QT_BUILD_TREE тоже в pro файлах оказывается пустая. Ее также добавляем в файл .qmake.cache.

Третий затык QT_ARCH

Итак qmake двинулся дальше по проектам и заткнулся в районе corelib/arch.pri . Сразу скажу , что QT_ARCH тоже пустая в файлах pro. Добавляем ее к .qmake.cache.

Примечание : чтобы облегчить себе жизнь можно убрать из набора каталогов лишнее QT_BUILD_PARTS = libs tools examples demos docs translations, то есть можно оставить только QT_BUILD_PARTS = libs . libs - это и будут после сборки наши статические библиотеки типа QtCore4.a . То есть наша задача их попробовать получить из открытых исходников Qt .

Теперь небольшое отступление.

Как определить где затыкается qmake?

Проблемка оказалась та еще... Пришлось пробовать опции прямо из командной строки. Обязательно надо сразу изучить опции командной строки qmake , так как прояснится сразу много вопросов :

Батник для запуска с максимальным уровнем отладочной информации по ошибкам и т.д. примерно такой :


set QTDIR=C:\QtSDK1.2.1\Desktop\Qt\4.8.1\mingw
set PATH=%QTDIR%\bin;%PATH%
set PATH=C:\QtSDK1.2.1\mingw\bin;%PATH%

qmake -makefile -Wall -Wparser -Wlogic -Wdeprecated -d -recursive -r -spec win32-g++ "CONFIG+=release" -o log_qmake.txt >log_echo_qmake.txt

Промучавшись с qmake и правкой .pro файлов примерно 1-2 дня (на изучение команд и переменных qmake для .pro фалов) можно получить приятный результат :

The process "c:\qtsdk1.2.1\desktop\qt\4.8.1\mingw\bin\qmake.exe" exited normally.

Вот с таким .qmake.cache у нас прошел процесс qmake до конца:

QT_SOURCE_TREE = $$quote(C:\\QtSDK1.2.1\\QtSources\\4.8.1)
QT_BUILD_TREE = $$QT_SOURCE_TREE
QT_ARCH = i386

config.exe

А теперь мы , как чаcто бывает , узнаем , что в каталоге C:\QtSDK1.2.1\QtSources\4.8.1 есть файл config.exe , который как раз и создает нам .qmake.cache и .qmake.cache автоматически.

config.exe создает файл .qmake.cache и .qmake.cache в этом же каталоге C:\QtSDK1.2.1\QtSources\4.8.1. А мы знаем уже ,что .qmake.cache должен быть на каталог выше чем наш файл с проектом .pro и на одном уровне каталогов с каталогом теневой сборки (это т тот куда вся сборка попадает). Поэтому догадались , что сonfig.exe готовит .qmake.cache для проектов на один уровень ниже себя, то есть например для src.pro или tools.pro.

Как окажется позднее сonfig.exe не совсем очевидно влияет на процесс сборки проекта исходников src.pro.

Поэтому открываем src.pro qt криатором , делаем qmake (нормально), и нормально проходит компиляция исходников . Но затыкаемся на этапе сборки :

g++ -Wl,-s -Wl,-subsystem,console -mthreads -o ..\..\..\bin\moc.exe release/moc.o release/preprocessor.o release/generator.o release/parser.o release/token.o release/main.o -L"c:\QtSDK1.2.1\QtSources\4.8.1\src\tools\bootstrap\release" -lbootstrap -luser32 .

Обращаю внимание на значение -L каталога , где надо искать libbootstrap.a : c:\QtSDK1.2.1\QtSources\4.8.1\src\tools\bootstrap\release - оно не корректно!.. Все это пока только наводит на мысли , что надо изучать язык qmake и makefile.


cannot find -lbootstrap

bootstrap - начальная загрузка. libbootstrap.a у нас (после компиляции) появился и лежит в каталоге :

C:\QtSDK1.2.1\QtSources\4.8.1\src\tools-build-desktop-Qt_4_8_1_for_Desktop_-_MinGW__Qt_SDK__Release\bootstrap\release\libbootstrap.a

src.pro

Теперь пытаемся собрать исходники из проекта scr.pro , который лежит у нас в C:\QtSDK1.2.1\QtSources\4.8.1\src .
Это и есть наши исходники Qt . Там же есть зависимости к другим каталогам (других проектов). Но все эти связи учитываются в .pro файлах.

Тут надо как-то уменьшить объем собираемых данных , иначе это затягивается на 20-30 минут. Оказывается , что для этого надо просто в проект src.pro уменьшить содержимое переменных SRC_SUBDIRS и QT_CONFIG. Откуда они берут начальные значения непонятно, но там изначально всего по максимуму.
Примечание: Читайте Конфигурирование среды.

Для того ,чтобы оставить только corelib делаем в начале src.pro так :


QT_CONFIG -= opengl openvg phonon multimedia webkit activeqt svg qt3support script declarative xmlpatterns gui
...
и в таком духе закоментим лишнее
# SRC_SUBDIRS += src_plugins

# то есть в результате SRC_SUBDIRS будет = src_corelib
# QT_CONFIG будет 

Останется только подсунуть из каталога C:\QtSDK1.2.1\QtSources\4.8.1\src-build-desktop-Qt_4_8_1_for_Desktop_-_MinGW__Qt_SDK__Release\tools\bootstrap\release файл libbootstrap.a в каталог c:\QtSDK1.2.1\QtSources\4.8.1\src\tools\bootstrap\release.