Android.mk

Esta página descreve a sintaxe do arquivo de compilação Android.mk usado pelo ndk-build.

Visão geral

O arquivo Android.mk fica em um subdiretório do diretório jni/ do projeto e descreve as bibliotecas compartilhadas e origens para o sistema de compilação. Ele é um pequeno fragmento do makefile 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 de ambiente deixam indefinidas. Ele também pode modificar as configurações em todo o projeto para módulos específicos.

A sintaxe do Android.mk permite agrupar as origens em módulos. Um módulo pode ser uma biblioteca estática, uma biblioteca compartilhada ou um executável autônomo. Você pode definir um ou mais módulos em cada arquivo Android.mk e usar o mesmo arquivo de origem em vários módulos. O sistema de compilação só inclui bibliotecas compartilhadas no pacote do app. Além disso, bibliotecas estáticas podem gerar bibliotecas compartilhadas.

Além do empacotamento de bibliotecas, o sistema de compilação gerencia diversos outros detalhes. Por exemplo, não é necessário listar os arquivos de cabeçalho nem as dependências explícitas entre os arquivos gerados no arquivo Android.mk. O sistema de compilação do NDK calcula essas relações automaticamente. Consequentemente, você poderá se beneficiar da compatibilidade com novos conjuntos de ferramentas/plataformas nas versões futuras do NDK, sem precisar alterar o arquivo Android.mk.

A sintaxe desse arquivo é muito parecida com a que é usada nos arquivos Android.mk, distribuídos com o Android Open Source Project completo. Embora a implementação do sistema de compilação que usa esses arquivos seja diferente, a similaridade entre eles é uma decisão de projeto intencional que visa permitir que os desenvolvedores de apps reutilizem códigos-fonte para bibliotecas externas com mais facilidade.

Noções básicas

Antes de analisar a sintaxe mais detalhadamente, é interessante entender primeiro os fundamentos do conteúdo de um arquivo Android.mk. Esta seção usa o arquivo Android.mk na amostra Hello-JNI com essa finalidade, explicando a função de cada linha do arquivo.

Primeiramente, o arquivo Android.mk precisa definir 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 da macro my-dir, fornecida pelo sistema de compilação, retorna o caminho do diretório atual (que contém o próprio arquivo Android.mk).

A linha a seguir declara a variável CLEAR_VARS, que tem o valor definido pelo sistema de compilação.

include $(CLEAR_VARS)
    

A variável CLEAR_VARS aponta para um Makefile especial do GNU que limpa muitas variáveis LOCAL_XXX, como LOCAL_MODULE, LOCAL_SRC_FILES e LOCAL_STATIC_LIBRARIES. Ela não limpa LOCAL_PATH. Essa variável precisa manter o valor, porque o sistema analisa todos os arquivos de controle de compilação em um único contexto de execução do GNU Make, em que todas as variáveis são globais. É necessário declarar novamente essa variável antes de descrever cada módulo.

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

LOCAL_MODULE := hello-jni
    

O nome de cada módulo precisa ser único e não pode conter espaços. Quando o sistema de compilação gera o arquivo final da biblioteca compartilhada, ele adiciona automaticamente o prefixo e o sufixo adequados ao nome que você atribui a LOCAL_MODULE. O exemplo que aparece acima resulta na geração de uma biblioteca chamada libhello-jni.so.

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

LOCAL_SRC_FILES := hello-jni.c
    

A variável LOCAL_SRC_FILES precisa conter uma lista de arquivos de origem C e/ou C++ que serão compilados em um módulo.

A última linha 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 determina o que será compilado e de que forma.

Há exemplos mais complexos nos diretórios de amostras, com arquivos Android.mk comentados que você pode conferir. Além disso, Sample: native-activity fornece uma explicação detalhada desse arquivo Android.mk da amostra. Por fim, a seção Variáveis e macros traz ainda mais informações sobre as variáveis desta seção.

Variáveis e macros

O sistema de compilação oferece muitas variáveis que podem ser usadas no arquivo Android.mk. Muitas dessas variáveis têm valores pré-atribuídos. As demais variáveis são definidas por você.

Além dessas variáveis, você também pode definir as próprias variáveis arbitrárias. Se você 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 usa essas opções internamente
  • Nomes em letras minúsculas, como my-dir. O sistema de compilação usa essas opções internamente

Se precisar definir as próprias variáveis de conveniência em um arquivo Android.mk, recomendamos que você use o prefixo MY_ nos nomes.

Variáveis "include" definidas pelo NDK

Esta seção discute as variáveis do GNU Make que o sistema de compilação define antes de analisar o arquivo Android.mk. Em determinadas circunstâncias, o NDK pode analisar seu arquivo Android.mk várias 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 remove a definição de praticamente todas as variáveis LOCAL_XXX listadas na seção “Variáveis definidas por desenvolvedor” abaixo. Use essa variável para incluir esse script antes de descrever um novo módulo. A sintaxe para usar essa variável é a seguinte:

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 uma biblioteca compartilhada de destino a partir das fontes listadas. O uso desse script exige que você já tenha atribuído valores a pelo menos LOCAL_MODULE e LOCAL_SRC_FILES. Para mais informações sobre essas variáveis, consulte Variáveis de descrição de módulo).

A sintaxe para usar essa variável é a seguinte:

include $(BUILD_SHARED_LIBRARY)
    

Uma variável de biblioteca compartilhada 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 usada para compilar uma biblioteca estática. O sistema de compilação não copia bibliotecas estáticas no 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 é a seguinte:

include $(BUILD_STATIC_LIBRARY)
    

Uma variável de biblioteca estática 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 de BUILD_SHARED_LIBRARY e BUILD_STATIC_LIBRARY, o valor de LOCAL_SRC_FILES não pode ser um arquivo de origem. Em vez disso, ele precisa ser um caminho único para uma biblioteca compartilhada pré-compilada, como foo/libfoo.so. A sintaxe para usar essa variável é a seguinte:

include $(PREBUILT_SHARED_LIBRARY)
    

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

PREBUILT_STATIC_LIBRARY

Essa variável é igual à PREBUILT_SHARED_LIBRARY, mas destina-se a uma biblioteca estática pré-compilada. Para mais informações sobre como usar bibliotecas pré-compiladas, consulte Usar bibliotecas pré-compiladas.

Variáveis de informação de destino

O sistema de compilação analisa Android.mk uma vez de acordo com a ABI especificada pela variável APP_ABI, que geralmente é definida no arquivo Application.mk. Se APP_ABI for all, o sistema de compilação analisará Android.mk uma vez de acordo com a ABI compatível com o NDK. Esta seção descreve as variáveis que o sistema de compilação define cada vez que analisa Android.mk.

TARGET_ARCH

A família de CPU que o sistema de compilação tem como alvo ao analisar o arquivo Android.mk. Essa variável será arm, arm64, x86 ou x86_64.

TARGET_PLATFORM

O número do nível da API do Android que o sistema de compilação tem como alvo ao analisar o arquivo Android.mk. Por exemplo, as imagens do sistema Android 5.1 correspondem ao nível 22 da API do Android: android-22. Para ver a lista completa de nomes de plataforma e imagens de sistema Android correspondentes, consulte APIs nativas do Android NDK. Os exemplos a seguir mostram a sintaxe para usar essa variável:

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

TARGET_ARCH_ABI

A ABI que o sistema de compilação tem como alvo ao analisar o arquivo Android.mk. A tabela 1 mostra a configuração de ABI usada para cada CPU e arquitetura compatíveis.

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

CPU e arquitetura Configuração
ARMv7 armeabi-v7a
ARMv8 AArch64 arm64-v8a
i867 x86
x86-64 x86_64

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

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

Para 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 API do Android 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 selecionar um dispositivo ARM de 64 bits com uma API de nível 22 do Android:

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

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

As variáveis desta seção descrevem seu módulo para o sistema de compilação. As descrições de cada módulo seguem este fluxo básico:

  1. Inicializar ou remover 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)
    

CLEAR_VARS aponta para um script que não limpa 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 precisa ser único dentre todos os nomes de módulos e não pode conter espaços. É necessário defini-lo antes de incluir scripts (exceto o de CLEAR_VARS). Não é necessário adicionar o prefixo lib nem as extensões de arquivo .so ou .a. O sistema de compilação faz essas modificações automaticamente. Nos arquivos Android.mk e Application.mk, refira-se ao módulo pelo nome não modificado dele. Por exemplo, a linha a seguir gera um módulo de biblioteca compartilhada chamado libfoo.so:

LOCAL_MODULE := "foo"
    

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

LOCAL_MODULE_FILENAME

Com essa variável opcional, é possível modificar os nomes que o sistema de compilação usa por padrão nos arquivos que ele gera. Por exemplo, se o nome de LOCAL_MODULE for foo, você poderá forçar o sistema a chamar o arquivo gerado 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.

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 calcula automaticamente quaisquer dependências associadas. Você pode usar os caminhos de arquivo relativo (para LOCAL_PATH) e absoluto.

É recomendável evitar caminhos de arquivo absolutos. Os caminhos relativos tornam o arquivo Android.mk mais portáteis.

LOCAL_CPP_EXTENSION

Use essa variável opcional para indicar uma extensão de arquivo diferente de .cpp para os arquivos de origem C++. Por exemplo, a linha abaixo altera a extensão para .cxx. A configuração precisa incluir o ponto.

LOCAL_CPP_EXTENSION := .cxx
    

É possível usar essa variável para especificar várias extensões. Por exemplo:

LOCAL_CPP_EXTENSION := .cxx .cpp .cc
    

LOCAL_CPP_FEATURES

Use essa variável opcional para indicar que o código depende de recursos C++ específicos. Ela ativa o compilador correto e as sinalizações do vinculador durante o processo de compilação. Para binários pré-compilados, essa variável também declara quais são os recursos de que o binário depende, o que ajuda no funcionamento correto da vinculação final. Recomendamos que você use essa variável em vez de ativar -frtti e -fexceptions diretamente na sua definição LOCAL_CPPFLAGS.

Ao usá-la, o sistema de compilação pode usar as sinalizações adequadas para cada módulo. O uso de LOCAL_CPPFLAGS faz o compilador utilizar todas as sinalizações especificadas para todos os módulos, independentemente da necessidade real.

Por exemplo, para indicar que seu código usa Informações do tipo de dado no momento da execução (RTTI, na sigla em inglês), escreva:

LOCAL_CPP_FEATURES := rtti
    

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

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 afeta o resultado.

LOCAL_C_INCLUDES

Use essa variável opcional para especificar uma lista de caminhos (com relação ao diretório root do NDK), a fim de adicioná-los ao caminho de pesquisa de inclusão ao compilar todas as fontes (C, C++ e Assembly). Por exemplo:

LOCAL_C_INCLUDES := sources/foo
    

Outra possibilidade:

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

Defina essa variável antes de configurar qualquer sinalização de inclusão correspondente por meio de 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 as sinalizações do compilador do sistema de compilação passem ao compilar arquivos de origem C e C++. Esse recurso pode ser útil para especificar outras definições de macro ou opções de compilação. Use LOCAL_CPPFLAGS para especificar sinalizações somente para C++.

Não altere o nível de otimização/depuração no arquivo Android.mk. O sistema de compilação pode gerenciar essa configuração automaticamente para você, usando as informações relevantes no arquivo [application.mk]. Dessa forma, o sistema de compilação pode gerar arquivos de dados úteis usados durante a depuração.

Para especificar caminhos de inclusão adicionais, escreva:

LOCAL_CFLAGS += -I<path>,
    

No entanto, é melhor usar LOCAL_C_INCLUDES para esse fim. Dessa forma, também é possível usar os caminhos disponíveis para depuração nativa com o ndk-gdb.

LOCAL_CPPFLAGS

Um conjunto opcional de sinalizações de compilador que serão passados somente ao compilar arquivos de origem C++. Elas aparecerão depois de LOCAL_CFLAGS na linha de comando do compilador. Use LOCAL_CFLAGS para especificar sinalizações para C e C++.

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á a vinculação dessas bibliotecas ao binário resultante.

Se o módulo atual for uma biblioteca estática, essa variável apenas 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 no momento da 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 precisa tratar os módulos de biblioteca associados como arquivos inteiros. Para saber mais sobre arquivos inteiros, consulte a documentação do GNU ld na seção referente à sinalização --whole-archive.

Essa variável é útil quando há dependências circulares entre várias 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 à geração de executáveis.

LOCAL_LDLIBS

Essa variável contém a lista de sinalizações adicionais do vinculador para uso na compilação da biblioteca compartilhada ou do executável. Com ela, é possível usar o prefixo -l para passar o nome das bibliotecas específicas do sistema. O exemplo a seguir solicita que o vinculador gere um módulo vinculado a /system/lib/libz.so no tempo de carregamento:

LOCAL_LDLIBS := -lz
    

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

LOCAL_LDFLAGS

Essa é a lista de outras sinalizações do vinculador que o sistema de compilação pode usar para compilar a biblioteca compartilhada ou o executável. Por exemplo, para usar o vinculador ld.bfd em ARM/X86:

LOCAL_LDFLAGS += -fuse-ld=bfd
    

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 gera um erro de símbolo indefinido. Esse erro pode ajudar você a identificar bugs no código-fonte.

Para desativar essa verificação, defina essa variável como true. Essa configuração pode fazer a biblioteca compartilhada carregar no momento da execução.

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 e está vinculada às bibliotecas STL no diretório thumb/. A definição dessa 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
    

Também é possível 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. O exemplo a seguir solicita que o sistema de compilação sempre compile bar.c em modo ARM e foo.c de acordo com o valor de LOCAL_ARM_MODE.

LOCAL_SRC_FILES := foo.c bar.c.arm
    

LOCAL_ARM_NEON

Essa variável só é importante quando o alvo é a ABI armeabi-v7a. Com ela, é possível usar intrínsecos do compilador ARM Advanced SIMD (NEON) nos arquivos de origem C e C++, assim como instruções do NEON em arquivos Assembly.

Nem todas as CPUs baseadas em ARMv7 são compatíveis com extensões de conjunto de instruções NEON. Por esse motivo, é necessário fazer a detecção no momento da execução para usar esse código no momento da execução com segurança. Para mais informações, consulte Compatibilidade com NEON e a biblioteca cpufeatures.

Outra alternativa é usar o sufixo .neon para determinar que o sistema de compilação só compilará arquivos de origem específicos compatíveis com NEON. No exemplo a seguir, o sistema compila foo.c compatível com Thumb e Neon, bar.c compatível com Thumb e zoo.c compatível com ARM e NEON:

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

Se você usar os dois sufixos, .arm terá precedência sobre .neon.

LOCAL_DISABLE_FORMAT_STRING_CHECKS

Por padrão, o sistema compila código com proteção da string de formato. Isso forçará 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 sinalizações de compilador C/C++ a serem adicionadas à definição de LOCAL_CFLAGS de qualquer outro módulo que use esse conjunto por meio das variáveis LOCAL_STATIC_LIBRARIES ou LOCAL_SHARED_LIBRARIES.

Por exemplo, considere o par de módulos foo e bar, que depende 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 as sinalizações -DFOO=1 e -DBAR=2 para o compilador durante a compilação de bar.c. Ele também adiciona as sinalizações exportadas ao início de LOCAL_CFLAGS no módulo para que você possa modificá-las com facilidade.

Além disso, o relacionamento entre os módulos é transitivo: se zoo depender de bar que, por sua vez, depende de foo, zoo também herdará todas as sinalizações exportadas de foo.

Por fim, o sistema de compilação não usa sinalizações exportadas ao compilar localmente (ou seja, ao compilar o módulo que tem as sinalizações exportadas). Portanto, no exemplo acima, -DFOO=1 não é passado para o compilador durante a compilação de foo/foo.c. Para compilar localmente, use LOCAL_CFLAGS.

LOCAL_EXPORT_CPPFLAGS

Essa variável é igual à LOCAL_EXPORT_CFLAGS, mas destina-se apenas a sinalizações C++.

LOCAL_EXPORT_C_INCLUDES

Essa variável é igual à LOCAL_EXPORT_CFLAGS, mas destina-se a caminhos de inclusão C. Ela é útil nos casos em que bar.c precisa incluir cabeçalhos do módulo foo.

LOCAL_EXPORT_LDFLAGS

Essa variável é igual à LOCAL_EXPORT_CFLAGS, mas destina-se a sinalizações do vinculador.

LOCAL_EXPORT_LDLIBS

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

O sistema acrescenta sinalizações importadas do vinculador ao valor da variável LOCAL_LDLIBS do módulo. Isso ocorre devido à maneira como os vinculadores Unix funcionam.

Em geral, essa variável é útil quando o módulo foo é uma biblioteca estática e tem código que depende de uma biblioteca do sistema. É possível 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. Isso informa ao vinculador que, como libbar.so depende de foo, ele 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, o sistema de compilação é forçado a usar a sintaxe @ para arquivos que contêm arquivos de objeto ou bibliotecas de vinculação intermediários.

Esse recurso pode ser útil no Windows, em que a linha de comando aceita apenas 8.191 caracteres no máximo, o que pode ser insuficiente para projetos complexos. Ele também influencia a compilação de arquivos de origem individuais, colocando quase todas as sinalizações do compilador dentro dos arquivos de lista também.

Qualquer valor diferente de true reativará o comportamento padrão. Também é possível 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 recurso 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 ele conteria normalmente.

Isso é útil para reduzir o tamanho do resultado da compilação. A desvantagem dessas bibliotecas é que elas 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. É possível definir um valor padrão no arquivo Application.mk por meio da variável APP_THIN_ARCHIVE.

LOCAL_FILTER_ASM

Defina essa variável como um comando de shell que o sistema de compilação usará para filtrar os arquivos Assembly extraídos ou gerados a partir dos arquivos que você especificou para LOCAL_SRC_FILES. A definição dessa variável tem as seguintes consequências:

  1. O sistema de compilação gera um arquivo Assembly temporário a partir de qualquer arquivo de origem 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 qualquer arquivo Assembly temporário e em qualquer 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 precisa ser um comando de shell autônomo que recebe o nome do arquivo de entrada como o 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 fornecidas pelo NDK

Esta seção explica as macros de função do GNU Make que o NDK fornece. Use $(call <function>) para avaliá-las. Elas retornarão informações textuais.

my-dir

Essa macro retorna o caminho do último makefile incluído, que normalmente é o diretório atual do Android.mk. my-dir é usado para definir LOCAL_PATH no começo do arquivo Android.mk. Por exemplo:

LOCAL_PATH := $(call my-dir)
    

Devido à forma como o GNU Make funciona, essa macro retorna, na verdade, o caminho do último makefile que o sistema de compilação incluiu ao analisar os scripts de compilação. Por esse motivo, não chame my-dir depois de incluir outro arquivo.

Veja o exemplo a seguir:

LOCAL_PATH := $(call my-dir)

    # ... declare one module

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

    LOCAL_PATH := $(call my-dir)

    # ... declare another module
    

O problema é que a segunda chamada para my-dir define LOCAL_PATH como $PATH/foo, não como $PATH, porque esse era o local indicado pela 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 dessa forma, 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 todos os subdiretórios do caminho do my-dir atual.

Use essa função para fornecer hierarquias de diretório de origem com vários níveis ao sistema de compilação. Por padrão, o NDK só busca arquivos no diretório que contêm o arquivo Android.mk.

this-makefile

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

parent-makefile

Retorna o caminho do makefile pai na árvore de inclusão (o caminho do makefile que incluiu o atual).

grand-parent-makefile

Retorna o caminho do makefile avô na árvore de inclusão (o caminho do makefile que incluiu o atual).

import-module

Função que permite encontrar e incluir o arquivo Android.mk de um módulo pelo nome do módulo. Veja a seguir um exemplo comum:

$(call import-module,<name>)
    

Nesse exemplo, o sistema de compilação busca o módulo sinalizado com <name> na lista de diretórios mencionada pela variável de ambiente NDK_MODULE_PATH e inclui o arquivo Android.mk de forma automática.