FreeType – это бесплатная низкоуровневая библиотека для работы со шрифтами. Она написана на ANSI C и используется в огромном количестве известных проектов. В Android, например. Но у прикладных Android-приложений нет прямого доступа к этой библиотеке. Поэтому, если вы хотите воспользоваться ей в собственном проекте, FreeType надо будет собрать для интересующей вас платформы. Мы будем собирать её для платформы x86, используя средства NDK.
NDK, помимо сборки библиотек для Android, обладает и другими полезными возможностями. Например, с его помощью можно писать мобильные приложения на C и C++, он поддерживает и множество служебных функций, таких, как автоматическое создание build-файлов и работа со структурой проекта.
Собирать библиотеки для Android можно разными способами. Например, используя автоматическую систему сборки NDK. Ещё один вариант – средства кросс-компиляции из Cygwin и отдельный набор инструментов NDK.
Здесь можно найти список библиотек для Android, которые поддерживают платформу x86. А в этом материале мы расскажем, как, используя IDE Eclipse, организовать автоматическую NDK-сборку библиотеки FreeType.
Создадим в Eclipse новый проект Android-приложения и добавим в него папку jni.
Папка jni в новом проекте Android-приложения
Теперь загрузим архив с кодом библиотеки FreeType. В нашем случае это версия 2.6. Распакуем архив в папку jni.
Исходный код FreeType в папке jni
Теперь добавим в проект приложения файлы Android.mk и Application.mk. Эти файлы должны располагаться в папке jni. Adroid.mk – это makefile GNU, который обрабатывает система сборки. В этом файле указывают сведения о файлах с исходным кодом приложения и о необходимых для сборки проекта внешних библиотеках.
Здесь можно найти подробности о синтаксисе Android.mk и об особенностях сборки Android-приложений, написанных на C и C++. Создадим этот файл в папке jni, он рассчитан на сборку библиотеки FreeType со всеми поддерживаемыми ей форматами шрифтов.
Файл Android.mk
По умолчанию система сборки NDK генерирует машинный код для архитектуры armeabi. Для того чтобы добавить поддержку архитектуры Intel, нам понадобится настроить файл Application.mk, расположенный в той же папке jni. А именно – добавить «x86» в переменную APP_ABI. Сборку можно осуществлять одновременно для нескольких платформ, их идентификаторы указывают через пробел.
Вот, как выглядит переменная APP_ABI, настроенная на две целевые архитектуры.
Для того чтобы сгенерировать машинный код для всех доступных наборов инструкций, можно воспользоваться такими настройками:
Переменная APP_PLATFORM содержит название целевой платформы Android. Наш Application.mk получился довольно простым:
Вот, как он выглядит в редакторе кода.
Настройка APP_ABI в файле Application.mk
Предварительная подготовка пройдена, теперь настроим автоматическую сборку проекта с использованием NDK. Для этого нужно, во-первых, настроить список сборщиков (Builders) для проекта, во-вторых – выбрать конкретный сборщик, которым нужно пользоваться при подготовке библиотеки.
Для того чтобы это сделать, щёлкнем правой кнопкой мыши по Android-проекту, выберем в меню пункт Properties. Для того чтобы добавить в список новую систему сборки, нужно, в левой части появившегося окна, перейти на закладку Builders, затем – нажать на кнопку New, расположенную справа.
Свойства проекта
Из списка в окне выбора типа конфигурации выберем Program. Этот вариант позволяет указать расположение внешних инструментов и то, как именно нужно выполнять скрипты, осуществляющие сборку.
Настройка конфигурации
В появившемся окне настроим следующие поля:
Настройка NDK
После выполнения вышеописанных настроек, запустим сборку проекта. Когда этот процесс успешно завершится, в папках, имена которых строятся по схеме /lib/<APP_ABI>, можно будет найти сборки библиотеки для платформ, указанных в Application.mk. В частности, нас интересуют папки x86 и x86_64.
Файлы libfreetype.so для Android- устройств, построенных на платформе x86
Библиотека FreeType собрана, теперь вы можете использовать её в собственных Android-приложениях.
NDK, помимо сборки библиотек для Android, обладает и другими полезными возможностями. Например, с его помощью можно писать мобильные приложения на C и C++, он поддерживает и множество служебных функций, таких, как автоматическое создание build-файлов и работа со структурой проекта.
Собирать библиотеки для Android можно разными способами. Например, используя автоматическую систему сборки NDK. Ещё один вариант – средства кросс-компиляции из Cygwin и отдельный набор инструментов NDK.
Здесь можно найти список библиотек для Android, которые поддерживают платформу x86. А в этом материале мы расскажем, как, используя IDE Eclipse, организовать автоматическую NDK-сборку библиотеки FreeType.
Настройка проекта и сборка библиотеки
Создадим в Eclipse новый проект Android-приложения и добавим в него папку jni.
Папка jni в новом проекте Android-приложения
Теперь загрузим архив с кодом библиотеки FreeType. В нашем случае это версия 2.6. Распакуем архив в папку jni.
Исходный код FreeType в папке jni
Теперь добавим в проект приложения файлы Android.mk и Application.mk. Эти файлы должны располагаться в папке jni. Adroid.mk – это makefile GNU, который обрабатывает система сборки. В этом файле указывают сведения о файлах с исходным кодом приложения и о необходимых для сборки проекта внешних библиотеках.
Здесь можно найти подробности о синтаксисе Android.mk и об особенностях сборки Android-приложений, написанных на C и C++. Создадим этот файл в папке jni, он рассчитан на сборку библиотеки FreeType со всеми поддерживаемыми ей форматами шрифтов.
Файл Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
FREETYPE_SRC_PATH :=
LOCAL_MODULE := freetype
LOCAL_CFLAGS := -DANDROID_NDK -DFT2_BUILD_LIBRARY=1
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include_all $(FREETYPE_SRC_PATH)include $(FREETYPE_SRC_PATH)src
LOCAL_SRC_FILES := $(FREETYPE_SRC_PATH)src/autofit/autofit.c $(FREETYPE_SRC_PATH)src/base/basepic.c $(FREETYPE_SRC_PATH)src/base/ftapi.c $(FREETYPE_SRC_PATH)src/base/ftbase.c $(FREETYPE_SRC_PATH)src/base/ftbbox.c $(FREETYPE_SRC_PATH)src/base/ftbitmap.c $(FREETYPE_SRC_PATH)src/base/ftdbgmem.c $(FREETYPE_SRC_PATH)src/base/ftdebug.c $(FREETYPE_SRC_PATH)src/base/ftglyph.c $(FREETYPE_SRC_PATH)src/base/ftinit.c $(FREETYPE_SRC_PATH)src/base/ftpic.c $(FREETYPE_SRC_PATH)src/base/ftstroke.c $(FREETYPE_SRC_PATH)src/base/ftsynth.c $(FREETYPE_SRC_PATH)src/base/ftsystem.c $(FREETYPE_SRC_PATH)src/cff/cff.c $(FREETYPE_SRC_PATH)src/pshinter/pshinter.c $(FREETYPE_SRC_PATH)src/pshinter/pshglob.c $(FREETYPE_SRC_PATH)src/pshinter/pshpic.c $(FREETYPE_SRC_PATH)src/pshinter/pshrec.c $(FREETYPE_SRC_PATH)src/psnames/psnames.c $(FREETYPE_SRC_PATH)src/psnames/pspic.c $(FREETYPE_SRC_PATH)src/raster/raster.c $(FREETYPE_SRC_PATH)src/raster/rastpic.c $(FREETYPE_SRC_PATH)src/sfnt/pngshim.c $(FREETYPE_SRC_PATH)src/sfnt/sfntpic.c $(FREETYPE_SRC_PATH)src/sfnt/ttbdf.c $(FREETYPE_SRC_PATH)src/sfnt/ttkern.c $(FREETYPE_SRC_PATH)src/sfnt/ttload.c $(FREETYPE_SRC_PATH)src/sfnt/ttmtx.c $(FREETYPE_SRC_PATH)src/sfnt/ttpost.c $(FREETYPE_SRC_PATH)src/sfnt/ttsbit.c $(FREETYPE_SRC_PATH)src/sfnt/sfobjs.c $(FREETYPE_SRC_PATH)src/sfnt/ttcmap.c $(FREETYPE_SRC_PATH)src/sfnt/sfdriver.c $(FREETYPE_SRC_PATH)src/smooth/smooth.c $(FREETYPE_SRC_PATH)src/smooth/ftspic.c $(FREETYPE_SRC_PATH)src/truetype/truetype.c $(FREETYPE_SRC_PATH)src/type1/t1driver.c $(FREETYPE_SRC_PATH)src/cid/cidgload.c $(FREETYPE_SRC_PATH)src/cid/cidload.c $(FREETYPE_SRC_PATH)src/cid/cidobjs.c $(FREETYPE_SRC_PATH)src/cid/cidparse.c $(FREETYPE_SRC_PATH)src/cid/cidriver.c $(FREETYPE_SRC_PATH)src/pfr/pfr.c $(FREETYPE_SRC_PATH)src/pfr/pfrgload.c $(FREETYPE_SRC_PATH)src/pfr/pfrload.c $(FREETYPE_SRC_PATH)src/pfr/pfrobjs.c $(FREETYPE_SRC_PATH)src/pfr/pfrsbit.c $(FREETYPE_SRC_PATH)src/type42/t42objs.c $(FREETYPE_SRC_PATH)src/type42/t42parse.c $(FREETYPE_SRC_PATH)src/type42/type42.c $(FREETYPE_SRC_PATH)src/winfonts/winfnt.c $(FREETYPE_SRC_PATH)src/pcf/pcfread.c $(FREETYPE_SRC_PATH)src/pcf/pcfutil.c $(FREETYPE_SRC_PATH)src/pcf/pcfdrivr.c $(FREETYPE_SRC_PATH)src/psaux/afmparse.c $(FREETYPE_SRC_PATH)src/psaux/psaux.c $(FREETYPE_SRC_PATH)src/psaux/psconv.c $(FREETYPE_SRC_PATH)src/psaux/psobjs.c $(FREETYPE_SRC_PATH)src/psaux/t1decode.c $(FREETYPE_SRC_PATH)src/tools/apinames.c $(FREETYPE_SRC_PATH)src/type1/t1afm.c $(FREETYPE_SRC_PATH)src/type1/t1gload.c $(FREETYPE_SRC_PATH)src/type1/t1load.c $(FREETYPE_SRC_PATH)src/type1/t1objs.c $(FREETYPE_SRC_PATH)src/type1/t1parse.c $(FREETYPE_SRC_PATH)src/bdf/bdfdrivr.c $(FREETYPE_SRC_PATH)src/bdf/bdflib.c $(FREETYPE_SRC_PATH)src/gzip/ftgzip.c $(FREETYPE_SRC_PATH)src/lzw/ftlzw.c
LOCAL_LDLIBS := -ldl -llog
include $(BUILD_SHARED_LIBRARY)
По умолчанию система сборки NDK генерирует машинный код для архитектуры armeabi. Для того чтобы добавить поддержку архитектуры Intel, нам понадобится настроить файл Application.mk, расположенный в той же папке jni. А именно – добавить «x86» в переменную APP_ABI. Сборку можно осуществлять одновременно для нескольких платформ, их идентификаторы указывают через пробел.
Вот, как выглядит переменная APP_ABI, настроенная на две целевые архитектуры.
APP_ABI := armeabi-v7a x86 #другие доступные варианты: x86_64, armeabi, arm64-v8a, mips, mips64
Для того чтобы сгенерировать машинный код для всех доступных наборов инструкций, можно воспользоваться такими настройками:
APP_ABI := all # другие доступные варианты all32 или all64
Переменная APP_PLATFORM содержит название целевой платформы Android. Наш Application.mk получился довольно простым:
APP_ABI :=all
APP_PLATFORM := android-20
Вот, как он выглядит в редакторе кода.
Настройка APP_ABI в файле Application.mk
Предварительная подготовка пройдена, теперь настроим автоматическую сборку проекта с использованием NDK. Для этого нужно, во-первых, настроить список сборщиков (Builders) для проекта, во-вторых – выбрать конкретный сборщик, которым нужно пользоваться при подготовке библиотеки.
Для того чтобы это сделать, щёлкнем правой кнопкой мыши по Android-проекту, выберем в меню пункт Properties. Для того чтобы добавить в список новую систему сборки, нужно, в левой части появившегося окна, перейти на закладку Builders, затем – нажать на кнопку New, расположенную справа.
Свойства проекта
Из списка в окне выбора типа конфигурации выберем Program. Этот вариант позволяет указать расположение внешних инструментов и то, как именно нужно выполнять скрипты, осуществляющие сборку.
Настройка конфигурации
В появившемся окне настроим следующие поля:
- Name: имя нового сборщика
- Location: путь к ndk-build.cmd
- Working Directory: путь к папке нашего проекта
Настройка NDK
После выполнения вышеописанных настроек, запустим сборку проекта. Когда этот процесс успешно завершится, в папках, имена которых строятся по схеме /lib/<APP_ABI>, можно будет найти сборки библиотеки для платформ, указанных в Application.mk. В частности, нас интересуют папки x86 и x86_64.
Файлы libfreetype.so для Android- устройств, построенных на платформе x86
Итоги
Библиотека FreeType собрана, теперь вы можете использовать её в собственных Android-приложениях.
Комментарии (3)
dev_troy
04.03.2016 21:23-3Сборка в эклипсе через билдеры! А как же тру-сборка через консоль или на CI сервере православным градлом, в котором настройка сборки с использованием NDK разжевана дальше некуда?
mkarev
06.03.2016 07:38Библиотека FreeType собрана, теперь вы можете использовать её в собственных Android-приложениях.
Замечательно, а можно примерчик использования такой библиотеки в православном Android Studio?
AllexIn
Минусанул.
Аргументирую:
freetype собирается абсолютно типично под любой Андроид.
Никаких хитростей и особенностей нет.
Статья из разряда — еще один мануал ничем не отличающийся от сотни таких же.
Статья в целом не бесполезная… Но это же хабр, Карл!