本篇記錄一下如何寫 Android.mk,雖然 Google 已經開始全面地改用 Android.bp,但這段過渡期可能還需幾年的時間,Android.mk 的了解以及如何撰寫還是值得學習的。
從 Android 7 Nougat 開始逐漸地改用 Android.bp
如何寫 Android.mk
首先先清理變數
1 2
| LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS)
|
指定模組名與模組變數
LOCAL_MODULE
︰模組名稱,這名稱必須是唯一,不能和既有模組相同。 如果 LOCAL_MODULE 未設定,則使用LOCAL_PACKAGE_NAME。 如果再沒有,就會編譯失敗。例如模組名叫做hello,那麼就可以透過 make hello 指令直接編譯hello這個模組。
LOCAL_SRC_FILES
︰原始碼檔案列表
引用編譯規則
1
| include $(BUILD_EXECUTABLE)
|
以下這些用來給Android.mk引用的文件及其變數,定義在build/core/config.mk
中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| BUILD_COMBOS:= $(BUILD_SYSTEM)/combo
CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk BUILD_HOST_STATIC_LIBRARY:= $(BUILD_SYSTEM)/host_static_library.mk BUILD_HOST_SHARED_LIBRARY:= $(BUILD_SYSTEM)/host_shared_library.mk BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk BUILD_SHARED_LIBRARY:= $(BUILD_SYSTEM)/shared_library.mk BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk BUILD_HOST_EXECUTABLE:= $(BUILD_SYSTEM)/host_executable.mk BUILD_PACKAGE:= $(BUILD_SYSTEM)/package.mk BUILD_PHONY_PACKAGE:= $(BUILD_SYSTEM)/phony_package.mk BUILD_HOST_PREBUILT:= $(BUILD_SYSTEM)/host_prebuilt.mk BUILD_PREBUILT:= $(BUILD_SYSTEM)/prebuilt.mk BUILD_MULTI_PREBUILT:= $(BUILD_SYSTEM)/multi_prebuilt.mk BUILD_JAVA_LIBRARY:= $(BUILD_SYSTEM)/java_library.mk BUILD_STATIC_JAVA_LIBRARY:= $(BUILD_SYSTEM)/static_java_library.mk BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.mk BUILD_DROIDDOC:= $(BUILD_SYSTEM)/droiddoc.mk BUILD_COPY_HEADERS := $(BUILD_SYSTEM)/copy_headers.mk BUILD_NATIVE_TEST := $(BUILD_SYSTEM)/native_test.mk BUILD_NATIVE_BENCHMARK := $(BUILD_SYSTEM)/native_benchmark.mk BUILD_HOST_NATIVE_TEST := $(BUILD_SYSTEM)/host_native_test.mk
BUILD_SHARED_TEST_LIBRARY := $(BUILD_SYSTEM)/shared_test_lib.mk BUILD_HOST_SHARED_TEST_LIBRARY := $(BUILD_SYSTEM)/host_shared_test_lib.mk BUILD_STATIC_TEST_LIBRARY := $(BUILD_SYSTEM)/static_test_lib.mk BUILD_HOST_STATIC_TEST_LIBRARY := $(BUILD_SYSTEM)/host_static_test_lib.mk
BUILD_NOTICE_FILE := $(BUILD_SYSTEM)/notice_files.mk BUILD_HOST_DALVIK_JAVA_LIBRARY := $(BUILD_SYSTEM)/host_dalvik_java_library.mk BUILD_HOST_DALVIK_STATIC_JAVA_LIBRARY := $(BUILD_SYSTEM)/host_dalvik_static_java_library.mk
|
範例:編譯一個可執行檔
模組名稱為 hellowrold,編譯出一個 hellowrold 的執行檔。
1 2 3 4 5 6 7 8 9
| LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS)
LOCAL_SRC_FILES := main.cpp LOCAL_MODULE := hellowrold LOCAL_CFLAGS := -Wall -Wno-unused-parameter -Werror LOCAL_SHARED_LIBRARIES :=
include $(BUILD_EXECUTABLE)
|
範例:編譯一個靜態函式庫
模組名稱為 libfoo,編譯出一個 libfoo.a 的靜態函式庫。
1 2 3 4 5 6 7 8
| LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS)
LOCAL_MODULE := libfoo LOCAL_SRC_FILES := aaa.cpp LOCAL_CFLAGS := -Wall -Wno-unused-parameter -Werror
include $(BUILD_STATIC_LIBRARY)
|
範例:編譯一個動態函式庫
模組名稱為 libfoo,編譯出一個 libfoo.so 的動態函式庫。
1 2 3 4 5 6 7 8
| LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS)
LOCAL_MODULE := libfoo LOCAL_SRC_FILES := aaa.cpp LOCAL_CFLAGS := -Wall -Wno-unused-parameter -Werror
include $(BUILD_SHARED_LIBRARY)
|
範例:編譯一個 APK 文件
1 2 3 4 5 6 7 8
| LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_STATIC_JAVA_LIBRARIES := static-library LOCAL_PACKAGE_NAME := LocalPackage
include $(BUILD_PACKAGE)
|
範例:編譯一個 Java 的靜態函式庫
1 2 3 4 5 6 7 8
| LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_JAVA_LIBRARIES := android.test.runner LOCAL_MODULE := sample
include $(BUILD_STATIC_JAVA_LIBRARY)
|
下表格為常用與常見的編譯規則
引用編譯規則變數 |
檔名 |
說明 |
BUILD_EXECUTABLE |
executable.mk |
編譯成裝置上的可執行檔 |
BUILD_STATIC_LIBRARY |
static_library.mk |
編譯成裝置上的靜態函式庫 |
BUILD_SHARED_LIBRARY |
shared_library.mk |
編譯成裝置上的動態函式庫 |
BUILD_PREBUILT |
prebuilt.mk |
處理一個預編譯好的檔案 (例如.a, .so, .jar) |
BUILD_PACKAGE |
package.mk |
編譯成apk |
參考
[1] Android.mk的深入介绍
https://note.qidong.name/2017/08/android-mk/
[2] 理解 Android Build 系統
https://www.ibm.com/developerworks/cn/opensource/os-cn-android-build/