Auf dieser Seite wird die Syntax der von ndk-build
verwendeten Build-Datei Android.mk
beschrieben.
Übersicht
Die Datei Android.mk
befindet sich in einem Unterverzeichnis des jni/
-Verzeichnisses Ihres Projekts und beschreibt Ihre Quellen und freigegebenen Bibliotheken für das Build-System.
Es ist in Wirklichkeit ein winziges GNU-Makefile-Fragment, das vom Build-System einmal oder mehrmals geparst wird. Mit der Datei Android.mk
können Sie projektweite Einstellungen definieren, die in Application.mk
, dem Build-System und Ihren Umgebungsvariablen nicht definiert sind. Außerdem können damit projektweite Einstellungen für bestimmte Module überschrieben werden.
Mit der Syntax von Android.mk
können Sie Ihre Quellen in Modulen gruppieren.
Ein Modul ist entweder eine statische Bibliothek, eine gemeinsam genutzte Bibliothek oder eine eigenständige ausführbare Bibliothek. Sie können in jeder Android.mk
-Datei ein oder mehrere Module definieren und dieselbe Quelldatei in mehreren Modulen verwenden. Das Build-System fügt nur gemeinsam genutzte Bibliotheken in das Anwendungspaket ein. Darüber hinaus können statische Bibliotheken gemeinsam genutzte Bibliotheken generieren.
Zusätzlich zu den Paketerstellungsbibliotheken übernimmt das Build-System eine Vielzahl anderer Details für Sie. So müssen Sie beispielsweise keine Headerdateien oder explizite Abhängigkeiten zwischen generierten Dateien in der Datei Android.mk
auflisten. Das NDK-Build-System berechnet diese Beziehungen automatisch für Sie. Dadurch sollten Sie in zukünftigen NDK-Releases von der neuen Toolchain-/Plattformunterstützung profitieren können, ohne die Android.mk
-Datei bearbeiten zu müssen.
Die Syntax dieser Datei entspricht sehr der Syntax, die in den Android.mk
-Dateien verwendet wird, die mit dem vollständigen Android Open Source-Projekt bereitgestellt werden. Die Implementierung des Build-Systems unterscheidet sich zwar, aber ihre Ähnlichkeit ist eine bewusste Designentscheidung, die Anwendungsentwicklern die Wiederverwendung von Quellcode für externe Bibliotheken erleichtern soll.
Grundlegende Informationen
Bevor Sie sich mit der Syntax genauer beschäftigen, sollten Sie sich zuerst mit den grundlegenden Inhalten einer Android.mk
-Datei vertraut machen. In diesem Abschnitt wird dafür die Datei Android.mk
aus dem Hello-JNI-Beispiel verwendet und die Rolle erklärt, die jede Zeile in der Datei spielt.
Eine Android.mk
-Datei muss mit der Definition der Variablen LOCAL_PATH
beginnen:
LOCAL_PATH := $(call my-dir)
Diese Variable gibt den Speicherort der Quelldateien in der Entwicklungsstruktur an. Hier gibt die vom Build-System bereitgestellte Makrofunktion my-dir
den Pfad des aktuellen Verzeichnisses zurück (das Verzeichnis, das die Datei Android.mk
selbst enthält).
In der nächsten Zeile wird die Variable CLEAR_VARS
deklariert, deren Wert vom Build-System bereitgestellt wird.
include $(CLEAR_VARS)
Die Variable CLEAR_VARS
verweist auf ein spezielles GNU-Makefile, das viele LOCAL_XXX
-Variablen für Sie löscht, z. B. LOCAL_MODULE
, LOCAL_SRC_FILES
und LOCAL_STATIC_LIBRARIES
. Beachten Sie, dass dadurch LOCAL_PATH
nicht gelöscht wird. Diese Variable muss ihren Wert beibehalten, da das System alle Build-Steuerdateien in einem einzelnen GNU Make-Ausführungskontext parst, in dem alle Variablen global sind. Sie müssen diese Variable vor dem Beschreiben der einzelnen Module (noch einmal) deklarieren.
Als Nächstes speichert die Variable LOCAL_MODULE
den Namen des Moduls, das Sie erstellen möchten. Verwenden Sie diese Variable einmal pro Modul in Ihrer Anwendung.
LOCAL_MODULE := hello-jni
Jeder Modulname muss eindeutig sein und darf keine Leerzeichen enthalten. Wenn das Build-System die endgültige Datei mit der gemeinsam genutzten Bibliothek generiert, fügt es dem Namen, den Sie LOCAL_MODULE
zuweisen, automatisch das richtige Präfix und Suffix hinzu. Im obigen Beispiel wird beispielsweise eine Bibliothek mit dem Namen libhello-jni.so
generiert.
In der nächsten Zeile sind die Quelldateien aufgelistet, wobei mehrere Dateien durch Leerzeichen voneinander getrennt sind:
LOCAL_SRC_FILES := hello-jni.c
Die Variable LOCAL_SRC_FILES
muss eine Liste von C- und/oder C++-Quelldateien enthalten, die in ein Modul integriert werden sollen.
Die letzte Zeile hilft dem System, alles miteinander zu verknüpfen:
include $(BUILD_SHARED_LIBRARY)
Die Variable BUILD_SHARED_LIBRARY
verweist auf ein GNU-Makefile-Skript, das alle Informationen erfasst, die Sie seit dem letzten include
in LOCAL_XXX
-Variablen definiert haben. Mit diesem Script wird festgelegt, was und wie dies erstellt wird.
In den Beispielverzeichnissen finden Sie komplexere Beispiele mit kommentierten Android.mk
-Dateien, die Sie sich ansehen können. Darüber hinaus enthält Sample: native-activity eine detaillierte Erklärung der Android.mk
-Datei dieses Beispiels. Weitere Informationen zu den Variablen aus diesem Abschnitt finden Sie unter Variablen und Makros.
Variablen und Makros
Das Build-System bietet viele mögliche Variablen für die Verwendung in der Datei Android.mk
.
Viele dieser Variablen haben vorab zugewiesene Werte. Andere weisen Sie zu.
Zusätzlich zu diesen Variablen können Sie auch eigene, beliebige Variablen definieren. Beachten Sie dabei, dass das NDK-Build-System die folgenden Variablennamen reserviert:
- Namen, die mit
LOCAL_
beginnen, z. B.LOCAL_MODULE
. - Namen, die mit
PRIVATE_
,NDK_
oderAPP
beginnen Diese werden vom Build-System intern verwendet. - Namen in Kleinbuchstaben wie
my-dir
. Diese werden auch vom Build-System intern verwendet.
Wenn Sie eigene willkürliche Variablen in einer Android.mk
-Datei definieren müssen, empfehlen wir, den Namen MY_
voranzustellen.
NDK-definierte einschließende Variablen
In diesem Abschnitt werden die GNU-Make-Variablen erläutert, die vom Build-System definiert werden, bevor die Android.mk
-Datei geparst wird. Unter bestimmten Umständen parst der NDK die Android.mk
-Datei mehrmals und verwendet für einige dieser Variablen jedes Mal eine andere Definition.
VARIANZEN_LÖSCHEN
Diese Variable verweist auf ein Build-Script, mit dem fast alle im Abschnitt „Vom Entwickler definierten Variablen“ aufgeführten Variablen des Typs LOCAL_XXX
nicht definiert werden. Verwenden Sie diese Variable, um dieses Skript einzuschließen, bevor Sie ein neues Modul beschreiben. Die Syntax für die Verwendung lautet:
include $(CLEAR_VARS)
CREATE_EXECUTABLE
Diese Variable verweist auf ein Build-Skript, das alle Informationen zu dem Modul erfasst, das Sie in den LOCAL_XXX
-Variablen bereitgestellt haben, und bestimmt, wie eine ausführbare Zieldatei aus den aufgeführten Quellen erstellt wird. Damit Sie dieses Skript verwenden können, müssen Sie mindestens LOCAL_MODULE
und LOCAL_SRC_FILES
bereits Werte zugewiesen haben. Weitere Informationen zu diesen Variablen finden Sie unter Variablen für die Modulbeschreibung.
Die Syntax für die Verwendung dieser Variablen lautet:
include $(BUILD_EXECUTABLE)
GETEILTE_LIBRARY_BAUEN
Diese Variable verweist auf ein Build-Script, das alle Informationen zu dem Modul erfasst, das Sie in den LOCAL_XXX
-Variablen bereitgestellt haben, und bestimmt, wie aus den aufgeführten Quellen eine gemeinsam genutzte Zielbibliothek erstellt wird. Damit Sie dieses Skript verwenden können, müssen Sie mindestens LOCAL_MODULE
und LOCAL_SRC_FILES
bereits Werte zugewiesen haben. Weitere Informationen zu diesen Variablen finden Sie unter Variablen für die Modulbeschreibung.
Die Syntax für die Verwendung dieser Variablen lautet:
include $(BUILD_SHARED_LIBRARY)
Eine Variable für gemeinsam genutzte Bibliothek generiert im Build-System eine Bibliotheksdatei mit der Erweiterung .so
.
STATISCHE_BIBLIOTHEK_ERSTELLEN
Eine Variante von BUILD_SHARED_LIBRARY
, die zum Erstellen einer statischen Bibliothek verwendet wird. Das Build-System kopiert statische Bibliotheken nicht in Ihr Projekt/Ihre Pakete, kann sie aber zum Erstellen gemeinsam genutzter Bibliotheken verwenden (siehe LOCAL_STATIC_LIBRARIES
und LOCAL_WHOLE_STATIC_LIBRARIES
unten). Die Syntax für die Verwendung dieser Variablen lautet:
include $(BUILD_STATIC_LIBRARY)
Eine static-library-Variable führt dazu, dass das Build-System eine Bibliothek mit der Erweiterung .a
generiert.
PREBUILT_SHARED_LIBRARY
Verweist auf ein Build-Script, mit dem eine vordefinierte gemeinsam genutzte Bibliothek angegeben wird. Im Gegensatz zu BUILD_SHARED_LIBRARY
und BUILD_STATIC_LIBRARY
kann der Wert von LOCAL_SRC_FILES
hier keine Quelldatei sein. Stattdessen muss es ein einzelner Pfad zu einer vordefinierten gemeinsam genutzten Bibliothek wie foo/libfoo.so
sein. Die Syntax für die Verwendung dieser Variablen lautet:
include $(PREBUILT_SHARED_LIBRARY)
Sie können auch mit der Variable LOCAL_PREBUILTS
auf eine vordefinierte Bibliothek in einem anderen Modul verweisen. Weitere Informationen zur Verwendung vordefinierter Bibliotheken finden Sie unter Vordefinierte Bibliotheken verwenden.
PREBUILT_STATIC_LIBRARY
Wie PREBUILT_SHARED_LIBRARY
, aber für eine vordefinierte statische Bibliothek. Weitere Informationen zur Verwendung vordefinierter Bibliotheken finden Sie unter Vordefinierte Bibliotheken verwenden.
Zielinformationsvariablen
Das Build-System parst Android.mk
einmal pro ABI, das durch die Variable APP_ABI
angegeben wird, die normalerweise in der Datei Application.mk
definiert ist. Wenn APP_ABI
all
ist, parst das Build-System Android.mk
einmal pro ABI, das vom NDK unterstützt wird. In diesem Abschnitt werden Variablen beschrieben, die vom Build-System bei jedem Parsen von Android.mk
definiert werden.
ZIEL_ARCH
Die CPU-Familie, die vom Build-System beim Parsen der Datei Android.mk
angegriffen wird. Diese Variable kann entweder arm
, arm64
, x86
oder x86_64
sein.
ZIEL_PLATTFORM
Die Nummer des Android API-Levels, auf das das Build-System beim Parsen dieser Android.mk
-Datei abzielt. Die Systemimages von Android 5.1 entsprechen beispielsweise dem Android API-Level 22: android-22
. Eine vollständige Liste der Plattformnamen und der entsprechenden Android-Systemimages finden Sie unter Native APIs. Das folgende Beispiel zeigt die Syntax zur Verwendung dieser Variablen:
ifeq ($(TARGET_PLATFORM),android-22)
# ... do something ...
endif
ZIEL_ARCH_ABI
Das ABI, auf das das Build-System beim Parsen dieser Android.mk
-Datei abzielt.
Tabelle 1 zeigt die ABI-Einstellung, die für jede unterstützte CPU und Architektur verwendet wird.
CPU und Architektur | Einstellung |
---|---|
ARMv7 | armeabi-v7a |
ARMv8 AArch64 | arm64-v8a |
i686 | x86 |
x86–64 | x86_64 |
Das folgende Beispiel zeigt, wie Sie nach ARMv8 AArch64 als Zielkombination aus CPU und ABI suchen:
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
# ... do something ...
endif
Weitere Informationen zu Architektur-ABIs und zugehörigen Kompatibilitätsproblemen finden Sie unter Android-ABIs.
Neue Ziel-ABIs werden in Zukunft andere Werte haben.
ZIEL_ABI
Eine Verkettung von Android-Ziel-API-Level und ABI. Dies ist besonders nützlich, wenn Sie mit einem bestimmten Zielsystem-Image für ein echtes Gerät testen möchten. So suchen Sie beispielsweise nach einem 64-Bit-ARM-Gerät mit Android API-Level 22:
ifeq ($(TARGET_ABI),android-22-arm64-v8a)
# ... do something ...
endif
Variablen für die Modulbeschreibung
Die Variablen in diesem Abschnitt beschreiben das Modul für das Build-System. Jede Modulbeschreibung sollte dem folgenden grundlegenden Ablauf folgen:
- Initialisieren oder heben Sie die Definition der mit dem Modul verknüpften Variablen auf, indem Sie die Variable
CLEAR_VARS
verwenden. - Weisen Sie den Variablen, die zur Beschreibung des Moduls verwendet werden, Werte zu.
- Legen Sie mithilfe der Variablen
BUILD_XXX
fest, dass das NDK-Build-System das entsprechende Build-Skript für das Modul verwendet.
LOCAL_PATH
Diese Variable gibt den Pfad der aktuellen Datei an. Sie müssen ihn am Anfang der Datei Android.mk
definieren. Das folgende Beispiel zeigt, wie das funktioniert:
LOCAL_PATH := $(call my-dir)
Das Skript, auf das CLEAR_VARS
verweist, löscht diese Variable nicht. Daher müssen Sie sie nur einmal definieren, auch wenn die Datei Android.mk
mehrere Module beschreibt.
LOCAL_MODULE
Diese Variable speichert den Namen Ihres Moduls. Er muss unter allen Modulnamen eindeutig sein und darf keine Leerzeichen enthalten. Sie müssen es definieren, bevor Sie Skripts einfügen (außer dem für CLEAR_VARS
). Sie müssen weder das Präfix lib
noch die Dateiendung .so
oder .a
hinzufügen. Das Build-System nimmt diese Änderungen automatisch vor. Beziehen Sie sich in Android.mk
- und Application.mk
-Dateien auf das Modul anhand seines unveränderten Namens. Die folgende Zeile führt beispielsweise dazu, dass ein Modul der gemeinsam genutzten Bibliothek namens libfoo.so
generiert wird:
LOCAL_MODULE := "foo"
Wenn das generierte Modul einen anderen Namen als lib
+ den Wert von LOCAL_MODULE
haben soll, können Sie dem generierten Modul stattdessen mit der Variablen LOCAL_MODULE_FILENAME
einen eigenen Namen geben.
LOCAL_MODULE_FILENAME
Mit dieser optionalen Variablen können Sie die Namen überschreiben, die das Build-System standardmäßig für von ihm generierte Dateien verwendet. Wenn der Name des LOCAL_MODULE
beispielsweise foo
lautet, können Sie das System zwingen, die Datei aufzurufen, die libnewfoo
generiert. Das folgende Beispiel zeigt, wie Sie dies tun können:
LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo
In diesem Beispiel wird für ein Modul der gemeinsam genutzten Bibliothek eine Datei mit dem Namen libnewfoo.so
generiert.
LOKALE SRC-DATEIEN
Diese Variable enthält die Liste der Quelldateien, die das Build-System zum Generieren des Moduls verwendet. Listen Sie nur die Dateien auf, die das Build-System tatsächlich an den Compiler übergibt, da das Build-System automatisch alle zugehörigen Abhängigkeiten berechnet. Beachten Sie, dass Sie sowohl relative (zu LOCAL_PATH
) als auch absolute Dateipfade verwenden können.
Wir empfehlen, absolute Dateipfade zu vermeiden. Relative Pfade machen Ihre Android.mk
-Datei portabler.
LOCAL_CPP_EXTENSION
Sie können diese optionale Variable verwenden, um eine andere Dateiendung als .cpp
für Ihre C++-Quelldateien anzugeben. Die folgende Zeile ändert beispielsweise die Erweiterung in .cxx
. (Die Einstellung muss einen Punkt enthalten.)
LOCAL_CPP_EXTENSION := .cxx
Mithilfe dieser Variablen können Sie mehrere Erweiterungen angeben. Beispiel:
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
LOCAL_CPP_FEATURES
Mit dieser optionalen Variablen können Sie angeben, dass Ihr Code auf bestimmten C++-Funktionen basiert. Während des Build-Prozesses werden die richtigen Compiler- und Verknüpfungs-Flags aktiviert. Bei vordefinierten Binärdateien deklariert diese Variable auch, von welchen Funktionen das Binärprogramm abhängt, sodass die endgültige Verknüpfung korrekt funktioniert. Wir empfehlen, diese Variable zu verwenden, anstatt -frtti
und -fexceptions
direkt in der LOCAL_CPPFLAGS
-Definition zu aktivieren.
So kann das Build-System die passenden Flags für jedes Modul verwenden. Bei Verwendung von LOCAL_CPPFLAGS
verwendet der Compiler unabhängig vom tatsächlichen Bedarf alle angegebenen Flags für alle Module.
Wenn Sie beispielsweise angeben möchten, dass in Ihrem Code RTTI (RunTime Type Information) verwendet wird, schreiben Sie Folgendes:
LOCAL_CPP_FEATURES := rtti
Um anzugeben, dass Ihr Code C++-Ausnahmen verwendet, schreiben Sie:
LOCAL_CPP_FEATURES := exceptions
Sie können auch mehrere Werte für diese Variable angeben. Beispiele:
LOCAL_CPP_FEATURES := rtti features
Die Reihenfolge, in der Sie die Werte beschreiben, spielt keine Rolle.
LOCAL_C_INCLUDES
Sie können diese optionale Variable verwenden, um eine Liste von Pfaden relativ zum NDK-Verzeichnis root
anzugeben, die beim Kompilieren aller Quellen (C, C++ und Assembly) in den „Einschließen“-Suchpfad hinzugefügt werden sollen. Beispiele:
LOCAL_C_INCLUDES := sources/foo
Oder sogar:
LOCAL_C_INCLUDES := $(LOCAL_PATH)/<subdirectory>/foo
Definieren Sie diese Variable, bevor Sie entsprechende Einschluss-Flags über LOCAL_CFLAGS
oder LOCAL_CPPFLAGS
festlegen.
Das Build-System verwendet außerdem automatisch LOCAL_C_INCLUDES
-Pfade, wenn das native Debugging mit ndk-gdb gestartet wird.
LOCAL_CFLAGS
Diese optionale Variable legt Compiler-Flags für das Build-System fest, die beim Erstellen von C- und C++-Quelldateien übergeben werden. Diese Möglichkeit kann nützlich sein, um zusätzliche Makrodefinitionen oder Kompilierungsoptionen anzugeben. Verwenden Sie LOCAL_CPPFLAGS
, um Flags nur für C++ anzugeben.
Ändern Sie möglichst nicht die Optimierungs-/Fehlerbehebungsstufe in der Android.mk
-Datei.
Das Build-System kann diese Einstellung automatisch für Sie übernehmen. Dabei werden die relevanten Informationen in der Datei Application.mk
verwendet. Auf diese Weise kann das Build-System nützliche Datendateien generieren, die für die Fehlerbehebung verwendet werden.
Sie können zusätzliche Einschlusspfade angeben, indem Sie Folgendes schreiben:
LOCAL_CFLAGS += -I<path>,
Es ist jedoch besser, für diesen Zweck LOCAL_C_INCLUDES
zu verwenden, da dadurch auch die Pfade verwendet werden können, die für das native Debugging mit ndk-gdb verfügbar sind.
LOCAL_CPPFLAGS
Ein optionaler Satz von Compiler-Flags, die nur beim Erstellen von C++-Quelldateien übergeben werden. Sie werden nach dem LOCAL_CFLAGS
in der Befehlszeile des Compilers angezeigt. Verwenden Sie LOCAL_CFLAGS
, um Flags für C und C++ anzugeben.
LOKALE_STATISCHE_LIBRARIES
Diese Variable speichert die Liste der statischen Bibliotheken, von denen das aktuelle Modul abhängt.
Wenn das aktuelle Modul eine gemeinsam genutzte Bibliothek oder eine ausführbare Datei ist, erzwingt diese Variable die Verknüpfung dieser Bibliotheken mit der resultierenden Binärdatei.
Wenn das aktuelle Modul eine statische Bibliothek ist, zeigt diese Variable lediglich an, dass andere Module, die vom aktuellen Modul abhängen, ebenfalls von den aufgeführten Bibliotheken abhängig sind.
LOCAL_SHARED_LIBRARIES
Diese Variable ist die Liste der Module der gemeinsam genutzten Bibliotheken, von denen dieses Modul zur Laufzeit abhängt. Diese Informationen sind zum Zeitpunkt der Verknüpfung und zum Einbetten der entsprechenden Informationen in der generierten Datei erforderlich.
LOCAL_WHOLE_STATIC_LIBRARIES
Diese Variable ist eine Variante von LOCAL_STATIC_LIBRARIES
und gibt an, dass die Verknüpfung die verknüpften Bibliotheksmodule als ganze Archive behandeln soll. Weitere Informationen zu ganzen Archiven finden Sie in der GNU ld-Dokumentation für das Flag --whole-archive
.
Diese Variable ist nützlich, wenn zwischen mehreren statischen Bibliotheken kreislaufbasierte Abhängigkeiten bestehen. Wenn Sie diese Variable zum Erstellen einer gemeinsam genutzten Bibliothek verwenden, wird das Build-System gezwungen, alle Objektdateien aus Ihren statischen Bibliotheken der endgültigen Binärdatei hinzuzufügen. Dasselbe gilt jedoch nicht, wenn ausführbare Dateien generiert werden.
LOCAL_LDLIBS
Diese Variable enthält eine Liste zusätzlicher Verknüpfungs-Flags zum Erstellen der gemeinsam genutzten Bibliothek oder ausführbaren Datei. Damit können Sie das Präfix -l
verwenden, um den Namen bestimmter Systembibliotheken zu übergeben. Im folgenden Beispiel wird die Verknüpfung z. B. angewiesen, ein Modul zu generieren, das beim Laden eine Verknüpfung zu /system/lib/libz.so
herstellt:
LOCAL_LDLIBS := -lz
Eine Liste der verfügbaren Systembibliotheken, die Sie in diesem NDK-Release verknüpfen können, finden Sie unter Native APIs.
LOCAL_LDFLAGS
Die Liste anderer Verknüpfungs-Flags, die das Build-System beim Erstellen der gemeinsam genutzten Bibliothek oder ausführbaren Datei verwenden soll. So verwenden Sie beispielsweise die ld.bfd
-Verknüpfung auf ARM/X86:
LOCAL_LDFLAGS += -fuse-ld=bfd
LOCAL_ALLOW_UNDEFINED_SYMBOLS
Wenn das Build-System beim Erstellen einer freigegebenen Referenz auf eine nicht definierte Referenz stößt, wird standardmäßig der Fehler undefined symbol ausgegeben. Mit diesem Fehler können Sie Programmfehler im Quellcode erkennen.
Um diese Prüfung zu deaktivieren, legen Sie diese Variable auf true
fest. Diese Einstellung kann dazu führen, dass die gemeinsam genutzte Bibliothek zur Laufzeit geladen wird.
LOCAL_ARM_MODE
Standardmäßig generiert das Build-System ARM-Zielbinärdateien im thumb-Modus, wobei jede Anweisung 16 Bit breit und mit den STL-Bibliotheken im Verzeichnis thumb/
verknüpft ist. Wenn Sie diese Variable als arm
definieren, wird das Build-System gezwungen, die Objektdateien des Moduls im 32-Bit-arm
-Modus zu generieren. Das folgende Beispiel zeigt, wie das funktioniert:
LOCAL_ARM_MODE := arm
Sie können das Build-System auch anweisen, nur bestimmte Quellen im arm
-Modus zu erstellen, indem Sie das Suffix .arm
an die Namen der Quelldateien anhängen. Im folgenden Beispiel wird das Build-System angewiesen, bar.c
immer im ARM-Modus zu kompilieren, aber foo.c
gemäß dem Wert von LOCAL_ARM_MODE
zu erstellen.
LOCAL_SRC_FILES := foo.c bar.c.arm
LOCAL_ARM_NEON
Diese Variable ist nur relevant, wenn du ein Targeting auf das ABI (armeabi-v7a
) vornimmst. Sie ermöglicht die Verwendung von NEON-Compiler (ARM Advanced SIMD) in Ihren C- und C++-Quellen sowie NEON-Anweisungen in Assembly-Dateien.
Beachten Sie, dass nicht alle ARMv7-basierten CPUs die NEON-Befehlssatzerweiterungen unterstützen. Aus diesem Grund müssen Sie eine Laufzeiterkennung durchführen, um diesen Code zur Laufzeit sicher verwenden zu können. Weitere Informationen finden Sie unter Neon-Unterstützung und CPU-Features.
Alternativ können Sie das Suffix .neon
verwenden, um anzugeben, dass das Build-System nur bestimmte Quelldateien mit NEON-Unterstützung kompiliert. Im folgenden Beispiel kompiliert das Build-System foo.c
mit Daumen- und Neon-Unterstützung, bar.c
mit Daumen- und zoo.c
-Unterstützung für ARM und NEON:
LOCAL_SRC_FILES = foo.c.neon bar.c zoo.c.arm.neon
Wenn Sie beide Suffixe verwenden, muss .arm
vor .neon
stehen.
LOCAL_DISABLE_FORMAT_STRING_CHECKS
Standardmäßig kompiliert das Build-System Code mit Formatstringschutz. Dies erzwingt einen Compiler-Fehler, wenn ein nicht konstanter Formatstring in einer Funktion im printf
-Stil verwendet wird. Dieser Schutz ist standardmäßig aktiviert, Sie können ihn aber deaktivieren, indem Sie den Wert dieser Variablen auf true
setzen. Wir raten davon ab, ohne einen triftigen Grund zu tun.
LOCAL_EXPORT_CFLAGS
Diese Variable zeichnet eine Reihe von C/C++-Compiler-Flags auf, die zur LOCAL_CFLAGS
-Definition jedes anderen Moduls hinzugefügt werden, das dieses Flag über die Variablen LOCAL_STATIC_LIBRARIES
oder LOCAL_SHARED_LIBRARIES
verwendet.
Sehen Sie sich beispielsweise das folgende Modulpaar an: foo
und bar
, abhängig von 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)
Hier übergibt das Build-System beim Erstellen von bar.c
die Flags -DFOO=1
und -DBAR=2
an den Compiler. Außerdem werden exportierte Flags dem LOCAL_CFLAGS
des Moduls vorangestellt, sodass Sie sie einfach überschreiben können.
Darüber hinaus ist die Beziehung zwischen den Modulen transitiv: Wenn zoo
von bar
abhängt, das wiederum von foo
abhängt, übernimmt zoo
auch alle aus foo
exportierten Flags.
Schließlich verwendet das Build-System keine exportierten Flags bei der lokalen Erstellung (d.h. beim Erstellen des Moduls, dessen Flags exportiert werden). Daher wird -DFOO=1
beim Erstellen von foo/foo.c
im obigen Beispiel nicht an den Compiler übergeben. Wenn Sie Builds lokal erstellen möchten, verwenden Sie stattdessen LOCAL_CFLAGS
.
LOCAL_EXPORT_CPPFLAGS
Diese Variable ist mit LOCAL_EXPORT_CFLAGS
identisch, gilt jedoch nur für C++-Flags.
LOCAL_EXPORT_C_INCLUDES
Diese Variable ist mit LOCAL_EXPORT_CFLAGS
identisch, aber für C sind Pfade erforderlich. Dies ist beispielsweise nützlich, wenn bar.c
Header aus dem Modul foo
enthalten muss.
LOCAL_EXPORT_LDFLAGS
Diese Variable ist mit LOCAL_EXPORT_CFLAGS
identisch, nur für Verknüpfungs-Flags.
LOCAL_EXPORT_LDLIBS
Diese Variable ist mit LOCAL_EXPORT_CFLAGS
identisch und weist das Build-System an, Namen bestimmter Systembibliotheken an den Compiler zu übergeben. Stellen Sie -l
dem Namen jeder Bibliothek voran, die Sie angeben.
Das Build-System fügt importierte Verknüpfungs-Flags an den Wert der Variablen LOCAL_LDLIBS
Ihres Moduls an. Dies basiert auf der Funktionsweise von Unix-Verknüpfungen.
Diese Variable ist in der Regel nützlich, wenn das Modul foo
eine statische Bibliothek ist und Code enthält, der von einer Systembibliothek abhängig ist. Anschließend können Sie die Abhängigkeit mit LOCAL_EXPORT_LDLIBS
exportieren. Beispiele:
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 diesem Beispiel setzt das Build-System -llog
an das Ende des Verknüpfungsbefehls, wenn libbar.so
erstellt wird. Dadurch wird der Verknüpfung mitgeteilt, dass libbar.so
von foo
abhängt und deshalb auch von der Logging-Bibliothek des Systems abhängt.
LOCAL_SHORT_COMMANDS
Legen Sie diese Variable auf true
fest, wenn das Modul eine sehr hohe Anzahl von Quellen und/oder abhängigen statischen oder gemeinsam genutzten Bibliotheken hat. Dadurch wird das Build-System gezwungen, die @
-Syntax für Archive zu verwenden, die Zwischenobjektdateien oder verknüpfte Bibliotheken enthalten.
Diese Funktion kann unter Windows nützlich sein, wo die Befehlszeile maximal 8.191 Zeichen akzeptiert, was für komplexe Projekte zu klein sein kann. Er wirkt sich auch auf die Kompilierung einzelner Quelldateien aus, da fast alle Compiler-Flags auch in Listendateien enthalten sind.
Beachten Sie, dass jeder andere Wert als true
auf das Standardverhalten zurückgesetzt wird. Sie können APP_SHORT_COMMANDS
auch in der Datei Application.mk
definieren, um dieses Verhalten für alle Module in Ihrem Projekt zu erzwingen.
Wir raten davon ab, dieses Feature standardmäßig zu aktivieren, da es den Build verlangsamt.
LOCAL_THIN_ARCHIVE
Legen Sie diese Variable beim Erstellen statischer Bibliotheken auf true
fest. Dadurch wird ein Thin-Archiv erstellt, also eine Bibliotheksdatei, die keine Objektdateien enthält, sondern nur Dateipfade zu den tatsächlichen Objekten, die sie normalerweise enthalten würde.
Dies ist nützlich, um die Größe Ihrer Build-Ausgabe zu reduzieren. Der Nachteil ist, dass solche Bibliotheken nicht an einen anderen Speicherort verschoben werden können (alle darin enthaltenen Pfade sind relativ).
Gültige Werte sind true
, false
oder leer. In der Datei Application.mk
kann über die Variable APP_THIN_ARCHIVE
ein Standardwert festgelegt werden.
LOCAL_FILTER_ASM
Definieren Sie diese Variable als Shell-Befehl, mit dem das Build-System die Assembly-Dateien filtert, die aus den für LOCAL_SRC_FILES
angegebenen Dateien extrahiert oder generiert wurden. Das Definieren dieser Variablen führt zu Folgendem:
- Das Build-System generiert eine temporäre Assembly-Datei aus einer beliebigen C- oder C++-Quelldatei, anstatt sie in eine Objektdatei zu kompilieren.
- Das Build-System führt den Shell-Befehl in
LOCAL_FILTER_ASM
für jede temporäre Assembly-Datei und für jede inLOCAL_SRC_FILES
aufgeführte Assembly-Datei aus und generiert so eine weitere temporäre Assembly-Datei. - Das Build-System kompiliert diese gefilterten Assembly-Dateien in eine Objektdatei.
Beispiele:
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“ entspricht dem Compiler, „2“ dem Filter und „3“ dem Assembler. Der Filter muss ein eigenständiger Shell-Befehl sein, der den Namen der Eingabedatei als erstes und den Namen der Ausgabedatei als zweites Argument verwendet. Beispiele:
myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S
myasmfilter bar.S $OBJS_DIR/bar.S
Von NDK bereitgestellte Funktionsmakros
In diesem Abschnitt werden die vom NDK bereitgestellten GNU Make-Funktionsmakros erläutert. Sie werden mit $(call <function>)
ausgewertet. Sie geben dann Textinformationen zurück.
mein-dir
Dieses Makro gibt den Pfad des letzten enthaltenen Makefile zurück. Dies ist in der Regel das aktuelle Verzeichnis von Android.mk
. Mit my-dir
können Sie LOCAL_PATH
am Anfang der Android.mk
-Datei definieren. Beispiele:
LOCAL_PATH := $(call my-dir)
Aufgrund der Funktionsweise von GNU Make gibt dieses Makro tatsächlich den Pfad des letzten Makefile zurück, das das Build-System beim Parsen der Build-Skripts eingefügt hat. Aus diesem Grund sollten Sie my-dir
nicht aufrufen, nachdem Sie eine weitere Datei hinzugefügt haben.
Betrachten Sie zum Beispiel das folgende Beispiel:
LOCAL_PATH := $(call my-dir)
# ... declare one module
include $(LOCAL_PATH)/foo/`Android.mk`
LOCAL_PATH := $(call my-dir)
# ... declare another module
Das Problem hier ist, dass der zweite Aufruf von my-dir
LOCAL_PATH
als $PATH/foo
und nicht als $PATH
definiert, da der letzte Einschluss darauf verwiesen wurde.
Sie können dieses Problem vermeiden, indem Sie zusätzliche "Einschließen"-Elemente nach allen anderen Elementen der Datei Android.mk
einfügen. Beispiele:
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
Wenn es nicht möglich ist, die Datei auf diese Weise zu strukturieren, speichern Sie den Wert des ersten my-dir
-Aufrufs in einer anderen Variablen. Beispiele:
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
Gibt die Liste der Android.mk
-Dateien zurück, die sich in allen Unterverzeichnissen des aktuellen my-dir
-Pfads befinden.
Sie können diese Funktion verwenden, um tief verschachtelte Quellverzeichnishierarchien für das Build-System bereitzustellen. Standardmäßig sucht der NDK nur in dem Verzeichnis nach Dateien, das die Datei Android.mk
enthält.
dieses Makefile
Gibt den Pfad des aktuellen Makefile zurück, von dem aus das Build-System die Funktion aufgerufen hat.
übergeordnetes Makefile
Gibt den Pfad des übergeordneten Makefile im Einschlussbaum zurück (der Pfad des Makefile, das das aktuelle Makefile enthält).
Großeltern-Makefile
Gibt den Pfad des übergeordneten Makefile im Einschlussbaum zurück (der Pfad des Makefile, in dem das aktuelle Makefile enthalten ist).
Modul importieren
Eine Funktion, mit der Sie die Datei Android.mk
eines Moduls nach dem Namen des Moduls suchen und einfügen können. Hier ein typisches Beispiel:
$(call import-module,<name>)
In diesem Beispiel sucht das Build-System in der Liste der Verzeichnisse, auf die Ihre NDK_MODULE_PATH
-Umgebungsvariablen verweist, nach dem Modul mit dem Tag <name>
und fügt die Datei Android.mk
automatisch für Sie ein.