Android.mk

На этой странице описан синтаксис файла сборки Android.mk , используемый ndk-build .

Обзор

Файл Android.mk находится в подкаталоге каталога jni/ вашего проекта и описывает ваши исходные коды и общие библиотеки для системы сборки. На самом деле это крошечный фрагмент make-файла GNU, который система сборки анализирует один или несколько раз. Файл Android.mk полезен для определения параметров всего проекта, которые Application.mk , система сборки и переменные среды оставляют неопределенными. Он также может переопределять общепроектные настройки для конкретных модулей .

Синтаксис Android.mk позволяет группировать источники в модули . Модуль — это статическая библиотека, общая библиотека или автономный исполняемый файл. Вы можете определить один или несколько модулей в каждом файле Android.mk и использовать один и тот же исходный файл в нескольких модулях. Система сборки помещает в пакет приложения только общие библиотеки. Кроме того, статические библиотеки могут создавать общие библиотеки.

Помимо упаковки библиотек, система сборки обрабатывает за вас множество других деталей. Например, вам не нужно перечислять файлы заголовков или явные зависимости между сгенерированными файлами в файле Android.mk . Система сборки NDK автоматически вычисляет эти отношения. В результате вы сможете воспользоваться поддержкой новой цепочки инструментов/платформы в будущих выпусках NDK, не трогая файл Android.mk .

Синтаксис этого файла очень близок к тому, который используется в файлах Android.mk , распространяемых вместе с полной версией Android Open Source Project . Хотя реализация системы сборки, использующая их, отличается, их сходство является преднамеренным проектным решением, призванным облегчить разработчикам приложений повторное использование исходного кода для внешних библиотек.

Основы

Прежде чем подробно изучать синтаксис, полезно начать с понимания основ того, что содержит файл Android.mk . В этом разделе для этой цели используется файл Android.mk из примера Hello-JNI, в котором объясняется роль, которую играет каждая строка в файле.

Файл Android.mk должен начинаться с определения переменной LOCAL_PATH :

LOCAL_PATH := $(call my-dir)

Эта переменная указывает расположение исходных файлов в дереве разработки. Здесь макрофункция my-dir , предоставляемая системой сборки, возвращает путь к текущему каталогу (каталогу, содержащему сам файл Android.mk ).

В следующей строке объявляется переменная CLEAR_VARS , значение которой предоставляет система сборки.

include $(CLEAR_VARS)

Переменная CLEAR_VARS указывает на специальный GNU Makefile, который очищает многие переменные LOCAL_XXX , такие как LOCAL_MODULE , LOCAL_SRC_FILES и LOCAL_STATIC_LIBRARIES . Обратите внимание, что LOCAL_PATH не очищается. Эта переменная должна сохранять свое значение, поскольку система анализирует все файлы управления сборкой в ​​одном контексте выполнения GNU Make, где все переменные являются глобальными. Вы должны (пере) объявить эту переменную перед описанием каждого модуля.

Далее, переменная LOCAL_MODULE хранит имя модуля, который вы хотите собрать. Используйте эту переменную один раз для каждого модуля вашего приложения.

LOCAL_MODULE := hello-jni

Имя каждого модуля должно быть уникальным и не содержать пробелов. Система сборки, когда она генерирует окончательный файл общей библиотеки, автоматически добавляет правильный префикс и суффикс к имени, которое вы назначаете LOCAL_MODULE . Например, приведенный выше пример приводит к созданию библиотеки под названием libhello-jni.so .

В следующей строке перечислены исходные файлы, разделенные пробелами:

LOCAL_SRC_FILES := hello-jni.c

Переменная LOCAL_SRC_FILES должна содержать список исходных файлов C и/или C++ для сборки в модуль.

Последняя строка помогает системе связать все воедино:

include $(BUILD_SHARED_LIBRARY)

Переменная BUILD_SHARED_LIBRARY указывает на сценарий GNU Makefile, который собирает всю информацию, которую вы определили в переменных LOCAL_XXX с момента последнего include . Этот сценарий определяет, что строить и как это делать.

В каталогах примеров есть более сложные примеры с прокомментированными файлами Android.mk , которые вы можете просмотреть. Кроме того, Sample:native-activity предоставляет подробное объяснение файла Android.mk этого примера. Наконец, в разделе «Переменные и макросы» представлена ​​дополнительная информация о переменных из этого раздела.

Переменные и макросы

Система сборки предоставляет множество возможных переменных для использования в файле Android.mk . Многие из этих переменных имеют заранее заданные значения. Другие, вы назначаете.

Помимо этих переменных, вы также можете определить свои произвольные. Если вы это сделаете, имейте в виду, что система сборки NDK резервирует следующие имена переменных:

  • Имена, начинающиеся с LOCAL_ , например LOCAL_MODULE .
  • Имена, начинающиеся с PRIVATE_ , NDK_ или APP . Система сборки использует их внутри себя.
  • Имена в нижнем регистре, например my-dir . Система сборки также использует их внутри себя.

Если вам нужно определить свои собственные удобные переменные в файле Android.mk , мы рекомендуем добавлять MY_ к их именам.

Включаемые переменные, определенные NDK

В этом разделе обсуждаются переменные GNU Make, которые определяет система сборки перед анализом файла Android.mk . При определенных обстоятельствах NDK может анализировать ваш файл Android.mk несколько раз, каждый раз используя разные определения для некоторых из этих переменных.

CLEAR_VARS

Эта переменная указывает на сценарий сборки, который отменяет определение почти всех переменных LOCAL_XXX , перечисленных в разделе «Переменные, определенные разработчиком» ниже. Используйте эту переменную, чтобы включить этот сценарий перед описанием нового модуля. Синтаксис его использования:

include $(CLEAR_VARS)

BUILD_EXECUTABLE

Эта переменная указывает на сценарий сборки, который собирает всю информацию о модуле, указанную вами в переменных LOCAL_XXX , и определяет, как собрать целевой исполняемый файл из перечисленных вами источников. Обратите внимание, что для использования этого сценария требуется, чтобы вы как минимум уже присвоили значения LOCAL_MODULE и LOCAL_SRC_FILES (дополнительную информацию об этих переменных см. в разделе Переменные описания модуля ).

Синтаксис использования этой переменной:

include $(BUILD_EXECUTABLE)

BUILD_SHARED_LIBRARY

Эта переменная указывает на сценарий сборки, который собирает всю информацию о модуле, указанную вами в переменных LOCAL_XXX , и определяет, как собрать целевую общую библиотеку из перечисленных вами источников. Обратите внимание, что для использования этого сценария требуется, чтобы вы как минимум уже присвоили значения LOCAL_MODULE и LOCAL_SRC_FILES (дополнительную информацию об этих переменных см. в разделе Переменные описания модуля ).

Синтаксис использования этой переменной:

include $(BUILD_SHARED_LIBRARY)

Переменная общей библиотеки заставляет систему сборки создавать файл библиотеки с расширением .so .

BUILD_STATIC_LIBRARY

Вариант BUILD_SHARED_LIBRARY , используемый для создания статической библиотеки. Система сборки не копирует статические библиотеки в ваш проект/пакеты, но может использовать их для сборки общих библиотек (см. LOCAL_STATIC_LIBRARIES и LOCAL_WHOLE_STATIC_LIBRARIES ниже). Синтаксис использования этой переменной:

include $(BUILD_STATIC_LIBRARY)

Переменная static-library заставляет систему сборки создавать библиотеку с расширением .a .

PREBUILT_SHARED_LIBRARY

Указывает на сценарий сборки, используемый для указания предварительно созданной общей библиотеки. В отличие от случаев BUILD_SHARED_LIBRARY и BUILD_STATIC_LIBRARY , здесь значение LOCAL_SRC_FILES не может быть исходным файлом. Вместо этого это должен быть единственный путь к предварительно созданной общей библиотеке, например foo/libfoo.so . Синтаксис использования этой переменной:

include $(PREBUILT_SHARED_LIBRARY)

Вы также можете ссылаться на предварительно созданную библиотеку в другом модуле, используя переменную LOCAL_PREBUILTS . Дополнительные сведения об использовании готовых библиотек см. в разделе Использование готовых библиотек .

PREBUILT_STATIC_LIBRARY

То же, что PREBUILT_SHARED_LIBRARY , но для предварительно созданной статической библиотеки. Дополнительные сведения об использовании готовых библиотек см. в разделе Использование готовых библиотек .

Целевые информационные переменные

Система сборки анализирует Android.mk один раз для каждого ABI, указанного в переменной APP_ABI , которая обычно определяется в файле Application.mk . Если APP_ABI имеет значение all , система сборки анализирует Android.mk один раз для каждого ABI, поддерживаемого NDK. В этом разделе описаны переменные, которые система сборки определяет каждый раз при анализе Android.mk .

TARGET_ARCH

Семейство процессоров, на которое ориентируется система сборки при анализе этого файла Android.mk . Эта переменная будет одной из: arm , arm64 , x86 или x86_64 .

TARGET_PLATFORM

Номер уровня Android API, на который ориентируется система сборки при анализе этого файла Android.mk . Например, образы системы Android 5.1 соответствуют уровню Android API 22: android-22 . Полный список названий платформ и соответствующих образов системы Android см. в разделе Собственные API . В следующем примере показан синтаксис использования этой переменной:

ifeq ($(TARGET_PLATFORM),android-22)
    # ... do something ...
endif

TARGET_ARCH_ABI

ABI, на который ориентируется система сборки при анализе этого файла Android.mk . В таблице 1 показаны настройки ABI, используемые для каждого поддерживаемого процессора и архитектуры.

Таблица 1. Настройки ABI для разных процессоров и архитектур.

Процессор и архитектура Параметр
ARMv7 armeabi-v7a
ARMv8 AArch64 arm64-v8a
я686 x86
х86-64 x86_64

В следующем примере показано, как проверить наличие ARMv8 AArch64 в качестве целевой комбинации ЦП и ABI:

ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
  # ... do something ...
endif

Дополнительные сведения об архитектурных ABI и связанных с ними проблемах совместимости см. в разделе Android ABI .

Новые целевые ABI в будущем будут иметь другие значения.

TARGET_ABI

Объединение целевого уровня Android API и ABI. Это особенно полезно, если вы хотите протестировать конкретный образ целевой системы для реального устройства. Например, чтобы проверить наличие 64-разрядного устройства ARM, работающего на уровне Android API 22:

ifeq ($(TARGET_ABI),android-22-arm64-v8a)
  # ... do something ...
endif

Переменные описания модуля

Переменные в этом разделе описывают ваш модуль для системы сборки. Описание каждого модуля должно следовать следующему базовому алгоритму:

  1. Инициализируйте или отмените определение переменных, связанных с модулем, используя переменную CLEAR_VARS .
  2. Присвойте значения переменным, используемым для описания модуля.
  3. Настройте систему сборки NDK на использование соответствующего сценария сборки для модуля, используя переменную BUILD_XXX .

ЛОКАЛ_ПУТЬ

Эта переменная используется для указания пути к текущему файлу. Вы должны определить его в начале файла Android.mk . В следующем примере показано, как это сделать:

LOCAL_PATH := $(call my-dir)

Сценарий, на который указывает CLEAR_VARS не очищает эту переменную. Поэтому вам нужно определить его только один раз, даже если ваш файл Android.mk описывает несколько модулей.

ЛОКАЛ_МОДУЛЬ

Эта переменная хранит имя вашего модуля. Оно должно быть уникальным среди всех имен модулей и не должно содержать пробелов. Вы должны определить его перед включением любых сценариев (кроме сценария для CLEAR_VARS ). Вам не нужно добавлять ни префикс lib , ни расширение файла .so или .a ; система сборки вносит эти изменения автоматически. В файлах Android.mk и Application.mk ссылайтесь на свой модуль по неизмененному имени. Например, следующая строка приводит к созданию модуля общей библиотеки под названием libfoo.so :

LOCAL_MODULE := "foo"

Если вы хотите, чтобы сгенерированный модуль имел имя, отличное от lib + значение LOCAL_MODULE , вы можете использовать переменную LOCAL_MODULE_FILENAME чтобы вместо этого дать сгенерированному модулю имя по вашему выбору.

LOCAL_MODULE_FILENAME

Эта необязательная переменная позволяет переопределить имена, которые система сборки использует по умолчанию для генерируемых ею файлов. Например, если имя вашего LOCAL_MODULEfoo , вы можете заставить систему вызвать созданный ею файл libnewfoo . В следующем примере показано, как это сделать:

LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo

Для модуля общей библиотеки в этом примере будет создан файл с именем libnewfoo.so .

LOCAL_SRC_FILES

Эта переменная содержит список исходных файлов, которые система сборки использует для создания модуля. Перечисляйте только те файлы, которые система сборки фактически передает компилятору, поскольку система сборки автоматически вычисляет любые связанные зависимости. Обратите внимание, что вы можете использовать как относительные (по отношению к LOCAL_PATH ), так и абсолютные пути к файлам.

Мы рекомендуем избегать абсолютных путей к файлам; относительные пути делают ваш файл Android.mk более переносимым.

LOCAL_CPP_EXTENSION

Вы можете использовать эту необязательную переменную, чтобы указать расширение файла, отличное от .cpp для исходных файлов C++. Например, следующая строка меняет расширение на .cxx . (Настройка должна включать точку.)

LOCAL_CPP_EXTENSION := .cxx

Вы можете использовать эту переменную для указания нескольких расширений. Например:

LOCAL_CPP_EXTENSION := .cxx .cpp .cc

LOCAL_CPP_FEATURES

Эту необязательную переменную можно использовать, чтобы указать, что ваш код использует определенные функции C++. Это позволяет использовать правильные флаги компилятора и компоновщика в процессе сборки. Для готовых двоичных файлов эта переменная также объявляет, от каких функций зависит двоичный файл, что помогает обеспечить правильную работу окончательного связывания. Мы рекомендуем использовать эту переменную вместо включения -frtti и -fexceptions непосредственно в определении LOCAL_CPPFLAGS .

Использование этой переменной позволяет системе сборки использовать соответствующие флаги для каждого модуля. Использование LOCAL_CPPFLAGS заставляет компилятор использовать все указанные флаги для всех модулей, независимо от фактической необходимости.

Например, чтобы указать, что ваш код использует RTTI (информацию о типе времени выполнения), напишите:

LOCAL_CPP_FEATURES := rtti

Чтобы указать, что ваш код использует исключения C++, напишите:

LOCAL_CPP_FEATURES := exceptions

Вы также можете указать несколько значений для этой переменной. Например:

LOCAL_CPP_FEATURES := rtti features

Порядок описания значений не имеет значения.

LOCAL_C_INCLUDES

Вы можете использовать эту необязательную переменную, чтобы указать список путей относительно root каталога NDK, чтобы добавить его к пути поиска при компиляции всех исходных кодов (C, C++ и Assembly). Например:

LOCAL_C_INCLUDES := sources/foo

Или даже:

LOCAL_C_INCLUDES := $(LOCAL_PATH)/<subdirectory>/foo

Определите эту переменную перед установкой любых соответствующих флагов включения через LOCAL_CFLAGS или LOCAL_CPPFLAGS .

Система сборки также автоматически использует пути LOCAL_C_INCLUDES при запуске встроенной отладки с помощью ndk-gdb.

LOCAL_CFLAGS

Эта необязательная переменная устанавливает флаги компилятора, которые будут передаваться системе сборки при сборке исходных файлов C и C++. Возможность сделать это может быть полезна для указания дополнительных определений макросов или параметров компиляции. Используйте LOCAL_CPPFLAGS чтобы указать флаги только для C++.

Старайтесь не менять уровень оптимизации/отладки в файле Android.mk . Система сборки может автоматически обработать этот параметр, используя соответствующую информацию в файле Application.mk . Подобный подход позволяет системе сборки генерировать полезные файлы данных, используемые во время отладки.

Можно указать дополнительные пути включения, написав:

LOCAL_CFLAGS += -I<path>,

Однако для этой цели лучше использовать LOCAL_C_INCLUDES , поскольку это также позволяет использовать пути, доступные для собственной отладки с помощью ndk-gdb.

LOCAL_CPPFLAGS

Необязательный набор флагов компилятора, который будет передаваться только при сборке исходных файлов C++. Они появятся после LOCAL_CFLAGS в командной строке компилятора. Используйте LOCAL_CFLAGS для указания флагов как для C, так и для C++.

LOCAL_STATIC_LIBRARIES

Эта переменная хранит список модулей статических библиотек, от которых зависит текущий модуль.

Если текущий модуль является общей библиотекой или исполняемым файлом, эта переменная заставит эти библиотеки скомпоноваться в результирующий двоичный файл.

Если текущий модуль является статической библиотекой, эта переменная просто указывает, что другие модули, зависящие от текущего, также будут зависеть от перечисленных библиотек.

LOCAL_SHARED_LIBRARIES

Эта переменная представляет собой список модулей общих библиотек, от которых этот модуль зависит во время выполнения. Эта информация необходима во время компоновки и для внедрения соответствующей информации в создаваемый файл.

LOCAL_WHOLE_STATIC_LIBRARIES

Эта переменная является вариантом LOCAL_STATIC_LIBRARIES и указывает, что компоновщик должен рассматривать связанные библиотечные модули как целые архивы . Для получения дополнительной информации о целых архивах см. документацию GNU ld для флага --whole-archive .

Эта переменная полезна, когда между несколькими статическими библиотеками существуют циклические зависимости. Когда вы используете эту переменную для сборки общей библиотеки, она заставит систему сборки добавить все объектные файлы из ваших статических библиотек в окончательный двоичный файл. Однако это не так при создании исполняемых файлов.

LOCAL_LDLIBS

Эта переменная содержит список дополнительных флагов компоновщика, которые можно использовать при создании вашей общей библиотеки или исполняемого файла. Он позволяет использовать префикс -l для передачи имени определенных системных библиотек. Например, следующий пример указывает компоновщику создать модуль, который ссылается на /system/lib/libz.so во время загрузки:

LOCAL_LDLIBS := -lz

Список открытых системных библиотек, с которыми можно ссылаться в этом выпуске NDK, см. в разделе Собственные API .

LOCAL_LDFLAGS

Список других флагов компоновщика, которые система сборки будет использовать при сборке вашей общей библиотеки или исполняемого файла. Например, чтобы использовать компоновщик ld.bfd на ARM/X86:

LOCAL_LDFLAGS += -fuse-ld=bfd

LOCAL_ALLOW_UNDEFINED_SYMBOLS

По умолчанию, когда система сборки обнаруживает неопределенную ссылку при попытке создать общий ресурс, она выдает ошибку неопределенного символа . Эта ошибка может помочь вам обнаружить ошибки в исходном коде.

Чтобы отключить эту проверку, установите для этой переменной значение true . Обратите внимание, что этот параметр может привести к загрузке общей библиотеки во время выполнения.

LOCAL_ARM_MODE

По умолчанию система сборки генерирует целевые двоичные файлы ARM в режиме большого пальца , где каждая инструкция имеет ширину 16 бит и связана с библиотеками STL в каталоге thumb/ . Определение этой переменной как arm заставляет систему сборки генерировать объектные файлы модуля в 32-битном режиме arm . В следующем примере показано, как это сделать:

LOCAL_ARM_MODE := arm

Вы также можете указать системе сборки собирать только определенные исходные коды в режиме arm , добавив суффикс .arm к именам исходных файлов. Например, в следующем примере система сборки сообщает системе сборки всегда компилировать bar.c в режиме ARM, но собирать foo.c в соответствии со значением LOCAL_ARM_MODE .

LOCAL_SRC_FILES := foo.c bar.c.arm

LOCAL_ARM_NEON

Эта переменная имеет значение только в том случае, если вы ориентируетесь на ABI armeabi-v7a . Он позволяет использовать встроенные функции компилятора ARM Advanced SIMD (NEON) в исходных кодах C и C++, а также инструкции NEON в файлах сборки.

Обратите внимание, что не все процессоры на базе ARMv7 поддерживают расширения набора команд NEON. По этой причине вам необходимо выполнить обнаружение во время выполнения, чтобы иметь возможность безопасно использовать этот код во время выполнения. Дополнительные сведения см. в разделе Поддержка Neon и функции ЦП .

Альтернативно вы можете использовать суффикс .neon , чтобы указать, что система сборки компилирует только определенные исходные файлы с поддержкой NEON. В следующем примере система сборки компилирует foo.c с поддержкой Thumb и Neon, bar.c с поддержкой Thumb и zoo.c с поддержкой ARM и NEON:

LOCAL_SRC_FILES = foo.c.neon bar.c zoo.c.arm.neon

Если вы используете оба суффикса, .arm должен предшествовать .neon .

LOCAL_DISABLE_FORMAT_STRING_CHECKS

По умолчанию система сборки компилирует код с защитой строки формата. Это приведет к ошибке компилятора, если строка непостоянного формата используется в функции printf -style. Эта защита включена по умолчанию, но вы можете отключить ее, установив для этой переменной значение true . Мы не рекомендуем делать это без веской причины.

LOCAL_EXPORT_CFLAGS

Эта переменная записывает набор флагов компилятора C/C++, которые можно добавить к определению LOCAL_CFLAGS любого другого модуля, использующего этот флаг, через переменные LOCAL_STATIC_LIBRARIES или LOCAL_SHARED_LIBRARIES .

Например, рассмотрим следующую пару модулей: foo и bar , которая зависит от foo :

include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_CFLAGS := -DFOO=1
include $(BUILD_STATIC_LIBRARY)


include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_CFLAGS := -DBAR=2
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)

Здесь система сборки передает флаги -DFOO=1 и -DBAR=2 компилятору при сборке bar.c Он также добавляет экспортированные флаги к LOCAL_CFLAGS вашего модуля, чтобы вы могли легко их переопределить.

Кроме того, отношения между модулями транзитивны: если zoo зависит от bar , который, в свою очередь, зависит от foo , то zoo также наследует все флаги, экспортированные из foo .

Наконец, система сборки не использует экспортированные флаги при локальной сборке (т. е. при сборке модуля, флаги которого она экспортирует). Таким образом, в приведенном выше примере компилятору не передается -DFOO=1 при построении foo/foo.c . Для локальной сборки используйте вместо этого LOCAL_CFLAGS .

LOCAL_EXPORT_CPPFLAGS

Эта переменная аналогична LOCAL_EXPORT_CFLAGS , но только для флагов C++.

LOCAL_EXPORT_C_INCLUDES

Эта переменная аналогична LOCAL_EXPORT_CFLAGS , но для C включает пути. Это полезно, например, в тех случаях, когда bar.c необходимо включить заголовки из модуля foo .

LOCAL_EXPORT_LDFLAGS

Эта переменная аналогична LOCAL_EXPORT_CFLAGS , но для флагов компоновщика.

LOCAL_EXPORT_LDLIBS

Эта переменная аналогична LOCAL_EXPORT_CFLAGS и указывает системе сборки передавать компилятору имена конкретных системных библиотек. Добавьте -l к имени каждой указанной вами библиотеки.

Обратите внимание, что система сборки добавляет импортированные флаги компоновщика к значению переменной 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)

В этом примере система сборки помещает -llog в конец команды компоновщика при сборке libbar.so . Это сообщает компоновщику, что, поскольку libbar.so зависит от foo , он также зависит от библиотеки системного журналирования.

LOCAL_SHORT_COMMANDS

Установите для этой переменной значение true , если ваш модуль имеет очень большое количество источников и/или зависимых статических или общих библиотек. В этом случае система сборки будет использовать синтаксис @ для архивов, содержащих промежуточные объектные файлы или связывающиеся библиотеки.

Эта функция может быть полезна в Windows, где командная строка может содержать не более 8191 символа, что может быть слишком мало для сложных проектов. Это также влияет на компиляцию отдельных исходных файлов, помещая почти все флаги компилятора внутри файлов списков.

Обратите внимание, что любое значение, кроме true , вернется к поведению по умолчанию. Вы также можете определить APP_SHORT_COMMANDS в файле Application.mk , чтобы принудительно использовать это поведение для всех модулей вашего проекта.

Мы не рекомендуем включать эту функцию по умолчанию, поскольку она замедляет сборку.

LOCAL_THIN_ARCHIVE

Установите для этой переменной значение true при создании статических библиотек. При этом будет создан тонкий архив — библиотечный файл, который не содержит объектных файлов, а содержит только пути к реальным объектам, которые он обычно содержит.

Это полезно для уменьшения размера вывода вашей сборки. Недостаток — такие библиотеки нельзя переместить в другое место (все пути внутри них относительные).

Допустимые значения: true , false или пусто. Значение по умолчанию можно установить в файле Application.mk через переменную APP_THIN_ARCHIVE .

LOCAL_FILTER_ASM

Определите эту переменную как команду оболочки, которую система сборки будет использовать для фильтрации файлов сборки, извлеченных или созданных из файлов, указанных вами для LOCAL_SRC_FILES . Определение этой переменной приводит к следующим событиям:

  1. Система сборки генерирует временный файл сборки из любого исходного файла C или C++ вместо того, чтобы компилировать его в объектный файл.
  2. Система сборки выполняет команду оболочки в LOCAL_FILTER_ASM для любого временного файла сборки и для любого файла сборки, указанного в LOCAL_SRC_FILES , создавая таким образом еще один временный файл сборки.
  3. Система сборки компилирует эти отфильтрованные файлы сборки в объектный файл.

Например:

LOCAL_SRC_FILES  := foo.c bar.S
LOCAL_FILTER_ASM :=

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

Функциональные макросы, предоставляемые NDK

В этом разделе объясняются макросы функций GNU Make, предоставляемые NDK. Используйте $(call <function>) для их оценки; они возвращают текстовую информацию.

мой директор

Этот макрос возвращает путь к последнему включенному make-файлу, который обычно является текущим каталогом Android.mk . my-dir полезен для определения LOCAL_PATH в начале вашего файла Android.mk . Например:

LOCAL_PATH := $(call my-dir)

Из-за особенностей работы GNU Make этот макрос на самом деле возвращает путь к последнему make-файлу, который система сборки включила при анализе сценариев сборки. По этой причине не следует вызывать my-dir после включения другого файла.

Например, рассмотрим следующий пример:

LOCAL_PATH := $(call my-dir)

# ... declare one module

include $(LOCAL_PATH)/foo/`Android.mk`

LOCAL_PATH := $(call my-dir)

# ... declare another module

Проблема здесь в том, что второй вызов my-dir определяет LOCAL_PATH как $PATH/foo вместо $PATH , потому что именно туда указывало его последнее включение.

Вы можете избежать этой проблемы, поместив дополнительные включения после всего остального в файле Android.mk . Например:

LOCAL_PATH := $(call my-dir)

# ... declare one module

LOCAL_PATH := $(call my-dir)

# ... declare another module

# extra includes at the end of the Android.mk file
include $(LOCAL_PATH)/foo/Android.mk

Если структурировать файл таким образом невозможно, сохраните значение первого вызова my-dir в другую переменную. Например:

MY_LOCAL_PATH := $(call my-dir)

LOCAL_PATH := $(MY_LOCAL_PATH)

# ... declare one module

include $(LOCAL_PATH)/foo/`Android.mk`

LOCAL_PATH := $(MY_LOCAL_PATH)

# ... declare another module

all-subdir-makefiles

Возвращает список файлов Android.mk , расположенных во всех подкаталогах текущего пути my-dir .

Вы можете использовать эту функцию для предоставления глубоко вложенной иерархии исходных каталогов в систему сборки. По умолчанию NDK ищет файлы только в каталоге, содержащем файл Android.mk .

этот make-файл

Возвращает путь к текущему make-файлу (из которого система сборки вызвала функцию).

родительский make-файл

Возвращает путь родительского make-файла в дереве включения (путь make-файла, включающего текущий).

дедовский-родительский make-файл

Возвращает путь к родительскому make-файлу в дереве включения (путь к make-файлу, включающему текущий).

импорт-модуль

Функция, позволяющая найти и включить файл Android.mk модуля по имени модуля. Типичный пример выглядит следующим образом:

$(call import-module,<name>)

В этом примере система сборки ищет модуль с тегом <name> в списке каталогов, на которые ссылается переменная среды NDK_MODULE_PATH , и автоматически включает для вас его файл Android.mk .