Android.mk

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

Geral

O arquivo Android.mk fica em um subdiretório do diretório jni/ do projeto e descreve as bibliotecas compartilhadas e fontes 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 que o Application.mk (o sistema de compilação) e as variáveis de ambiente deixam indefinidas em todo o projeto. 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 fontes em módulos. Um módulo pode ser uma biblioteca estática, uma biblioteca compartilhada 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-fonte 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 principais nem as dependências explícitas entre os arquivos gerados em Android.mk. O sistema de compilação do NDK calcula essas relações automaticamente. Como resultado, você poderá se beneficiar da compatibilidade com novas cadeias de ferramentas/plataformas nas versões futuras do NDK sem precisar modificar o arquivo Android.mk.

A sintaxe desse arquivo é muito parecida com a 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.

Primeiro, o arquivo Android.mk precisa definir a variável LOCAL_PATH:

LOCAL_PATH := $(call my-dir)
    

Essa variável indica o local dos arquivos-fonte na árvore de desenvolvimento. Aqui, a função de macro my-dir, fornecida pelo sistema de compilação, retorna o caminho da pasta 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 do GNU que apaga muitas variáveis LOCAL_XXX para você, como LOCAL_MODULE, LOCAL_SRC_FILES e LOCAL_STATIC_LIBRARIES. No entanto, ele não apaga LOCAL_PATH. Essa variável precisa manter o valor dela, 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 de biblioteca compartilhada final, ele adiciona automaticamente o prefixo e o sufixo adequado ao nome que você atribuir a LOCAL_MODULE. Por exemplo, o arquivo acima gera uma biblioteca chamada libhello-jni.so.

A linha a seguir enumera os arquivos-fonte, 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á criado e de que forma.

Há mais exemplos complexos nos diretórios 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, 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 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 "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_EXECUTABLE

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 criar um executável de destino a partir das fontes listadas. Para usar esse script, você precisa já ter 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_EXECUTABLE)
    

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. Para usar esse script, você precisa já ter 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 criar uma biblioteca estática. O sistema de compilação não copia bibliotecas estáticas no seu projeto/pacotes, mas pode usá-las para criar 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 a extensão .a.

PREBUILT_SHARED_LIBRARY

Aponta para um script de compilação usado para especificar uma biblioteca compartilhada criada previamente. Ao contrário de BUILD_SHARED_LIBRARY e BUILD_STATIC_LIBRARY, o valor de LOCAL_SRC_FILES não pode ser um arquivo-fonte. Em vez disso, ele precisa ser um caminho único para uma biblioteca compartilhada criada previamente, 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 ele 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 poderá 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 plataformas e imagens de sistema Android correspondentes, consulte APIs nativas do Android NDK. O exemplo a seguir mostra a sintaxe para usar esta 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 da ABI e do nível de API do Android escolhido. Esse valor é útil para fazer testes com uma imagem do sistema específica 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 vários módulos.

LOCAL_MODULE

Essa variável armazena o nome do módulo. Ele precisa ser único entre todos os nomes de módulos e não pode conter espaços. É necessário defini-lo antes de incluir qualquer script (exceto o de CLEAR_VARS). Não é necessário adicionar o prefixo lib nem a extensão de arquivo .so ou .a. O sistema de compilação faz essas modificações automaticamente. Nos arquivos Android.mk e Application.mk, consulte o 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 outro nome a ele.

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, será possível 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.

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 transmite 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 móvel.

LOCAL_CPP_EXTENSION

Use essa variável opcional para indicar uma extensão de arquivo diferente de .cpp para os arquivos-fonte em C++. Por exemplo, a linha a seguir 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. É recomendável 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 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 de tipo em tempo de execução (RTTI, na sigla em inglês), programe:

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 relativos ao diretório root do NDK, a fim de adicioná-los ao caminho de busca 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 mude o nível de otimização/depuração no arquivo Android.mk. O sistema de compilação pode processar essa configuração automaticamente 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á transmitido somente ao criar arquivos-fonte em 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 das outras sinalizações do vinculador para uso na criação da biblioteca compartilhada ou do executável. Com ela, é possível usar o prefixo -l para transmitir o nome das bibliotecas específicas do sistema. Por exemplo, o exemplo a seguir solicita que o vinculador gere um módulo que seja 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 criar a biblioteca compartilhada ou o executável. Por exemplo, para usar o vinculador ld.bfd em ARM/X86, faça o seguinte:

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 ambiente de 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 de comprimento e está vinculada às bibliotecas STL no diretório 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
    

Também é possível instruir o sistema de compilação a criar somente arquivos-fonte específicos no modo arm anexando o sufixo .arm ao nome dos arquivos-fonte. Por exemplo, o exemplo a seguir solicita que o sistema de compilação sempre crie 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 é importante apenas quando o destino é a ABI armeabi-v7a. Com ela, é possível usar intrínsecos do compilador ARM Advanced SIMD (NEON) nos arquivos-fonte 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.

Como alternativa, é possível usar o sufixo .neon para determinar que o sistema compile apenas arquivos-fonte específicos compatíveis com NEON. No exemplo a seguir, o sistema de compilação cria 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 precisa preceder .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 os 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 transmite as sinalizações -DFOO=1 e -DBAR=2 ao compilador durante a criação de bar.c. Ele também adiciona as sinalizações exportadas ao LOCAL_CFLAGS no módulo para que você possa modificá-las com facilidade.

Além disso, a relação entre módulos é transitiva: se zoo depende de bar, que por sua vez depende de foo, zoo também herda todas as sinalizações exportadas de foo.

Por fim, o sistema de compilação não usa sinalizações exportadas em criações locais (ou seja, ao criar o módulo que tem as sinalizações exportadas). Portanto, no exemplo acima, -DFOO=1 não é transmitido ao compilador durante a criação de foo/foo.c. Para criar 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. Por exemplo, ela é útil em casos em que bar.c precise 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 transmitir 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 de compilação 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.

Essa variável normalmente é útil quando o foo do módulo é 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 ao criar 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 compactados 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-fonte individuais, colocando quase todas as sinalizações do compilador dentro dos arquivos de lista também.

Qualquer valor diferente de true voltará ao 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 o build mais lento.

LOCAL_THIN_ARCHIVE

Defina essa variável como true ao criar 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 pela 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-fonte 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 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 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 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)
    

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 de my-dir define LOCAL_PATH como $PATH/foo, e 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

Essa variável 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 fonte 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

Uma 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 a que a variável de ambiente NDK_MODULE_PATH faz referência e inclui o arquivo Android.mk automaticamente.