Android.mk

Halaman ini menjelaskan sintaksis file build Android.mk yang digunakan oleh ndk-build.

Ringkasan

File Android.mk terletak dalam subdirektori yang ada dalam direktori jni/ project Anda, serta menjelaskan sumber dan library bersama untuk sistem build. File ini merupakan fragmen GNU makefile yang sangat kecil, yang diurai sebanyak satu atau beberapa kali oleh sistem build. File Android.mk berguna untuk menentukan setelan tingkat project yang dibiarkan tidak ditentukan oleh Application.mk, sistem build, dan variabel lingkungan Anda. File ini juga dapat menggantikan setelan tingkat project untuk modul tertentu.

Sintaksis Android.mk memungkinkan Anda mengelompokkan sumber menjadi beberapa modul. Modul dapat berupa library statis, library bersama, atau executable mandiri. Anda dapat menentukan satu atau beberapa modul dalam setiap file Android.mk, dan menggunakan file sumber yang sama dalam beberapa modul sekaligus. Sistem build hanya menempatkan library bersama ke dalam paket aplikasi Anda. Selain itu, library statis dapat menghasilkan library bersama.

Selain memaketkan library, sistem build juga menangani detail lainnya untuk Anda. Misalnya, Anda tidak perlu mencantumkan file header atau dependensi eksplisit antar-file yang dihasilkan dalam file Android.mk. Sistem build NDK otomatis menghitung hubungan ini untuk Anda. Dengan demikian, Anda dapat memanfaatkan dukungan platform/toolchain baru dalam rilis NDK mendatang tanpa harus mengubah file Android.mk.

Sintaksis file ini sangat mirip dengan yang digunakan dalam file Android.mk yang didistribusikan bersama Proyek Open Source Android lengkap. Meskipun implementasi sistem build yang menggunakannya berbeda, keputusan desain intensionalnya tetap sama, yang dimaksudkan untuk memudahkan developer aplikasi menggunakan kembali kode sumber untuk library eksternal.

Dasar-dasar

Sebelum mempelajari sintaksisnya secara mendetail, mulailah dengan memahami hal-hal dasar tentang apa yang ada dalam file Android.mk. Bagian ini menggunakan file Android.mk dalam contoh Hello-JNI sampai akhir, yang menjelaskan peran setiap baris dalam file.

File Android.mk harus dimulai dengan menentukan variabel LOCAL_PATH:

LOCAL_PATH := $(call my-dir)

Variabel ini menunjukkan lokasi file sumber dalam struktur pengembangan. Di sini, fungsi makro my-dir yang disediakan oleh sistem build akan menampilkan jalur direktori saat ini (direktori yang berisi file Android.mk itu sendiri).

Baris berikutnya mendeklarasikan variabel CLEAR_VARS, yang nilainya diberikan oleh sistem build.

include $(CLEAR_VARS)

Variabel CLEAR_VARS mengarah ke GNU Makefile khusus yang mengosongkan banyak variabel LOCAL_XXX untuk Anda, seperti LOCAL_MODULE, LOCAL_SRC_FILES, dan LOCAL_STATIC_LIBRARIES. Perlu diperhatikan bahwa variabel ini tidak mengosongkan LOCAL_PATH. Variabel ini harus mempertahankan nilainya karena sistem akan mengurai semua file kontrol build dalam satu konteks eksekusi GNU Make, yang semua variabelnya bersifat global. Anda harus mendeklarasikan (kembali) variabel ini sebelum menjelaskan setiap modul.

Selanjutnya, variabel LOCAL_MODULE menyimpan nama modul yang ingin Anda buat. Gunakan variabel ini sekali per modul dalam aplikasi Anda.

LOCAL_MODULE := hello-jni

Setiap nama modul harus unik dan tidak memuat spasi. Saat menghasilkan versi final file library bersama, sistem build akan otomatis menambahkan awalan dan akhiran yang sesuai pada nama yang Anda berikan untuk LOCAL_MODULE. Misalnya, contoh di atas menghasilkan pembuatan library yang bernama libhello-jni.so.

Baris berikutnya mengenumerasi file sumber, dengan spasi untuk memisahkan beberapa file:

LOCAL_SRC_FILES := hello-jni.c

Variabel LOCAL_SRC_FILES harus memuat daftar file sumber C dan/atau C++ untuk di-build menjadi sebuah modul.

Baris terakhir membantu sistem menyatukan semuanya:

include $(BUILD_SHARED_LIBRARY)

Variabel BUILD_SHARED_LIBRARY mengarah ke skrip GNU Makefile yang mengumpulkan semua informasi yang Anda tentukan dalam variabel LOCAL_XXX sejak include terbaru. Skrip ini menentukan apa yang akan dibuat, dan cara membuatnya.

Anda dapat melihat contoh yang lebih kompleks dalam direktori contoh, dengan file Android.mk yang sudah diberi komentar. Selain itu, Contoh: native-activity memberikan penjelasan mendetail tentang file Android.mk contoh tersebut. Terakhir, Variabel dan Makro memberikan informasi lebih lanjut tentang variabel tersebut dari bagian berikut ini.

Variabel dan Makro

Sistem build menyediakan berbagai kemungkinan variabel untuk digunakan dalam file Android.mk. Beberapa variabel ini disertai nilai yang sudah ditetapkan sebelumnya. Untuk variabel lainnya, Anda perlu menetapkan sendiri nilainya.

Selain variabel-variabel tersebut, Anda juga dapat menentukan variabel bebas. Jika ingin menentukannya, perlu diingat bahwa sistem build NDK tidak mengizinkan nama variabel berikut:

  • Nama yang diawali dengan LOCAL_, seperti LOCAL_MODULE.
  • Nama yang diawali dengan PRIVATE_, NDK_, atau APP. Sistem build menggunakannya secara internal.
  • Nama yang menggunakan huruf kecil, misalnya my-dir. Sistem build juga menggunakannya secara internal.

Jika perlu menentukan sendiri variabel yang diinginkan dalam file Android.mk, sebaiknya awali namanya dengan MY_.

Variabel penyertaan yang ditentukan NDK

Bagian ini membahas berbagai variabel GNU Make yang ditentukan oleh sistem build sebelum mengurai file Android.mk. Dalam keadaan tertentu, NDK mungkin mengurai file Android.mk beberapa kali, menggunakan definisi yang selalu berbeda untuk sebagian variabel ini.

CLEAR_VARS

Variabel ini menunjuk ke skrip build yang menghapus definisi hampir semua variabel LOCAL_XXX yang tercantum di bagian "Variabel yang ditentukan developer" di bawah. Gunakan variabel ini untuk menyertakan skrip berikut sebelum membuat modul baru. Sintaksis untuk menggunakannya adalah:

include $(CLEAR_VARS)

BUILD_EXECUTABLE

Variabel ini mengarah ke skrip build yang mengumpulkan semua informasi tentang modul yang Anda berikan dalam variabel LOCAL_XXX, dan menentukan cara mem-build executable target dari sumber yang Anda cantumkan. Perlu diperhatikan bahwa untuk menggunakan skrip ini, Anda harus sudah menetapkan nilai setidaknya ke variabel LOCAL_MODULE dan LOCAL_SRC_FILES (untuk mengetahui informasi selengkapnya tentang variabel tersebut, lihat Variabel Deskripsi Modul).

Sintaksis untuk menggunakan variabel ini adalah:

include $(BUILD_EXECUTABLE)

BUILD_SHARED_LIBRARY

Variabel ini mengarah ke skrip build yang mengumpulkan semua informasi tentang modul yang Anda berikan dalam variabel LOCAL_XXX, dan menentukan cara mem-build library bersama target dari sumber yang Anda cantumkan. Perlu diperhatikan bahwa untuk menggunakan skrip ini, Anda harus sudah menetapkan nilai setidaknya ke variabel LOCAL_MODULE dan LOCAL_SRC_FILES (untuk mengetahui informasi selengkapnya tentang variabel tersebut, lihat Variabel Deskripsi Modul).

Sintaksis untuk menggunakan variabel ini adalah:

include $(BUILD_SHARED_LIBRARY)

Variabel library bersama menyebabkan sistem build menghasilkan file library dengan ekstensi .so.

BUILD_STATIC_LIBRARY

Salah satu varian BUILD_SHARED_LIBRARY yang digunakan untuk mem-build library statis. Sistem build tidak menyalin library statis ke project/paket Anda, tetapi dapat menggunakannya untuk mem-build library bersama (lihat LOCAL_STATIC_LIBRARIES dan LOCAL_WHOLE_STATIC_LIBRARIES di bawah). Sintaksis untuk menggunakan variabel ini adalah:

include $(BUILD_STATIC_LIBRARY)

Variabel library statis menyebabkan sistem build menghasilkan library dengan ekstensi .a.

PREBUILT_SHARED_LIBRARY

Mengarah ke skrip build yang digunakan untuk menetapkan library bersama bawaan. Tidak seperti BUILD_SHARED_LIBRARY dan BUILD_STATIC_LIBRARY, di sini nilai LOCAL_SRC_FILES tidak boleh berupa file sumber. Nilai harus berupa jalur tunggal ke library bersama bawaan, misalnya foo/libfoo.so. Sintaksis untuk menggunakan variabel ini adalah:

include $(PREBUILT_SHARED_LIBRARY)

Anda juga dapat mereferensikan library bawaan dalam modul lain menggunakan variabel LOCAL_PREBUILTS. Untuk mengetahui informasi selengkapnya tentang penggunaan library bawaan, lihat Menggunakan Library Bawaan.

PREBUILT_STATIC_LIBRARY

Sama seperti PREBUILT_SHARED_LIBRARY, tetapi untuk library statis bawaan. Untuk mengetahui informasi selengkapnya tentang penggunaan library bawaan, lihat Menggunakan Library Bawaan.

Variabel informasi target

Sistem build akan mengurai Android.mk satu kali per ABI yang ditetapkan oleh variabel APP_ABI, yang biasanya ditentukan dalam file Application.mk. Jika APP_ABI adalah all, sistem build akan mengurai Android.mk sekali per ABI yang didukung NDK. Bagian ini menjelaskan variabel yang ditentukan oleh sistem build setiap kali sistem mengurai Android.mk.

TARGET_ARCH

Jenis CPU yang menjadi target sistem build ketika mengurai file Android.mk ini. Variabel ini akan berupa salah satu dari: arm, arm64, x86, atau x86_64.

TARGET_PLATFORM

Nomor API level Android yang ditargetkan sistem build saat mengurai file Android.mk ini. Misalnya, image sistem Android 5.1 memiliki Android API level 22: android-22. Untuk melihat daftar lengkap nama platform dan image sistem Android terkait, lihat API Native Android NDK. Contoh berikut menampilkan sintaksis untuk menggunakan variabel ini:

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

TARGET_ARCH_ABI

ABI yang ditargetkan sistem build saat mengurai file Android.mk ini. Tabel 1 menunjukkan setelan ABI yang digunakan untuk setiap CPU dan arsitektur yang didukung.

Tabel 1. Setelan ABI untuk berbagai CPU dan arsitektur.

CPU dan arsitektur Setelan
ARMv7 armeabi-v7a
AArch64 ARMv8 arm64-v8a
i686 x86
x86-64 x86_64

Contoh berikut menunjukkan cara memeriksa AArch64 ARMv8 sebagai kombinasi CPU-dan-ABI target:

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

Untuk mengetahui detail selengkapnya tentang ABI arsitektur dan masalah kompatibilitas terkait, lihat Pengelolaan ABI.

Di masa mendatang, ABI target baru akan memiliki nilai yang berbeda.

TARGET_ABI

Penyambungan ABI dan API level Android target. Berguna khususnya saat Anda ingin menguji image sistem target tertentu untuk perangkat aktual. Misalnya, untuk memeriksa perangkat ARM 64 bit yang dijalankan di Android API level 22:

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

Variabel Deskripsi Modul

Variabel-variabel di bagian ini mendeskripsikan modul Anda ke sistem build. Setiap deskripsi modul harus mengikuti alur dasar berikut:

  1. Menginisialisasi atau menghapus definisi variabel yang terkait dengan modul, dengan menggunakan variabel CLEAR_VARS.
  2. Menetapkan nilai ke variabel yang digunakan untuk mendeskripsikan modul.
  3. Menetapkan sistem build NDK untuk menggunakan skrip build yang sesuai untuk modul, dengan menggunakan variabel BUILD_XXX.

LOCAL_PATH

Variabel ini digunakan untuk memberikan jalur file saat ini. Anda harus menentukannya di bagian awal file Android.mk. Contoh berikut menunjukkan cara melakukannya:

LOCAL_PATH := $(call my-dir)

Skrip yang ditunjukkan CLEAR_VARS tidak mengosongkan variabel ini. Oleh karena itu, Anda hanya perlu menentukannya satu kali, meskipun file Android.mk Anda menjelaskan beberapa modul.

LOCAL_MODULE

Variabel ini menyimpan nama modul. Nama ini harus unik di antara semua nama modul, dan tidak boleh berisi spasi. Anda harus menentukannya sebelum menyertakan skrip apa pun (selain skrip untuk CLEAR_VARS). Anda tidak perlu menambahkan awalan lib maupun ekstensi file .so atau .a; sistem build melakukan perubahan ini secara otomatis. Di seluruh file Android.mk dan Application.mk, rujuk modul Anda dengan namanya yang belum diubah. Misalnya, baris berikut menghasilkan pembuatan modul library bersama yang bernama libfoo.so:

LOCAL_MODULE := "foo"

Jika ingin modul yang dihasilkan memiliki nama selain lib + nilai LOCAL_MODULE, Anda dapat menggunakan variabel LOCAL_MODULE_FILENAME untuk menamai modul yang dihasilkan sesuai keinginan Anda sendiri.

LOCAL_MODULE_FILENAME

Variabel opsional ini memungkinkan Anda mengganti nama yang digunakan secara default oleh sistem build untuk file yang dihasilkannya. Misalnya, jika nama LOCAL_MODULE Anda adalah foo, Anda dapat memaksa sistem untuk memanggil file libnewfoo yang dihasilkannya. Contoh berikut menunjukkan cara melakukannya:

LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo

Untuk modul library bersama, contoh berikut ini akan menghasilkan file bernama libnewfoo.so.

LOCAL_SRC_FILES

Variabel ini memuat daftar file sumber yang digunakan sistem build untuk menghasilkan modul. Hanya cantumkan file yang benar-benar diteruskan oleh sistem build ke compiler; karena sistem build akan otomatis menghitung setiap dependensi yang terkait. Perlu diperhatikan bahwa Anda dapat menggunakan jalur file relatif (untuk LOCAL_PATH) dan juga absolut.

Namun, sebaiknya hindari jalur file absolut; karena dengan jalur relatif file Android.mk akan menjadi lebih portabel.

LOCAL_CPP_EXTENSION

Anda dapat menggunakan variabel opsional ini untuk mengindikasikan ekstensi file selain .cpp bagi file sumber C++. Misalnya, baris berikut ini akan mengubah ekstensi menjadi .cxx. (Setelan ini harus menyertakan titik.)

LOCAL_CPP_EXTENSION := .cxx

Anda dapat menggunakan variabel ini untuk menentukan banyak ekstensi. Sebagai contoh:

LOCAL_CPP_EXTENSION := .cxx .cpp .cc

LOCAL_CPP_FEATURES

Anda dapat menggunakan variabel opsional ini untuk menunjukkan bahwa kode Anda bergantung pada fitur C++ tertentu. Variabel ini akan mengaktifkan flag compiler dan linker yang tepat selama proses build. Untuk biner bawaan, variabel ini juga mendeklarasikan pada fitur mana biner bergantung, yang kemudian membantu memastikan penautan akhir berjalan dengan benar. Sebaiknya gunakan variabel ini, bukan mengaktifkan -frtti dan -fexceptions secara langsung dalam definisi LOCAL_CPPFLAGS.

Penggunaan variabel ini memungkinkan sistem build menggunakan tanda yang sesuai untuk setiap modul. Penggunaan LOCAL_CPPFLAGS menyebabkan compiler menggunakan semua tanda yang ditentukan untuk semua modul, terlepas dari kebutuhan sebenarnya.

Misalnya, untuk menunjukkan bahwa kode Anda menggunakan RTTI (waktu proses Type Information), tulislah:

LOCAL_CPP_FEATURES := rtti

Untuk menunjukkan bahwa kode Anda menggunakan pengecualian C++, tulislah:

LOCAL_CPP_FEATURES := exceptions

Anda juga bisa menetapkan banyak nilai untuk variabel ini. Contoh:

LOCAL_CPP_FEATURES := rtti features

Urutan Anda mendeskripsikan nilai-nilai tersebut tidaklah penting.

LOCAL_C_INCLUDES

Anda dapat menggunakan variabel opsional ini untuk menetapkan daftar jalur, yang relatif terhadap direktori root NDK, yang akan ditambahkan ke jalur penelusuran penyertaan saat mengompilasi semua sumber (C, C++, dan Assembly). Contoh:

LOCAL_C_INCLUDES := sources/foo

Atau bahkan:

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

Tentukan variabel ini sebelum menetapkan flag penyertaan yang terkait melalui LOCAL_CFLAGS atau LOCAL_CPPFLAGS.

Sistem build juga otomatis menggunakan jalur LOCAL_C_INCLUDES saat meluncurkan proses debug native dengan ndk-gdb.

LOCAL_CFLAGS

Variabel opsional ini menetapkan flag compiler yang akan diteruskan oleh sistem build saat mem-build file sumber C dan C++. Kemampuan ini dapat berguna untuk menentukan definisi makro atau opsi kompilasi tambahan. Gunakan LOCAL_CPPFLAGS untuk menentukan flag bagi C++ saja.

Cobalah untuk tidak mengubah level pengoptimalan/proses debug dalam file Android.mk. Sistem build dapat otomatis menangani setelan ini untuk Anda, menggunakan informasi yang relevan dalam file Application.mk. Dengan cara ini, sistem build dapat menghasilkan file data berguna yang digunakan pada proses debug.

Jalur penyertaan tambahan dapat ditetapkan dengan menulis:

LOCAL_CFLAGS += -I<path>,

Namun, sebaiknya gunakan LOCAL_C_INCLUDES untuk keperluan ini, karena cara tersebut juga memungkinkan penggunaan jalur yang tersedia untuk proses debug native dengan ndk-gdb.

LOCAL_CPPFLAGS

Kumpulan flag compiler opsional yang akan diteruskan saat mem-build file sumber C++ saja. Flag tersebut akan ditampilkan setelah LOCAL_CFLAGS pada command line compiler. Gunakan LOCAL_CFLAGS untuk menetapkan flag bagi C dan C++.

LOCAL_STATIC_LIBRARIES

Variabel ini menyimpan daftar modul library statis yang menjadi tempat bergantung modul saat ini.

Jika modul saat ini berupa library bersama atau file executable, variabel ini akan memaksa library tersebut untuk ditautkan ke biner yang dihasilkan.

Jika modul saat ini berupa library statis, variabel ini hanya menunjukkan bahwa modul lain yang bergantung pada library saat ini juga akan bergantung pada library yang dicantumkan.

LOCAL_SHARED_LIBRARIES

Variabel ini adalah daftar modul library bersama yang menjadi tempat bergantungnya modul ini selama waktu proses. Informasi ini diperlukan pada waktu penautan, dan untuk menyematkan informasi yang sesuai ke dalam file yang dihasilkan.

LOCAL_WHOLE_STATIC_LIBRARIES

Variabel ini merupakan varian dari LOCAL_STATIC_LIBRARIES, dan menyatakan bahwa linker harus memperlakukan modul library yang terkait sebagai arsip utuh. Untuk mengetahui informasi selengkapnya tentang arsip utuh, baca dokumentasi Id GNU untuk flag --whole-archive.

Variabel ini berguna apabila ada dependensi sirkular di antara beberapa library statis. Jika Anda menggunakan variabel ini untuk mem-build library bersama, sistem build akan dipaksa untuk menambahkan semua file objek dari library statis Anda ke biner akhir. Akan tetapi, hal yang sama tidak berlaku saat menghasilkan file executable.

LOCAL_LDLIBS

Variabel ini memuat daftar flag linker tambahan untuk digunakan dalam pembuatan library bersama atau executable. Dengan variabel ini, Anda dapat menggunakan awalan -l untuk meneruskan nama library sistem tertentu. Misalnya, contoh berikut memberi tahu linker untuk menghasilkan modul yang menautkan ke /system/lib/libz.so pada waktu pemuatan:

LOCAL_LDLIBS := -lz

Untuk melihat daftar library sistem terbuka yang dapat Anda tautkan dalam rilis NDK ini, lihat API Native Android NDK.

LOCAL_LDFLAGS

Daftar flag linker lain yang akan digunakan sistem build saat mem-build library bersama atau executable. Misalnya, untuk menggunakan linker ld.bfd di ARM/X86:

LOCAL_LDFLAGS += -fuse-ld=bfd

LOCAL_ALLOW_UNDEFINED_SYMBOLS

Secara default, saat sistem build menemukan referensi yang tidak ditentukan sewaktu mencoba mem-build library bersama, maka error simbol yang tidak ditentukan akan muncul. Error ini dapat membantu Anda menemukan bug dalam kode sumber.

Untuk menonaktifkan pemeriksaan ini, tetapkan variabel ini ke true. Perhatikan bahwa setelan ini dapat menyebabkan library bersama dimuat pada waktu proses.

LOCAL_ARM_MODE

Secara default, sistem build menghasilkan biner target ARM dalam mode thumb, yang setiap petunjuknya berukuran 16 bit dan tertaut dengan library STL dalam direktori thumb/. Menentukan variabel ini sebagai arm akan memaksa sistem build menghasilkan file objek modul dalam mode arm 32 bit. Contoh berikut menunjukkan cara melakukannya:

LOCAL_ARM_MODE := arm

Anda juga dapat memerintahkan sistem build agar hanya mem-build sumber tertentu dalam mode arm dengan menambahkan akhiran .arm ke nama file sumber. Misalnya, contoh berikut ini memberi tahu sistem build agar selalu mengompilasi bar.c dalam mode ARM, tetapi mem-build foo.c menurut nilai LOCAL_ARM_MODE.

LOCAL_SRC_FILES := foo.c bar.c.arm

LOCAL_ARM_NEON

Variabel ini hanya diperlukan jika Anda menargetkan ABI armeabi-v7a. Dengan variabel ini, Anda dapat menggunakan intrinsik compiler ARM Advanced SIMD (NEON) dalam sumber C dan C++, serta petunjuk NEON dalam file Assembly.

Perhatikan, tidak semua CPU berbasis ARMv7 mendukung ekstensi kumpulan petunjuk NEON. Karena alasan ini, Anda harus menjalankan deteksi waktu proses agar dapat menggunakan kode ini dengan aman pada waktu proses. Untuk mengetahui informasi selengkapnya, lihat Dukungan NEON dan Library cpufeatures.

Atau, Anda dapat menggunakan akhiran .neon untuk menentukan bahwa sistem build hanya mengompilasi file sumber tertentu dengan dukungan NEON. Dalam contoh berikut, sistem build mengompilasi foo.c dengan dukungan thumb dan NEON, bar.c dengan dukungan thumb, dan zoo.c dengan dukungan untuk ARM dan NEON:

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

Jika Anda menggunakan kedua akhiran, .arm harus mendahului .neon.

LOCAL_DISABLE_FORMAT_STRING_CHECKS

Secara default, sistem build mengompilasi kode dengan perlindungan string format. Dengan cara ini, error compiler akan ditampilkan jika string format nonkonstanta digunakan dalam fungsi bergaya printf. Perlindungan ini diaktifkan secara default, tetapi Anda dapat menonaktifkannya dengan menetapkan nilai variabel ini ke true. Kami tidak merekomendasikan tindakan ini jika tidak diharuskan.

LOCAL_EXPORT_CFLAGS

Variabel ini mencatat sekumpulan flag compiler C/C++ yang akan ditambahkan ke definisi LOCAL_CFLAGS milik modul lain yang menggunakannya melalui variabel LOCAL_STATIC_LIBRARIES atau LOCAL_SHARED_LIBRARIES.

Misalnya, pertimbangkan sepasang modul berikut: foo dan bar, yang bergantung pada 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)

Di sini, sistem build meneruskan flag -DFOO=1 dan -DBAR=2 ke compiler saat mem-build bar.c. Sistem build juga terlebih dahulu menambahkan flag yang diekspor ke LOCAL_CFLAGS modul sehingga Anda dapat menggantinya dengan mudah.

Selain itu, hubungan antarmodul bersifat transitif: Jika zoo bergantung pada bar, yang kemudian bergantung pada foo, maka zoo juga akan mewarisi semua flag yang diekspor dari foo.

Terakhir, sistem build tidak menggunakan flag yang diekspor saat mem-build modul secara lokal (yaitu mem-build modul yang flag-nya sedang diekspor olehnya). Oleh karena itu, dalam contoh di atas, sistem ini tidak meneruskan -DFOO=1 ke compiler saat mem-build foo/foo.c. Untuk mem-build modul secara lokal, gunakan LOCAL_CFLAGS.

LOCAL_EXPORT_CPPFLAGS

Variabel ini sama dengan LOCAL_EXPORT_CFLAGS, tetapi hanya untuk tanda C++.

LOCAL_EXPORT_C_INCLUDES

Variabel ini sama dengan LOCAL_EXPORT_CFLAGS, tetapi untuk jalur penyertaan C. Variabel ini akan berguna jika, misalnya, bar.c perlu menyertakan header dari modul foo.

LOCAL_EXPORT_LDFLAGS

Variabel ini sama dengan LOCAL_EXPORT_CFLAGS, tetapi untuk tanda linker.

LOCAL_EXPORT_LDLIBS

Variabel ini sama dengan LOCAL_EXPORT_CFLAGS, yang memberi tahu sistem build untuk meneruskan nama library sistem tertentu ke compiler. Tambahkan -l di depan nama setiap library yang Anda tetapkan.

Perlu diperhatikan bahwa sistem build menambahkan flag linker yang diimpor pada nilai variabel LOCAL_LDLIBS modul Anda. Hal ini dilakukan untuk mengikuti cara kerja linker Unix.

Variabel ini biasanya berguna ketika modul foo merupakan library statis dan memiliki kode yang bergantung pada library sistem. Anda kemudian dapat menggunakan LOCAL_EXPORT_LDLIBS untuk mengekspor dependensi tersebut. Contoh:

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)

Dalam contoh ini, sistem build menempatkan -llog di akhir perintah linker saat mem-build libbar.so. Cara ini akan memberi tahu linker bahwa, karena libbar.so bergantung pada foo, library ini juga bergantung pada library logging sistem.

LOCAL_SHORT_COMMANDS

Tetapkan variabel ini ke true jika modul Anda memiliki banyak sekali sumber dan/atau library statis dependen atau library bersama. Dengan demikian, sistem build akan dipaksa menggunakan sintaksis @ untuk arsip yang berisi file objek perantara atau library penghubung.

Fitur ini dapat berguna di Windows, dengan fitur command line yang hanya menerima maksimal 8191 karakter. Batas ini mungkin terlalu kecil untuk project yang kompleks. Batas ini juga memengaruhi kompilasi setiap file sumber, karena menempatkan hampir semua flag compiler ke dalam file daftar.

Perlu diperhatikan bahwa nilai selain true akan kembali ke perilaku default. Anda juga dapat menentukan APP_SHORT_COMMANDS dalam file Application.mk untuk memaksa perilaku ini bagi semua modul dalam project Anda.

Kami tidak merekomendasikan pengaktifan fitur ini secara default karena akan memperlambat build.

LOCAL_THIN_ARCHIVE

Tetapkan variabel ini ke true saat mem-build library statis. Cara ini akan menghasilkan arsip tipis, yaitu file library yang tidak memuat file objek, tetapi hanya jalur file ke objek aktual yang biasanya dimuatnya.

Hal ini berguna untuk mengurangi ukuran output build. Kelemahannya adalah library semacam ini tidak dapat dipindahkan ke lokasi lain (semua jalur di dalamnya bersifat relatif).

Nilai yang valid adalah true, false, atau kosong. Nilai default dapat ditetapkan dalam file Application.mk melalui variabel APP_THIN_ARCHIVE.

LOCAL_FILTER_ASM

Definisikan variabel ini sebagai perintah shell yang akan digunakan sistem build untuk memfilter file assembly yang diekstrak atau dihasilkan dari file yang Anda tetapkan untuk LOCAL_SRC_FILES. Menentukan variabel ini akan menyebabkan terjadinya hal berikut:

  1. Sistem build akan menghasilkan file assembly sementara dari setiap file sumber C atau C++, bukan mengompilasinya menjadi file objek.
  2. Sistem build akan menjalankan perintah shell di LOCAL_FILTER_ASM atas setiap file assembly sementara dan setiap file assembly yang tercantum di LOCAL_SRC_FILES, sehingga menghasilkan file assembly sementara lainnya.
  3. Sistem build akan mengompilasi file assembly yang telah difilter ini ke dalam file objek.

Contoh:

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" berkaitan dengan compiler, "2" dengan filter, dan "3" dengan assembler. Filter harus berupa perintah shell mandiri yang menggunakan nama file input sebagai argumen pertama, dan nama file output sebagai yang kedua. Contoh:

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

Makro fungsi yang disediakan NDK

Bagian ini menjelaskan makro fungsi GNU Make yang disediakan NDK. Gunakan $(call <function>) untuk mengevaluasinya; makro ini akan menampilkan informasi tekstual.

my-dir

Makro ini menampilkan jalur makefile yang terakhir disertakan, yang biasanya adalah direktori Android.mk saat ini. my-dir berguna untuk menentukan LOCAL_PATH pada awal file Android.mk. Contoh:

LOCAL_PATH := $(call my-dir)

Karena cara kerja GNU Make, hasil yang sebenarnya ditampilkan oleh makro ini adalah jalur makefile terakhir yang disertakan sistem build saat mengurai skrip build. Oleh karena itu, Anda tidak boleh memanggil my-dir setelah menyertakan file lain.

Misalnya, perhatikan contoh berikut:

LOCAL_PATH := $(call my-dir)

# ... declare one module

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

LOCAL_PATH := $(call my-dir)

# ... declare another module

Masalah yang ada di sini adalah panggilan kedua ke my-dir menentukan LOCAL_PATH sebagai $PATH/foo, bukan $PATH, karena penyertaan yang paling baru mengarah padanya.

Anda dapat menghindari masalah ini dengan memberikan penyertaan tambahan di bagian akhir file Android.mk. Contoh:

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

Jika tidak memungkinkan untuk menyusun file dengan cara ini, simpan nilai panggilan my-dir yang pertama ke dalam variabel lain. Contoh:

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

Menampilkan daftar file Android.mk yang berada dalam semua subdirektori jalur my-dir saat ini.

Anda dapat menggunakan fungsi ini untuk memberikan hierarki direktori sumber yang tersusun cukup dalam pada sistem build. Secara default, NDK hanya mencari file dalam direktori yang berisi file Android.mk.

this-makefile

Menampilkan jalur makefile saat ini (yang digunakan sistem build untuk memanggil fungsi).

parent-makefile

Menampilkan jalur makefile induk pada struktur penyertaan (jalur makefile yang menyertakan makefile saat ini).

grand-parent-makefile

Menampilkan jalur makefile induk dari induk pada struktur penyertaan (jalur makefile yang menyertakan makefile saat ini).

import-module

Fungsi yang memungkinkan Anda menemukan dan menyertakan file Android.mk modul menurut nama modul. Contoh umumnya adalah seperti berikut:

$(call import-module,<name>)

Dalam contoh ini, sistem build mencari modul yang memiliki tag <name> dalam daftar direktori yang direferensikan oleh variabel lingkungan NDK_MODULE_PATH, dan otomatis menyertakan file Android.mk miliknya untuk Anda.