Android.mk

Esta página descreve a sintaxe do arquivo de compilação Android.mk, que liga seus arquivos C e C++ de origem ao Android NDK.

Visão geral

O arquivo Android.mk fica em um subdiretório do diretório jni/ do projeto e descreve as bibliotecas de origem e as compartilhadas para o sistema de compilação. É um fragmento de makefile minúsculo do GNU que o sistema de compilação analisa uma vez ou mais. O arquivo Android.mk é útil para definir configurações em todo o projeto que o Application.mk, o sistema de compilação, e as variáveis do seu ambiente deixam indefinidas. Ele também pode modificar as configurações para todo o projeto para módulos específicos.

A sintaxe do Android.mk permite agrupar as fontes em módulos. Um módulo pode ser uma biblioteca estática, uma biblioteca compartilhável ou um executável autônomo. É possível definir um ou mais módulos em cada arquivo Android.mk, e você pode usar o mesmo arquivo de origem em diversos módulos. O sistema de compilação só coloca bibliotecas compartilhadas no pacote do seu aplicativo. Além disso, bibliotecas estáticas podem gerar bibliotecas compartilhadas.

Além de empacotar bibliotecas, o sistema de compilação gerencia diversos outros detalhes para você. Por exemplo, você não precisa listar arquivos de cabeçalho nem explicitar dependências entre arquivos gerados no arquivo Android.mk. O sistema de compilação do NDK computa essas relações automaticamente para você. Como resultado, você deve poder se beneficiar da nova compatibilidade de cadeia de ferramentas/plataforma nas versões futuras do NDK sem precisar tocar no arquivo Android.mk.

A sintaxe desse arquivo é muito parecida com a usada nos arquivos Android.mk distribuídos com o Projeto Android de código aberto completo. Apesar de a implementação do sistema de compilação que os usa ser diferente, a similaridade entre eles é uma decisão de projeto intencional que visa facilitar para os desenvolvedores de aplicativos a reutilização de código-fonte para bibliotecas externas.

Conceitos básicos

Antes de explorar a sintaxe em detalhe, vale a pena começar entendendo os fundamentos do que um arquivo Android.mk contém. Esta seção usa o arquivo Android.mk no exemplo do Hello-JNI com essa finalidade, explicando a função de cada linha do arquivo.

Um arquivo Android.mk deve começar definindo a variável LOCAL_PATH:

LOCAL_PATH := $(call my-dir)

Essa variável indica o local dos arquivos de origem na árvore de desenvolvimento. Aqui, a função macro my-dir, fornecida pelo sistema de compilação, retorna o caminho da pasta atual (a pasta contendo o próprio arquivo Android.mk).

A linha a seguir declara a variável CLEAR_VARS, cujo valor é fornecido pelo sistema de compilação.

include $(CLEAR_VARS)

A variável CLEAR_VARS aponta para um Makefile do GNU que apaga muitas variáveis LOCAL_XXX para você, como LOCAL_MODULE, LOCAL_SRC_FILES e LOCAL_STATIC_LIBRARIES. Observe que ele não apaga a LOCAL_PATH. Essa variável deve reter seu valor porque o sistema analisa todos os arquivos de controle de compilação em um único contexto de execução do Makefile do GNU, em que todas as variáveis são globais. Você deve (re)declarar essa variável antes de descrever cada módulo.

Em seguida, a variável LOCAL_MODULE armazena o nome do módulo que você deseja compilar. Use essa variável uma vez por módulo no seu aplicativo.

LOCAL_MODULE := hello-jni

Cada nome de módulo deve ser único e não pode conter espaços. O sistema de compilação, quando gera o arquivo shared-library final, automaticamente adiciona o prefixo e o sufixo adequados ao nome que você atribuir a LOCAL_MODULE. Por exemplo, o exemplo acima é resultado da geração de uma biblioteca chamada libhello-jni.so.

Observação: Se o nome do seu módulo já começa com lib, o sistema de compilação não precede um prefixo lib adicional, ele assume o nome do módulo da forma que está e adiciona a extensão .so. Assim, um arquivo de origem originalmente chamado, por exemplo, libfoo.c, ainda produz um arquivo de objeto compartilhado chamado libfoo.so. Esse comportamento visa oferecer compatibilidade com bibliotecas que as fontes da plataforma Android gera a partir dos arquivos Android.mk. O nome de todas essas bibliotecas começa com lib.

A linha seguinte enumera os arquivos de origem, com espaços delimitando diversos arquivos:

LOCAL_SRC_FILES := hello-jni.c

A variável LOCAL_SRC_FILES deve conter uma lista de arquivos de origem em C e/ou C++ para compilar em um módulo.

A última alinha ajuda o sistema a juntar tudo:

include $(BUILD_SHARED_LIBRARY)

A variável BUILD_SHARED_LIBRARY aponta para um script do Makefile do GNU, que coleta todas as informações definidas nas variáveis LOCAL_XXX desde o include mais recente. Esse script determinar o que compilar e como.

Há mais exemplos complexos nas pastas de exemplos, com arquivos Android.mk comentados que você pode conferir. Além disso, Exemplo: native-activity fornece uma explicação detalhada desse exemplo de arquivo Android.mk. Por fim, Variáveis e macros fornece ainda mais informações sobre as variáveis desta seção.

Variáveis e macros

O sistema de compilação fornece muitas variáveis possíveis para usar no arquivo Android.mk. Muitas dessas variáveis vêm com valores pré-atribuídos. Os outras é você que atribui.

Além dessas variáveis, você também pode definir suas próprias variáveis arbitrárias. Se fizer isso, lembre-se de que o sistema de compilação do NDK reserva os seguintes nomes de variável:

  • Nomes que começam com LOCAL_, como LOCAL_MODULE.
  • Nomes que começam com PRIVATE_, NDK_ ou APP. O sistema de compilação os usa internamente.
  • Nomes em letras minúsculas, como my-dir. O sistema de compilação os usa internamente também.

Se for necessário definir suas próprias variáveis de conveniência em um arquivo Android.mk, recomendamos usar o prefixo MY_ nos nomes.

Variáveis definidas pelo NDK

Esta seção discute as variáveis do GNU Make que o sistema de compilação definem antes de analisar o arquivo Android.mk. Em determinadas circunstâncias, o NDK pode analisar seu arquivo Android.mk diversas vezes, usando uma definição diferente para algumas dessas variáveis a cada vez.

CLEAR_VARS

Essa variável aponta para um script de compilação que retira a definição de praticamente todas as variáveis LOCAL_XXX listadas na seção “Variáveis definidas pelo desenvolvedor” abaixo. Use essa variável para incluir este script antes de descrever um novo módulo. A sintaxe de uso é:

include $(CLEAR_VARS)

BUILD_SHARED_LIBRARY

Essa variável aponta para um script de compilação que coleta todas as informações sobre o módulo que você forneceu nas variáveis LOCAL_XXX e determina como compilar determinada biblioteca de compartilhamento das fontes que você listou. Observe que usar esse script exige que você já tenha valores atribuídos, no mínimo, a LOCAL_MODULE e LOCAL_SRC_FILES (para obter mais informações sobre essas variáveis, consulte Variáveis de descrição de módulo).

A sintaxe para usar essa variável é:

include $(BUILD_SHARED_LIBRARY)

Uma variável shared-library faz o sistema de compilação gerar um arquivo de biblioteca com uma extensão .so.

BUILD_STATIC_LIBRARY

Uma variante de BUILD_SHARED_LIBRARY que seja usada para compilar uma biblioteca estática. O sistema de compilação não copia bibliotecas estáticas para o seu projeto/pacotes, mas pode usá-las para compilar bibliotecas compartilhadas (veja LOCAL_STATIC_LIBRARIES e LOCAL_WHOLE_STATIC_LIBRARIES abaixo). A sintaxe para usar essa variável é:

include $(BUILD_STATIC_LIBRARY)

Uma variável static-library faz o sistema de compilação gerar uma biblioteca com uma extensão .a.

PREBUILT_SHARED_LIBRARY

Aponta para um script de compilação usado para especificar uma biblioteca compartilhada pré-compilada. Ao contrário do caso de BUILD_SHARED_LIBRARY e BUILD_STATIC_LIBRARY, aqui, o valor de LOCAL_SRC_FILES não pode ser um arquivo de origem. Em vez disso, ele precisa ser um caminho exclusivo a uma biblioteca compartilhada pré-compilada, como foo/libfoo.so. A sintaxe para usar essa variável é:

include $(PREBUILT_SHARED_LIBRARY)

Você também pode referenciar uma biblioteca pré-compilada em outro módulo usando a variável LOCAL_PREBUILTS. Para obter mais informações sobre como usar pré-compilados, consulte Usar bibliotecas pré-compiladas.

PREBUILT_STATIC_LIBRARY

Igual a PREBUILT_SHARED_LIBRARY, mas para uma biblioteca estática pré-compilada. Para obter mais informações sobre como usar pré-compilados, consulte Usar bibliotecas pré-compiladas.

TARGET_ARCH

O nome da arquitetura do CPU em questão da forma que o Projeto Android de código aberto a especifica. Para qualquer compilação compatível com ARM, use arm, independentemente da revisão da arquitetura do CPU ou da ABI (veja TARGET_ARCH_ABI abaixo).

O valor dessa variável é obtido na variável APP_ABI, que você define no arquivo Android.mk, que o sistema lê antes de analisar o arquivo Android.mk.

TARGET_PLATFORM

O número do nível da Android API a que o sistema de compilação deve se direcionar. Por exemplo, as imagens do sistema do Android 5.1 correspondem à Android API de nível 22: android-22. Para obter uma lista completa de nomes de plataforma e imagens de sistema Android correspondentes, consulte APIs nativas do Android NDK. O exemplo a seguir mostra a sintaxe para usar essa variável:

TARGET_PLATFORM := android-22

TARGET_ARCH_ABI

Essa variável armazena o nome do CPU e da arquitetura visados quando o sistema de compilação analisa esse arquivo Android.mk. É possível especificar um ou mais dos valores a seguir usando um espaço como delimitador entre diversos alvos. A tabela 1 mostra a configuração de ABI a usar para cada CPU e arquitetura compatíveis.

Tabela 1. Configurações de ABI para diferentes CPUs e arquiteturas.

CPU e arquitetura Configuração
ARMv5TE armeabi
ARMv7 armeabi-v7a
ARMv8 AArch64 arm64-v8a
i686 x86
x86-64 x86_64
mips32 (r1) mips
mips64 (r6) mips64
Todos all

O exemplo a seguir mostra como definir ARMv8 AArch64 como a combinação de CPU e ABI escolhida:

TARGET_ARCH_ABI := arm64-v8a

Observação: Até o Android NK 1.6_r1, essa variável é definida como arm.

Para obter mais detalhes sobre ABIs de arquitetura e problemas de compatibilidade relacionados, consulte Gerenciamento de ABI.

Novas ABIs disponibilizadas no futuro terão valores diferentes.

TARGET_ABI

Uma concatenação do nível da Android API e da ABI em questão é especialmente útil quando se quer testar em uma determinada imagem do sistema de um dispositivo real. Por exemplo, para especificar um dispositivo ARM de 64 bits em execução em uma Android API de nível 22:

TARGET_ABI := android-22-arm64-v8a

Observação: Até o Android NDK 1.6_r1, o valor padrão era android-3-arm.

Variáveis de descrição de módulo

As variáveis desta seção descrevem seu módulo para o sistema de compilação. Cada descrição de módulo deve seguir esse fluxo básico:

    1. Inicializar ou retirar a definição das variáveis associadas ao módulo usando a variável CLEAR_VARS.
    2. Atribuir valores às variáveis usadas para descrever o módulo.
    3. Configurar o sistema de compilação do NDK para usar o script de compilação adequado para o módulo, usando a variável BUILD_XXX.

LOCAL_PATH

Essa variável é usada para fornecer o caminho do arquivo atual. É preciso defini-la no início do arquivo Android.mk. O exemplo a seguir mostra como fazê-lo:

LOCAL_PATH := $(call my-dir)

O script para o qual CLEAR_VARS aponta não apaga essa variável. Portanto, só é preciso defini-la uma única vez, mesmo que o arquivo Android.mk descreva diversos módulos.

LOCAL_MODULE

Essa variável armazena o nome do módulo. Ele deve ser exclusivo dentre todos os nomes de módulo e não pode conter espaços. É necessário defini-lo antes de incluir scripts (diferentes dos de CLEAR_VARS). Você não precisa adicionar o prefixo lib nem as extensões de arquivo .so ou .a: o sistema de compilação faz essas modificações automaticamente. Ao longo dos arquivos Android.mk e Application.mk, consulte o seu módulo pelo nome não modificado. Por exemplo, a linha a seguir produz a geração de um módulo de biblioteca compartilhada chamado libfoo.so:

LOCAL_MODULE := "foo"

Se quiser que o módulo gerado tenha um nome diferente de lib + o valor de LOCAL_MODULE, você pode usar a variável LOCAL_MODULE_FILENAME para dar a ele o nome que quiser.

LOCAL_MODULE_FILENAME

Essa variável opcional permite modificar os nomes que o sistema de compilação usa por padrão para os arquivos que gera. Por exemplo, se o nome de LOCAL_MODULE for foo, você pode forçar o sistema a chamar o arquivo que ele gera de libnewfoo. O exemplo a seguir mostra como fazer isso:

LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo

Para o módulo de uma biblioteca compartilhada, esse exemplo geraria um arquivo chamado libnewfoo.so.

Observação: Não é possível modificar o caminho nem a extensão do arquivo.

LOCAL_SRC_FILES

Essa variável contém a lista de arquivos de origem que o sistema de compilação usa para gerar o módulo. Liste somente os arquivos que o sistema de compilação realmente passa para o compilador, já que o sistema computa automaticamente eventuais dependências associadas.

Observe que você pode usar caminhos de arquivo absolutos e relativos (para LOCAL_PATH).

Recomendamos evitar caminhos de arquivo absolutos. Os caminhos relativos tornam seu arquivo Android.mk mais móvel.

Observação: sempre use barras (/) nos arquivos de compilação. O sistema de compilação não aceita contrabarras do Windows (\) adequadamente.

LOCAL_CPP_EXTENSION

Você pode usar essa variável opcional para indicar uma extensão de arquivo diferente de .cpp para os arquivos de origem em C++. Por exemplo, a linha a seguir altera a extensão para .cxx (a configuração deve incluir o ponto).

LOCAL_CPP_EXTENSION := .cxx

A partir do NDK r7, é possível usar essa variável para especificar diversas extensões. Por exemplo:

LOCAL_CPP_EXTENSION := .cxx .cpp .cc

LOCAL_CPP_FEATURES

Você pode usar essa variável opcional para indicar que o código depende de recursos C++ específicos. Ela ativa o compilador correto e os sinalizadores do vinculador durante o processo de compilação. Para binários pré-compilados, essa variável também declara de que recursos o binário depende, ajudando assim a garantir que a vinculação final funcione corretamente. Recomendamos usar essa variável em vez de ativar -frtti e -fexceptions diretamente na definição de LOCAL_CPPFLAGS.

Ao usá-la, o sistema de compilação pode usar os sinalizadores adequados para cada módulo. Usar LOCAL_CPPFLAGS faz o compilador usar todos os sinalizadores especificados para todos os módulos, independentemente da necessidade real.

Por exemplo, para indicar que seu código usa RTTI (informações de tipo RunTime), programe:

LOCAL_CPP_FEATURES := rtti

Para indicar que seu código usa exceções de C++, progame:

LOCAL_CPP_FEATURES := exceptions

Você também pode especificar diversos valores para essa variável. Por exemplo:

LOCAL_CPP_FEATURES := rtti features
A ordem de descrição dos valores não importa.

LOCAL_C_INCLUDES

Você pode usar essa variável opcional para especificar uma lista de caminhos, referente à pasta root do NDK, para adicionar ao caminho de busca de inclusão ao compilar todas as fontes (C, C++ e Assembly). Por exemplo:

LOCAL_C_INCLUDES := sources/foo

Ou até:

LOCAL_C_INCLUDES := $(LOCAL_PATH)//foo

Definir essa variável antes de configurar sinalizadores de inclusão correspondentes com LOCAL_CFLAGS ou LOCAL_CPPFLAGS.

O sistema de compilação também usa caminhos de LOCAL_C_INCLUDES automaticamente ao inicializar a depuração nativa com ndk-gdb.

LOCAL_CFLAGS

Essa variável opcional determina que os sinalizadores do compilador do sistema de compilação passem ao compilar arquivos de origem em C e C++. Esse recurso pode ser útil para especificar definições macro adicionais ou compilar opções.

Não tente alterar o nível de otimização/depuração no arquivo Android.mk. O sistema de compilação pode lidar com essa configuração automaticamente para você usando as informações relevantes do arquivo Application.mk. Fazer isso dessa forma permite ao sistema de compilação gerar arquivos de dados úteis usados durante a depuração.

Observação: No android-ndk-1.5_r1, os sinalizadores correspondentes só se aplicam a arquivos de origem em C, e não aos em C++. Agora eles têm o mesmo comportamento do sistema de compilação completo do Android (agora você pode usar LOCAL_CPPFLAGS para especificar sinalizadores somente para fontes C++).

É possível especificar caminhos de inclusão adicionais escrevendo:

LOCAL_CFLAGS += -I<path>,
No entanto, é melhor usar LOCAL_C_INCLUDES para esse fim, já que, assim, você também tornará possível usar os caminhos disponíveis para depuração nativa com o ndk-gdb.

LOCAL_CPPFLAGS

Um conjunto opcional de sinalizadores de compilador que serão passados ao somente ao compilar arquivos de origem em C++. Eles aparecerão depois de LOCAL_CFLAGS na linha de comando do compilador.

Observação: No android-ndk-1.5_r1, os sinalizadores correspondentes são aplicados às fontes C e C++. Isso foi corrigido para igualar ao sistema de compilação completo do Android. Para especificar sinalizadores para fontes C e C++, use LOCAL_CFLAGS.

LOCAL_STATIC_LIBRARIES

Essa variável armazena a lista de módulos de bibliotecas estáticas de que o módulo atual depende.

Se o módulo atual for uma biblioteca compartilhada ou um executável, essa variável forçará essas bibliotecas a se vincular ao binário resultante.

Se o módulo atual for uma biblioteca estática, essa variável simplesmente indicará que outros módulos que dependem do atual também dependerão das bibliotecas listadas.

LOCAL_SHARED_LIBRARIES

Essa variável é a lista dos módulos das bibliotecas compartilhadas de que este módulo depende em tempo de execução. Essas informações são necessárias no momento da vinculação e para incorporar as informações correspondentes ao arquivo gerado.

LOCAL_WHOLE_STATIC_LIBRARIES

Essa variável é uma variante de LOCAL_STATIC_LIBRARIES e expressa que o vinculador deve tratar os módulos de biblioteca associados como arquivos inteiros. Para saber mais sobre arquivos inteiros, consulte a documentação do vinculador do GNU quanto ao sinalizador --whole-archive.

Essa variável é útil quando há dependências circulares entre diversas bibliotecas estáticas. Ao usar essa variável para criar uma biblioteca compartilhada, ela forçará o sistema de compilação a adicionar todos os arquivos de objeto das bibliotecas estáticas ao binário final. No entanto, isso não se aplica ao se gerar executáveis.

LOCAL_LDLIBS

Essa variável contém a lista de sinalizadores adicionais do vinculador para uso na compilação da biblioteca compartilhada ou do executável. Ela permite usar o prefixo -l para passar o nome das bibliotecas específicas do sistema. Por exemplo, o exemplo a seguir comanda o vinculador a gerar um módulo que se vincule a /system/lib/libz.so em tempo de carregamento:

LOCAL_LDLIBS := -lz

Para ver a lista de bibliotecas do sistema expostas em relação às que você pode vincular a essa versão do NDK, consulte APIs nativas do Android NDK.

Observação: Se você definir essa variável para uma biblioteca estática, o sistema de compilação a ignorará e ndk-build gerará uma advertência.

LOCAL_LDFLAGS

A lista de outros sinalizadores do vinculador para o sistema de compilação usar ao compilar a biblioteca compartilhada ou o executável. Por exemplo, o exemplo a seguir usa o vinculador ld.bfd em GCC 4.6 ou posterior com ARM/X86, em que ld.gold é o padrão

LOCAL_LDFLAGS += -fuse-ld=bfd

Observação: Se você definir essa variável para uma biblioteca estática, o sistema de compilação a ignorará e o ndk-build gerará uma advertência.

LOCAL_ALLOW_UNDEFINED_SYMBOLS

Por padrão, quando o sistema de compilação encontra uma referência não definida enquanto tenta compilar uma biblioteca compartilhada, ele acionará um erro de símbolo indefinido. Esse erro pode ajudar você a identificar erros no código-fonte.

Para desativar essa verificação, defina essa variável como true. Observe que essa configuração pode fazer a biblioteca compartilhada carregar em tempo de execução.

Observação: Se você definir essa variável para uma biblioteca estática, o sistema de compilação a ignorará e o ndk-build gerará uma advertência.

LOCAL_ARM_MODE

Por padrão, o sistema de compilação gera binários de destino ARM em modo thumb, em que cada instrução tem 16 bits de comprimento e está vinculada às bibliotecas STL na pasta thumb/. Definir essa variável como arm força o sistema de compilação a gerar os arquivos de objeto do módulo em modo arm de 32 bits. O exemplo a seguir mostra como fazer isso:

LOCAL_ARM_MODE := arm

Você ainda pode instruir o sistema de compilação a compilar somente arquivos de origem específicos no modo arm anexando o sufixo .arm ao nome dos arquivos de origem. Por exemplo, o exemplo a seguir diz ao sistema de compilação para sempre compilar bar.c em modo ARM, mas para compilar foo.c de acordo com o valor de LOCAL_ARM_MODE.

LOCAL_SRC_FILES := foo.c bar.c.arm

Observação: Você também pode forçar o sistema de compilação a gerar binários ARM definindo APP_OPTIM no arquivo Application.mk como debug. Especificar debug força uma compilação de ARM porque o depurador da cadeia de ferramentas não consegue lidar com código Thumb de forma adequada.

LOCAL_ARM_NEON

Essa variável só é importante quando se está almejando a ABI armeabi-v7a. Ela permite usar intrínsecos do GCC ARM de SIMD avançado (NEON) nos arquivos de origem em C e C++, assim como instruções do NEON em arquivos Assembly.

Observe que nem todos os CPUs baseados em ARMv7 oferecem compatibilidade com extensões de conjunto de instrução NEON. Por esse motivo, voc6e deve realizar detecção em tempo de execução para poder usar esse código em tempo de execução com segurança. Para obter mais informações, consulte Compatibilidade com NEON e A biblioteca cpufeatures.

Como alternativa, você pode usar o sufixo .neon para determinar que o sistema de compilação só compilará arquivos de origem específicos com compatibilidade com NEON. No exemplo a seguir, o sistema de compilação compila foo.c compatível com thumb e neon, bar.c compatível com thumb e zoo.ccompatível com ARM e NEON:

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

Se você usar ambos os sufixos, .arm deve preceder .neon.

LOCAL_DISABLE_NO_EXECUTE

O Android NDK r4 adicionou compatibilidade com o recurso de segurança “NX bit”. Ele fica ativo por padrão, mas é possível desativá-lo definindo essa variável como true. Não recomendamos fazer isso sem um motivo relevante.

Esse recurso não modifica a ABI e só está disponível em kernels voltados a dispositivos de CPU ARMv6+. O código de máquina, com esse recurso ativado, será executado sem modificação em dispositivos que operam com arquiteturas de CPU antigas.

Para saber mais, consulte Wikipedia: NX bit e Primeiros passos com a pilha do GNU.

LOCAL_DISABLE_RELRO

Por padrão, o NDK compila código com relocações somente leitura e proteção de GOT. Essa variável instrui o vinculador de tempo de execução a marcar determinadas regiões da memória como de “somente leitura” após a relocação, tornando algumas explorações da segurança (como sobrescrever GOT) mais difíceis de ocorrer. Observe que essas proteções só funcionam na Android API de nível 16 ou em posteriores. Em APIs de nível mais baixo, o código ainda será executado, mas sem proteção de memória.

Essa variável está ativa por padrão, mas é possível desativá-la definindo seu valor como true. Não recomendamos fazer isso sem um motivo relevante.

Para obter mais informações, consulte RELRO: RELocação somente leitura e Melhorias de segurança no RedHat Enterprise Linux (seção 6).

LOCAL_DISABLE_FORMAT_STRING_CHECKS

Por padrão, o sistema de compilação compila código com proteção da string de formato. Fazer isso força um erro no compilador se uma string de formato não constante for usada em uma função de estilo printf.

Essa proteção fica ativa por padrão, mas é possível desativá-la definindo o valor dessa variável como true. Não recomendamos fazer isso sem um motivo relevante.

LOCAL_EXPORT_CFLAGS

Essa variável registra um conjunto de sinalizadores de compilador C/C++ para adicionar à definição de LOCAL_CFLAGS de outros módulos que usam esse conjunto pelas variáveis LOCAL_STATIC_LIBRARIES ou LOCAL_SHARED_LIBRARIES.

Por exemplo, considere o seguinte par de módulos: foo e bar, que dependem 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)

Aqui, o sistema de compilação passa -DFOO=1 e -DBAR=2 dos sinalizadores ao compilador ao compilar bar.c. Ele também precede sinalizadores exportados à LOCAL_CFLAGS do seu módulo, assim você pode modificá-los com facilidade.

Além disso, a relação entre os módulos é transitiva: Se zoo depende de bar que, por sua vez, depende de foo, zoo também herda todos os sinalizadores exportados de foo.

Por fim, o sistema de compilação não usa sinalizadores exportados ao compilar localmente (ou seja, compilar o módulo que exporta os sinalizadores). Portanto, no exemplo acima, não se passa -DFOO=1 para o compilador ao compilar foo/foo.c. Para compilar localmente, use LOCAL_CFLAGS.

LOCAL_EXPORT_CPPFLAGS

Essa variável é igual à LOCAL_EXPORT_CFLAGS, mas voltada somente para sinalizadores C++.

LOCAL_EXPORT_C_INCLUDES

Essa variável é igual à LOCAL_EXPORT_CFLAGS, mas para caminhos de inclusão em C. Ela é útil em casos em que, por exemplo, bar.c precise incluir cabeçalhos do módulo foo.

LOCAL_EXPORT_LDFLAGS

Essa variável é igual à LOCAL_EXPORT_CFLAGS, mas para sinalizadores de vinculador.

LOCAL_EXPORT_LDLIBS

Essa variável é igual à LOCAL_EXPORT_CFLAGS, que instrui ao sistema de compilação a passar nomes de bibliotecas específicas do sistema ao compilador. Use o prefixo -l no nome de todas as bibliotecas que você especificar.

Observe que o sistema acrescenta sinalizadores de vinculador importados ao valor da variável LOCAL_LDLIBS do módulo. Isso ocorre em virtude da forma de trabalhar dos vinculadores Unix.

Essa variável normalmente é útil quando foo do módulo é uma biblioteca estática e tem código que depende de uma biblioteca do sistema. Você pode usar LOCAL_EXPORT_LDLIBS para exportar a dependência. Por exemplo:

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)

Nesse exemplo, o sistema de compilação coloca -llog no fim do comando do vinculador quando compila libbar.so. Fazer isso diz ao vinculador que, como libbar.so depende de foo, também depende da biblioteca de registros do sistema.

LOCAL_SHORT_COMMANDS

Defina essa variável como true quando o módulo tiver um número muito alto de fontes e/ou bibliotecas compartilhadas ou estáticas dependentes. Ao fazer isso, você forçará o sistema de compilação a usar a sintaxe @ para arquivos que contêm arquivos de objeto ou bibliotecas de vinculação intermediárias.

Esse recurso pode ser útil no Windows, em que a linha de comando aceita um máximo de apenas 8191 caracteres, o que pode ser muito pouco para projetos complexos. Ele também influencia na compilação individual de arquivos de origem, colocando quase todos os sinalizadores do compilador dentro dos arquivos de lista também.

Observe que todo valor diferente de true o retornará ao comportamento padrão. Você também pode definir APP_SHORT_COMMANDS no arquivo Application.mk para forçar esse comportamento em todos os módulos do projeto.

Não recomendamos ativar esse recursos por padrão, já que ele torna a compilação mais lenta.

LOCAL_THIN_ARCHIVE

Defina essa variável como true ao compilar bibliotecas estáticas. Fazer isso gerará um arquivo dinâmico, um arquivo de biblioteca que não contém arquivos de objeto, apenas caminhos de arquivo dos objetos reais que normalmente conteria.

Isso é útil para reduzir o tamanho do resultado da compilação. Em contrapartida, essas bibliotecas não podem ser movidas para um local diferente (todos os caminhos dentro delas são relativos).

Os valores válidos são true, false ou vazio. Um valor padrão pode ser definido no arquivo Application.mk pela variável APP_THIN_ARCHIVE.

Observação: Isso é ignorado em módulos de bibliotecas não estáticas ou de bibliotecas estáticas pré-compiladas.

LOCAL_FILTER_ASM

Define essa variável como um comando de shell que o sistema de compilação usará para filtrar os arquivos assembly extraídos ou gerados pelos arquivos que você especificou para LOCAL_SRC_FILES.

Definir essa variável causa o seguinte:

    1. O sistema de compilação gera um arquivo assembly temporário a partir de qualquer arquivo de origem em C ou C++, em vez de compilá-lo em um arquivo de objeto.
    2. O sistema de compilação executa o comando de shell em LOCAL_FILTER_ASM em um arquivo assembly temporário e em um arquivo assembly listado em LOCAL_SRC_FILES, gerando, assim, outro arquivo assembly temporário.
    3. O sistema de compilação compila esses arquivos assembly filtrados em um arquivo de objeto.

Por exemplo:

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” corresponde ao compilador, “2”, ao filtro e “3” ao assembler. O filtro deve ser um comando de shell autônomo que obtém o nome do arquivo de entrada como seu primeiro argumento e o nome do arquivo de saída como o segundo. Por exemplo:

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

Macros de função fornecidos pelo NDK

Esta seção explica os macros de função do GNU Make que o NDK fornece. Use $(call <function>) para avaliá-los: eles retornam informações textuais.

my-dir

Esse marco retorna o caminho do último makefile incluído, que normalmente é a pasta do Android.mk atual. my-dir é útil para definir LOCAL_PATH no início do arquivo Android.mk. Por exemplo:

LOCAL_PATH := $(call my-dir)

Em virtude da forma de trabalhar do GNU Make, o que esse macro realmente retorna é o caminho do último makefile que o sistema de compilação incluiu ao analisar os scripts de compilação. Por esse motivo, você não deve chamar my-dir depois de incluir outro arquivo.

Por exemplo, considere o seguinte:

LOCAL_PATH := $(call my-dir)

# ... declare one module

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

LOCAL_PATH := $(call my-dir)

# ... declare another module

O problema aqui é que a segunda chamada de my-dir define LOCAL_PATH como $PATH/foo em vez de como $PATH, porque esse era o local indicado da inclusão mais recente.

É possível evitar esse problema colocando inclusões adicionais depois de tudo no arquivo Android.mk. Por exemplo:

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

Se não for viável estruturar o arquivo assim, salve o valor da primeira chamada de my-dir em outra variável. Por exemplo:

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

Retorna a lista de arquivos Android.mk localizados em todas as subpastas do caminho do my-dir atual.

Você pode usar essa função para fornecer hierarquias de diretório de origem de diversos níveis ao sistema de compilação. Por padrão, o NDK só busca arquivos na pasta que contêm o arquivo Android.mk.

this-makefile

Retorna o caminho do makefile atual (pelo qual o sistema de compilação chamou a função).

parent-makefile

Retorna o caminho do makefile um nível acima na árvore de inclusão (o caminho do makefile que incluiu o atual).

grand-parent-makefile

Retorna o caminho do makefile dois níveis acima na árvore de inclusão (o caminho do makefile que incluiu o atual).

import-module

Uma função que permite encontrar e incluir o arquivo Android.mk de um módulo pelo nome do módulo. Eis um exemplo comum:

$(call import-module,<name>)

Nesse exemplo, o sistema de compilação busca o módulo rotulado com <name> na lista de pastas referenciadas que a variável NDK_MODULE_PATH do seu ambiente referencia e inclui seu arquivo Android.mk automaticamente para você.