Сборка FreeType2 под iOS

    imageimage
    В интернете есть множество заметок о том, как собирать freetype под iOS.
    Все эти заметки объединены общей характеристикой — они не работают.
    Дело в том, что все инструкции оперируют gcc для сборки библиотеки, но начиная с XCode 5 gcc не входит в поставку и для сборки под iOS надо использовать clang.
    Нет ни одной заметки о том, как компилировать правильно.
    Исправляем эту несправедливость.


    Подготовка к сборке


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

    Для сборки универсальной библиотеки нам понадобится 5 раз повторить компиляцию библиотеки с разными параметрами.
    Все инструкции выполняются из корневого каталога freetype.

    i386


    $ ./configure --enable-static=yes --enable-shared=no CC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc CFLAGS="-arch i386 -Wno-extended-offsetof -miphoneos-version-min=4.2 -I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/usr/include -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk" CPP=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cpp AR=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar LDFLAGS="-arch i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk -miphoneos-version-min=4.2"
    $ make

    Этими командами мы настраиваем сборку для i386 архитектуры и собираем библиотеку. Полученная библиотека разместится в каталоге objs/.libs/libfreetype.a
    Переименовываем полученную библиотеку и копируем в корень. Она понадобится нам на последнем шаге сборки.

    $ cp objs/.libs/libfreetype.a libfreetype-i386.a

    x86_64


    Аналогичным способом собираем под x86_64, добавляем команду make clean, чтобы избавиться от результатов предыдущей сборки

    $ ./configure --enable-static=yes --enable-shared=no CC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc CFLAGS="-arch x86_64 -Wno-extended-offsetof -miphoneos-version-min=4.2 -I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/usr/include -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk" CPP=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cpp AR=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar LDFLAGS="-arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk -miphoneos-version-min=4.2";make clean;make
    $ cp objs/.libs/libfreetype.a libfreetype-x86_64.a


    armv7

    armv7 используется в iPhone 3GS, iPhone 4, iPhone 4S. Добавляем параметры для кросс-компиляции.

    $ ./configure --host=arm-apple-darwin --enable-static=yes --enable-shared=no CC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc CFLAGS="-arch armv7 -pipe -std=c99 -Wno-extended-offsetof -Wno-trigraphs -fpascal-strings -O2 -Wreturn-type -Wunused-variable -fmessage-length=0 -fvisibility=hidden -miphoneos-version-min=4.2 -I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk" AR=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar LDFLAGS="-arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk -miphoneos-version-min=4.2"
    $ make clean;make
    $ cp objs/.libs/libfreetype.a libfreetype-arm7.a


    armv7s

    armv7s используется в iPhone 5, iPhone 5S. Конфигурация отличается минимально.

    $ ./configure --host=arm-apple-darwin --enable-static=yes --enable-shared=no CC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc CFLAGS="-arch armv7s -pipe -std=c99 -Wno-extended-offsetof -Wno-trigraphs -fpascal-strings -O2 -Wreturn-type -Wunused-variable -fmessage-length=0 -fvisibility=hidden -miphoneos-version-min=5.0 -I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk" AR=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar LDFLAGS="-arch armv7s -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk -miphoneos-version-min=5.0"
    $ make clean;make
    $ cp objs/.libs/libfreetype.a libfreetype-arm7s.a


    arm64

    arm64 — самая актуальная архитектура на момент написания заметки.

    $ ./configure --host=arm-apple-darwin --enable-static=yes --enable-shared=no CC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc CFLAGS="-arch arm64 -pipe -std=c99 -Wno-extended-offsetof -Wno-trigraphs -fpascal-strings -O2 -Wreturn-type -Wunused-variable -fmessage-length=0 -fvisibility=hidden -miphoneos-version-min=6.0 -I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk" AR=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar LDFLAGS="-arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk -miphoneos-version-min=6.0"
    $ make clean;make
    $ cp objs/.libs/libfreetype.a libfreetype-arm64.a


    Важно

    Не забудьте поменять iPhoneOS7.1.sdk на ту версию sdk, которая установлена у Вас сейчас. 7.1 — актуальная версия на момент написания заметки, но обновления выходят достаточно часто и, вполне вероятно, что к моменту прочтения Вами этой инструкции версия уже изменилась.

    Сборка универсальной библиотеки

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

    $ lipo -create -output libfreetype.a libfreetype-i386.a libfreetype-x86_64.a libfreetype-arm7.a libfreetype-arm7s.a libfreetype-arm64.a

    Теперь там же в корне лежит долгожданная libfreetype.a, поддерживающая все нужные нам архитектуры.

    Ну вот и все. Добавляйте полученную библиотеку в свой XCode проект и работайте с ней!
    Удачи!
    Share post

    Similar posts

    Comments 21

      0
      Вот это совпадение! Только вчера под Android собирал, и в это время мой друг в Стиме тоже собирал :D
      Разве -DFT2_BUILD_LIBRARY не надо?
        0
        Не, не надо.
        Оно уже прописано в makefile:
        # Note what we also define the macro FT2_BUILD_LIBRARY when building
        # FreeType. This is required to let our sources include the internal
        # headers (something forbidden by clients).

        Про сборку под Андроид я не стал писать ничего, потому что это уже раписано достаточно подробно.
        А вот про использование clang почему-то в основном молчат. Видимо из-за того, что gcc совсем недавно выпилили.
        0
        Ну вот есть рабочий билд
          0
          Плохо искали. github.com/PaulWagener/mapnik-ios-framework Тут собирают растровый рендер (mapnik) и freetype не самая сложная из зависимостей. :)

          Мне очень понравился подход и организация Makefile, так что на основе их подхода я организовал сборку всех своих внешних зависимостей. Среди всего прочего там есть пример как надо собирать libicu, которая может понадобится для нормальной работы с арабскими символами.
            0
            Не совсем понимаю, как мне надо было формировать запросы в гугле, чтобы в итоге выйти на этот фреймворк.
              0
              Я и сам не помню как его нашел. Видимо в каком-то из похожих обсуждений кросскомпиляции под iOS на stackoverflow.
                0
                Не так давно пришло понимание, что не о чем писать вообще. :)
                Потому что практически про любую ситуацию можно сказать: решение уже есть в интернете.
                Я сам же его как-то нашел или пришел к нему самостоятельно, а значит и другие смогут найти.
                Здесь же причиной написать стало то, что решение не гуглится с очевидных запросов.
                А параметры для configure не все могут подобрать самостоятельно.
                  +1
                  Я совсем не против этого поста. Это обмен опытом. Так и я чтобы не создавать новый пост, решил написать в комментарии, о тонкостях с которыми пришлось не так давно разобраться.
              0
              Еще важный момент у кросскомпиляции — заголовочные файлы, которые генерятся под текущую платформу при помощи ./configure Опасно может быть использовать одни и те же заголовочные файлы для всех архитектур при сборке проекта. Т.к. с добавлением amd64 могут быть проблемы с внутренними типами библиотек. Решение в следующем:
              1. Собирать библиотеки с --prefix=build/$arch, как это делает вышеуказанный Makefile, так чтобы в папке build были доступны все h файлы для каждой из архитектур.
              2. Потом прописать в User Header Search File что-то вроде следующей строки: "$(SRCROOT)/../libs/build/$(arch)/include". Так во время сборки каждой из архитектур приложения Xcode будет использовать правильные версии h файлов.
                0
                Насколько я могу судить в случае с FreeType это не актуально, т.к. все типы жестко прописаны и не меняются в разных архитектурах.
              +1
              Спасибо, воспользовался!

              Кстати, в строчке конфигурации для armv7s — LDFLAGS="-arch armv7s -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk -miphoneos-version-min=4.2", а должно быть 5.0, не?
                0
                Да, верно. Исправил
                0
                AllexIn, а вам не сложно было бы это оформить в виде .sh скрипта?
                  0
                  А нечего оформлять. Просто берете все вставки кода из заметки, объединяете в одну портянку — вот вам и готовый скрипт.
                    +1
                    Нет особого смысла. Я набирал ручками, заодно проверяя пути. У меня например не стоит 7.1 SDK, зато есть 7.0.
                      0
                      Из тех же соображений не запускаю все команды за раз. Каждый шаг проверяю что все нормально отработало.
                        0
                        вот поэтому и прошу оформить в скрипт) а версию передавать параметром
                          0
                          Я вас услышал. Будет свободная минутка — соберу и проверю скрипт.
                    0
                    Было бы неплохо в статье указать коротко — что такое freetype и зачем он нужен
                      0
                      Заметка нацелена в первую очередь на тех, кто убдет искать способы собрать freetype. То есть на тех, кто уже знает что это такое.
                      Делать обзор в заметке особого смысла нет — freetype уже подробно разобран, в том числе и на хабре.
                      0
                      Пока собирал, получилось вот. На скорую руку, зато проще управлять. Цель для сборки определяется параметром [all|i386|x86_64|arm7|arm7s|arm64|universal]. Исправил возможную проблему с ranlib для arm64. Можно брать и пользоваться (или исправлять этот ужас)

                      Only users with full accounts can post comments. Log in, please.