Android.MK

Questa pagina descrive la sintassi del file di build Android.mk utilizzato da ndk-build.

Panoramica

Il file Android.mk si trova in una sottodirectory della directory jni/ del progetto e descrive le origini e le librerie condivise nel sistema di compilazione. Si tratta di un minuscolo frammento del makefile GNU che il sistema di compilazione analizza una o più volte. Il file Android.mk è utile per definire le impostazioni a livello di progetto che Application.mk, il sistema di build e le variabili di ambiente lasciano non definite. Può anche eseguire l'override delle impostazioni a livello di progetto per moduli specifici.

La sintassi di Android.mk consente di raggruppare le origini in moduli. Un modulo è una libreria statica, una libreria condivisa o un file eseguibile autonomo. Puoi definire uno o più moduli in ogni file Android.mk e utilizzare lo stesso file di origine in più moduli. Il sistema di compilazione inserisce solo librerie condivise nel pacchetto dell'applicazione. Inoltre, le librerie statiche possono generare librerie condivise.

Oltre alla pacchettizzazione delle librerie, il sistema di build gestisce automaticamente una serie di altri dettagli. Ad esempio, non è necessario elencare i file di intestazione o le dipendenze esplicite tra i file generati nel file Android.mk. Il sistema di build NDK calcola automaticamente queste relazioni. Di conseguenza, nelle future release NDK dovresti poter beneficiare del nuovo supporto per la catena di strumenti/della piattaforma senza dover modificare il file Android.mk.

La sintassi di questo file è molto simile a quella utilizzata nei file Android.mk distribuiti nell'ambito del progetto open source Android completo. Sebbene l'implementazione del sistema di build che li utilizzi sia diversa, la loro somiglianza è una decisione di progettazione intenzionale volta a facilitare agli sviluppatori di applicazioni il riutilizzo del codice sorgente per le librerie esterne.

Concetti di base

Prima di esplorare la sintassi in dettaglio, è utile comprendere le nozioni di base dei contenuti di un file Android.mk. Questa sezione utilizza il file Android.mk nell'esempio Hello-JNI a questo scopo, spiegando il ruolo svolto da ogni riga del file.

Un file Android.mk deve iniziare definendo la variabile LOCAL_PATH:

LOCAL_PATH := $(call my-dir)

Questa variabile indica la posizione dei file di origine nella struttura di sviluppo. In questo caso, la funzione macro my-dir, fornita dal sistema di compilazione, restituisce il percorso della directory corrente (la directory contenente lo stesso file Android.mk).

La riga successiva dichiara la variabile CLEAR_VARS, di cui viene fornito il valore dal sistema di build.

include $(CLEAR_VARS)

La variabile CLEAR_VARS rimanda a un Makefile GNU speciale che cancella automaticamente molte variabili LOCAL_XXX, ad esempio LOCAL_MODULE, LOCAL_SRC_FILES e LOCAL_STATIC_LIBRARIES. Tieni presente che LOCAL_PATH non viene cancellato. Questa variabile deve conservare il suo valore perché il sistema analizza tutti i file di controllo della build in un singolo contesto di esecuzione GNU in cui tutte le variabili sono globali. Devi (ri)dichiarare questa variabile prima di descrivere ogni modulo.

La variabile LOCAL_MODULE memorizza poi il nome del modulo che vuoi creare. Utilizza questa variabile una volta per modulo nella tua applicazione.

LOCAL_MODULE := hello-jni

Ogni nome di modulo deve essere univoco e non deve contenere spazi. Quando genera il file finale della libreria condivisa, il sistema di build aggiunge automaticamente il prefisso e il suffisso appropriati al nome che assegni a LOCAL_MODULE. Ad esempio, l'esempio riportato sopra comporta la generazione di una libreria denominata libhello-jni.so.

La riga successiva elenca i file di origine, con gli spazi che delimitano più file:

LOCAL_SRC_FILES := hello-jni.c

La variabile LOCAL_SRC_FILES deve contenere un elenco di file di origine C e/o C++ per integrarsi in un modulo.

L'ultima riga aiuta il sistema a unire tutto:

include $(BUILD_SHARED_LIBRARY)

La variabile BUILD_SHARED_LIBRARY rimanda a uno script GNU Makefile che raccoglie tutte le informazioni definite nelle variabili LOCAL_XXX a partire dal include più recente. Questo script determina cosa creare e come farlo.

Nelle directory di esempio sono disponibili esempi più complessi, con i file Android.mk commentati che puoi esaminare. Inoltre, Sample: native-activity fornisce una spiegazione dettagliata del file Android.mk di quel campione. Infine, Variabili e macro fornisce ulteriori informazioni sulle variabili di questa sezione.

Variabili e macro

Il sistema di compilazione fornisce molte possibili variabili da utilizzare nel file Android.mk. Molte di queste variabili hanno valori preassegnati. Altre, le assegni tu.

Oltre a queste variabili, puoi anche definire altre variabili arbitrarie. In questo caso, tieni presente che il sistema di compilazione NDK riserva i seguenti nomi di variabili:

  • Nomi che iniziano con LOCAL_, come LOCAL_MODULE.
  • Nomi che iniziano con PRIVATE_, NDK_ o APP. Il sistema di build le utilizza internamente.
  • Nomi minuscoli, come my-dir. Il sistema di build le utilizza anche internamente.

Se devi definire le tue variabili di convenienza in un file Android.mk, ti consigliamo di anteporre MY_ ai nomi.

Variabili di inclusione definite da NDK

Questa sezione illustra le variabili Crea GNU definite dal sistema di compilazione prima di analizzare il file Android.mk. In determinate circostanze, l'NDK potrebbe analizzare il file Android.mk più volte, utilizzando ogni volta una definizione diversa per alcune di queste variabili.

CLEAR_VARS

Questa variabile rimanda a uno script di build che non definisce quasi tutte le variabili LOCAL_XXX elencate nella sezione "Variabili definite dallo sviluppatore" di seguito. Utilizza questa variabile per includere lo script prima di descrivere un nuovo modulo. La sintassi per utilizzarlo è:

include $(CLEAR_VARS)

CREAZIONE_ESECUBILE

Questa variabile rimanda a uno script di build che raccoglie tutte le informazioni sul modulo che hai fornito nelle variabili LOCAL_XXX e determina come creare un file eseguibile di destinazione dalle origini elencate. Tieni presente che l'utilizzo di questo script richiede almeno l'assegnazione di valori a LOCAL_MODULE e LOCAL_SRC_FILES (per saperne di più su queste variabili, consulta la sezione Variabili di descrizione modulo).

La sintassi per utilizzare questa variabile è la seguente:

include $(BUILD_EXECUTABLE)

LIBRERIA_CONDIVISIONE_COSTRUIRE

Questa variabile rimanda a uno script di build che raccoglie tutte le informazioni sul modulo che hai fornito nelle variabili LOCAL_XXX e determina come creare una libreria condivisa di destinazione dalle origini elencate. Tieni presente che l'utilizzo di questo script richiede almeno l'assegnazione di valori a LOCAL_MODULE e LOCAL_SRC_FILES (per saperne di più su queste variabili, consulta la sezione Variabili di descrizione modulo).

La sintassi per utilizzare questa variabile è la seguente:

include $(BUILD_SHARED_LIBRARY)

Una variabile di libreria condivisa fa sì che il sistema di compilazione generi un file di libreria con estensione .so.

LIBRERIA_STATICA_COSTRUIRE

Una variante di BUILD_SHARED_LIBRARY utilizzata per creare una libreria statica. Il sistema di compilazione non copia le librerie statiche nel progetto o nei pacchetti, ma può utilizzarle per creare librerie condivise (consulta LOCAL_STATIC_LIBRARIES e LOCAL_WHOLE_STATIC_LIBRARIES di seguito). La sintassi per utilizzare questa variabile è la seguente:

include $(BUILD_STATIC_LIBRARY)

Una variabile static-library fa sì che il sistema di compilazione generi una libreria con un'estensione .a.

LIBRERIA_CONDIVISIONE_PREBUILT

Indirizza a uno script di build utilizzato per specificare una libreria condivisa predefinita. A differenza del caso di BUILD_SHARED_LIBRARY e BUILD_STATIC_LIBRARY, in questo caso il valore LOCAL_SRC_FILES non può essere un file di origine. Deve invece essere un unico percorso a una libreria condivisa predefinita, come foo/libfoo.so. La sintassi per utilizzare questa variabile è:

include $(PREBUILT_SHARED_LIBRARY)

Puoi anche fare riferimento a una libreria predefinita in un altro modulo utilizzando la variabile LOCAL_PREBUILTS. Per ulteriori informazioni sull'utilizzo delle librerie predefinite, consulta Utilizzare le librerie predefinite.

LIBRERIA_STATICA_PREBUILT

Uguale a PREBUILT_SHARED_LIBRARY, ma per una libreria statica predefinita. Per ulteriori informazioni sull'utilizzo delle librerie predefinite, consulta Utilizzare le librerie predefinite.

Variabili delle informazioni di destinazione

Il sistema di build analizza Android.mk una volta per ogni ABI specificata dalla variabile APP_ABI, che è in genere definita nel tuo file Application.mk. Se APP_ABI è all, il sistema di build analizza Android.mk una volta per ABI supportata dall'NDK. Questa sezione descrive le variabili definite dal sistema di build ogni volta che analizza Android.mk.

ARCH.TARGET

La famiglia di CPU scelta come target dal sistema di compilazione durante l'analisi di questo file Android.mk. Il valore di questa variabile sarà arm, arm64, x86 o x86_64.

PIATTAFORMA_TARGET

Il numero del livello API Android scelto come target dal sistema di build durante l'analisi di questo file Android.mk. Ad esempio, le immagini di sistema Android 5.1 corrispondono al livello API Android 22: android-22. Per un elenco completo dei nomi delle piattaforme e delle immagini di sistema Android corrispondenti, consulta API native. L'esempio seguente mostra la sintassi per l'utilizzo di questa variabile:

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

ARCH_ABI TARGET

L'ABI scelta come target dal sistema di compilazione durante l'analisi di questo file Android.mk. La tabella 1 mostra l'impostazione ABI utilizzata per ogni CPU e architettura supportate.

Tabella 1. Impostazioni ABI per CPU e architetture diverse.

CPU e architettura Impostazione
ARM 7 armeabi-v7a
ARMv8 AArch64 arm64-v8a
i686 x86
x86-64 x86_64

L'esempio seguente mostra come cercare ARMv8 AArch64 come combinazione di CPU e ABI di destinazione:

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

Per maggiori dettagli sulle ABI dell'architettura e sui problemi di compatibilità associati, consulta la pagina relativa alle ABI di Android.

Le nuove ABI di destinazione in futuro avranno valori diversi.

ABI_TARGET

Una concatenazione del livello API Android target e dell'ABI. È particolarmente utile quando vuoi eseguire un test rispetto a un'immagine di sistema di destinazione specifica per un dispositivo reale. Ad esempio, per verificare la presenza di un dispositivo ARM a 64 bit con livello API Android 22:

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

Variabili modulo-descrizione

Le variabili di questa sezione descrivono il modulo al sistema di compilazione. Ogni descrizione del modulo deve seguire questo flusso di base:

  1. Inizializza o annulla la definizione delle variabili associate al modulo utilizzando la variabile CLEAR_VARS.
  2. Assegna un valore alle variabili utilizzate per descrivere il modulo.
  3. Imposta il sistema di compilazione NDK in modo che utilizzi lo script di build appropriato per il modulo, mediante la variabile BUILD_XXX.

PERCORSO LOCAL_

Questa variabile viene utilizzata per fornire il percorso del file corrente. Devi definirlo all'inizio del file Android.mk. Nell'esempio seguente viene illustrato come eseguire questa operazione:

LOCAL_PATH := $(call my-dir)

Lo script a cui rimanda CLEAR_VARS non cancella questa variabile. Pertanto, devi definire la definizione una sola volta, anche se il tuo file Android.mk descrive più moduli.

MODULO_LOCALE

Questa variabile memorizza il nome del modulo. Deve essere univoco tra i nomi di tutti i moduli e non deve contenere spazi. Devi definirlo prima di includere eventuali script (diversi da quello di CLEAR_VARS). Non devi aggiungere il prefisso lib né l'estensione del file .so o .a; il sistema di compilazione apporta queste modifiche automaticamente. In tutti i file Android.mk e Application.mk, fai riferimento al modulo con il nome non modificato. Ad esempio, la riga seguente genera un modulo della libreria condivisa denominato libfoo.so:

LOCAL_MODULE := "foo"

Se vuoi che il nome del modulo generato sia diverso da lib + il valore LOCAL_MODULE, puoi utilizzare la variabile LOCAL_MODULE_FILENAME per assegnare al modulo generato un nome di tua scelta.

LOCAL_MODULE_FILENAME

Questa variabile facoltativa consente di sostituire i nomi utilizzati per impostazione predefinita dal sistema di build per i file che genera. Ad esempio, se il nome di LOCAL_MODULE è foo, puoi forzare il sistema a chiamare il file che genera libnewfoo. Nell'esempio seguente viene illustrato come eseguire questa operazione:

LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo

Per un modulo della libreria condivisa, questo esempio genera un file denominato libnewfoo.so.

FILE_SRC_LOCAL_SRC

Questa variabile contiene l'elenco dei file di origine utilizzati dal sistema di compilazione per generare il modulo. Elenca solo i file che il sistema di compilazione passa effettivamente al compilatore, poiché il sistema di compilazione calcola automaticamente le dipendenze associate. Tieni presente che puoi utilizzare percorsi di file sia relativi (a LOCAL_PATH) sia assoluti.

Consigliamo di evitare percorsi di file assoluti; quelli relativi rendono il tuo file Android.mk più portabile.

ESTENSIONE_CPP_LOCAL_CPP

Puoi utilizzare questa variabile facoltativa per indicare un'estensione file diversa da .cpp per i file di origine C++. Ad esempio, la riga seguente modifica l'estensione in .cxx. L'impostazione deve includere il punto.

LOCAL_CPP_EXTENSION := .cxx

Puoi utilizzare questa variabile per specificare più estensioni. Ad esempio:

LOCAL_CPP_EXTENSION := .cxx .cpp .cc

LOCAL_CPP_FEATURES

Puoi utilizzare questa variabile facoltativa per indicare che il tuo codice si basa su funzionalità specifiche di C++. Abilita i giusti flag del compilatore e del linker durante il processo di compilazione. Per i programmi binari predefiniti, questa variabile dichiara anche da quali caratteristiche dipende il file binario, contribuendo così a garantire che il collegamento finale funzioni correttamente. Ti consigliamo di utilizzare questa variabile invece di abilitare -frtti e -fexceptions direttamente nella definizione di LOCAL_CPPFLAGS.

L'uso di questa variabile consente al sistema di compilazione di utilizzare i flag appropriati per ogni modulo. L'utilizzo di LOCAL_CPPFLAGS fa sì che il compilatore utilizzi tutti i flag specificati per tutti i moduli, indipendentemente dalle effettive esigenze.

Ad esempio, per indicare che il codice utilizza RTTI (RunTime Type Information), scrivi:

LOCAL_CPP_FEATURES := rtti

Per indicare che il codice utilizza eccezioni C++, scrivi:

LOCAL_CPP_FEATURES := exceptions

Puoi anche specificare più valori per questa variabile. Ecco alcuni esempi:

LOCAL_CPP_FEATURES := rtti features

L'ordine in cui descrivi i valori non è importante.

LOCAL_C_INCLUDES

Puoi utilizzare questa variabile facoltativa per specificare un elenco di percorsi, relativi alla directory NDK root, da aggiungere al percorso di ricerca di inclusione durante la compilazione di tutte le origini (C, C++ e Assembly). Ecco alcuni esempi:

LOCAL_C_INCLUDES := sources/foo

Oppure:

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

Definisci questa variabile prima di impostare eventuali flag di inclusione corrispondenti tramite LOCAL_CFLAGS o LOCAL_CPPFLAGS.

Il sistema di build inoltre utilizza automaticamente i percorsi LOCAL_C_INCLUDES all'avvio del debug nativo con ndk-gdb.

LOCAL_CFLAGS

Questa variabile facoltativa imposta i flag del compilatore che il sistema di build deve passare durante la creazione di file di origine C e C++. Questa operazione può essere utile per specificare ulteriori definizioni di macro o opzioni di compilazione. Usa LOCAL_CPPFLAGS per specificare i flag solo per C++.

Cerca di non modificare il livello di ottimizzazione/debug nel file Android.mk. Il sistema di compilazione può gestire automaticamente questa impostazione utilizzando le informazioni pertinenti contenute nel file Application.mk. In questo modo, il sistema di compilazione può generare file di dati utili utilizzati durante il debug.

È possibile specificare ulteriori percorsi di inclusione scrivendo:

LOCAL_CFLAGS += -I<path>,

Tuttavia, è preferibile utilizzare LOCAL_C_INCLUDES a questo scopo, poiché così facendo è possibile utilizzare anche i percorsi disponibili per il debug nativo con ndk-gdb.

LOCAL_CPPFLAGS

Un insieme facoltativo di flag del compilatore che verranno passati solo durante la creazione di file sorgente C++. Verranno visualizzati dopo LOCAL_CFLAGS nella riga di comando del compilatore. Usa LOCAL_CFLAGS per specificare i flag sia per C che per C++.

LOCAL_STATIC_LIBRARIES

Questa variabile archivia l'elenco dei moduli delle librerie statiche da cui dipende il modulo attuale.

Se il modulo attuale è una libreria condivisa o un file eseguibile, questa variabile forzerà il collegamento di queste librerie al programma binario risultante.

Se il modulo attuale è una libreria statica, questa variabile indica semplicemente che anche altri moduli, a seconda di quello attuale, dipenderanno dalle librerie elencate.

LOCAL_SHARED_LIBRARIES

Questa variabile è l'elenco dei moduli delle librerie condivise da cui dipende il modulo in fase di runtime. Queste informazioni sono necessarie al momento del collegamento e per incorporare le informazioni corrispondenti nel file generato.

LIBRERIE_STATICHE_LOCAL_WHOLE

Questa variabile è una variante di LOCAL_STATIC_LIBRARIES e indica che il linker deve considerare i moduli della libreria associati come archivi interi. Per ulteriori informazioni su interi archivi, consulta la documentazione GNU ld per il flag --whole-archive.

Questa variabile è utile quando esistono dipendenze circolari tra diverse librerie statiche. Quando utilizzi questa variabile per creare una libreria condivisa, il sistema di compilazione forza l'aggiunta di tutti i file degli oggetti dalle tue librerie statiche al programma binario finale. Lo stesso non vale per la generazione di file eseguibili.

LOCAL_LDLIBS

Questa variabile contiene l'elenco di flag linker aggiuntivi da utilizzare per la creazione di una libreria condivisa o di un file eseguibile. Consente di utilizzare il prefisso -l per passare il nome di librerie di sistema specifiche. Ad esempio, l'esempio seguente indica al linker di generare un modulo che si collega a /system/lib/libz.so al momento del caricamento:

LOCAL_LDLIBS := -lz

Consulta API native per l'elenco delle librerie di sistema esposte alle quali puoi collegarti in questa release NDK.

LOCAL_LDFLAGS

L'elenco di altri flag del linker che il sistema di build utilizza durante la creazione della libreria condivisa o dell'eseguibile. Ad esempio, per utilizzare il linker ld.bfd su ARM/X86:

LOCAL_LDFLAGS += -fuse-ld=bfd

LOCAL_ALLOW_UNDEFINED_SYMBOLS

Per impostazione predefinita, quando il sistema di build rileva un riferimento non definito rilevato durante il tentativo di creazione di un elemento condiviso, viene visualizzato un errore simbolo non definito. Questo errore può aiutarti a individuare eventuali bug nel codice sorgente.

Per disattivare questo controllo, imposta questa variabile su true. Tieni presente che questa impostazione potrebbe causare il caricamento della libreria condivisa in fase di runtime.

MODALITÀ_ARM (LOCAL_ARM)

Per impostazione predefinita, il sistema di compilazione genera programmi binari di destinazione ARM in modalità thumb, in cui ogni istruzione ha una larghezza di 16 bit ed è collegata alle librerie STL nella directory thumb/. La definizione di questa variabile come arm impone al sistema di compilazione di generare i file degli oggetti del modulo in modalità arm a 32 bit. L'esempio seguente mostra come eseguire questa operazione:

LOCAL_ARM_MODE := arm

Puoi anche indicare al sistema di compilazione di creare origini specifiche solo in modalità arm aggiungendo il suffisso .arm ai nomi file di origine. Ad esempio, l'esempio seguente indica al sistema di build di compilare sempre bar.c in modalità ARM, ma di creare foo.c in base al valore di LOCAL_ARM_MODE.

LOCAL_SRC_FILES := foo.c bar.c.arm

LOCAL_ARM_NEON

Questa variabile è importante solo quando scegli come target l'ABI armeabi-v7a. Consente l'utilizzo di funzionalità intrinseche del compilatore ARM Advanced SIMD (NEON) nelle origini C e C++, nonché istruzioni NEON nei file Assembly.

Tieni presente che non tutte le CPU basate su ARMv7 supportano le estensioni del set di istruzioni NEON. Per questo motivo, devi eseguire il rilevamento di runtime per poter utilizzare in sicurezza il codice in fase di runtime. Per ulteriori informazioni, consulta Supporto Neon e Funzionalità CPU.

In alternativa, puoi utilizzare il suffisso .neon per specificare che il sistema di compilazione compila solo file sorgente specifici con supporto NEON. Nell'esempio seguente, il sistema di build compila foo.c con supporto per pollice e neon, bar.c con supporto per pollice e zoo.c con supporto per ARM e NEON:

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

Se utilizzi entrambi i suffissi, .arm deve precedere .neon.

LOCAL_DISABLE_FORMAT_STRING_CONTROLS

Per impostazione predefinita, il sistema di compilazione compila il codice con la protezione delle stringhe di formato. In questo modo viene forzato un errore del compilatore se in una funzione di stile printf viene utilizzata una stringa di formato non costante. Questa protezione è attiva per impostazione predefinita, ma puoi disattivarla impostando il valore di questa variabile su true. Sconsigliamo di farlo senza un motivo valido.

LOCAL_EXPORT_CFLAGS

Questa variabile registra un insieme di flag del compilatore C/C++ da aggiungere alla definizione LOCAL_CFLAGS di qualsiasi altro modulo che utilizza questo modulo tramite le variabili LOCAL_STATIC_LIBRARIES o LOCAL_SHARED_LIBRARIES.

Ad esempio, considera la seguente coppia di moduli: foo e bar, che dipende da 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)

In questo caso, il sistema di compilazione passa i flag -DFOO=1 e -DBAR=2 al compilatore durante la creazione di bar.c. Inoltre, antepone i flag esportati alla LOCAL_CFLAGS del tuo modulo in modo da poterli facilmente sostituire.

Inoltre, la relazione tra i moduli è transitiva: se zoo dipende da bar, che a sua volta dipende da foo, zoo eredita anche tutti i flag esportati da foo.

Infine, il sistema di build non utilizza i flag esportati durante la creazione locale (ovvero la creazione del modulo di cui vengono esportati i flag). Pertanto, nell'esempio riportato sopra, non passa -DFOO=1 al compilatore durante la creazione di foo/foo.c. Per creare in locale, utilizza invece LOCAL_CFLAGS.

LOCAL_EXPORT_CPPFLAGS

Questa variabile è uguale a LOCAL_EXPORT_CFLAGS, ma solo per i flag C++.

LOCAL_EXPORT_C_INCLUDES

Questa variabile è uguale a LOCAL_EXPORT_CFLAGS, ma per C include percorsi. È utile nei casi in cui, ad esempio, bar.c deve includere le intestazioni del modulo foo.

LOCAL_EXPORT_LDFLAGS

Questa variabile è uguale a LOCAL_EXPORT_CFLAGS, ma per i flag del linker.

LOCAL_EXPORT_LDLIBS

Questa variabile equivale a LOCAL_EXPORT_CFLAGS e indica al sistema di compilazione di passare i nomi di librerie di sistema specifiche al compilatore. Anteponi -l al nome di ogni libreria specificata.

Tieni presente che il sistema di compilazione aggiunge i flag del linker importati al valore della variabile LOCAL_LDLIBS del modulo. Ciò è dovuto al funzionamento dei linker Unix.

Questa variabile è in genere utile quando il modulo foo è una libreria statica con un codice che dipende da una libreria di sistema. Puoi quindi utilizzare LOCAL_EXPORT_LDLIBS per esportare la dipendenza. Ecco alcuni esempi:

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)

In questo esempio, il sistema di compilazione inserisce -llog alla fine del comando linker quando crea libbar.so. In questo modo indichi al linker che, poiché libbar.so dipende da foo, dipende anche dalla libreria di logging del sistema.

LOCAL_SHORT_COMANDI

Imposta questa variabile su true quando il modulo ha un numero molto elevato di origini e/o librerie statiche o condivise dipendenti. In questo modo costringe il sistema di compilazione a utilizzare la sintassi @ per gli archivi che contengono file di oggetti intermedi o che collegano librerie.

Questa funzionalità può essere utile su Windows, dove la riga di comando accetta un massimo di 8191 caratteri, che potrebbero essere troppo piccoli per progetti complessi. Influisce anche sulla compilazione di singoli file di origine, inserendo quasi tutti i flag del compilatore anche all'interno dei file di elenco.

Tieni presente che qualsiasi valore diverso da true verrà ripristinato sul comportamento predefinito. Puoi anche definire APP_SHORT_COMMANDS nel file Application.mk per forzare questo comportamento per tutti i moduli del tuo progetto.

Sconsigliamo di abilitare questa funzionalità per impostazione predefinita, poiché rende la build più lenta.

ARCHIVIO_LOCAL_THIN

Imposta questa variabile su true durante la creazione di librerie statiche. In questo modo verrà generato un archivio sottile, un file di libreria che non contiene file di oggetti, ma solo percorsi di file relativi agli oggetti effettivi che normalmente conterrebbe.

Ciò è utile per ridurre le dimensioni dell'output della build. Lo svantaggio è che queste librerie non possono essere spostate in una posizione diversa (tutti i percorsi al loro interno sono relativi).

I valori validi sono true, false o vuoto. Puoi impostare un valore predefinito nel file Application.mk tramite la variabile APP_THIN_ARCHIVE.

ASM LOCAL_FILTER

Definisci questa variabile come un comando shell che il sistema di compilazione utilizzerà per filtrare i file di assemblaggio estratti o generati dai file specificati per LOCAL_SRC_FILES. La definizione di questa variabile determina il verificarsi di quanto segue:

  1. Il sistema di compilazione genera un file di assemblaggio temporaneo da qualsiasi file di origine C o C++, invece di compilarlo in un file di oggetto.
  2. Il sistema di compilazione esegue il comando shell in LOCAL_FILTER_ASM su qualsiasi file di assemblaggio temporaneo e su qualsiasi file di assemblaggio elencato in LOCAL_SRC_FILES, generando così un altro file di assemblaggio temporaneo.
  3. Il sistema di compilazione compila questi file di assemblaggio filtrati in un file di oggetti.

Ecco alcuni esempi:

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" corrisponde al compilatore, "2" al filtro e "3" all'assembler. Il filtro deve essere un comando shell autonomo che prende il nome del file di input come primo argomento e il nome del file di output come secondo. Ecco alcuni esempi:

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

Macro di funzione fornite da NDK

In questa sezione vengono spiegate le macro della funzione GNU Make fornite da NDK. Utilizza $(call <function>) per valutarli; restituisce informazioni testuali.

la-mia-dir

Questa macro restituisce il percorso dell'ultimo makefile incluso, che in genere è la directory attuale di Android.mk. my-dir è utile per definire LOCAL_PATH all'inizio del file Android.mk. Ecco alcuni esempi:

LOCAL_PATH := $(call my-dir)

A causa del funzionamento di GNU Make, questa macro restituisce in realtà il percorso dell'ultimo makefile incluso dal sistema di compilazione durante l'analisi degli script di build. Per questo motivo, non devi chiamare my-dir dopo aver incluso un altro file.

Prendi in considerazione il seguente esempio:

LOCAL_PATH := $(call my-dir)

# ... declare one module

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

LOCAL_PATH := $(call my-dir)

# ... declare another module

Il problema è che la seconda chiamata a my-dir definisce LOCAL_PATH come $PATH/foo invece di $PATH, perché è qui che è indirizzato l'elemento di inclusione più recente.

Puoi evitare questo problema inserendo inclusioni aggiuntive dopo tutto il resto nel file Android.mk. Ecco alcuni esempi:

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 non è possibile strutturare il file in questo modo, salva il valore della prima chiamata my-dir in un'altra variabile. Ecco alcuni esempi:

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

tutte-subdir-makefiles

Restituisce l'elenco dei file Android.mk che si trovano in tutte le sottodirectory del percorso my-dir corrente.

Puoi utilizzare questa funzione per fornire gerarchie di directory di origine nidificate in modo approfondito al sistema di compilazione. Per impostazione predefinita, l'NDK cerca solo i file nella directory contenente il file Android.mk.

questo-makefile

Restituisce il percorso del makefile corrente (da cui il sistema di compilazione ha chiamato la funzione).

file-make-principale

Restituisce il percorso del makefile principale nella struttura di inclusione (il percorso del makefile che include quello corrente).

non-parent-makefile

Restituisce il percorso del makefile non principale nella struttura di inclusione (il percorso del makefile che include quello corrente).

importa-modulo

Una funzione che consente di trovare e includere il file Android.mk di un modulo in base al nome del modulo. Di seguito è riportato un esempio tipico:

$(call import-module,<name>)

In questo esempio, il sistema di compilazione cerca il modulo con il tag <name> nell'elenco di directory a cui fa riferimento la variabile di ambiente NDK_MODULE_PATH e include automaticamente il relativo file Android.mk.