Android.mk - это специальный настроечный текстовый файл, предназначенный для автоматизации компиляции приложений Android на основе NDK. Это по сути так называемый файл makefile, но составленный по определенным правилам. Компиляция с участием файлов Android.mk делается под управлением утилиты-скрипта ndk-build. Файл Android.mk широко используется для компиляции модулей приложений (библиотек) как из командной строки, так и из среды разработки Eclipse. В статье использовался перевод документации Google [1].
[Основная концепция]
Синтаксис файла Android.mk разработан так, чтобы позволить Вам группировать исходный код в "модули". Модуль в данном контексте - это специальный файл библиотеки, который создан из исходного кода на языке программирования C/C++ (native language). Модулем может быть либо статическая библиотека (static library), либо разделяемая общая (shared library, динамически загружаемая библиотека). Т. е. в модуле собраны функции, которые Вы можете использовать в приложении, и этот модуль может быть присоединен к приложению либо статически, на этапе компиляции, либо динамически, в процессе загрузки. В виде отдельных файлов в выходной пакет приложения (.apk) попадут только общие разделяемые библиотеки. Однако статическими библиотеками можно пользоваться, чтобы создать общие разделяемые библиотеки.
Вы можете задать для компиляции один или большее количество модулей в каждом файле Android.mk. При этом можно использовать один и тот же исходный файл для нескольких модулей. Вот простой пример файла Android.mk:
# Символом # всегда начинается строка комментария.
# Файл Android.mk всегда должен начинаться с определения переменной LOCAL_PATH.
# Она используется для указания размещения исходных файлов в дереве разработки.
# В этом примере макро-функция 'my-dir', предоставляемая системой сборки, используется
# для возврата пути текущей директории (т. е. директории, в которой находится сам
# файл Android.mk).
LOCAL_PATH := $(call my-dir)
# Переменная CLEAR_VARS также предоставляется системой сборки, и указывает на специальный
# GNU makefile, который очищает для Вас множество переменных LOCAL_xxx, за исключением
# переменной LOCAL_PATH.
include $(CLEAR_VARS)
# Переменная LOCAL_MODULE должна быть определена для идентификации каждого модуля,
# который описываете в Вашем Android.mk. В ней содержится имя модуля, которое
# впоследствии будет использоваться в приложении для загрузки библиотеки. Имя
# должно быть уникальным и не должно содержать в себе пробелов. Имейте в виду,
# что система сборки автоматически добавит правильные префикс и суффикс генерируемому
# файлу. Другими словами, если Вы зададите для общей библиотеки имя mylib, то
# сгенерируется модуль библиотеки в файле libmylib.so.
LOCAL_MODULE := mylib
# Переменная LOCAL_SRC_FILES должна содержать список файлов C или C++, которые будут
# скомпилированы и собраны в модуль. Имейте в виду, что здесь не нужно указывать
# заголовки и подключаемые файлы (с расширением *.h), потому что система сборки
# будет для Вас автоматически вычислять зависимости. Компилятору напрямую должен
# быть передан только список файлов исходного кода. Расширением по умолчанию для
# файлов C++ является ".cpp". Вы можете поменять это установкой
# LOCAL_CPP_EXTENSION=”.cxx”
LOCAL_SRC_FILES := com_mp1_MyActivity.c
# Переменная BUILD_SHARED_LIBRARY предоставляется системой сборки, и она указывает
# на скрипт GNU makefile, который отвечает за сбор всей информации, которую Вы
# определили в переменных LOCAL_xxx (начиная от последнего include $(CLEAR_VARS)).
# Этот скрипт также определяет, что нужно создать, и в точности как это сделать.
# Можно также указать BUILD_STATIC_LIBRARY, чтобы сгенерировать статическую
# библиотеку.
include $(BUILD_SHARED_LIBRARY)
[Система именования (Naming convention)]
Вы можете задать другие переменные для собственного использования, но система сборки NDK резервирует для себя следующие имена переменных:
• Имена, начинающиеся с LOCAL_ (например LOCAL_MODULE). • Имена, начинающиеся с PRIVATE_, NDK_ или APP_ (используются внутренне). • Имена в нижнем регистре (используются внутренне, например 'my-dir').
Если Вам нужно определить собственные переменные для удобства в файле Android.mk, то рекомендуется использовать префикс MY_ как в этом простом примере:
MY_SOURCES := foo.c
ifneq ($(MY_CONFIG_BAR),)
MY_SOURCES += bar.c
endif
LOCAL_SRC_FILES += $(MY_SOURCES)
[Переменные, предоставляемые NDK]
Эти переменные GNU Make определены системой сборки перед тем, как будет обработан Ваш файл Android.mk. Имейте в виду, что при определенных обстоятельствах NDK может сделать парсинг файла Android.mk несколько раз, причем каждый раз с разными значениями для некоторых из этих переменных.
CLEAR_VARS Указывает на скрипт сборки, который удаляет все ранее заданные переменные LOCAL_xxx, перечисленные в секции описания модулей ниже. Вы должны подключить этот скрипт перед тем, как начать компилировать новый модуль, как было ранее показано в примере файла Android.mk.
BUILD_SHARED_LIBRARY Указывает на скрипт сборки, который собирает всю информацию о модуле, которую Вы предоставили в переменных LOCAL_xxx, и определяет, как собрать целевую разделяемую библиотеку из перечисленных Вами исходников. Имейте в виду, что Вы как минимум должны определить LOCAL_MODULE и LOCAL_SRC_FILES перед подключением этого скрипта. Пример использования:
include $(BUILD_SHARED_LIBRARY)
При этом будет сгенерирован библиотечный модуль с именем файла lib$(LOCAL_MODULE).so.
BUILD_STATIC_LIBRARY Это вариант скрипта BUILD_SHARED_LIBRARY, который используется для сборки статической библиотеки. Статические библиотеки не копируются в Ваш проект/пакет, но он может быть использован для сборки разделяемых библиотек (см. LOCAL_STATIC_LIBRARIES и LOCAL_WHOLE_STATIC_LIBRARIES, описанные ниже). Пример использования:
include $(BUILD_STATIC_LIBRARY)
При этом будет сгенерирован файл lib$(LOCAL_MODULE).a.
PREBUILT_SHARED_LIBRARY Указывает на скрипт сборки, используемый для указания предварительно собранной разделяемой библиотеки (prebuilt shared library). В отличие от BUILD_SHARED_LIBRARY и BUILD_STATIC_LIBRARY, значение LOCAL_SRC_FILES должно быть одиночным путем до файла prebuilt shared library (например foo/libfoo.so), вместо указания файла исходного кода.
Вы можете обращаться к prebuilt library в другом модуле, используя переменную LOCAL_PREBUILTS (см. docs/PREBUILTS.html для получения дополнительной информации).
PREBUILT_STATIC_LIBRARY То же самое, что и PREBUILT_SHARED_LIBRARY, но только вместо этого для файла статической библиотеки (static library). Подробности см. в docs/PREBUILTS.html.
TARGET_ARCH Имя архитектуры целевого CPU, как это указывается в полной открытой сборке Android. Это 'arm' для любой ARM-совместимой сборки, независимо от ревизии архитектуры CPU.
TARGET_PLATFORM Имя целевой платформы Android, когда этот Android.mk будет обработан. Например, 'android-3' соответствует системному образу Android 1.5. Для полного списка имен платформ и соответствующих им образов систем Android см. docs/STABLE-APIS.html.
TARGET_ARCH_ABI Имя целевых CPU+ABI, когда этот Android.mk будет обработан. В настоящее время поддерживаются 2 значения:
armeabi для ARMv5TE и armeabi-v7a
Примечание: до NDK 1.6_r1 эта переменная была просто задана как 'arm'. Однако значение было переназначено для лучшего соответствия используемой внутренней платформе Android. Для дополнительной информации по архитектуре ABI и соответствующим проблемам совместимости см. docs/CPU-ARCH-ABIS.html.
Другое целевое ABI будет представлено в будущих релизах NDK, и будет иметь другое имя. Имейте в виду, что все ABI, основанные на ARM, имеют 'TARGET_ARCH' заданной как 'arm', но могут иметь разные 'TARGET_ARCH_ABI'.
TARGET_ABI Связь целевой платформы и ABI реально задается как $(TARGET_PLATFORM)-$(TARGET_ARCH_ABI), и это полезно, когда Вы хотите проверить специфический образ целевой системы для реального устройства. По умолчанию это будет задано как 'android-3-armeabi' (до Android NDK 1.6_r1 использовалось по умолчанию 'android-3-arm').
[Макрофункции, предоставленные NDK]
Далее обсудим макросы-'функции' GNU Make, которые должны вызываться с помощью выражения '$(call < function >)'. Они возвращают текстовую информацию.
my-dir Возвращает путь последнего подключенного (included) Makefile, обычно это каталог текущего файла Android.mk. Эта функция полезна для задания LOCAL_PATH от начальной точки, где находится Ваш Android.mk, следующим образом:
LOCAL_PATH := $(call my-dir)
Важное замечание: поскольку так работает GNU Make, это действительно возвратит путь *последнего* *подключенного* *Makefile* в процессе парсинга скриптов сборки. Не делайте вызов my-dir после подключения другого файла. К примеру:
LOCAL_PATH := $(call my-dir)
... декларирование одного модуля
include $(LOCAL_PATH)/foo/Android.mk
LOCAL_PATH := $(call my-dir)
... декларирование другого модуля
Здесь может возникнуть проблема, что второй вызов 'my-dir' задаст LOCAL_PATH в значение $PATH/foo вместо $PATH, поскольку перед этим было выполнено включение include. По этой причине лучше сделать все включения после всех операций в Android.mk, вот так:
LOCAL_PATH := $(call my-dir)
... декларирование одного модуля
LOCAL_PATH := $(call my-dir)
... декларирование другого модуля
# дополнительные подключения в конце должны быть
# сделаны в конце Android.mk
include $(LOCAL_PATH)/foo/Android.mk
Если так делать неудобно, то сохраните первый вызов my-dir в другую переменную, например:
MY_LOCAL_PATH := $(call my-dir)
LOCAL_PATH := $(MY_LOCAL_PATH)
... декларирование одного модуля
include $(LOCAL_PATH)/foo/Android.mk
LOCAL_PATH := $(MY_LOCAL_PATH)
... декларирование другого модуля
all-subdir-makefiles Возвращает список Android.mk, размещенных во всех подкаталогах текущего пути 'my-dir'. К примеру, имеется иерархия:
sources/foo/Android.mk sources/foo/lib1/Android.mk sources/foo/lib2/Android.mk
Если sources/foo/Android.mk содержит одну строку:
include $(call all-subdir-makefiles)
то к нему будут автоматически подключены также sources/foo/lib1/Android.mk и sources/foo/lib2/Android.mk. Эта функция может использоваться для предоставления системе сборки иерархии глубоко вложенных друг в друга директорий. Имейте в виду, что по умолчанию NDK будет просматривать файлы в sources/*/Android.mk.
this-makefile Возвращает путь до текущего Makefile (т. е. того, из которого была вызвана эта функция).
parent-makefile Возвращает путь родительского Makefile в дереве включений (inclusion tree), например путь до Makefile, который подключил текущий Makefile.
grand-parent-makefile Догадайтесь сами, что это... (прим. переводчика - наверное это корневой Makefile, от которого началась цепочка вложенных включений).
import-module Функция, которая позволяет Вам найти и подключить Android.mk другого модуля по имени. Типичный пример:
$(call import-module, < name >)
Эта строка вызовет просмотр в поиске модуля, помеченного именем < name > в списке каталогов, определенных Вашей переменной окружения NDK_MODULE_PATH, и автоматически подключит его в этот Android.mk. Подробности см. в docs/IMPORT-MODULE.html.
[Переменные для описания модуля (Module-description variables)]
Переменные, обсуждаемые в этом разделе, описывают Ваш модуль для системы сборки. Вы должны определить некоторые из них между 'include $(CLEAR_VARS)' и 'include $(BUILD_XXXXX)'. Как уже было упомянуто ранее, , $(CLEAR_VARS) является скриптом для очистки/удаления всех этих переменных, за исключением специально упомянутых в их описании.
LOCAL_PATH Эта переменная используется для предоставления пути текущего файла. Вы ДОЛЖНЫ задать эту переменную в самом начале файла Android.mk, и это можно сделать такой строкой:
LOCAL_PATH := $(call my-dir)
Эта переменная НЕ очищается скриптом $(CLEAR_VARS), так что для неё нужно только одно определение на каждый файл Android.mk (в случае, если Вы определяете компиляцию нескольких модулей в одном файле Android.mk ).
LOCAL_MODULE Это имя Вашего модуля. Оно должно быть уникальным среди всех имен модулей, и в нем не должно содержаться пробелов. Вы ДОЛЖНЫ задать имя перед подключением любого скрипта $(BUILD_XXXX). По умолчанию имя модуля определяет имя генерируемых файлов, например lib< foo >.so для модуля разделяемой библиотеки (shared library module), поименованного как < foo >. Однако Вы должны обращаться к другим модулям только по их 'нормальному' имени (например < foo >) в Ваших файлах сборки NDK (или Android.mk, или Application.mk). Вы можете поменять это умолчание через LOCAL_MODULE_FILENAME (см. далее).
LOCAL_MODULE_FILENAME Эта переменная необязательная, и она позволяет Вам переназначить имя генерируемых файлов. По умолчанию для модуля с именем < foo > будет всегда генерироваться статическая библиотека с именем файла lib< foo >.a, или разделяемся библиотека с именем файла lib< foo >.so, в соответствии со стандартами соглашений в Unix. Вы можете поменять это поведение определением LOCAL_MODULE_FILENAME, например:
LOCAL_MODULE := foo-version-1
LOCAL_MODULE_FILENAME := libfoo
Примечание: Вы не должны помещать путь или расширение имени файла в переменную LOCAL_MODULE_FILENAME, это будет обрабатываться автоматически системой сборки.
LOCAL_SRC_FILES Это список файлов исходного кода, которые будут компилироваться при сборке Вашего модуля. Компилятору будет передан только список файлов, поскольку система сборки будет автоматически вычислять для Вас зависимости. Имейте в виду, что имена файлов будут все указаны относительно LOCAL_PATH и Вы можете использовать компоненты пути, например:
LOCAL_SRC_FILES := foo.c \
toto/bar.c
Примечание: всегда используйте прямые слеши (/) для построения пути файлов в стиле Unix. Обратные слеши в стиле Windows будут некорректно обработаны.
LOCAL_CPP_EXTENSION Это необязательная переменная, которая может быть задана для указания расширений файлов исходного кода на языке C++. Переменная должна начинаться с точки. Значение по умолчанию '.cpp', но с помощью этой переменной Вы можете расширение поменять, например:
LOCAL_CPP_EXTENSION := .cxx
Начиная с NDK r7 можно в этой переменной задавать список расширений:
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
LOCAL_CPP_FEATURES Это необязательная переменная, которая может быть задана для указания, что код отражает определенные особенности (фичи) C++. Чтобы показать, то Ваш код использует RTTI (RunTime Type Information, информация от типе времени выполнения), используйте:
LOCAL_CPP_FEATURES := rtti
Чтобы показать, что Ваш код использует исключения C++ (exceptions), используйте:
LOCAL_CPP_FEATURES := exceptions
Вы можете также использовать несколько опций в одной строке (их порядок следования не имеет никакого значения):
LOCAL_CPP_FEATURES := rtti features
Эффект от использования этой переменной в том, чтобы разрешить правильные флаги компилятора/линкера, когда осуществляется сборка Ваших модулей из файлов исходного кода. Для предварительно собранного двоичного кода это также позволит помочь декларировать, какие фичи реализованы в двоичном коде, чтобы окончательная сборка работала корректно. Рекомендуется использовать эту переменную вместо разрешения -frtti и -fexceptions напрямую в определении LOCAL_CPPFLAGS.
LOCAL_C_INCLUDES Необязательный список путей относительно корневой директории NDK, который будет добавлен к пути поиска включаемых файлов при компиляции всех файлов исходного кода (на языках C, C++ и ассемблер). Например:
LOCAL_C_INCLUDES := sources/foo
Или также:
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo
Это должно быть размещено перед любым соответствующим флагом подключения в LOCAL_CFLAGS / LOCAL_CPPFLAGS. Путь LOCAL_C_INCLUDES также автоматически используется, когда запускается отладка (native debugging) через ndk-gdb.
LOCAL_CFLAGS Необязательный набор флагов компиляции, который будет передан, когда компилируются исходные файлы C и C++. Это может быть полезным для указания дополнительных макроопределений или опций компиляции.
Важное замечание: не пытайтесь поменять уровень оптимизации/отладки в Вашем Android.mk, это может быть автоматически осуществлено для Вас путем указания соответствующей информации в Вашем файле Application.mk, и это позволит NDK генерировать полезные файлы данных для использования в отладке.
Примечание: в android-ndk-1.5_r1 соответствующие флаги прикладываются только к файлам исходного кода C, но не к файлам C++. Это скорректировано для соответствия поведению полной системы сборки Android (Вы теперь также можете использовать LOCAL_CPPFLAGS для указания флагов только для исходного кода C++).
Можно указать дополнительные пути включения (пути include) в опцией LOCAL_CFLAGS += -I< path >, однако лучше для этого использовать LOCAL_C_INCLUDES, поскольку пути подключения также используются при отладке (native debugging) через ndk-gdb.
LOCAL_CXXFLAGS Это алиас для LOCAL_CPPFLAGS. Имейте в виду, что использование этого флага не рекомендуется, так как он устарел, и его поддержка может быть отменена в будущих релизах NDK.
LOCAL_CPPFLAGS Необязательной набор флагов компиляции, которые будут переданы только при компиляции исходного кода C++. Эт флаги появятся после LOCAL_CFLAGS в командной строке компилятора. !! --std=c++0x
Примечание: в android-ndk-1.5_r1 соответствующие флаги будут применены и к файлам кода C, и к файлам кода C++. Это скорректировано для соответствия поведению полной системы сборки Android (Вы теперь также можете использовать LOCAL_CFLAGS для указания флагов и для C, и для C++).
LOCAL_STATIC_LIBRARIES Список модулей статических библиотек (собираемых с BUILD_STATIC_LIBRARY) должен быть слинкован с этим модулем. Это актуально только для модулей разделяемых библиотек (shared library modules).
LOCAL_SHARED_LIBRARIES Список модулей разделяемых библиотек (shared libraries), от которых этот модуль зависит во время выполнения (runtime). Это необходимо во время линковки для встраивания соответствующей информации в генерируемый файл.
LOCAL_WHOLE_STATIC_LIBRARIES Вариант LOCAL_STATIC_LIBRARIES, используемый для выражения, что соответствующий модуль библиотеки должен быть использован как "полный архив" (whole archives) для линкера. См. документацию линкера GNU для флага --whole-archive. Это обычно используется, когда имеются циклические зависимости между несколькими статическими библиотеками. Имейте в виду, что когда используется сборка разделяемой библиотеки (shared library), это принудительно добавит все Ваши объектные файлы из статических библиотек к конечному двоичному файлу. Это все же неверно, когда генерируются исполняемые файлы.
LOCAL_LDLIBS Список дополнительных флагов линкера для использования при сборке Вашего модуля. Это полезно для передачи имени специальных системных библиотек с префиксом "-l". Например, следующая строка укажет линкеру генерировать модуль, который присоединяется к /system/lib/libz.so во время загрузки:
См. docs/STABLE-APIS.html для списка представленных системных библиотек, которые Вы можете линковать с этим релизом NDK.
LOCAL_ALLOW_UNDEFINED_SYMBOLS По умолчанию любой встреченный нераспознанный идентификатор при сборке разделяемой библиотеки приведет к ошибке "undefined symbol". Это дает хорошую помощь для вылавливания багов в исходном коде. Однако, если по некоторым причинам Вам нужно запретить эту проверку, то установите эту переменную в значение 'true'. Имейте в виду, что соответствующая разделяемая библиотека может потерпеть неудачу загрузки во время выполнения.
LOCAL_ARM_MODE По умолчанию целевые двоичные файлы ARM будут генерироваться в режиме 'thumb', когда каждая инструкция имеет длину 16 бит. Вы можете задать эту переменную в значение 'arm', если хотите принудительно генерировать объектные файлы модуля в режиме 'arm' (с 32-битными инструкциями). Пример:
Обратите внимание, что Вы также можете инструктировать систему сборки компилировать только определенные исходники в режиме ARM, путем добавления суффикса '.arm' к имени этого исходного файла, например:
LOCAL_SRC_FILES := foo.c bar.c.arm
Эта команда указывает системе сборки всегда компилировать 'bar.c' в режиме ARM, и компилировать foo.c в соответствии со значением переменной LOCAL_ARM_MODE.
Внимание: установка APP_OPTIM в значение 'debug' в Вашем Application.mk также будет принуждать генерировать бинарники ARM. Это происходит из-за багов в отладчике тулчейна, который не очень хорошо может обрабатывать код режима thumb.
LOCAL_ARM_NEON Определение этой переменной в значение 'true' позволяет использовать ARM Advanced SIMD (так называемые NEON), выражения GCC intrinsics в Вашем исходном коде C и C++, также как и инструкции NEON в файлах ассемблера. Вы должны задавать эту переменную таким образом только тогда, когда цель сборки 'armeabi-v7a' ABI, которая соответствует набору инструкций ARMv7. Имейте в виду, что не все основанные на ARMv7 процессоры CPU поддерживают расширение NEON набора инструкций, так что Вам нужно выполнить детектирование во время выполнения - можно ли использовать такой код безопасно, или нет. Чтобы больше узнать об этом, см. документацию docs/CPU-ARM-NEON.html и docs/CPU-FEATURES.html.
Альтернативно Вы можете указать только отдельные исходные файлы, которые можно компилировать с поддержкой NEON, если будете использовать суффикс '.neon':
LOCAL_SRC_FILES = foo.c.neon bar.c zoo.c.arm.neon
В этом примере 'foo.c' будет скомпилирован в режиме thumb+neon, 'bar.c' будет компилироваться в режиме 'thumb', и 'zoo.c' будет компилироваться в режиме 'arm+neon'. Обратите внимание, что суффикс '.neon' должен идти после суффикса '.arm', если Вы используете их совместно (например foo.c.arm.neon будет работать, но только не foo.c.neon.arm!).
LOCAL_DISABLE_NO_EXECUTE Android NDK r4 добавил поддержку бита защиты "NX bit". Он разрешен по умолчанию, однако Вы можете его запретить (если Вам действительно это нужно) путем установки этой переменной в 'true'.
Внимание: эта фича не модифицирует ABI и будет разрешена только на ядрах, нацеленных на устройства с ARMv6+ CPU. Генерируемый машинный код с этой фичей, будет работать в немодифицированном виде на устройствах с более ранними архитектурами CPU. Для дополнительной информации см. [3, 4].
LOCAL_EXPORT_CFLAGS Задайте эту переменную в набор флагов компилятора C/C++, которые будут добавлены к определению LOCAL_CFLAGS любого другого модуля, который использует его с LOCAL_STATIC_LIBRARIES или LOCAL_SHARED_LIBRARIES. Например, рассмотрим, что модуль 'foo' задан со следующим определением:
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_CFLAGS := -DFOO=1
include $(BUILD_STATIC_LIBRARY)
И в другом модуле с именем 'bar', который зависит от него:
include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_CFLAGS := -DBAR=2
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)
Тогда флаги flags '-DFOO=1 -DBAR=2' будут переданы компилятору, когда будет компилироваться bar.c.
Экспортируемые флаги присоединяются к LOCAL_CFLAGS Вашего модуля, так что Вы можете легко перезадать их. Это также транзитивная особенность: если 'zoo' зависит от 'bar', который зависит от 'foo', то 'zoo' будет также наследовать все флаги, экспортируемые 'foo'. В заключение следует указать, что экспортируемые флаги НЕ используются, когда собирается модуль, который экспортирует их. В приведенном выше примере -DFOO=1 не будет передаваться компилятору, когда идет сборка foo/foo.c.
LOCAL_EXPORT_CPPFLAGS То же самое, что и LOCAL_EXPORT_CFLAGS, но только для флагов C++.
LOCAL_EXPORT_C_INCLUDES То же, что и LOCAL_EXPORT_CFLAGS, но для путей подключения C. Это полезно, если для 'bar.c' нужно подключить заголовки, которые предоставлены модулем'foo'.
LOCAL_EXPORT_LDLIBS То же самое, что и LOCAL_EXPORT_CFLAGS, но для флагов линкера. Имейте в виду, что импортированные флаги линкера будут добавлены к Вашему модулю через LOCAL_LDLIBS, потому что так работают линковщики Unix.
Переменная обычно полезна, когда модуль 'foo' является статической библиотекой, и имеет код, который зависит от системной библиотеки. Тогда LOCAL_EXPORT_LDLIBS можно использовать для экспортирования зависимости. Пример:
include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)
Здесь libbar.so будет собран с -llog по окончании команды линкера, чтобы показать, что он зависит от системной библиотеки логгинга, потому что он зависит от 'foo'.
LOCAL_SHORT_COMMANDS Установите эту переменную в 'true', когда Ваш модуль имеет очень большое количество исходного кода и/или зависимостей от статических или разделяемых библиотек. Это принудительно даст системе сборки указание использовать промежуточный файловый список, и применить его с архиватором библиотеки или статическим линкером с синтаксисом @$(listfile). Это может быть полезно в операционной системе Windows, где командная строка может принимать максимум до 8191 символов, что подходит для не очень больших и не слишком сложных проектов. Это также влияет на компиляцию отдельных исходных файлов, помещая почти все флаги компилятора внутри этого списка файлов. Имейте в виду, что любое другое значение переменной, отличающееся от 'true', вернет поведение по умолчанию. Вы можете также задать APP_SHORT_COMMANDS в Вашем Application.mk, чтобы указать такое поведение для всех модулей в Вашем проекте.
Примечание: не рекомендуется по умолчанию разрешать эту возможность, поскольку это замедляет процесс сборки.
LOCAL_FILTER_ASM Задайте эту переменную в команду шелла, которая будет использоваться для фильтрации файлов ассемблера от (или сгенерированных от) Ваших LOCAL_SRC_FILES. Когда переменная задана, то получается следующее:
• Любой исходный файл C или C++ генерируется во временный файл ассемблера (вместо того, чтобы компилироваться в объектный файл). • Любой временный файл ассемблера, и любой файл ассемблера, перечисленный в LOCAL_SRC_FILES, будет отправлен через команду LOCAL_FILTER_ASM для генерации _другого_ временного файла ассемблера. • Эти отфильтрованные файлы ассемблера компилируются в объектный файл.
Другими словами, если у Вас:
LOCAL_SRC_FILES := foo.c bar.S
LOCAL_FILTER_ASM := myasmfilter
foo.c --1--> $OBJS_DIR/foo.S.original --2--> $OBJS_DIR/foo.S --3--> $OBJS_DIR/foo.o bar.S --2--> $OBJS_DIR/bar.S --3--> $OBJS_DIR/bar.o
Здесь "1" соответствует компилятору, "2" фильтру, и "3" ассемблеру. Фильтр должен быть отдельной командой шелла, которая принимает имя входного файла в качестве своего первого аргумента, и имя выходного файла в качестве второго аргумента, вот так:
myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S
myasmfilter bar.S $OBJS_DIR/bar.S
[Ссылки]
1. Android.mk site:docs.google.com. 2. Managing Projects from the Command Line site:developer.android.com. 3. NX bit site:wikipedia.org. 4. Hardened/GNU stack quickstart site:wiki.gentoo.org. |