суббота, 28 ноября 2009 г.

Сборка Qt Creator из исходников

На выходных решил посмотреть свежайший Qt Creator. Не тот, который 1.3-RC1 (т.е. 1.2.94), и не тот который можно найти в Qt Creator snapshots (1.3.0), а тот, который можно собрать из официального репозитория (1.3.80). Мимоходом замечу, что 1.3-RC1 отличается от свежака на 86 (!) ревизий. Такое впечатление, что за официальным 1.3 сразу выйдет beta 1.4.

Похоже, однако, что копают больше вглубь, чем вширь. Что видно сразу: в master branch добавили плагин для Mecurial. И все.

Однако, вернемся к предмету разговора. Итак, что нужно, чтобы получить 1.3.80? Нужно всего ничего:
1. Установить git.
2. Склонировать исходники Qt Creator из репозитория.
3. Собрать Qt Creator.

Ну и еще куча времени, потому как билд от 28.11.09 не особенно хочет работать под Windows. Об этом ниже.

1. Установка git.

Установка из исходников или бинарников для разных систем отлично описана, в том числе и по-русски, в книжке про git, см. главу 1.4. В главе 1.5 рассказано как нужно сконфигурировать git сразу после установки, т.е. задать имя пользователя и пр.

Вкратце, я делал вот так:

Под Ubuntu:
$ sudo apt-get install git-core

Под Windows нам нужен msysGit, живет он на Google Code. Не знаю, есть ли другие порты git'a для Windows, но этот сделан что-то уж чересчур сердито. Скачиваем и устанавливаем последнюю версию msysGit (на момент написания- 1.6.5.1) отсюда.

После установки нужно задать имя, мэйл, редактор и инструмент merge. Под Windows все делается все равно из-под bash, так что синтаксис одинаковый:
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
$ git config --global core.editor notepad
$ git config --global merge.tool kdiff3

Проверка установок:
$ git config --list

2. Клонирование исходников из репозитория.

После того, как установка git завершена, заходим в директорию, где будет создана директория qt-creator и клонируем проект с сайта троллей:
$ cd /Projects
$ git clone git://gitorious.org/qt-creator/qt-creator.git

На будущее, если нам нужно достать последние обновления Qt Creator, делаем
$ git fetch

Отмечу, что fetch не делает merge автоматически. Если что-то меняли локально, надо делать pull.

3. Сборка Qt Creator.

Я собирал из-под Qt Creator 1.3-RC1 с Qt 4.6-RC1.

3.1. Под Ubuntu.

Под Ubuntu все оказалось просто. Ну, почти. :-) Запускаем Qt Creator 1.3-RC1, открываем проект /Projects/qt-creator/qtcreator.pro, выбираем Build->Set build configuration Release (или Debug), Build->Set run configuration qtcreator(bin).

Проект компилируется с восемью ворнингами, что совсем неплохо. Выходим из Qt Creator 1.3-RC1. Запускаем ./Projects/qt-creator/bin/qtcreator.bin и получаем сообщение о том что /plugins/Nokia/libQtScriptEditor.so: The shared library was not found.

Понятно, что что-то не так в зависимостях, и надо собрать плагины явно. Запускаем Qt Creator 1.3-RC1, открываем проект /Projects/qt-creator/src/libs/libs.pro, собираем. Не забываем про Build->Set build configuration Release (или Debug). Аналогично собираем /Projects/qt-creator/src/plugins/plugins.pro. Все! Закрываем Qt Creator 1.3-RC1 и запускаем только что собранный 1.3.80.

Я его толком не пользовал, но проекты в нем запускаются. Отладкой не занимался.

3.2. Под Windows.

Для Windows, если хотим использовать MSVC, надо скачать Qt, собранную под MSVC 2008. Ну, или пересобрать самим.

Запускаем Qt Creator 1.3-RC1, открываем проект d:/Projects/qt-creator/qtcreator.pro. Запускаем Build->Build Project. У меня сборка заняла 40 минут.

Запускаем 1.3.80, получаем вот такое сообщение:




В директорию qt-creator/bin надо скопировать вот эти Qt библиотеки:
QtCLucene4.dll
QtCore4.dll
QtDesigner4.dll
QtDesignerComponents4.dll
QtGui4.dll
QtHelp4.dll
QtNetwork4.dll
QtScript4.dll
QtSql4.dll
QtWebKit4.dll
QtXml4.dll
QtXmlPatterns4.dll

Копируем, запускаем по новой, получаем вот что:



Как с этим бороться я знаю- надо дебажить, смотреть, что же там такое вызывается. Но- в лом, да и времени нет. Скорее всего и так пофиксят не сегодня-завтра.

UPD: Все вылечилось добавлением Qt 4.6.0, собранной под MSVC, в переменную PATH, т.e.
PATH=...;d:\Qt\4.6.0\bin;

Qt Creator 1.3.80 теперь запускается без каких-либо жалоб, проекты открываются и т.п. Осталось неясным, что же было сломано в Qt 4.6-RC1. К тому же, вот здесь обсуждалась сходная проблема со сборкой Qt Creator 1.3.0, правда не написано, как она была решена.

Заключение.

Понятно, что попробовать самое свежее хочется всегда. Надо только соразмерять затраты времени с возможным результатом. В случае с 1.3.80 я и не знаю, стоит ли сейчас прям так уж упираться. Тем более, что есть пара невыясненных вопросов.

Весь Qt Creator- это несколько больше, чем то, что можно собрать из репов. К примеру, нету jom. Кто знает, чего еще не хватает для нормальной работы, и чего нет в исходниках. Я погуглил в поисках описалова как делать ежедневные билды (1.3.0 на текущий момент), но безрезультатно. А в них ведь есть абсолютно все, что и RC1.

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

Я напишу в Qt Creator мэйллист узнать что это за функция такая в Core.dll или что я там при сборке накосячил.

UPD: Мне ответили, что в переменной PATH надо указать путь к библиотеке, но он там и так уже был:
PATH=...;d:\Qt\4.6.0-rc1\;

Также, посоветовали поиграться с утилитой с названием depends_x86 или похожим, которая проверяет зависимости.

Проблема решилась сама собой после установки Qt 4.6.0 и добавлением ее в PATH (см. UPD выше).

среда, 18 ноября 2009 г.

Mercurial Plugin

Я уже писал про плагин для Perforce. И про то, что из всех систем управления версиями (дальше СУВ), Perforce мне понравился больше всего. Это считая только те, c которыми я работал по крайней мере несколько месяцев. Я их перепробовал несколько, помимо Perforce,- DBPS, Subversion и ClearCase. Все, как видно, централизованные. Самая ужасная- это, наверное, DBPS. Хотя, ClearCase тоже особо не радует. Сейчас всей конторой переходим с ClearCase на SVN. Почему не на Git/Bazaar/Mercurial- не знаю, инженеры решения не принимают и начальство перед ними не отчитывается. :)

От нечего делать, решил таки образоваться в области распределенных СУВ. Нашел очень толковый пост о применимости git, Bazaar и Mercurial, особенно в домашних условиях. Погуглив и почитав обзоры и краткие руководства, быстро понял, что с теорией пора завязывать и надо попробовать что-то ручками. Решил начать с Mercurial (кстати, вот здесь неплохое описание базовых use case'ов), поставил ее пока только под Windows. Заработало все сразу, команды оказались простые- одно удовольствие. Порадовали hg serve и hg merge (с помощью KDiff3). Буду признателен, если кто поделится, каким инструментом для merge пользуется.

Стало интересно, а нельзя ли эту штуку прикрутить к Qt Creator. Он в плане плагинов для распределенных СУВ особо не блещет- "из коробки" поддерживается только Git. Гугление показало, что есть проект плагина для Mercurial за авторством Brian McGillion. Лежит здесь. Последний commit от 21 сентября этого года, так что проект, вроде бы, живой. Ну, плагины- это для меня самое интересное, что в Qt Creator есть, хочется в их устройстве разобраться. И код чужой посмотреть для этого полезно весьма.

Ну, пользуясь проторенной дорожкой, я стал собирать этот самый плагин под Qt Creator 1.2.92. Плагин оказался под 1.2.91, так что без жалоб компилятора не обошлось. Все вылечилось довольно просто, diff в конце этого поста.

Восле сборки и копирования длльки и манифеста в каталог плагинов, можно запускать Qt Creator. Плагин написан изначально под Ubuntu, так что в Options надо поменять команду "hg" на "hg.exe". Есть еще пара вещей, которые можно в коде поправить, а можно и забить. Брайану я написал, посмотрим, что он ответит. UPD: Брайан ответил, что поправит, и что проект был перенесен в основной репозиторий Qt Creator. Я проверил, текущая версия 1.3.80, так что скоро ждем.

Набор команд в плагине- это необходимый минимум: Annotate для текущего файла, Diff, Log, Revert и Status для текущего файла и проекта, Pull, Push, Update, Import, Incoming, Outgoing и, конечно, Commit. Все я пока не пробовал, но на первый взгляд- работает. Из того, чего не хватает- Merge с помощью внешнего инструмента и графа или таблицы коммитов. И еще тагов и веток. Так что есть простор для творчества.

В целом, вещь полезная. Если время будет (ага, разбежался), можно этот плагин превратить в плагин для Bazaar. Или подумать об общих классах для этих двух систем, чтобы не плодить копии.

Обещанный diff:

changeset: 1:b7b7b8d4d0c1
tag: tip
user: Qt Creator Geek
date: Tue Nov 17 23:30:46 2009 -0600
summary: Updated for Qt Creator 1.2.92.

diff --git a/Mercurial.pluginspec b/Mercurial.pluginspec
--- a/Mercurial.pluginspec
+++ b/Mercurial.pluginspec
@@ -1,4 +1,4 @@
-
+
Brian McGillion
(C) 2008-2009 Brian McGillion
@@ -19,9 +19,9 @@
Mercurial integration.
http://www.qtsoftware.com
-
-
-
-
+
+
+
+
diff --git a/mercurialcommitwidget.cpp b/mercurialcommitwidget.cpp
--- a/mercurialcommitwidget.cpp
+++ b/mercurialcommitwidget.cpp
@@ -84,7 +84,7 @@
MercurialCommitWidget::MercurialCommitWidget(QWidget *parent) :
- Core::Utils::SubmitEditorWidget(parent),
+ Utils::SubmitEditorWidget(parent),
mercurialCommitPanel(new QWidget)
{
mercurialCommitPanelUi.setupUi(mercurialCommitPanel);
diff --git a/mercurialcommitwidget.h b/mercurialcommitwidget.h
--- a/mercurialcommitwidget.h
+++ b/mercurialcommitwidget.h
@@ -12,7 +12,7 @@
Some extra fields have been added to the standard SubmitEditorWidget,
to help to conform to the commit style that is used by both git and Mercurial*/
-class MercurialCommitWidget : public Core::Utils::SubmitEditorWidget
+class MercurialCommitWidget : public Utils::SubmitEditorWidget
{
public:
diff --git a/mercurialjobrunner.cpp b/mercurialjobrunner.cpp
--- a/mercurialjobrunner.cpp
+++ b/mercurialjobrunner.cpp
@@ -11,6 +11,8 @@
#include
#include
+#include
+
using namespace Mercurial::Internal;
using namespace Mercurial;
@@ -155,18 +157,18 @@
}
if ((hgProcess.exitStatus() == QProcess::NormalExit) && (hgProcess.exitCode() == 0)) {
- QByteArray stdout = hgProcess.readAllStandardOutput();
+ QByteArray stdOut = hgProcess.readAllStandardOutput();
/*
* sometimes success means output is actually on error channel (stderr)
* e.g. "hg revert" outputs "no changes needed to 'file'" on stderr if file has not changed
* from revision specified
*/
- if (stdout == "")
- stdout = hgProcess.readAllStandardError();
- emit output(stdout);
+ if (stdOut == "")
+ stdOut = hgProcess.readAllStandardError();
+ emit output(stdOut);
} else {
- QByteArray stderr = hgProcess.readAllStandardError();
- emit error(stderr);
+ QByteArray stdErr = hgProcess.readAllStandardError();
+ emit error(stdErr);
}
hgProcess.close();
diff --git a/mercurialplugin.cpp b/mercurialplugin.cpp
--- a/mercurialplugin.cpp
+++ b/mercurialplugin.cpp
@@ -22,6 +22,9 @@
#include
+#include
+#include
+
#include
#include
@@ -216,33 +219,33 @@
{
Core::Command *command;
- annotateFile = new Core::Utils::ParameterAction(tr("Annotate Current File"), tr("Annotate \"%1\""), Core::Utils::ParameterAction::AlwaysEnabled, this);
+ annotateFile = new Utils::ParameterAction(tr("Annotate Current File"), tr("Annotate \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
command = actionManager->registerAction(annotateFile, Constants::ANNOTATE, context);
command->setAttribute(Core::Command::CA_UpdateText);
connect(annotateFile, SIGNAL(triggered()), this, SLOT(annotateCurrentFile()));
mercurialContainer->addAction(command);
- diffFile = new Core::Utils::ParameterAction(tr("Diff Current File"), tr("Diff \"%1\""), Core::Utils::ParameterAction::AlwaysEnabled, this);
+ diffFile = new Utils::ParameterAction(tr("Diff Current File"), tr("Diff \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
command = actionManager->registerAction(diffFile, Constants::DIFF, context);
command->setAttribute(Core::Command::CA_UpdateText);
command->setDefaultKeySequence(QKeySequence(tr(Constants::MENUKEY) + tr(Constants::MODIFIER) + "D"));
connect(diffFile, SIGNAL(triggered()), this, SLOT(diffCurrentFile()));
mercurialContainer->addAction(command);
- logFile = new Core::Utils::ParameterAction(tr("Log Current File"), tr("Log \"%1\""), Core::Utils::ParameterAction::AlwaysEnabled, this);
+ logFile = new Utils::ParameterAction(tr("Log Current File"), tr("Log \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
command = actionManager->registerAction(logFile, Constants::LOG, context);
command->setAttribute(Core::Command::CA_UpdateText);
command->setDefaultKeySequence(QKeySequence(tr(Constants::MENUKEY) + tr(Constants::MODIFIER) + "L"));
connect(logFile, SIGNAL(triggered()), this, SLOT(logCurrentFile()));
mercurialContainer->addAction(command);
- revertFile = new Core::Utils::ParameterAction(tr("Revert Current File"), tr("Revert \"%1\""), Core::Utils::ParameterAction::AlwaysEnabled, this);
+ revertFile = new Utils::ParameterAction(tr("Revert Current File"), tr("Revert \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
command = actionManager->registerAction(revertFile, Constants::REVERT, context);
command->setAttribute(Core::Command::CA_UpdateText);
connect(revertFile, SIGNAL(triggered()), this, SLOT(revertCurrentFile()));
mercurialContainer->addAction(command);
- statusFile = new Core::Utils::ParameterAction(tr("Status Current File"), tr("Status \"%1\""), Core::Utils::ParameterAction::AlwaysEnabled, this);
+ statusFile = new Utils::ParameterAction(tr("Status Current File"), tr("Status \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
command = actionManager->registerAction(statusFile, Constants::STATUS, context);
command->setAttribute(Core::Command::CA_UpdateText);
command->setDefaultKeySequence(QKeySequence(tr(Constants::MENUKEY) + tr(Constants::MODIFIER) + "S"));
diff --git a/mercurialplugin.h b/mercurialplugin.h
--- a/mercurialplugin.h
+++ b/mercurialplugin.h
@@ -20,11 +20,11 @@
class IVersionControl;
class IEditorFactory;
class IEditor;
+} // namespace Core
namespace Utils {
class ParameterAction;
} //namespace Utils
-} // namespace Core
namespace ProjectExplorer {
class ProjectExplorerPlugin;
@@ -137,12 +137,12 @@
QTemporaryFile *changeLog;
//Menu Items (file actions)
- Core::Utils::ParameterAction *annotateFile;
- Core::Utils::ParameterAction *diffFile;
- Core::Utils::ParameterAction *logFile;
- Core::Utils::ParameterAction *renameFile;
- Core::Utils::ParameterAction *revertFile;
- Core::Utils::ParameterAction *statusFile;
+ Utils::ParameterAction *annotateFile;
+ Utils::ParameterAction *diffFile;
+ Utils::ParameterAction *logFile;
+ Utils::ParameterAction *renameFile;
+ Utils::ParameterAction *revertFile;
+ Utils::ParameterAction *statusFile;
//submit editor actions
QAction *editorCommit;
diff --git a/optionspage.cpp b/optionspage.cpp
--- a/optionspage.cpp
+++ b/optionspage.cpp
@@ -12,7 +12,7 @@
QWidget(parent)
{
m_ui.setupUi(this);
- m_ui.commandChooser->setExpectedKind(Core::Utils::PathChooser::Command);
+ m_ui.commandChooser->setExpectedKind(Utils::PathChooser::Command);
m_ui.commandChooser->setPromptDialogTitle(tr("Mercurial Command"));
}
diff --git a/srcdestdialog.cpp b/srcdestdialog.cpp
--- a/srcdestdialog.cpp
+++ b/srcdestdialog.cpp
@@ -9,7 +9,7 @@
m_ui(new Ui::SrcDestDialog)
{
m_ui->setupUi(this);
- m_ui->localPathChooser->setExpectedKind(Core::Utils::PathChooser::Directory);
+ m_ui->localPathChooser->setExpectedKind(Utils::PathChooser::Directory);
}
SrcDestDialog::~SrcDestDialog()
@@ -17,7 +17,7 @@
delete m_ui;
}
-void SrcDestDialog::setPathChooserKind(Core::Utils::PathChooser::Kind kind)
+void SrcDestDialog::setPathChooserKind(Utils::PathChooser::Kind kind)
{
m_ui->localPathChooser->setExpectedKind(kind);
}
diff --git a/srcdestdialog.h b/srcdestdialog.h
--- a/srcdestdialog.h
+++ b/srcdestdialog.h
@@ -18,7 +18,7 @@
SrcDestDialog(QWidget *parent = 0);
~SrcDestDialog();
- void setPathChooserKind(Core::Utils::PathChooser::Kind kind);
+ void setPathChooserKind(Utils::PathChooser::Kind kind);
QString getRepositoryString();
protected:



вторник, 17 ноября 2009 г.

Qt Creator 1.3 и Qt 4.6.0 Release Candidates

Тролли сегодня выпустили кандидатов: Qt Creator 1.3 RC и Qt 4.6 RC.

пятница, 6 ноября 2009 г.

QSQLITE driver not loaded

В посте про отладку плагинов я писал, что собранный у меня Qt Creator стартует с ошибками
QSqlDatabase: QSQLITE driver not loaded.

Все оказалось просто- я собрал Qt с отключенной поддержкой SQL (сэкономив примерно 2 часа на компиляции [UPD: на примерах и демонстрашках]). Ну что ж, надо переконфигурировать и пересобрать библиотеку.

Перенастраиваем Qt из MS Visual Command Prompt:

cd c:\Qt\4.6.0-beta1\
configure -qt-sql-sqlite -no-qt3support -no-opengl -platform win32-msvc2008 -no-libtiff -no-dbus -no-phonon -no-phonon-backend -no-webkit

UPD: используем вот такой configure:

configure -nomake examples -nomake demos -qt-sql-sqlite -no-qt3support -no-opengl -platform win32-msvc2008 -no-dbus -no-phonon -no-phonon-backend

Я убрал отмену генерации webkit и libtiff, которые используются в Qt Creator. Для конфигурирования установленной Qt это не важно, а вот если собирать ее из исходников, то разница будет заметна. Также, я отменил сборку примеров и демонстрашек, что сокращает время компиляции часа на три.

Затем пересобираем:

nmake

Отмечу, что nmake занял почти 4 часа на моей машине.
UPD: если использовать -nomake examples -nomake demos, то на сборку ушло 2 часа.

Добавляем пересобранную Qt в Qt Creator (Options -> Qt4), и делаем ее default. Все, можно пересобирать Qt Creator.

Qt Creator и баги в GDB 7.0

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

Qt Creator не может работать с GDB 7.0 по причине ошибок в новом GDB. Как указал Andre Poenitz, первая ошибка не позволяет использовать debugging helpers, из-за второй GDB не работает с классами с bitfields, а это, например, QObject и контейнеры.

Поэтому всем, кто проапгрейдился до Ubuntu 9.10 (Karmic), Qt предлагает поставить старый GDB 6.8, например этот пакет из Ubuntu Janity. Рецепт должен работать до Qt Creator 1.3 включительно.

понедельник, 2 ноября 2009 г.

Шпора по горячим клавишам Qt Creator

Вот здесь лежит, в вариантах для Win/Linux и Mac.

Шпора для версии 1.2.1, новых клавиш, добавленных в 1.3, пока нет.

Спасибо Nicolas из KDAB.

воскресенье, 1 ноября 2009 г.

Отладка плагинов под Windows

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

Для отладки нужен CDB, его надо установить с сайта Майкрософт: MS Debugging Tools for Windows 32-bit.

Для отладки плагина, нужно немного:
1. Пересобрать Qt под VC++ и сделать ее дефолтной в Qt Creator.
2. Пересобрать Qt Creator для отладки.
3. Начать отлаживать плагин.

Шаг 1 описан здесь. UPD А исправления с решением проблемы, речь о которой ниже- здесь.

Шаг 2. Исходный код Qt Creator 1.3.0 beta можно скачать из репозитория: архив.

Сборку можно делать прямо из Qt Creator, достаточно открыть проект qtcreator.pro. В меню Build -> Set Build Configuration выбрать Debug. В меню Build -> Set Run Configuration указать qtcreator (app). Также во вкладке Project проверить: Active Run Configuration = app, Build Configuration for qtcreator = Debug, и параметры для них. Осталось только сделать Build -> Build Project (qtcreator) (Ctrl+B). Сборка на моей машине заняла 45 минут.

Шаг 3 ничего сложного из себя не представляет. Заходим в папку src/plugins, находим нужный, открываем его исходник, ставим breakpoint... После этого делаем Debug -> Start Debugging -> Start Debugging (F5).

Единственная неприятность- это то, что у меня почему-то не находится драйвер QSQLITE:

QSqlDatabase: QSQLITE driver not loaded
QSqlDatabase: available drivers:
Warning: Failed to open settings database at "C:/Documents and Settings/qtcreatorgeek/Application Data/Nokia/QtCreator.db" ("Driver not loaded")
QSqlDatabase: QSQLITE driver not loaded
QSqlDatabase: available drivers:
Could not initialize help engine: "Cannot load sqlite database driver!"
QSqlDatabase: QSQLITE driver not loaded
QSqlDatabase: available drivers:
QSqlDatabase: QSQLITE driver not loaded
QSqlDatabase: available drivers:
QSqlDatabase: QSQLITE driver not loaded
QSqlDatabase: available drivers:
Could not initialize help engine: "Cannot load sqlite database driver!"
QSqlDatabase: QSQLITE driver not loaded
...

Не знаю, с чем это связано. Копирование sqldrivers\qsqlite4.dll в \bin ничего не дало.