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 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 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 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 de origem na árvore de desenvolvimento. Aqui, a função de macro my-dir
, fornecida pelo sistema de build, retorna
o caminho da pasta atual, que contém
o 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 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á 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 fornece 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_
, comoLOCAL_MODULE
- Nomes que começam com
PRIVATE_
,NDK_
ouAPP
. O sistema de compilação usa essas opções 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 "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
criar 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 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 se destina a uma biblioteca estática pré-compilada. Para
mais informações sobre como usar pré-compilados, 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 à
API de nível 22 do Android: android-22
. Para ver uma lista completa de nomes de plataformas e
imagens de sistema Android correspondentes, consulte APIs nativas. 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.
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 ver mais detalhes sobre ABIs de arquitetura e problemas de compatibilidade relacionados, consulte ABIs do Android.
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:
- Inicializar ou remover a definição das variáveis associadas ao módulo usando a variável
CLEAR_VARS
. - Atribuir valores às variáveis usadas para descrever o módulo.
- 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 build usa para
gerar o módulo. Liste somente os arquivos que esse sistema realmente transmite
para o compilador, já que o sistema de build calcula automaticamente todas as 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 de origem 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 usar a variável, o sistema de build pode utilizar as flags 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), 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 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_ASFLAGS
Sinalizações que serão transmitidas ao Clang ao criar arquivos .s
ou .S
.
LOCAL_ASMFLAGS
Flags que serão transmitidas para o yasm ao criar arquivos .asm
.
LOCAL_CFLAGS
Flags que serão transmitidas ao Clang ao criar arquivos de origem C, C++ e alguns
arquivos de montagem (.s
e .S
, mas não .asm
). 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++. Use LOCAL_CONLYFLAGS
para
especificar flags apenas 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_CONLYFLAGS
Flags que serão transmitidas ao Clang ao compilar origens C. Ao contrário de
LOCAL_CFLAGS
, LOCAL_CONLYFLAGS
não será transmitido ao Clang ao compilar
fontes C++ ou Assembly.
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 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 precisa tratar os módulos de biblioteca associados como arquivos inteiros. Para saber mais sobre arquivos inteiros, consulte a documentação do GNU ld (link em inglês) 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. 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 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 criar 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 tempo 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 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 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 tempo de execução para usar esse código no momento da execução com segurança. Para mais informações, consulte Compatibilidade com o Neon e Recursos de CPU.
Como alternativa, é possível usar o sufixo .neon
para determinar que o sistema
compile apenas arquivos origem de 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
precisará 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 se destina 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 de origem 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 a compilação mais lenta.
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 pelos arquivos que você especificou para LOCAL_SRC_FILES
. Definir essa variável causa o seguinte:
- 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.
- 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 emLOCAL_SRC_FILES
, gerando, assim, outro arquivo Assembly temporário. - 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.