Android.mk

En esta página, se describe la sintaxis del archivo de compilación Android.mk que utiliza ndk-build.

Descripción general

El archivo Android.mk reside en un subdirectorio del directorio jni/ del proyecto y describe las fuentes y las bibliotecas compartidas al sistema de compilación. Es un fragmento muy pequeño de un archivo makefile de GNU que el sistema de compilación analiza una o varias veces. El archivo Android.mk es útil para definir configuraciones en todo el proyecto que Application.mk, el sistema de compilación, y las variables de tu entorno dejan sin definir. También puede anular la configuración de todo el proyecto para módulos específicos.

La sintaxis Android.mk te permite agrupar tus fuentes en módulos. Un módulo puede ser una biblioteca estática, una biblioteca compartida o un elemento ejecutable independiente. Puedes definir uno o más módulos en cada archivo Android.mk y usar el mismo archivo de origen en varios módulos. El sistema de compilación solo coloca bibliotecas compartidas en el paquete de tu aplicación. Asimismo, las bibliotecas estáticas pueden generar bibliotecas compartidas.

Además de empaquetar bibliotecas, el sistema de compilación se encarga de varios otros detalles por ti. Por ejemplo, no necesitas indicar archivos de encabezados ni dependencias explícitas entre los archivos generados en tu archivo Android.mk. El sistema de compilación del NDK calcula estas relaciones automáticamente. En consecuencia, te beneficiarás con la compatibilidad con cadenas de herramientas y plataformas nuevas en versiones futuras del NDK sin tener que tocar tu archivo Android.mk.

La sintaxis de este archivo es muy similar a la que se usa en los archivos Android.mk, que se distribuyen con el Proyecto de código abierto de Android completo. Si bien la implementación del sistema de compilación que los usa es diferente, la similitud está en una decisión de diseño intencional de que los desarrolladores de apps puedan facilitar la reutilización del código fuente para bibliotecas externas.

Conceptos básicos

Antes de explorar la sintaxis en detalle, es útil comenzar por comprender los aspectos básicos de lo que contiene un archivo Android.mk. En esta sección, se usa el archivo Android.mk de la muestra Hello-JNI para ese fin y se explica la función de cada línea en el archivo.

El punto de partida de un archivo Android.mk es definir la variable LOCAL_PATH:

LOCAL_PATH := $(call my-dir)

Esta variable indica la ubicación de los archivos de origen en el árbol de desarrollo. Aquí, la función macro my-dir, proporcionada por el sistema de compilación, muestra la ruta de acceso del directorio actual (el que contiene el archivo Android.mk).

En la siguiente línea, se declara la variable CLEAR_VARS, cuyo valor lo proporciona el sistema de compilación.

include $(CLEAR_VARS)

La variable CLEAR_VARS apunta a un archivo makefile de GNU especial que borra muchas variables LOCAL_XXX, como LOCAL_MODULE, LOCAL_SRC_FILES y LOCAL_STATIC_LIBRARIES. Ten en cuenta que no borra LOCAL_PATH. Esta variable debe retener su valor porque el sistema analiza todos los archivos de control de la compilación en un solo contexto de ejecución de GNU Make donde todas las variables son globales. Debes (volver a) declarar esta variable antes de describir cada módulo.

Luego, la variable LOCAL_MODULE almacena el nombre del módulo que quieres compilar. Usa esta variable una vez por módulo en tu aplicación.

LOCAL_MODULE := hello-jni

Los nombres de los módulos deben ser únicos y no tener espacios. Cuando genera el archivo final de biblioteca compartida, el sistema de compilación agrega automáticamente el prefijo y el sufijo adecuados al nombre que le asignaste a LOCAL_MODULE. Con el ejemplo anterior, se genera una biblioteca llamada libhello-jni.so.

En la próxima línea, se enumeran los archivos de origen, con espacios para delimitar varios archivos:

LOCAL_SRC_FILES := hello-jni.c

La variable LOCAL_SRC_FILES debe tener una lista de archivos de origen C y C++ para compilar en un módulo.

La última línea ayuda al sistema a unificar todo:

include $(BUILD_SHARED_LIBRARY)

La variable BUILD_SHARED_LIBRARY apunta a una secuencia de comandos de archivo makefile de GNU que recopila toda la información definida en las variables LOCAL_XXX desde el include más reciente. Esta secuencia de comandos determina qué se compilará y cómo.

Hay ejemplos más complejos en los directorios de muestra, con archivos Android.mk comentados que puedes consultar. Además, en la sección Ejemplo: native-activity, hay una explicación detallada del archivo Android.mk de ese ejemplo. Por último, en la sección Variables y macros, hay información adicional sobre las variables de esta sección.

Variables y macros

El sistema de compilación proporciona muchas variables posibles para usar en el archivo Android.mk. Una gran cantidad de esas variables poseen valores previamente asignados. En el caso de las demás, debes encargarte de asignarlos.

Además de esas variables, también puedes definir tus propias variables arbitrarias. Si lo haces, recuerda que el sistema de compilación del NDK reserva los siguientes nombres de variables:

  • Nombres que comienzan con LOCAL_, como LOCAL_MODULE.
  • Nombres que comienzan con PRIVATE_, NDK_ o APP. El sistema de compilación los usa internamente.
  • Nombres en minúscula, como my-dir. El sistema de compilación también usa estos nombres internamente.

Si necesitas definir variables de conveniencia propias en un archivo Android.mk, te recomendamos anexar MY_ a los nombres.

Variables de inclusión definidas por NDK

En esta sección, se abordan las variables de GNU Make que el sistema de compilación define antes de analizar tu archivo Android.mk. En determinadas circunstancias, el NDK puede analizar tu archivo Android.mk varias veces, con una definición diferente para algunas de estas variables en cada oportunidad.

CLEAR_VARS

Esta variable apunta a una secuencia de comandos de compilación que anula la definición de casi todas las variables LOCAL_XXX enumeradas en la sección "Variables definidas por el desarrollador" que se muestra debajo. Usa la variable para incluir esta secuencia de comandos antes de describir un módulo nuevo. La sintaxis para usarla es la siguiente:

include $(CLEAR_VARS)

BUILD_EXECUTABLE

Esta variable apunta a una secuencia de comandos de compilación que recopila toda la información sobre el módulo incluido en las variables LOCAL_XXX y determina cómo compilar un destino ejecutable a partir de las fuentes que enumeraste. Recuerda que el uso de esta secuencia de comandos requiere que ya tengas valores asignados a LOCAL_MODULE y LOCAL_SRC_FILES, como mínimo (para obtener más información sobre estas variables, consulta Variables de descripción de módulos).

La sintaxis para usar esta variable es la siguiente:

include $(BUILD_EXECUTABLE)

BUILD_SHARED_LIBRARY

Esta variable apunta a una secuencia de comandos de compilación que recopila toda la información sobre el módulo incluido en las variables LOCAL_XXX y determina cómo compilar una biblioteca compartida de destino a partir de los archivos de origen que enumeraste. Recuerda que el uso de esta secuencia de comandos requiere que ya tengas valores asignados a LOCAL_MODULE y LOCAL_SRC_FILES, como mínimo (para obtener más información sobre estas variables, consulta Variables de descripción de módulos).

La sintaxis para usar esta variable es la siguiente:

include $(BUILD_SHARED_LIBRARY)

Una variable de biblioteca compartida hace que el sistema de compilación genere un archivo de biblioteca con la extensión .so.

BUILD_STATIC_LIBRARY

Una variante de BUILD_SHARED_LIBRARY que se usa para compilar una biblioteca estática. El sistema de compilación no copia bibliotecas estáticas en tu proyecto ni tus paquetes, pero puede usarlas para compilar bibliotecas compartidas (consulta LOCAL_STATIC_LIBRARIES y LOCAL_WHOLE_STATIC_LIBRARIES abajo). La sintaxis para usar esta variable es la siguiente:

include $(BUILD_STATIC_LIBRARY)

Una variable de biblioteca estática hace que el sistema de compilación genere una biblioteca con una extensión .a.

PREBUILT_SHARED_LIBRARY

Apunta a una secuencia de comandos de compilación usada para especificar la biblioteca compartida compilada previamente. A diferencia de BUILD_SHARED_LIBRARY y BUILD_STATIC_LIBRARY, aquí, el valor de LOCAL_SRC_FILES no puede ser un archivo de origen. En su lugar, debe ser una ruta de acceso única a una biblioteca compartida compilada previamente, como foo/libfoo.so. La sintaxis para usar esta variable es la siguiente:

include $(PREBUILT_SHARED_LIBRARY)

También puedes hacer referencia a una biblioteca compilada previamente en otro módulo si usas la variable LOCAL_PREBUILTS. Consulta Cómo usar bibliotecas compiladas previamente para obtener más información.

PREBUILT_STATIC_LIBRARY

Igual que PREBUILT_SHARED_LIBRARY, pero para una biblioteca estática compilada previamente. Consulta Cómo usar bibliotecas compiladas previamente para obtener más información.

Variables de información de destino

El sistema de compilación analiza Android.mk una vez por cada ABI especificada por la variable APP_ABI, que, en general, está definida en el archivo Application.mk. Si APP_ABI es all, el sistema de compilación analiza Android.mk una vez por cada ABI compatible con el NDK. En esta sección, se describen las variables del sistema de compilación que el sistema define cada vez que analiza Android.mk.

TARGET_ARCH

Es la familia de la CPU a la que apunta el sistema de compilación cuando analiza el archivo Android.mk. Esta variable será una de las siguientes: arm, arm64, x86 o x86_64.

TARGET_PLATFORM

Es el número de nivel de API de Android al que apunta el sistema de compilación cuando analiza el archivo Android.mk. Por ejemplo, las imágenes del sistema de Android 5.1 corresponden al nivel 22 de la API de Android: android-22. Para obtener una lista completa de los nombres de las plataformas y las imágenes del sistema de Android correspondientes, consulta API nativas del NDK de Android. En el siguiente ejemplo, se muestra la sintaxis para utilizar esta variable:

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

TARGET_ARCH_ABI

La ABI a la que apunta el sistema de compilación cuando analiza el archivo Android.mk. En la tabla 1, se muestra la configuración de la ABI que se usa para cada CPU y arquitectura admitidos.

Tabla 1: Configuración de ABI para diferentes CPU y arquitecturas.

CPU y arquitectura Configuración
ARMv7 armeabi-v7a
ARMv8 AArch64 arm64-v8a
i686 x86
x86-64 x86_64

En el siguiente ejemplo, se muestra cómo comprobar ARMv8 AArch64 como la combinación de CPU y ABI de destino:

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

Para obtener más información sobre la arquitectura de las ABI y los problemas de compatibilidad relacionados, consulta Administración de ABI.

En el futuro, las ABI de destino nuevas tendrán valores diferentes.

TARGET_ABI

Es una concatenación de ABI y nivel de API de Android de destino. Es particularmente útil cuando deseas realizar pruebas en una imagen específica del sistema de destino para un dispositivo real. Por ejemplo, para comprobar un dispositivo ARM de 64 bits con nivel 22 de API de Android:

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

Variables de descripción de módulo

Las variables en esta sección describen tu módulo al sistema de compilación. La descripción de cada módulo debe respetar el siguiente flujo básico:

  1. Inicializa o anula la definición de las variables asociadas con el módulo mediante la variable CLEAR_VARS.
  2. Asigna valores a las variables empleadas para describir el módulo.
  3. Establece el sistema de compilación del NDK a fin de que use la secuencia de comandos de compilación apropiada para el módulo mediante la variable BUILD_XXX.

LOCAL_PATH

Esta variable se usa para proporcionar la ruta de acceso del archivo actual. Debes definirla al comienzo del archivo Android.mk. En el siguiente ejemplo, se muestra cómo hacerlo:

LOCAL_PATH := $(call my-dir)

La secuencia de comandos a la que se apunta CLEAR_VARS no borra esta variable. Por lo tanto, solo necesitas definirla una vez, aunque tu archivo Android.mk describa varios módulos.

LOCAL_MODULE

Esta variable almacena el nombre de tu módulo. Debe ser única entre todos los nombres de módulos y no debe contener espacios. Debes definirla antes de incluir cualquier secuencia de comandos (que no sea la de CLEAR_VARS). No es necesario agregar el prefijo lib o la extensión de archivo .so o .a, ya que el sistema de compilación realiza esas modificaciones automáticamente. En los archivos Android.mk y Application.mk, haz referencia al módulo por su nombre sin modificar. Por ejemplo, la siguiente línea genera un módulo de biblioteca compartida llamado libfoo.so:

LOCAL_MODULE := "foo"

Si deseas que el módulo generado tenga un nombre diferente de lib más el valor de LOCAL_MODULE, puedes usar la variable LOCAL_MODULE_FILENAME para asignar el nombre que desees al módulo generado.

LOCAL_MODULE_FILENAME

Esta variable opcional te permite anular los nombres que el sistema de compilación usa de forma predeterminada para los archivos que genera. Por ejemplo, si el nombre de tu LOCAL_MODULE es foo, puedes hacer que el sistema asigne por la fuerza el nombre libnewfoo al archivo que genera. En el siguiente ejemplo, se muestra cómo lograrlo:

LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo

En un módulo de biblioteca compartida, este ejemplo generaría un archivo llamado libnewfoo.so.

LOCAL_SRC_FILES

Esta variable tiene la lista de archivos de origen que usa el sistema de compilación para generar el módulo. Solo se deben enumerar los archivos que el sistema de compilación le transmite al compilador, ya que el sistema de compilación computa automáticamente todas las dependencias asociadas. Recuerda que puedes usar tanto la ruta de acceso al archivo relativa (a LOCAL_PATH) como la absoluta.

Recomendamos que evites las rutas de acceso a archivos absolutas, ya que las relativas permiten que el archivo Android.mk sea más portátil.

LOCAL_CPP_EXTENSION

Puedes usar esta variable opcional a fin de indicar una extensión de archivo diferente de .cpp para tus archivos de origen C++. Por ejemplo, la siguiente línea cambia la extensión a .cxx. (Esta configuración debe incluir el punto).

LOCAL_CPP_EXTENSION := .cxx

Puedes usar esta variable para especificar varias extensiones. Por ejemplo:

LOCAL_CPP_EXTENSION := .cxx .cpp .cc

LOCAL_CPP_FEATURES

Puedes usar esta variable opcional para indicar que tu código se basa en funciones específicas de C++. Habilita las marcas correctas del compilador y del vinculador durante el proceso de compilación. En el caso de los objetos binarios compilados previamente, esta variable también declara las funciones en las que se basa el objeto binario. Así, se garantiza que la vinculación final funcione de manera correcta. Recomendamos que uses esta variable en lugar de habilitar -frtti y -fexceptions directamente en la definición de LOCAL_CPPFLAGS.

El uso de esta variable permite que el sistema de compilación utilice las marcas correctas para cada módulo. El uso de LOCAL_CPPFLAGS hace que el compilador utilice todas las marcas especificadas para todos los módulos, sin importar la necesidad real.

Por ejemplo, para indicar que tu código usa RTTI (Información de tipo RunTime), escribe lo siguiente:

LOCAL_CPP_FEATURES := rtti

Para indicar que tu código usa excepciones C++, escribe lo siguiente:

LOCAL_CPP_FEATURES := exceptions

También puedes especificar diferentes valores para esta variable. Por ejemplo:

LOCAL_CPP_FEATURES := rtti features

No importa el orden en el que describas los valores.

LOCAL_C_INCLUDES

Puedes usar esta variable opcional para especificar una lista de rutas de acceso, relacionadas con el directorio root del NDK, que agregarás a la ruta de acceso de inclusión de búsqueda cuando se compilan todas las fuentes (C, C++ y Assembly). Por ejemplo:

LOCAL_C_INCLUDES := sources/foo

O incluso:

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

Puedes definir esta variable antes de configurar las marcas de inclusión correspondientes mediante LOCAL_CFLAGS o LOCAL_CPPFLAGS.

El sistema de compilación también usa rutas de acceso LOCAL_C_INCLUDES automáticamente cuando se inician depuraciones nativas con ndk-gdb.

LOCAL_CFLAGS

Esta variable opcional establece marcas del compilador para que el sistema de compilación las pase cuando se compilan archivos de origen C y C++, lo que es útil a fin de especificar definiciones de macro adicionales, o bien, opciones de compilación. Usa LOCAL_CPPFLAGS a fin de especificar marcas solo para C++.

Intenta no cambiar el nivel de optimización/depuración del archivo Android.mk. El sistema de compilación puede controlar esta configuración automáticamente por ti con la información relevante en el archivo Application.mk. Al hacerlo de esta manera, el sistema de compilación puede generar archivos de datos útiles que se usan durante la depuración.

Escribe lo siguiente para especificar rutas de acceso de inclusión adicionales:

LOCAL_CFLAGS += -I<path>,

Sin embargo, es mejor usar LOCAL_C_INCLUDES con este propósito, ya que también podrás usar las rutas disponibles para depuraciones nativas con ndk-gdb.

LOCAL_CPPFLAGS

Indica un conjunto opcional de marcas de compilador que se pasarán cuando se compilan archivos de origen C++ únicamente. Aparecerán después de LOCAL_CFLAGS en la línea de comandos del compilador. Usa LOCAL_CFLAGS a fin de especificar marcas para C y C++.

LOCAL_STATIC_LIBRARIES

Esta variable almacena la lista de módulos de bibliotecas estáticas de los cuales depende el módulo actual.

Si el módulo actual es una biblioteca compartida o un ejecutable, esta variable forzará la vinculación de esas bibliotecas en el objeto binario resultante.

Si el módulo actual es una biblioteca estática, esta variable simplemente indica que otros módulos basados en el actual también se basarán en las bibliotecas indicadas.

LOCAL_SHARED_LIBRARIES

Esta variable es la lista de módulos de bibliotecas compartidas en las cuales se basa este módulo durante el tiempo de ejecución. La información se necesita en el momento de la vinculación y para incorporar la información correspondiente al archivo generado.

LOCAL_WHOLE_STATIC_LIBRARIES

Esta variable es una variante de LOCAL_STATIC_LIBRARIES y expresa que el vinculador debe tratar los módulos de bibliotecas asociados como archivos enteros. Para obtener más información sobre los archivos enteros, consulta la documentación de GNU ld de la marca --whole-archive.

Esta variable es útil cuando hay dependencias circulares entre varias bibliotecas estáticas. Cuando uses la variable para compilar una biblioteca compartida, forzarás al sistema de compilación a agregar todos los archivos de objetos de las bibliotecas estáticas al objeto binario final. No obstante, no ocurre lo mismo cuando se generan ejecutables.

LOCAL_LDLIBS

Esta variable contiene la lista de marcas adicionales del vinculador para usar en la compilación de tu biblioteca compartida o ejecutable. Te permite usar el prefijo -l para pasar el nombre de bibliotecas específicas del sistema. Por ejemplo, en el siguiente ejemplo, se indica al vinculador que genere un módulo que se vincule con /system/lib/libz.so durante el tiempo de carga:

LOCAL_LDLIBS := -lz

Para obtener la lista de las bibliotecas del sistema a las que te puedes vincular en esta versión del NDK, consulta API nativa del NDK de Android.

LOCAL_LDFLAGS

Indica la lista de otras marcas del vinculador para el sistema de compilación que deben usarse cuando se compila tu biblioteca compartida o ejecutable. Por ejemplo, para usar el vinculador ld.bfd en ARM/X86:

LOCAL_LDFLAGS += -fuse-ld=bfd

LOCAL_ALLOW_UNDEFINED_SYMBOLS

De forma predeterminada, cuando el sistema de compilación encuentra una referencia indefinida mientras intenta compilar una biblioteca compartida, generará un error de símbolo sin definir. El error puede ayudarte a detectar otros errores en tu código fuente.

Para inhabilitar esta comprobación, establece esta variable en true. Recuerda que esta configuración puede hacer que la biblioteca compartida se cargue durante el tiempo de ejecución.

LOCAL_ARM_MODE

De forma predeterminada, el sistema de compilación genera objetos binarios de destino ARM en el modo thumb, en el que cada instrucción tiene 16 bits de ancho y está vinculada a bibliotecas STL en el directorio thumb/. Definir esta variable como arm fuerza al sistema de compilación a generar los archivos de objeto del módulo en el modo arm de 32 bits. En el siguiente ejemplo, se muestra cómo hacerlo:

LOCAL_ARM_MODE := arm

También puedes anexar el sufijo .arm a los nombres de archivo de origen para indicar al sistema de compilación que solo compile fuentes específicas en el modo arm. Por ejemplo, en el siguiente ejemplo, se indica al sistema de compilación que siempre compile bar.c en el modo ARM, excepto para compilar foo.c según el valor de LOCAL_ARM_MODE.

LOCAL_SRC_FILES := foo.c bar.c.arm

LOCAL_ARM_NEON

Esta variable solo es importante cuando se apunta a la ABI armeabi-v7a. Permite el uso de elementos intrínsecos del compilador de SIMD avanzado de ARM (NEON) en las archivos de origen C y C++, así como instrucciones NEON en archivos Assembly.

Ten en cuenta que no todas las CPU basadas en ARMv7 admiten extensiones para el conjunto de instrucciones NEON. Por eso, debes realizar una detección del tiempo de ejecución para poder usar este código de forma segura durante el tiempo de ejecución. Para obtener más información, consulta Compatibilidad con NEON y la biblioteca cpufeatures.

Como alternativa, puedes usar el sufijo .neon para indicar que el sistema de compilación solo compile archivos de origen específicos compatibles con NEON. En el siguiente ejemplo, el sistema de compilación compila foo.c con compatibilidad para thumb y neon, bar.c con compatibilidad para thumb y zoo.c con compatibilidad para ARM y NEON:

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

Si usas ambos sufijos, .arm debe preceder a .neon.

LOCAL_DISABLE_FORMAT_STRING_CHECKS

De forma predeterminada, el sistema de compilación compila código con protección de strings de formato. En consecuencia, si se usa una string de formato que no es constante en una función de estilo printf se genera un error de compilador. La protección se activa de forma predeterminada, pero puedes inhabilitarla si estableces el valor de la variable en true. No recomendamos hacer esto sin un motivo específico.

LOCAL_EXPORT_CFLAGS

La variable registra un conjunto de marcas C/C++ del compilador para agregar a la definición LOCAL_CFLAGS de cualquier otro módulo que la use a través de las variables LOCAL_STATIC_LIBRARIES o LOCAL_SHARED_LIBRARIES.

Por ejemplo, considera el par de módulos foo y bar, que dependen de 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)

Aquí, el sistema compilación pasa las marcas -DFOO=1 y -DBAR=2 al compilador durante la compilación de bar.c. También anexa marcas exportadas al LOCAL_CFLAGS del módulo para que puedas anularlas fácilmente.

Asimismo, la relación entre los módulos es transitiva. Si zoo depende de bar, que, a su vez, depende de foo, entonces zoo también hereda todas las marcas exportadas de foo.

Por último, el sistema de compilación no usa marcas exportadas cuando hace compilaciones a nivel local (es decir, cuando compila el módulo cuyas marcas exporta). Por lo tanto, en el ejemplo anterior, no pasa -DFOO=1 al compilador mientras compila foo/foo.c. Para hacer compilaciones localmente, usa LOCAL_CFLAGS.

LOCAL_EXPORT_CPPFLAGS

Esta variable es la misma que LOCAL_EXPORT_CFLAGS, pero para indicadores C++ únicamente.

LOCAL_EXPORT_C_INCLUDES

Esta variable es la misma que LOCAL_EXPORT_CFLAGS, pero para rutas de acceso de inclusión de C. Es útil cuando, por ejemplo, bar.c debe incluir encabezados del módulo foo.

LOCAL_EXPORT_LDFLAGS

Esta variable es la misma que LOCAL_EXPORT_CFLAGS, pero para indicadores del vinculador.

LOCAL_EXPORT_LDLIBS

Esta variable es la misma que LOCAL_EXPORT_CFLAGS y le indica al sistema de compilación que pase al compilador nombres de bibliotecas específicas del sistema. Agrega el prefijo -l al nombre de cada biblioteca que especifiques.

Recuerda que el sistema de compilación anexa marcas de vinculador importadas al valor de la variable LOCAL_LDLIBS de tu módulo. Lo hace como consecuencia del funcionamiento de los vinculadores de Unix.

La variable suele ser útil cuando el módulo foo es una biblioteca estática y tiene código que depende de una biblioteca del sistema. Entonces, puedes usar LOCAL_EXPORT_LDLIBS para exportar la dependencia. Por ejemplo:

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)

En este ejemplo, el sistema de compilación agrega -llog al final del comando del vinculador cuando compila libbar.so. Al hacerlo, se indica al vinculador que, como libbar.so depende de foo, también depende de la biblioteca de registro del sistema.

LOCAL_SHORT_COMMANDS

Establece la variable como true cuando tu módulo tenga una gran cantidad de archivos de origen y bibliotecas compartidas o estáticas dependientes. De esta manera, se fuerza al sistema de compilación a usar la sintaxis @ para los archivos que tengan bibliotecas vinculantes o archivos de objeto intermedios.

La función puede ser útil en Windows, donde la línea de comandos acepta una cantidad máxima de 8,191 caracteres, que pueden ser muy pocos para proyectos complejos. También afecta la compilación de archivos de origen individuales y coloca prácticamente todas las marcas del compilador en archivos de lista.

Ten en cuenta que cualquier valor diferente de true restablecerá el comportamiento predeterminado. También puedes definir APP_SHORT_COMMANDS en tu archivo Application.mk a fin de forzar este comportamiento en todos los módulos de tu proyecto.

No recomendamos habilitar esta función de forma predeterminada porque hace que la compilación sea más lenta.

LOCAL_THIN_ARCHIVE

Establece esta variable como true cuando compiles bibliotecas estáticas. Al hacerlo, se generará un archivo fino, un archivo de biblioteca sin archivos de objeto, sino solo las rutas de acceso a archivos de los objetos reales que normalmente contendría.

Esto es útil para reducir el tamaño de la compilación final. La desventaja es que esas bibliotecas no se pueden mover a una ubicación diferente (todas las rutas de acceso dentro de ellas son relativas).

Los valores válidos son true, false o vacío. Puedes establecer un valor predeterminado en el archivo Application.mk con la variable APP_THIN_ARCHIVE.

LOCAL_FILTER_ASM

Define esta variable como un comando shell que el sistema de compilación usará a fin de filtrar los archivos de ensamblado extraídos o generados a partir de los archivos que especificaste para LOCAL_SRC_FILES. La definición de esta variable hace lo siguiente:

  1. El sistema de compilación genera un archivo de ensamblado temporal a partir de cualquier archivo de origen C o C++, en lugar de compilarlos en un archivo de objeto.
  2. El sistema de compilación ejecuta el comando shell en LOCAL_FILTER_ASM en cualquier archivo de ensamblado temporal y cualquier archivo de ensamblado enumerado en LOCAL_SRC_FILES. Así, se genera otro archivo de ensamblado temporal.
  3. El sistema de compilación compila estos archivos de ensamblado filtrados en un archivo de objeto.

Por ejemplo:

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

En este caso, "1" corresponde al compilador, "2" al filtro y "3" al ensamblador. El filtro debe ser un comando shell independiente que tome el nombre del archivo de entrada como el primer argumento y el nombre del archivo de salida como el segundo. Por ejemplo:

myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S
myasmfilter bar.S $OBJS_DIR/bar.S

Macros de función proporcionados por el NDK

En esta sección, se explican las macros de la función GNU Make que proporciona el NDK. Usa $(call <function>) para evaluarlas. Las macros muestran información textual.

my-dir

La macro muestra la ruta de acceso del último archivo makefile incluido, que generalmente es el directorio Android.mk actual. my-dir es útil para definir LOCAL_PATH al comienzo de tu archivo Android.mk. Por ejemplo:

LOCAL_PATH := $(call my-dir)

Por cómo funciona GNU Make, lo que esta macro muestra realmente es la ruta de acceso del último archivo makefile que el sistema de compilación incluyó cuando analizó las secuencias de comandos de compilación. Por eso, no debes llamar a my-dir después de incluir otro archivo.

Considera el siguiente ejemplo:

LOCAL_PATH := $(call my-dir)

# ... declare one module

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

LOCAL_PATH := $(call my-dir)

# ... declare another module

El problema aquí es que la segunda llamada a my-dir define LOCAL_PATH como $PATH/foo en lugar de $PATH, ya que allí es a donde apuntaba la inclusión más reciente.

Puedes disponer inclusiones adicionales después de todo lo demás en el archivo Android.mk para evitar este problema. Por ejemplo:

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

Si no se puede estructurar el archivo de esta manera, guarda el valor de la primera llamada a my-dir en otra variable. Por ejemplo:

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

Muestra la lista de archivos Android.mk de todos los subdirectorios de la ruta de acceso my-dir actual.

Puedes usar esta función para proporcionar jerarquías de directorios de origen anidados profundamente al sistema de compilación. De forma predeterminada, el NDK solo busca archivos en el directorio que contiene el archivo Android.mk.

this-makefile

Devuelve la ruta de acceso del archivo makefile actual (desde el cual el sistema de compilación llamó a la función).

parent-makefile

Devuelve la ruta de acceso del archivo makefile superior en el árbol de inclusión (la ruta de acceso del archivo makefile que incluyó al actual).

grand-parent-makefile

Devuelve la ruta de acceso del archivo makefile primario en el árbol de inclusión (la ruta de acceso del archivo makefile que incluyó el actual).

import-module

Esta función te permite buscar e incluir el archivo Android.mk de un módulo por el nombre de ese módulo. Un ejemplo típico es el siguiente:

$(call import-module,<name>)

En este ejemplo, el sistema de compilación busca el módulo con la etiqueta <name> en la lista de directorios a los que hace referencia la variable NDK_MODULE_PATH del entorno e incluye automáticamente el archivo Android.mk.