22 ноября 2010 г.

Проблемы линковки библиотек clang и llvm

При линковке приложения с библиотеками clang и llvm может возникнуть такая проблема, что нужно передавать линковщику список библиотек в строгом порядке, иначе может возникнуть ошибка "undefined reference" даже если нужная библиотека указана в параметрах линковки. (Как здесь, например. Правда, там у человека еще и строка линковки некорректна.)

Пример:

$ g++ -o ./a.out main.o `llvm-config --ldflags` -lclangFrontend -lclangBasic -lclangDriver -lclangSerialization -lclangCodeGen -lclangSema -lclangChecker -lclangAnalysis -lclangIndex -lclangRewrite -lclangAST -lclangParse -lclangLex `llvm-config --libs`

libclangParse.a(Parser.o): In function `clang::Parser::ExpectAndConsume(clang::tok::TokenKind, unsigned int, char const*, clang::tok::TokenKind)':
Parser.cpp:151: undefined reference to `clang::tok::getTokenSimpleSpelling(clang::tok::TokenKind)'
libclangLex.a(Preprocessor.o): In function `clang::Preprocessor::DumpToken(clang::Token const&, bool) const':
Preprocessor.cpp:155: undefined reference to `clang::tok::getTokenName(clang::tok::TokenKind)'
collect2: ld returned 1 exit status



Все нужные библиотеки указаны, но не в том порядке, в каком хотелось бы линковщику. Проблема в том, что линковщик ищет в каждой библиотеке по одному разу и именно в том порядке, в каком они указаны в командной строке. Например, символ clang::tok::getTokenName находится в библиотеке libclangBasic.a, которая в списке линковки указана раньше.

Можно попытаться поискать правильный порядок (долгая и неблагодарная работа), а можно воспользоваться возможностью группировки библиотек:

$ g++ -o ./a.out ../build/obj/testclang.o `llvm-config --ldflags` -lgtest -lgtest_main -Wl,--start-group -lclangFrontend -lclangBasic -lclangDriver -lclangSerialization -lclangCodeGen -lclangSema -lclangChecker -lclangAnalysis -lclangIndex -lclangRewrite -lclangAST -lclangParse -lclangLex `llvm-config --libs` -Wl,--end-group

Линковщик будет перебирать библиотеки, указанные между ключами --start-group и --end-group снова и снова, пока не отыщет все требуемые символы.

Теперь всё ОК.

18 ноября 2010 г.

Цитата: Бек

У программиста во время работы появляется соблазн думать только о компьютере. Однако во время программирования стоит подумать и о других людях.

Кент Бек, "Шаблоны реализации
корпоративных приложений"

16 ноября 2010 г.

Исключения C++ и производительность (1)

Существует очень много книг с советами, как лучше программировать на С++, и все они рекомендуют использовать исключения C++ для обработки ошибок. Возможно, есть книги, в которых не рекомендуется использовать исключения, но я таких не встречал. Сейчас как раз дочитываю "Чистый код" Роберта Мартина, и в разделе "Обработка ошибок" опять встретил этот настоятельный совет. Мотивация — использование исключений делает код более чистым и понятным. С такой формулировкой трудно поспорить, но жаль, что авторы таких советов никак не поясняют в своих книгах, в каких случаях использовать исключения, а в каких лучше не использовать.

Я встречал две крайности: разработчики, которые используют исключения везде, и разработчики, которые вообще не используют исключений. В первом случае объяснением было "потому что это круто правильно и объектно-ориентированно", в другом — "потому что они дают слишком большой оверхэд". И я задумался, кто из них прав? И, вообще, какова цена использования исключений в C++? Можно ли как-то управлять этим? Может, стоит выработать для себя какие-то правила?..

9 ноября 2010 г.

g++ 4.5 и clang

В Ubuntu 10.10 уже входит gcc 4.5, и я вчера решил собрать clang из репозитория. Всё было хорошо, пока процесс линковки не сожрал полтора гигабайта памяти. После этого он был торжественно убит системой, потому что у меня для виртуалки выделено всего полтора гигабайта. Попробовал собрать с gcc 4.4 — собрался без проблем.

Жаль, но gcc 4.5 всё-таки еще сыроват.

UPD: Смог добиться того, чтобы gcc 4.4 тоже сожрал больше 1,5 Гб. Для этого нужно включить дебаг-режим, включить ассерты и expensive checks, и выключить оптимизатор. Но это, конечно, извращение.

Еще жаль, что clang нельзя собрать без сборки llvm. Или я чего-то не знаю?

25 октября 2010 г.

Битхаки

Хороший сборник хаков по работе с битами — Bit Twiddling Hacks. Мне особенно понравился макрос инициализации таблицы для разворачивания битов.

28 июля 2010 г.

Цитата: Кларк

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

Артур Кларк, Второй закон Кларка

23 июля 2010 г.

fuse_operations::flush и реальность

В библиотеке FUSE (Filesystem in userspace) есть обработчики flush и release. Судя по описанию, обработчик flush вызывается, когда происходит системный вызов close() для файлового дескриптора. То есть сколько раз вызывался open() для файла, столько же раз будет вызван close() и, соответственно, flush. А release вызывается всего один раз, когда в системе не осталось больше ни одного открытого дескриптора этого файла.

В описании fuse_operations::flush есть небольшое примечание:
NOTE:The flush() method may be called more than once for each open(). (...) It is not possible to determine if a flush is final, so each flush should be treated equally. Multiple write-flush sequences are relatively rare, so this shouldn't be a problem.

На деле оказывается, что первый же вызов команды echo с выводом результата в файл (например, "echo blablabla >./1.txt") приводит к следующей последовательности вызовов обработчиков: create - flush - write - flush - release. То есть flush вызывается два раза, причем один раз до записи данных в файл, а второй раз — после. Получается, что корректно закрыть файловый дескриптор в обработчике flush невозможно.

Как с этим бороться — непонятно. Можно, конечно, отказаться от поддержки команд, которые приводят к "multiple write-flush sequences", но так поступать не очень хочется. Поэтому пока реализовал извращение в обработчике release, чтобы хоть как-то обойти проблему двойного вызова flush, а обработчик flush остаётся пустой, потому что при таком раскладе он совершенно бесполезен.

24 февраля 2010 г.

Поиск в Яндекс.Блогах

Честно говоря, я не очень понимаю, как работает поиск в Яндекс.Блоги, не говоря уже о рейтинге.

Например, сейчас на странице Яндекс.Блогов вот такая картинка:






Как видно, за последние три дня о трех главных темах блоггеры написали 478 постов. Однако, судя по рейтингам, которые сам же Яндекс и предоставляет, на пост пользователя abstract2001 "Дочка главы избиркома не должна уйти от ответственности" за сутки уже поставлено 430 ссылок (а с момента написания - 534, то есть за 36 часов). Об этом можно узнать, например, у Лебедева или на whoyougle. Вон она в Яндексе на четвертом месте -- "Новые подробности ДТП в Иркутске".

Странно, что за 36 часов блоггеры умудрились поставить ссылок на сообщение об Анне Шавенковой больше, чем по главным темам за три дня, а тема почему-то стоит на четвертом месте. Но фиг с ними. Скорее всего, ссылки с форумов тоже дают результат.

Поиск. Жму на "Новые подробности ДТП в Иркутске". На первой странице вижу, что найдено примерно 570 записей.


Ок. А можно всех посмотреть? Оказывается, нет. На второй странице вижу, что записей уже примерно не 570, а только 300.


А на третьей меня вообще обламывают, сообщая, что записей вообще-то всего 22, и умещаются они всего на трех страницах.


Это как понимать?


Update 24.02.2010  9:30

Тема дня "ДТП в Иркутске" уже на первом месте в Яндекс.Блогах. Видимо, обновляется раз в сутки или что-то типа того. Но поиск все равно лажает.

21 января 2010 г.

Юзабилити мобильных телефонов

Интересно, почему еще никто не додумался сделать в мобильных телефонах поиск контактов по номерам телефонов? У меня в телефоне не так много контактов, около двухсот. У многих моих знакомых список контактов раза в два больше. Но сколько бы их не было — всех не запомнишь.

Вот маленький пример. Есть у Мегафона такая услуга "Всегда на связи". Если ты был недоступен, то при появлении твоего телефона в сети придет СМСка с информацией когда и с какого номера тебе звонили. Сам по себе номер мне ничего не говорит. Вот если б там были написаны имя и фамилия... Или, например, был бы в телефоне пункт меню "Найти контакт по номеру"...

Производители телефонов, добавьте такой функционал! Пожалуйста. Хотя, может, уже есть у кого, просто я не в курсе?

20 января 2010 г.

Thunderbird 3 и Касперский

Обновил свой Thunderbird до версии 3 и получил картинку, похожую на эту:



Исчезла вся почта, папки... Осталась информация о почтовых аккаунтах, контакты и события в календаре. Тааак, думаю, проапгрейдился, блин. Посмотрел в папке Local Settings/Thunderbird. Нет, всё нормально — вся почта на месте, лежит там, разложенная по папкам.

Вспомнил, что Thunderbird не дружит с Касперским. Отключил Касперского, запустил Thunderbird — то же самое. Попробовал переустановить Thunderbird при отключенном Касперском — не помогло.

Порылся в инете. Оказалось, что модуль Kaspersky Anti-Spam Extension 9.0 не совместим с новой версией Thunderbird, но при этом является источником проблемы.

Решение (http://forums.mozillazine.org/viewtopic.php?f=39&t=1637865):

1. Деинсталлировать Thunderbird.
2. Зайти в папку C:\Program Files\Mozilla Thunderbird и удалить из нее оставшееся (а именно — папку components с компонентом Anti-Spam).
3. Установить Thunderbird 3. Всё должно работать корректно.