LINUX.ORG.RU

Qt переходит с qmake на CMake

 , , ,


4

4

Сегодня в официальной рассылке Ларс Кнолл (Lars Knoll) подтвердил давно ходящие слухи об отказе от qmake в пользу CMake начиная с Qt 6.

Данное решение было результатом многочисленных дискуссий по поводу будущего системы сборки Qt. Команда признаёт, что эволюция qmake зашла в тупик и замена его было лишь вопросом времени. В июле Тьяго Мацейра (Thiago Macieira) перечислил требования к будущей системе сборки, из потенциальных кандидатов, удовлетворяющих им, в итоге остались Qbs и CMake.

Qbs разрабатывался внутри The Qt Company как альтернативная система сборки общего назначения, призванная избавиться от болячек qmake и предложить разработчикам декларативный язык описания проекта на основе QML. К сожалению, проект так и не получил достаточного развития и в последнее время поддерживался усилиями буквально одного человека. Для того чтобы Qbs конкурировал на рынке необходимо было бы приложить усилия, несоизмеримые с текущими возможностями и бизнес-целями компании. Таким образом, единственной областью применимой для Qbs мог бы стать перевод на неё самой Qt. Но даже это оказалось трудновыполнимой задачей из-за циклических зависимостей между Qt и Qbs, что прямо противоречило одному из основных требований.

И Qbs, и CMake показали хорошие результаты в ходе эксперимента по сборке Qt, но разработчики отмечают насколько далеко они сумели продвинуться именно с CMake за короткий промежуток времени.

Среди прочих достоинств CMake упоминаются широкое расспространение в экосистеме C++, в частности KDE, хорошая поддержка в популярных IDE и пакетных менеджерах (VCPkg, Conan и прочие), а также большая база пользователей.

Модули CMake уже официально входят в состав Qt 5 и планировались поддерживаться и далее наряду с qmake. Добавление третей системы сборки стало бы слишком тяжёлой задачей, поэтому отказ от Qbs был во многом предопределён.

Компания уверена в своём выборе CMake для Qt 6. Результаты уже сейчас можно опробовать в проекте qtbase, переключившись на ветку wip/cmake. Желающие принять участие в портировании остальных модулей приглашаются к сотрудничеству.

В дополнение, в официальном блоге Qt сегодня также заявили про прекращение разработки Qbs: http://blog.qt.io/blog/2018/10/29/deprecation-of-qbs.

>>> Подробности

★★★★★

Проверено: jollheef ()
Последнее исправление: Deleted (всего исправлений: 13)

Ответ на: комментарий от Dendy

Со слов Тобиаса, они вообще не хотят марать руки ручным разбором CMakeLists.txt. Я как-то загорелся парсер рисовать... Никита Барышников (Axonian) подкинул мне свои наработки, я подадаптировал к текущим исходникам, прикинул объём работы и... забил нафиг!

Или я не правильно понял и ты имел ввиду сам CMake и какие-то телодвижения с его стороны?

h4tr3d ★★★★★
()
Ответ на: комментарий от Dendy

Улыбнуло (-: qmake собран с бутстрапной статической копией Qt.

Нет.

anonymous
()
Ответ на: комментарий от h4tr3d

ручным разбором CMakeLists.txt

Я имел в виду, что эти маркеры мог бы находить сам CMake и добавить в сервер команды на добавление файлов через протокол. Пользователь бы потом сам руками допричёсывал код. В принципе, как оно сейчас и делается в Android Studio.

Или может проблема преувеличена и этот функционал никому не нужен. Люди сто лет вписывали файлы в Makefile, и норм.

Dendy ★★★★★
() автор топика
Ответ на: комментарий от dimgel

Library добавляет таргет же. Ему нужны только исходники для сборки.

Adds a library target called <name> to be built from the source files listed in the command invocation

invy ★★★★★
()
Ответ на: комментарий от anonymous

Некоторые анонимусы не могу угомониться, ляпнул глупость и давай до упора её раскручивать, придираясь к словам. Вопрос на засыпку: чем линковка статической библиотеки (.a) отличается от линковки набора объектников (.o)?

Dendy ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Перечисленные исходники в qmake.pro — это и есть QtCore. Как они линкуются, предварительно создав промежуточную библиотеку или перечислены явно или включив .pri-файл — значения не имеет. Это статическая линковка. В пределах этого треда значение имеет только кроссзависимость между qmake и Qt, и bootstrap как способ решения этой проблемы.

Dendy ★★★★★
() автор топика
Ответ на: комментарий от Dendy

значения не имеет

Ой, всё (с). Уроки иди учи.

anonymous
()
Ответ на: комментарий от Dendy

Люди сто лет вписывали файлы в Makefile, и норм.

$(wildcard) в GNU make уже не помню сколько и ленивые пацаки пользуются.

kawaii_neko ★★★★
()
Ответ на: комментарий от Dendy

Вопрос на засыпку: чем линковка статической библиотеки (.a) отличается от линковки набора объектников (.o)?

Тем, что при дазании списка объектников они все будут влинкованы в результирующий бинарь, а при линковке со статической библиотекой из нее будут выбраны только те объектники, в которых нашлись unresolved символы в данный момент (вот почему флажки -l нужно указывать после всех объектников, а для особо запущенных случаев существуют -Wl,--start-group / -Wl,--end-group

Кстати, постоянно замечаю, что среди сторонников cmake куча людей не осилила GNU make и binutils на сколько-нибудь достойном уровне, зато лезут поучать, как надо правильно проекты собирать.

kawaii_neko ★★★★
()
Ответ на: комментарий от kawaii_neko

Линковку всего можно сделать через -whole-archive / -no-whole-archive. Мой поинт был в том, что принципиальной разницы нет, .a это просто склейка .o-файлов.

Dendy ★★★★★
() автор топика
Ответ на: комментарий от Dendy

Да ты вообще нить дискуссии потерял.

anonymous
()
Ответ на: комментарий от anonymous

Сделай уже

strings `which qmake` | c++filt | grep Q

И успокойся. Там кусок QtCore.

EXL ★★★★★
()
Ответ на: комментарий от invy

А, понял о чём ты. Прописывание хидеров в список файлов — это (можно сказать официальный) костыль для QtCreator, чтобы он их в дереве проектов показывал. На сборку это никак не влияет.

dimgel ★★★★★
()
Последнее исправление: dimgel (всего исправлений: 1)
Ответ на: комментарий от EXL

У меня тоже не qt. Может в какой-то момент починили, но я помнится нагугливал именно такое решение проблемы: пихать хидеры в CMakeLists.

dimgel ★★★★★
()
Ответ на: комментарий от dimgel

попробуй source_group, а так вроде и само добавляется.

invy ★★★★★
()
Последнее исправление: invy (всего исправлений: 1)
Ответ на: комментарий от Dendy

Есть. Все нужные мне хедеры отображаются в дерево=>headers.

http://esxi.z-lab.me:666/~exl_lab/screens/cmake-headers-qtc2.png

В самом CMakeLists.txt никакого списка header'ов или дичи вроде '*.h' нет. Хотя, возможно, за это отвечает include_directories(headers). Но ведь не добавляет же оно header'ы в список файлов, верно?

P.S. Qt Creator 4.7.1

EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 1)
Ответ на: комментарий от invy

Возможно, это связано с переходом на cmake-server и теперь дерево проектов парсится нормально благодаря ему. А не через костылину как это было раньше: Qt Creator вызывал cmake с парметром «генерировать проектные файлы для Code::Blocks IDE», потом читал этот XML-файл и дерево строил он кажется только по нему.

Кроме того, в проектное дерево Qt Creator теперь можно добавить различные файлы, которые иногда требуется тоже редактировать: ресурсы, переводы и прочее. За это отвечает опция SOURCES у CMake-макроса (функции? метода?) add_custom_target():

The SOURCES option specifies additional source files to be included in the custom target. Specified source files will be added to IDE project files for convenience in editing even if they have not build rules.

Приятно удивился, когда узнал, что оно работает и с Qt Creator. У себя сделал как-то так:

add_custom_target(Resources ALL
	DEPENDS ${PROJECT_NAME}
	SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/res/${RES_DIR}/Resources.rdef)
add_custom_command(TARGET Resources
	COMMAND rc -o Resources.rsrc
		${CMAKE_CURRENT_SOURCE_DIR}/res/${RES_DIR}/Resources.rdef
	COMMENT "Compiling 'Resources.rsrc' resource file from 'Resources.rdef' script."
	VERBATIM)

И теперь в дереве Qt Creator могу выбрать этот Resources.rdef файл и отредактировать его.

EXL ★★★★★
()
Ответ на: комментарий от EXL

Возможно, это связано с переходом на cmake-server

Теперь осталось понять откуда сервер знает про заголовочники (-:

Dendy ★★★★★
() автор топика
Ответ на: комментарий от EXL

Можно и без add_custom_target:

add_custom_command(OUTPUT "Resources.rsrc"
  COMMAND rc -o Resources.rsrc
          "${CMAKE_CURRENT_SOURCE_DIR}/res/${RES_DIR}/Resources.rdef"
  MAIN_DEPENDENCY "res/${RES_DIR}/Resources.rdef"
  VERBATIM)

Darth_Revan ★★★★★
()
Ответ на: комментарий от Gorthauer

+ Сам перешел на cargo. Проще, удобней. А синтаксис cmake постоянно гуглить приходится, как то не запоминается.

anonymous
()
Ответ на: комментарий от EXL

Ага, создаёт. Просто может быть использован системный CMake, который ещё не умеет Server Mode, ну и для простоты всегда используется Code::Blocks+Makefile: они в один проход вместе генерируются, так что, почему бы и нет.

h4tr3d ★★★★★
()
Ответ на: комментарий от Dendy

Да тут проблема не проблема. Много народу привыкло к подходу как Borland C++, Borland Delphi, Borland C++ Builder, MSVC, когда сборка и правка проекта осуществляется из среды. У такой тесной интеграции есть плюс: всегда понятно как и куда добавить файлы, как их собрать и куда прилинковать. Сборка без среды посредством генерации Makefile и иже с ними, это бонус, примочка, но не для основной разработки.

В случае с CMake всё с точностью до наоборот: то, что очень плохо может быть синтегрировано с IDE является исходником.

Ну и в мире *nix как бы принято считать, что сама среда - IDE.

В контексте QtC, я для себя запилил добавление, ну и пофиг, что файл выделен неярко, сразу понятно - не отнесён ни к одному таргету, и уже ясно, почему на него ругается кодовая модель. Берёшь, открываешь нужный CMakeLists.txt, добавляешь файл к цели, сохраняешь, CMake автоматом обновляет результаты генерации. Мне этого хватает.

h4tr3d ★★★★★
()
Ответ на: комментарий от Dendy

Ммм... в командной строке ты указываешь один файл .a, вместо пачки .o? ;-)

h4tr3d ★★★★★
()
Ответ на: комментарий от Dendy

Срываю покровы :)

Это как раз то, что я частично пропихнул в апстрим из своего плагина (правда на уровне идеи, мой код был сделан на коленке и был синхронным). У меня дерево сканировалось и отображалось вместо того, что бралось из CMake. Они сказали, что это идеологически не канает, дерево должно отображать только то, что в проекте (точнее: в CMakeLists.txt), но с хидерами да, косяк получается, поэтому сделаем так, что мы его просканируем, а возьмём только заголовочники для отображения. Они там сереньким цветом, как бы неактивными выделены.

Никакой тайны, кому интересно смотрите TreeScanner.

В моём «форке» дерево проекта берётся как раз из TreeScanner, информация из CMake - только что бы подсветить правильно файлы, которые описаны в самом CMakeLists.txt. Так как в моём понимании: проект это всё, что в директории, и документация и картинки и т.п. подобный фуфел.

Кому интересно: https://github.com/h4tr3d/cmakeprojectmanager2

Отличия с апстримом:

git diff qtc-master master

h4tr3d ★★★★★
()
Ответ на: комментарий от EXL

У меня была шальная мысля сделать добавление подобных таргетов или файлов к ним через какой-нить qtc.cmake.user, который подсовывать cmake при запуске через опция -C (не канает, там только set(... CACHE ...)), либо через каскадирование CMAKE_TOOLCHAIN_FILE... Этот файл можно перегенерировать из IDE как душе угодно, но, лучше бы найти аналог который подключится ПОСЛЕ корневого CMakeLists.txt. Пока только идея. Но это бы решило ряд проблем, правда не без ограничений:

  1. можно было бы отказаться от TreeScanner. Изначальное дерево строить только на основании данных cmake, при работе из IDE уже добавлять существующие файлы, нужные заголовочники через qtc.cmake.user или типа того.
  2. файлы бы в дереве были только те, что нужны для работы: нужно README.md, да пожалуйста! Будет через псевдо-таргет OtherFiles добавлено.
  3. это бы не мешало работать cmake без QtC и не нужно добавлять каких-то подсказок в сам CMakeLists.txt
  4. ну и дерево проекта и кодовая модель реально не загаживалось бы лишними и не нужными в работе файлами, проект будет открываться быстрее.

Но проблему добавления файла к таргету и правку CMakeLists.txt это снова не решает :)

h4tr3d ★★★★★
()

Похрен. Лиш-бы уже вобще, что-нибудь собиралось. А то прийдется переходить на электроны всякие.

Deleted
()
Ответ на: комментарий от h4tr3d

либо через каскадирование CMAKE_TOOLCHAIN_FILE...

Это как раз то, что я частично пропихнул в апстрим из своего плагина (правда на уровне идеи, мой код был сделан на коленке и был синхронным). У меня дерево сканировалось и отображалось вместо того, что бралось из CMake.

Уж не является ли это дальнейшим развитием этой идеи?

https://htrd.su/wiki/zhurnal/2017/01/18/qt_creator_cmake_otobrazhenie_vsex_fa...

Я даже пользовался этим, но со сменой дистрибутива забыл про эту фичу.

EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 1)
Ответ на: комментарий от anonymous

изменения в proto-файле через раз не подхватываются.

Вы не здорово умеете его готовить. И .thrift, и .proto в проекте используются и нареканий не вызывают. Проверьте зависимости.

Про суффиксные правила — такой лаконичности, как в make, наверное, не достичь, в любом случае будет add_* (add_executable/add_custom_target... в зависимости от задачи), но, в целом, тоже никакой магии.

AlexM ★★★★★
()
Ответ на: комментарий от DawnCaster

Некоторых фич, вроде простого добавления файлов в проект, конечно, не хватает, но тут уже виновата «универсальность» CMake'а

KDevelop при следовании стандартным схемам наименования, вроде, умел.

AlexM ★★★★★
()
Ответ на: комментарий от EXL

Как в CMake включить отлов изменений файла не по дате файла

Короткий ответ: перестать пользоваться make как бэкендом. Цитата отсюда https://cmake.org/pipermail/cmake/2012-August/051553.html :

CMake really leaves the decision when to recompile something to the backend, i.e. GNU Make, Xcode, Visual Studio, ninja etc. It merely defines dependencies and then lets the actual build tool handle the rest, and most of them choose to use simple time-stamps instead of hashes.

Но, понятное дело, перед шаловливым умом и пытливыми ручками ничего не устоит, см. например, https://stackoverflow.com/questions/36600111/how-does-cmake-detect-changed-files

AlexM ★★★★★
()
Последнее исправление: AlexM (всего исправлений: 1)
Ответ на: комментарий от EXL

Да, является. Но всё никак не дойдут руки/мозги на подумать и вообще взвесить все «за» и «против» такого решения. Тем более, что в прямой реализации такого подхода есть и жирный минус: файлы через такие превдо-цели попадают в кодовую модель и... могут сломать парсинг. В заметке, что ты привёл, это упомянуто.

Как минимум, используя подход «проект - все файлы» уже длительное время, я вижу и его минусы: при большом количестве файлов становится труднее в них ориентироваться. Кроме того, засоряется и выхлоп Locator'а в QtC, особенно когда где-то завалялся вывод Doxygen, где файлов много, названия их частично совпадают с исходниками, сам выхлоп под игнорированием VCS, но впиливать подобные игнорирования в плагин, тоже костыль. Хотя стоит изучить возможности API QtC в этой части.

В общем, я склоняюсь, что нужна возможность добавления новых, добавления существующих файлов, их переименование в отображение проекта. Что бы это отображение можно было сохранять как дополнение к информации из CMakeLists.txt. Добавление файлов же в CMakeLists.txt оставить так же на плечах разработчика. Тем более, что сейчас уже существует возможность выделить файлы которые пришли из CMakeLists.txt и из других источников, которые закреплены за определёнными целями, а которые - нет. При первом же запуске, при отсутствии информации о дополнительных файлах, чистая основа будет взята именно из CMakeLists.txt. Есть ещё нюансы синхронизации: кто-то может работать вне QtC с проектом и что-то, что есть в общем, пусть будет CMakeLists.txt.qtc, может уже отсутвовать в файловой системе. Хотя, к примеру, в VS на это забивают, максимум к иконке дорисовывают восклицательный знак, типа файла на диске нет.

Вторым вариантом видится: оставить существующий подход со сканированием дерева, но настраиваемым фильтром, что (маска/mime) и по каким путям брать и отображать в проекте. Но тоже куча вопросов остаётся, типа где хранить настройку фильтра: если в CMakeLists.txt.user, то тогда придётся его настраивать при каждой новой загрузке проекта из репозитория.

h4tr3d ★★★★★
()
Последнее исправление: h4tr3d (всего исправлений: 1)
Ответ на: комментарий от h4tr3d

Может тогда будет проще FileSystem подрихтовать? Чтобы была возможность сделать что-то типа «Project Directory», где дерево начинается от проектной директории, а не всей ФС вообще, чтобы ничего не мешалось лишнего.

В различных IDE от JetBrains используется нечто похожее.

То бишь у нас есть вариант просмотра только проектных сущностей, которые влияют на кодовую модель/сам проект:

http://esxi.z-lab.me:666/~exl_lab/screens/as_project_view_1.png

И все директории и файлы проекта в целом:

http://esxi.z-lab.me:666/~exl_lab/screens/as_project_view_2.png

EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.