Предисловие


Не смотря то, что Apple предоставляет довольно полный SDK для iPhone, иногда необходимо приложение, выходящие за рамки документированных возможностей. Пример такого приложения — Veency, VNC сервер для джейлбрейкнутых iPhone'ов.
Я бы хотел поделиться опытом компиляции Veency «с нуля». Надеюсь, что этот пост окажется познавательным.

Проблема


Необходимо внести небольшие изменения в код VNC сервера для джейлбрейкнутого iPhone'а, перекомпилить и установить на девайс. Имеется: девайс, Ubuntu 9.04 и мак.

Решение


Приведённое ниже решение не является пошагвым руководством. Я бы хотел рассказать о процессе сборки в общем и о сложностях, с которыми я встретился. Более того, я попытался собрать в этом посте все необходимые ссылки, а также выложить некоторые результаты своей работы.

Компоненты

Saurik (aka Jay Freeman) — разработчик Cydia, Veency, многих других iPhone'овских фишек и, похоже, очень неплохой человек.

SpringBoard — библиотека, которая по сути рисует homescreen iPhone'а. Стартует вместе с девайсом.

toolchain — набор инструментов для компиляции iPhone-приложений. Его мы скоро будем строить.

libvncserver — VNC сервер с открытым исходным кодом. Его мы будем кросс-компилировать для iPhone'а.

Veency — VNC сервер для iPhone'a. Его-то мы и будем строить. Соль — в файле Tweak.mm, остальное нам не интересно.

MobileSubstrate — библиотека, написанная sаurik'ом. В частности позволяет запускать приложения в бекграунде. Нам интереснa следующая фича: если положить библиотеку (dylib) в /Library/MobileSubstrate/DynamicLibraries, то она будет подгружена, когда стартует SpringBoard. Продукт нашего опыта — Veency.dylib, которая как раз будет лежать в DynamicLibraries.

Шаг 1: Toolchain для Ubuntu

Оказывается, собрать toolchain не так сложно, как кажется. Мы будем строить toolchain для 2.2.1. Она сможет компилировать приложения и для 3.0.

Есть такой проект, iphonedevonlinux. Это, по сути, один скрипт, ./toolchain.sh, который загружает почти все необходимые файлы, раскидывает всё по папкам и собирает toolchain.

Для работы этого скрипта я скачал: iPhone ipsw версии 2.2.1 и XCode SDK dmg версии 2.2.1. Более того, надо иметь аккаунт на developer.apple.com (это бесплатно). На Ubuntu надо иметь gobjc и некоторые другие девелоперские утилиты. Всё устанавливается из стандартных репозиториев.

Итак, sudo ./toolchain.sh all.

У меня заработало далеко не с первого раза. Я встретился со следующими траблами:
1. *** buffer overflow detected ***: решил apt-get reinstall gcc
2. не может скомпилировать toolchain/src/cctools/otool/print_objc.c: решил apt-get install libc6
3. какая-то рандомная ошибка: поменял gcc 4.3.3 на gcc 4.2.4. Потом поменял обратно и всё заработало. В результате скомпилилось gcc 4.3.3.

Когда всё будет готово, скрипт скажет "All stages completed. The toolchain is ready."

Шаг 2: VNC Server

Тут всё просто. Надо скачать исходники libvncserver'a, и кросс-компилировать их. Собственно, ./configure --host=arm-apple-darwin9, а дальше обычный make. Единственное, что мне помешало, это то, что в главном Makefile'e билдились всякие левые проекты (типа libvncclinet, examples и т. п.). Их я убрал руками.
Если лень строить ��амому, то я выложил библиотеку и хедеры на ifolder.

Когда всё будет готово, появится libvncserver/.lib/libvncserver.dylib.

Шаг 3: Veency Makefile

Saurik, конечно, выложил свой makefile. Однако, у него это часть его билд-фреймворка, так что мне показалось проще написать свой Makefile, где всё в одном файле. Особых сложностей я не встретил.

Вот результат моей работы: Makefile на pastie.

Шаг 4: MobileSubstrate

Нужен хедер и библиотека. Можно либо собрать из репозитория, либо скачать уже собранный архив. Я сделал второе.

Шаг 5: Headers & Frameworks

Для билда Veency нужны хедеры и фреймворки. Какие именно очевидно из импортов.

Хедеры. Тут зарыта собака. Хедеров найти непросто. Есть секретный репозиторий, где кое-что храниться. Есть программа class-dump-x для дампа Objective-C хедеров. Есть де-компилятор (arm-apple-darwin9-otool), но до этого дойти не должно. Хочу обратить внимание на класс GraphicsServices.h: для него правильный заголовки оказалось найти сложнее всего (нашлись в секретном репозитории).

Фреймворки. Тут всё просто. Если на этапе линковки не хватает каких-то символов, смело можно копировать фреймворки либо из iPhone SDK (/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks/ на маке), либо scp с девайса. Единственная сложность: библиотеки из 3.0 и 2.2.1 перемешивать не стоит.

Шаг 6: Make

Если ломается на этапе компиляции, то надо дать не хватающих хедеров. Их надо добыть и добавить в инклюд-папку (SB_PATH в Makefile'е).
Если ломается на стадии линковки, то надо добавить фреймворков в $(SYS_PATH)/System/Library (SYS_PATH из Makefile'е).

Результат: Veency.dylib

Шаг 7: Подписывание

Собранную библиотеку необходимо подписать. Для этого есть утилита ldid. Она есть для десктопа и для iPhone'а. На десктопе у меня она так и не заработала. На iPhone она устанавливается из Cydia. Дальше — просто: надо scp Veency.dylib на девайс и набрать ldid -S Veency.dylib.

Результат: подписанная Veency.dylib

Шаг 8: Установка

А это совсем просто: скопировать Veency.dylib в /Library/MobileSubstrate/DynamicLibraries. Это автоматизированно в Makefile'е таргетом install (надо только переменную IP проставить).

Результат: Вы — хакер :)

Про этот пост


А хотите узнать, зачем я всё это написал? Во-первых, поделиться некоторыми знаниями. А, во-вторых, поддержать Хабр. Последнее время уж больно много статей про то, что Хабр не тот, что НЛО уже на луне, что сделать ИИ — тривиально. Много всяких досужих мыслей, бессмысленных вопросов, ссылок на новости других ресурсов и т. п. Вот и хочется этому как-то противостоять.

Читатель, прошу тебя, напиши и ты что-нибудь про IT. Пусть на узкую тему, пусть только верхушки идей, путь это интересно единицам. Зато Хабр будет торт ещё!