Qt Software / Параллельная компиляция Qt в Windows

в 15:52, , рубрики: Новости, метки: , ,

Qt Software / Параллельная компиляция Qt в Windows
Параллельная компиляция Qt-проектов под Windows с использованием QtCreator — зверь загадочный и очень привередливый. В этой небольшой статье я расскажу, как же все-таки его приручить. Параллельная компиляция может быть выполнена достаточно просто в теории, на практике дела обстоят не совсем гладко, чему в подтверждение бесконечное число тем на форумах, где предлагаются всевозможные решения. Ни одно из них, к сожалению, нам не помогло.
В теории для случая MinGW достаточно указать параметр –j[число процессов компиляции] у команды сборки make, которая в QtSDK MinGW представлена mingw32-make. Например, получается команда mingw32-make.exe –j10.
Рекомендуемое число процессов компиляции составляет число процессоров+1. Если параметр не задается, то считается, что j=1. Если указать слишком большое число также ничего страшного не случится. Make запустит ровно столько, сколько дает прирост производительности.
Для удобства можно воспользоваться переменной окружения %NUMBER_OF_PROCESSORS%, которая показывает число процессоров в системе. Получается команда видаmingw32-make.exe –j%NUMBER_OF_PROCESSORS%
Однако, не все так просто. Qmake создает три make-файла. Общий Makefile, который по определенным define’ам выбирает из Makefile.Debug и Makefile.Release в зависимости от сборки релиза или дебага. Дело в том, что параметр –j не наследуемый. И когда в QtCreator вызывается make, то он вызывается для Makefile. А вот до Makefile.Debug или Makefile.Release уже не добирается.
Для того чтобы это исправить придется написать команду в явном виде. Например,mingw32-make.exe –j9 –f Makefile.Debug.
Не очень удобно, но прирост скорости сборки это сильно компенсирует. Для примера, пересборка нашего проекта на core-i7-2630 без распараллеливания осуществляется за 12 минут, с флагом –j9 сборка занимает менее двух минут. Прирост производительности в шесть раз заставляет задуматься.
Но даже после указания таких флагов сборки у нас на двух машинах это стало работать, а на двух нет. На форумах пишут, что дело может быть в версии Qt, в кривости mingw, в особенностях работы qmake, версии ОС. Однако, конфигурации наших машин таковы, что методом исключения можно сделать вывод о непричастности версий QtSDK, QtCreator, Windows или разрядности системы ко всему этому.
Решение оказывается очень простым, но в тоже время не таким очевидным. Нужно добавить абcолютный путь к mingw32-make в переменную окружения PATH. На всякий случай, лучше поставить точку с запятой после пути. И после этого чудесным образом начинает работать параллельная компиляция, а программистам не придется по 10 минут отвлекаться каждый раз при добавлении какого-нибудь Q_OBJECT к проекту и его пересборке.
Все эти флаги компиляции могут быть заданы в QtCreator на вкладке Проекты в параметрах make.
Надеюсь, статья окажется полезным и решит вопросы многих у кого до этого не работала параллельная сборка в QtCreator.UPD (из комментариев): Что касается Linux/MacOS пользователей, им повезло гораздо больше — достаточно только ключа -jX.
Также если вы используете компилятор MSVC, то проблем быть не должно.
В случае QtCreator нужно добавить записьQMAKE_CXXFLAGS_RELEASE += -MP[число процессов]
в .pro файл проекта и установление переменной окружения как я описал.
В случае Visual Studio свойствах VS проекта: «Properties»=>«Configuration Properties»=>«C/C++»=>«Command Line». А в поле «Additional options» дописать -MP[число процессов]. Спасибо IGHOR
Также при использовании компилятора MSVC помочь может jom.
Постоянную часть флагов можно вынести в отдельную переменную окружения MAKEFLAGS. Make сам возьмет оттуда установленные флаги. К примеру MAKEFLAGS=-j10. А в параметрах make остается только не забыть указать файл для сборки. Например, -f Makefile.Debug. Если вы все время собираете одну версию, то можно вынести все флаги целиков в MAKEFLAGS и забыть про настройку будущих проектов.
Спасибо всем за дополнения.

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js