среда, 1 февраля 2012 г.

Как я контрибьютил в Qt Creator

Собственно, это наконец то свершилось. Мой фикс попал в апстрим Qt Creator'а:

C++: Type deduction for auto-declared variables implemented:

In qt-creator/qt-creator.git:master


Собственно, с чего всё началось. Осенью я решил подобрать для себя новую среду разработки. VS2010 показала себя бесперспективной (на ближайшую пару лет) да и без VAX от неё мало толку C++-разработчику, с Eclipse CDE отношения как-то не сложились (кроме того имеется некоторая идиосинкразия в отношении Java-сред разработки), в итоге решил попробовать Qt Creator, тем более, что все домашние проекты в той или иной степени завязаны на Qt. Скачал, установил, попробовал поработать. Возможности среды приятно порадовали. Всё, что было необходимо - достигалось без лишних заморочек. Особенно приятно поразил тот факт, как легко можно переключаться между различным сборочными конфигурациями на базе разных тулчейнов. В общем, несколько часов работы - и я начал чувствовать себя в Qt Creator'е вполне комфортно. Но... Не обошлось и без ложки дёгтя. В своих проектах активно использую возможности C++11, поддержка которого в Qt Creator'е, мягко говоря, слабовата. Причём, не работает самое востребованное - лямбды, range based for loops и auto-декларации. "Фигня-война", - подумал я, - "Что я, не девелопер, что-ли?", и вооружившись максимой "Не умеет - научим, не хочет - заставим" полез качать исходники среды. Скачал. Попробовал собрать под gcc - не получилось. Покрутил так, сяк, ткнулся туда, ткнулся сюда, в итоге версия, собранная с помощью Visual Studio 2008, заработала. Настала очередь фиксить баги.

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

Необходимо отметить, что всю свою сознательную программерскую жизнь я работал с только централизованными репозиториями (Visual Source Safe, CVS, SVN, Perforce). А тут - Git. Скачать Tortuise Git - не проблема. Проблема - просечь workflow работы с ним. Возможно, моя ошибка была в том, что я не уделил должного внимания документации. Надо было найти что-то, по уровню чуть выше Git for Dummers, и внимательно изучить. Я же решил учится плавать, прыгнув сразу в воду и опираясь на прошлый опыт. Это стоило мне определённых нервов и времени. В итоге, вроде, со всем разобрался. Репозиторий склонировал, свои коммиты туда залил, проверил сборку под MSVC, под gcc, работоспособность (только под VC), решил, что патч готов к публикации. Но не тут то было. Быстро выяснилось, что Gitorous, на котором хостится публичный репозиторий Qt, это не совсем то место, куда следует заливать патчи. Полез на сайт Qt. На этот раз внимательно всё прочитал, пришёл к выводу, что патч в том виде, в котором я его подготовил, лучше не отправлять, потому как:
- он содержал фиксы сразу нескольких проблем.
- не совсем подходил по CSG, принятому в команде контрибьюторовQtC.
- в моём репозитории было несколько инкрементальных коммитов, отражавших процесс багфикса. 

Всё откатил, пофиксил стиль (привёл к общепринятому), распилил на несколько частей, немного помучался с накатыванием патчей из одной версии репозитория на другую. В итоге, вроде, всё срослось. Несколько полных пересборок проекта (после каждого git pull'а для приведения репозитория в полностью консистентное состояние с его удалённой версией), и вот он, долгожданный момент. git push в репозиторий на codereview.qt-projects.com прошёл раза с четвёртого (если не пятого) - сначала возня с SSH-ключами, потом - правильная настройка целевого бранча, потом - недовольство скрипта на "той" стороны тем, что в описании коммита отсутствует Change-Id, добавить который нет возможности (мой коммит в локальном клоне оказался уже погребённым под кучей коммитов, приехавших вместе с pull'ами). Как результат - создание патча, откат локального клона, git pull, накатывание патча, пересборка, контроль работоспособности, git push, git commit --amend, ииииииии.... Bingo! push прошёл, ревью создано. Дальше всё пошло как по маслу и известному сценарию. Комментарии, пара фиксов (через тот же git commit --amend/git push), и ревью заапрувлено. Фуф. :) Теперь осталось по уже известной схеме залить фиксы к range-based for и лямбдам. Тут уже проблем не предвижу, схема известна.

12 комментариев:

  1. Недавно посетила дурная мысль самому вытянуть и собрать последний qt creator, и пофиксить уже порядком надоевшую проблему с lambda и range based for, как вот наткнулся на ваш блог :) Спасибо за проделанную работу, надеюсь в 2.5 попадет все, а не только auto. Кстати, нет ли возможности куда-нибудь выложить вашу версию (желательно в исходниках чтобы можно было собрать под linux)?

    ОтветитьУдалить
    Ответы
    1. Спасибо за оценку. :)

      Исходники Qt Creator'а доступны из его публичного git-репозитория:
      https://qt.gitorious.org/qt-creator/qt-creator/

      Фикс с auto там доступен. Фикс для for и для лямбд сейчас готовлю к push'у в апстрим.

      Удалить
    2. Исходники из публичного репозитория уже давно выкачаны и собраны, и auto там действительно работает. Просто подумал, что если вы уже реализовали поддержку for и lambda, то возможно есть локальная копия исходников где это все присутствует, собственно ее я и имел в виду, когда спрашивал про возможность выложить куда-нибудь. Если это проблемно - не настаиваю, лучше потратить время на push в официальный репозиторий.

      Кстати, а что за проблемы у вас вылезли при сборке с gcc? Под убунтой 10.04 (с qt-4.7.4) собралось вообще без всяких бубнов.

      Удалить
    3. "Кстати, а что за проблемы у вас вылезли при сборке с gcc? Под убунтой 10.04 (с qt-4.7.4) собралось вообще без всяких бубнов."
      Я его собирал под MinGW. После сборки - не запустился. Разбираться не стал, переключился на Visual C, и всё заработало. :) Это не значит, что gcc плох, просто при сборке в моём окружении возникли траблы, на решение которых я решил не тратить время.

      "Просто подумал, что если вы уже реализовали поддержку for и lambda, то возможно есть локальная копия исходников где это все присутствует"
      Ну разве что в виде патчей могу выложить.

      Удалить
    4. "Я его собирал под MinGW. После сборки - не запустился. Разбираться не стал, переключился на Visual C, и всё заработало."
      Ну, с MinGW действительно часто косяки вылазят.

      "Ну разве что в виде патчей могу выложить."
      Если действительно несложно, и прогнозы по срокам когда это попадет в апстрим больше месяца. Просто недавно в рабочем проекте перешли на gcc 4.6 и местами очень кстати пришлись лямбды и for, но вот отсутствие их поддержки в qtcreator (особенно у for) сильно портит удобство использования. Поэтому и "загорелось".

      Удалить
    5. На самом деле, постараюсь выложить в апстрим до конца февраля (то есть до срока features complete). Но с gcc 4.6 есть ещё один прикол. Встроенный в QtC препроцессор просто не переваривает макросы, с помощью которых объявляется пространство имён "std" в STL от gcc. Для этого у меня тоже есть патч, но есть подозрение, что в апстрим его не возьмут.

      И да, ещё ложечка дёгтя. auto с range based for не будет работать даже с моими фиксами. Тут уже проблема в том, как QtC работает с шаблонами классов. Обрабатываются только самые простые случаи, под которые большинство контейнеров не попадает... :(

      Удалить
    6. Этот комментарий был удален автором.

      Удалить
    7. "Встроенный в QtC препроцессор просто не переваривает макросы, с помощью которых объявляется пространство имён "std" в STL от gcc. Для этого у меня тоже есть патч, но есть подозрение, что в апстрим его не возьмут."
      Какой-нибудь хак? :)

      "И да, ещё ложечка дёгтя. auto с range based for не будет работать даже с моими фиксами"
      В большинстве случаев это не страшно, т.к. там в явном виде указывать тип не проблема (например const RenderOp&) в отличие от обычного for (tbb::flattened2d<tbb::enumerable_thread_specific<std::vector<RenderOp>>>::const_iterator)

      Удалить
    8. "Какой-нибудь хак? :)"
      Вроде того. Захардкодил в препроцессоре соответствующий макрос. Правильный фикс проблемы весьма трудоёмок.

      "В большинстве случаев это не страшно, т.к. там в явном виде указывать тип не проблема"
      Ну, в принципе - да, согласен.

      Удалить
    9. "Захардкодил в препроцессоре соответствующий макрос."
      Случайно не __GXX_EXPERIMENTAL_CXX0X__?

      Удалить
    10. "Случайно не __GXX_EXPERIMENTAL_CXX0X__?"
      Нет. _GLIBCXX_BEGIN_NAMESPACE(N).

      Удалить
    11. Мой фикс с range-based for закоммитили.

      Удалить