CMake & Clang

Решил изменить сборку с идущего по умолчанию GCC на Clang для CMake проекта. Сходу наткнулся на граблю. Стандартная команда CMake:

set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_C_COMPILER clang)

Вводит его в вечный цикл, который выглядит как-то так:

You have changed variables that require your cache to be deleted.
Configure will be re-run and you may have to reset some variables.
The following variables have changed:
CMAKE_C_COMPILER= /usr/bin/gcc
CMAKE_CXX_COMPILER= /usr/bin/c++

-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Checking whether C compiler has -isysroot
-- Checking whether C compiler has -isysroot - yes
-- Checking whether C compiler supports OSX deployment target flag
-- Checking whether C compiler supports OSX deployment target flag - yes
…и так до бесконечности…

Лечится не удобно, но юзабельно:

export CXX=/usr/bin/clang++
export CC=/usr/bin/clang
cmake CMakeLists.txt
make

Как начать писать приложения для Mac OS X и iOS

Итак, по пунктам, что надо сделать для начала разработки под Mac OS X или iOS:

  1. Покупка Mac или установка Хакинтош. Я бы крайне не рекомендовал начинать с работы с виртуальной машиной, они работаютнастолько тормознуто, что такой вариант подходит разве что для “одним глазком на Mac OS X взглянуть”. Поэтому наиболее дешевым и доступным вариантом будет либо Хикинтош, либо покупка Mac Mini.
  2. Бесплатно зарегистрироваться в качестве разработчика Apple. Это необходимо сделать для доступа к документации и возможности загрузить 3-й Xcode.
  3. Загрузить бесплатно 3-й Xcode или купить за $4.99 Xcode 4. С учетом стоимости Xcode 4, я думаю что его купить все же логичнее. В то же время, в Xcode 3 доступна iOS SDK 4.3 и SDK для Mac OS X 10.6, так что “на посмотреть” его хватит.

Continue reading

Tasks Explorer 1.5

Ура! Я допилил его! Из нововведений: появилась возможность посмотреть стек вызовов и я решил открыть код под BSD лицензией. Из неприятных нововведений – похоже он стал немного течь. Если у кого-то есть желание поучаствовать в разработке – добро пожаловать!
Выглядит эта радость как-то так:

Ищем быстро. Очень быстро.

Незнаю кто как, но я обычно пишу код в Vim, отлаживаюсь в GDB, ищу Grep. Если первые два пункта не вызывают никаких нареканий, но вот Grep на больших объемах данных, например на проекте с 1GB исходных кодов, несколько нерасторопен.
Решение проблемы довольно простое: надо скрестить Spotlight с Grep и получить шустрый и удобный в работе механизм. Для zsh это можно сделать так:

g()

{
mdfind -onlyin . $1 -0 | xargs -0 grep -n --color=always $1
}

Коллекция Cocoa контролов

Я долгое время считал что количество дополнительных библиотек для Mac OS X и iOS очень скромное. В крайнем случае ни о каких библиотеках кроме как OmniGroup, BWToolkit и Sparkle я особо не слышал. Поэтому, сайт CocoaControls был для меня очень приятным открытием. Пусть большинство контролов и не подойдет для непосредственного использования, но вот как набор идей и подсказок сайт реально великолепен!

Работа с мэйкфайлами.

На просторах интернета нашел очень понравившуюся мне книгу посвященную работе с GNU Make – Managing Projects with GNU Make, 3.Xth Edition, которая еще и распространяется под GNU Free Documentation License. В книге подробно рассматривают работу с GNU Make начиная с азов и простейшего Makefile заканчивая вопросами производительности, отладкой Makefile и различными трюками.
Однозначно стоит прочесть!

C++ man(3)

Давно хотел разжиться маном по плюсам ибо задрало лазить в инет за этой информацией.
Подходящий ман берется вот тут: ftp://ftp.gwdg.de//pub/misc/gcc/libstdc++/doxygen/
И копируется вот сюда: /usr/share/man/man3
Ну а если к Vim-у добавить вот этот плагин, жизнь становится еще прекраснее :)))

LLVM, чтоб его.

Баг 2008 года в LLVM портит мне жизнь. Берем тестовый файлик следующего содержания:

class RPC_Service
{
public:
  virtual ~RPC_Service ();
};
class EventLoggingInterface
{
  virtual void
    Ev (const char *file, int line, int sev, const char *fmt,
        ...) const = 0;
};
class RPCCore : RPC_Service, EventLoggingInterface
{
  virtual void
    Ev (const char *file, int line, int sev, const char *fmt, ...) const;
};
void
RPCCore::Ev (const char *file, int line, int sev, const char *format, ...) const
{
}

Выполняем команду:

/Developer/usr/bin/llvm-g++ thunk_error.cpp -c

И в результате получаем:

thunk_error.cpp:19: error: generic thunk code fails for method ‘virtual void RPCCore::Ev(const char*, int, int, const char*, ...) const’ which uses ‘...’

Неужели придется отказаться от LLVM? Интерфейс, в моем случае, поменять врятли удастся. Вобщем писать кроссплатформенный код это еще та засада

GDB. Легко и даже изящно.

Хотя в начале GDB вызывал у меня ощущение ужаса и сильно отторжение, сейчас я к нему привык и он мне даже начал нравится. Что интересно, пришлось выучить не так уж и много команд.

Итак, по группам.

Запуск отладки

attach pid – присоединение к процессу с идентификатором pid для отладки.
set args args – установка args в качестве аргументов приложения.
run – запустить открытое приложение на отладку.
continue – продолжить выполнение приложения (например после того как сработала точка останова или в случае в присоединением к процессе).

Установка точек останова.

break file:line – установить точку останова на заданную линию заданного файла.
break func_name – установить точку останова на заданную функцию.
break – установить точку останова на текущую линию в файле.
watch – установка точки наблюдения за изменением состояния переменной (write).
rwatch addr – установка точки наблюдения за изменением состояния переменной (read). Например команда rwatch *0xfeedface, означает что необходимо наблюдать за изменением данных находящихся по адресу 0xfeedface.

Сигналы

handle SIGNAL_NAME nostop – не останавливаться на сигнале SIGNAL_NAME. Бывает очень полезно для SIGPIPE.

Управление отладкой

n – шаг, не заходя в функцию.
s – шаг в функцию.
fin – закончить функцию.

Просмотр состояния объектов

whatis – информация о типе объекта по указателю на него.
ptype – детальное описание типа.
print – распечатать значение объекта.
Кроме того, необходимо скачать файл stl-views.gdb, который легко гуглится по фразе “STL GDB evaluators/views/utilities”. Благодаря нему появляется возможность выводить содержимое контейнеров STL. Например, появляются команды pvector, pmap и т.д.

Сбор дополнительной информации

bt – показать вызовов.
i sharedlibrary – показать список загруженный динамических библиотек.
i threads – показать все активные потоки.
i line numb – отобразить информацию о линии с номером numb.
i thread – детальная информация по текущему потоку.
thread apply all command – применить команду command ко всем потокам. Очень полезно использовать thread apply all bt для вывода стека всех потоков.
frame – текущая позиция в отлаживаемом коде.
list – отобразить линию либо функцию. Если вызывается без аргументов, отображается текущая линия.
disassemble start end – диассемблировать код начинающийся по адресу start и заканчивающийся на адресе end. Команда бывает полезна в купе с i line.

Далее. Крайне желательно установить скрип который можно найти у IBM вот тут.
Благодаря ему открываются такие прекрасные команды как:

reg – вывести содержимое регистров.
dd addr – вывести содержание памяти по адресу addr в формате HEX | ASCII.

Самописные ништяки

Так же будут полезны команды загрузки/сохранения точек останова:

define bsave
shell rm -f brestore.txt
set logging file brestore.txt
set logging on
info break
set logging off
# reformat on-the-fly to a valid gdb command file
shell perl -n -e 'print "break $1n" if /^d+.+?( S+)$/g' brestore.txt > brestore.gdb
shell rm -f brestore.txt
end
document bsave
store actual breakpoints
end
define brestore
source brestore.gdb
end
document brestore
restore saved breakpoints
end

И вывод значений wchar_t строки:

define pwchar
echo "
set $c = ( wchar_t*)$arg0
while ( *$c )
if ( *$c > 0x7f )
printf "
[ %x]", *$c
else
printf "
%c", *$c
end
set $c++
end
echo "
n
end

Вобщем как-то так. Еще планирую написать о том, как искать падения по дампам при помощи GDB, что тоже довольно занимательно.