суббота, 16 февраля 2013 г.

chromium

"Гонять" v8 придется под chromium. Выгрузка его кодовой базы и настройка сборки заняли не так уж и мало времени и не прошли гладко: gclient заявил (если я верно понял, устами svn), что не может продолжить работу вследствие наличия папки (развернутой из bootstrap-архива), не принадлежащей проекту. Удалил её вручную, надеюсь, именно так и нужно было поступить. В ходе дальнейшего конфигурирования gсlient выдал два десятка предупреждений с рекомендацией удалить те или иные каталоги. Переместил их в отдельную папочку. Запустил сборку. Если всё пойдет хорошо, это на часы или даже десятки часов.

UPD.
Chromium успешно собрался, примерно за 3.5-4 часа. Папка с репозиторием потяжелела до 14 Гб., бинарный файл (собранный в дебаге, конечно) "весит" 1.6 Гб. На первый взгляд всё работает, пока заметил только странный эффект при обновлении экрана - мелькает сплошная зелёная заливка. Дебажная версия отличается не только отладочными символами в бинарных файлах - в консоль много чего логируется при работе.

v8

Кажется, настала пора ковырять JavaScript-движок от Google v8. Собрался он на ура, благо подробные (и при том простые) инструкции по сборке присутствуют в документации. Пока только было замечено, что движок неплохо покрыт тестами - их очень много и они долго выполняются (много дольше довольно шустрой сборки), хотя не все проходят успешно несмотря на то, что собиралась релизная версия десятидневной давности. Посмотрим, как быстро закончится документация.

суббота, 21 июля 2012 г.

Подключение к VirtualBox физического жесткого диска

Вы можете создать виртуальную машину, работающую со специальным *.vmdk-диском, в действительности напрямую отображаемом в реальный жесткий диск, в том числе внешний.

Так создается описанная связь (предполагается, что вы хотите создать *.vmdk-диск с именем usb-hdd320 и соединить его с пустым физическим диском /dev/sdc, и все происходит в ОС семейства Linux):

# cd ~/VirtualBox\ VMs
# sudo vboxmanage internalcommands createrawvmdk -filename usb-hdd320.vmdk -rawdisk /dev/sdc

Вы должны получить сообщение "RAW host disk access VMDK file usb-hdd320.vmdk created successfully", если все прошло хорошо. Далее необходимо создать виртуальную машину с именем, например, minilab, для работы с жестким диском через *.vmdk файл:

# sudo vboxmanage createvm --name minilab --ostype Ubuntu --register
# sudo vboxmanage modifyvm minilab --memory 512
# sudo vboxmanage storagectl minilab --name "IDE Controller" --add ide
# sudo vboxmanage storageattach minilab --storagectl "IDE Controller"--port=0 --device=0 --type hdd --medium ~/VirtualBox\ VMs/usb-hdd320.vmdk

Если вы хотите подкючить к ней iso-образ инсталляционного диска с именем, скажем, installation_cd.iso, то по образу и подобию подключения жесткого диска можете сделать следующее:

# sudo vboxmanage storageattach minilab --storagectl "IDE Controller" --port=0 --device=1 --type dvddrive --medium ~/VirtualBox\ VMs/installation_cd.iso

Запускается виртуальная машина minilab так:

# sudo vboxmanage startvm minilab

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

понедельник, 30 апреля 2012 г.

Objective-C

Если вы давно хотели попробовать, что же такое Objective-C, но не знали, с чего начать, то вам определенно будет более, чем достаточно на первое время материала двух лишь только статей:
википедии и руководства по GNUstep

UPD.
Ну и разумеется замечательная страничка документации по GNUstep.

среда, 11 апреля 2012 г.

Qt & multiple definition

QГрабля#5


При инстанцировании шаблонов внутри классов, использующих мета-объектную систему Qt, а также в ряде других ситуаций при использовании этой библиотеки (на практике особенно часто - при создании Unit-тестов силами QTestLib) возможно возникновение ошибки линковки multiple definition. Связано это с тем, что moc парсит заголовочные файлы и для всех файлов, содержащих класс с макросом Q_OBJECT генерирует *.cpp-файл с необходимым для функционирования мета-объектной системы Qt кодом. Такой файл становится отдельной единицей компиляции, и если в нем, как пример, инстанцируется какой-либо шаблон, то он, согласно правилам компиляции шаблонов C++, полностью включается в генерируемый объектный файл. Врочем, ровно то же происходит при инстанцировании такого шаблона в любом другом *.cpp файле, например, содержащем main(). В итоге в ходе линковки один и тот же шаблон обнаруживается сразу в нескольких объектных файлах, что и приводит к возникновению описанной выше ошибки.

Поправить ситуацию можно несколькими способами. Можно все методы шаблона сделать
inline-овыми (см. описание похожей ситуации), можно модифицировать сборку Qt-проекта вручную так, чтобы генерируемый moc'ом файл просто включался в файл, по которому он был сгенерирован (именно это в простых случаях автоматизировано выполняет этот скрипт (см. замечания)) Либо можно позволить линковщику самостоятельно разрешать такие конфликты, просто выбирая первое из многочисленных определений (ключ -z muldefs для *nix-линковщика ld) Интегрировать нужные ключи можно автоматически в Makefile с помощью этого скрипта (см. описание), либо просто ключив в *.pro-файл строку вида:

QMAKE_LFLAGS += -z muldefs


понедельник, 12 марта 2012 г.

Перенесу сюда сообщение из своего аккаунта в контакте:
Выяснение отношений с непокорным C++ привело меня к заключению, что чтобы детально разбираться во всех тонкостях инициализации и уничтожения объектов классов нужно положить на это жизнь. Если при попытке писать что-то ООП-шное вы часто получаете непонятные ошибки, возможно, причина кроется как раз в непонимании одного из 847528345-и моментов, касающихся именно этой области C++. Очень хорошо эти вопросы освещены в соответсвующих главах Брюса Эккеля "Философия C++, том 1", в которых будет проще и продуктивнее следить за мыслью автора с помощью вот этого: https://github.com/ramntry/constructors
Получить пакет и попробовать запустить пример на *nix-совместимых системах можно следующим образом:

git clone git://github.com/ramntry/constructors.git
cd constructors
./constructors -f examples/virtual_destructors.cpp
В системе должны быть установлены bash (или другой совместимый shell), git, g++ (gcc) и sed

понедельник, 5 марта 2012 г.

Qt и шаблоны

Не пытайтесь создать шаблонный класс, использующий мета-возможности Qt - в текующей реализации (Qt 4.8) ключевое слово template перед заголовком класса и макрос Q_OBJECT в его приватном блоке вещи несовместимые (просто шаблонный наследник QObject имет право на существование, но ведь это уже совсем другая история)

Поведение системы сборки Qt

QГрабля#4

Во многих случаях вам не удастся тривиальным образом скомпилировать код, который определяет класс, использующий расширенные возможности Qt, в том же файле, в котором расположена функция main - этот класс едва ли будет обработан утилитой MOC.

Решение

Всегда определяйте Qt-классы в отдельных заголовочных файлах. Реализация такого класса допустима как in situ, так в *.cpp-файле.

UPD


Также об этой проблеме можно почитать в небольшой ветке форума Qt

Управление памятью в Qt

QГрабля#3


Известно, что немалая часть объектов Qt, с которыми приходится иметь дело, в той или иной мере являются контейнерами для других объектов, иногда это непосредственно так (например, для layout'ов), иногда вырождается в повсеместно существующую возможность назначить объекту некоторого родителя. Так или иначе, крайне часто вы передаете в метод (в т. ч. конструктор) объекта указатель на другой объект. Не таким уж странным в таком случае кажется решение создать объект на стеке, а в случае необходимости его куда-то передать просто использовать оператор взятия адреса.

Однако Qt в рамках своей юрисдикции сама управляет памятью - если вы удаляете объект, его деструктор автоматически удаляет всех своих детей и (вероятно) элементы, содержащиеся в нем. Естесственно, ей невозможно знать, был ли создан указатель операцией new, или он указывает на объект, для которого вовсе не освобождалась память в куче - при удалении вашему указателю сделают delete, что выльется в реальной практике в backtrace и memory dump на экран при завершении Qt-шного приложения, если этот указатель увел delete на стек. Однако если вы все объекты будете создавать в куче не заботясь об их удалении, то вы получите утечки памяти. Ясно, что позаботиться обо всех объектах также невозможно разумным образом - в частности, не удалить экземпляр QApplication (QCoreApplication) без странных костылей типа

int returnCode = app->exec();
delete app;
return returnCode;

которых вы никогда не увидите ни в одном руководстве по Qt. Ровно те же проблемы возникнут с объектом главного окна приложения.

Решение.

Все Qt-шные объекты и их наследники создавайте в динамической памяти, следя за тем, что вы или верно поддерживаете естесственную для Qt иерархию объектов (на отношении родитель-потомок), либо разумным образом удаляете их самостоятельно. Все объекты, являющиеся корнями иерархий (не имеющие родителей) создавайте на стеке, обеспечивая их автоматическое удаление. Иначе говоря, остерегайтесь когда-либо применять операцию взятия адреса к Qt-объектам, а в остальном управляйте памятью обычным образом.


UPD


Несомненно более точно и тонко проблему освещает таки документация Qt
QГрабля#2


Если ваш класс использует систему свойств Qt, то вы можете неожиданно получить проблему на стадии компиляции при попытке вызвать setProperty.
( <YourClass or ParentClass>::setProperty("PropertyName", propertyValue); )

Вам сообщат что-то в духе
"no known conversion for argument 2 from <propertyValueType> to ‘const QVariant&"

Проблема связана с тем, что по известным причинам свойства имеют тип QVariant, а в данном блоке кода компилятору просто не известен этот тип.

Решение

Включайте заголовочный файл <QVariant> (QtCore/QVariant> в файлы-определения классов,
использующих свойства Qt. (или даже в main-файл)

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

QГрабля#1


Если в приватной секции определения класса, использующего метаобъектную систему Qt, вы забыли указать макрос Q_OBJECT, а затем исправили свою оплошность, то вы вполне можете снова (и снова, и снова...) получить ошибку компиляции со словами в духе "undefined reference" и "vtable of <YourClass>" в строках клиентского кода, использующих в вашем классе дополнительные возможности наследников QObject (сигналы и слоты, свойства, возможности интроспекции).
Подобное может произойти в том случае, если ранее ваш класс, определенный без макроса Q_OBJECT уже успешно компилировался (то есть, дополнительные возможности не использовались) - и в папке сборки уже лежит Makefile, сгенерированный по *.pro-файлу утилитой qmake. Дело в том, что даже после внесенных исправлений, пересборка проекта заключается в вызове make, подхватывающей старый Makefile, который не вызывает MOC для файлов вашего класса (так что даже make clean не поможет).

Решение


Вручную удалите Makefile в директории сборки проекта и пересоберите его.

Так же полезно завести в директории ~/bin файлик с содержимым вроде


#!/bin/sh
if [ -e "Makefile" ]
then
    make clean
    rm Makefile
fi
qmake -project
qmake
make
(не забудьте сделать chmod +x <имя файла> и убедиться в том, что ~/bin есть в переменной окружения PATH (иначе можно ее туда добавить, дописав в ~/.profile строку
PATH="$HOME/bin:$PATH" ))

... и затем собирать проекты вызовом этого скрипта. У меня это выглядит так:

qqmake


воскресенье, 1 января 2012 г.

Мучает info?

Когда-нибудь Emacs придется освоить, ну а пока - перенаправляйте:

user@host cwd$ info something | less

Парсер параметров ядра

Код, стиль и подход которого почитателями всевозможных высокоуровневых style-guide'ов будет осужден и высмеян. Однако - что в этом фрагменте кода ядра непрозрачно, трудноподдерживаемо или опасно? Смотрите сами.

Linux-kernel в комментариях

Скотт Максвелл, первое издание на русском языке, неплохая интернет-версия