Android.mk編譯C/C++,APP,改APK簽章

1. 編譯C/C++程式

##是用來單行註解
LOCAL_PATH:= $(call my-dir) # call function my-dir will return the path of Android.mk
include $(CLEAR_VARS) # 清除內建以LOCAL_開頭的變數
LOCAL_SRC_FILES:= foo.c # 程式碼檔案, 用空格,如果要換行,必須在每行結尾打\
LOCAL_MODULE:= foo # 本模組名稱, 整個AOSP內的模組名稱必須不同
include $(BUILD_EXECUTABLE) # 模組編譯成執行檔

增加C/C++編譯器的flag

LOCAL_CFLAGS += -Wall
這功能比較常用的是增加Macro定義的功能
LOCAL_CFLAGS += -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION)
LOCAL_CFLAGS += -DPLATFORM_VERSION=$(PLATFORM_VERSION)

只針對C++編譯時加入flag使用CXXFLAGS
LOCAL_CXXFLAGS += -Wall

增加C/C++的header引用目錄

LOCAL_C_INCLUDES := \
    $(TOP)/frameworks/av/media/libstagefright/include \
    $(TOP)/frameworks/av/include/media
如果要寫多行的時候記得注意換行時要用\符號,然後, 有些編輯器會自動把第2行前面的空白變成Tab造成編譯問題(這是因為Makefile的規則寫法是要用Tab才有效)
$(TOP)是AOSP編譯時會自動帶入workspace的頂層目錄

使用Static Library

LOCAL_STATIC_LIBRARIES := \
    libstagefright_nuplayer \
    libstagefright_rtsp

使用的Shared Library

LOCAL_SHARED_LIBRARIES := \
    libbinder \
    libcamera_client

指定模組輸出的路徑

LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/myconfig
LOCAL_MODULE_PATH :=$(TARGET_OUT)/lib

一些常用的目錄:
TOP  你目前AOSP的workspace頂層目錄
TARGET_OUT               => out/target/product/{your-device-name}/system
TARGET_ROOT_OUT  => out/target/product/{your-device-name}/root
TARGET_OUT_DATA  => out/target/product/{your-device-name}/data

TARGET_OUT_ETC    => out/target/product/{your-device-name}/etc

2. 編譯APP

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := MyDemoApp
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_DEX_PREOPT := false
include $(BUILD_PACKAGE)

上面的編譯會在src目錄下搜尋所有java原始碼並編譯

如果要在其他Android裝置上安裝編譯出來的APK,設置LOCAL_DEX_PREOPT := false才會生成含有classes.dex的APK檔案

如果要納入APP使用的JNI library,請加入
LOCAL_JNI_SHARED_LIBRARIES := libyourjni

提醒您:APP程式碼記得要load library
    static {
        System.loadLibrary("yourjni");
    }

如果要生成特權APP,請設置
LOCAL_PRIVILEGED_MODULE := true

如果要用特殊簽章, 可以用LOCAL_CERTIFICATE指定成media,platform,shared,testkey等
LOCAL_CERTIFICATE := platform

如果要使用自己的簽章, 也可以用LOCAL_CERTIFICATE指定成檔案
LOCAL_CERTIFICATE := $(LOCAL_PATH)/mykey

產生APP用簽章

到AOSP頂層目錄用make_key產生簽章用pk8和.x509.pem
development/tools/make_key mykey '/C=TW/ST=Taipei/L=Taipei/O=Example Inc./OU=Taipei /CN=Example/emailAddress=test@example.com.tw'

C     : Country Name (2 letter code)
ST    : State or Province Name (full name)
L     : Locality Name (eg, city)
O     : Organization Name (eg, company)
OU    : Organizational Unit Name (eg, section)
CN    : Common Name (eg, your name or your server’s hostname)
emailAddress : Contact email address

Ref: https://maoao530.github.io/2017/01/31/android-build-sign/

3. 改APK簽章

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := AppName # APP的模組名稱
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk #如果
模組名稱和檔案不一樣,這裡請改成檔案名稱
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_MODULE_TAGS := optional
include $(BUILD_PREBUILT)

4. 其他好用的Android.mk語法

印出platform及SDK版本

$(warning PLATFORM_VERSION [$(PLATFORM_VERSION)] PLATFORM_SDK_VERSION [$(PLATFORM_SDK_VERSION)])

條件判斷

依照板子的平台版本不同, 用不同的目錄編譯
ifeq ($(TARGET_BOARD_PLATFORM),meson6)
    src_dir := src-m6
else ifeq ($(TARGET_BOARD_PLATFORM),meson8)
    src_dir := src-m8
else
    src_dir := src
endif

依照Android的版本不同加入不同CFLAG

ifneq (0, $(shell expr $(PLATFORM_VERSION) \> 4.1.0))
    LOCAL_CFLAGS += -D_VERSION_JB
else
    ifneq (0, $(shell expr $(PLATFORM_VERSION) \> 4.0.0))
        LOCAL_CFLAGS += -D_VERSION_ICS
    endif
endif

將data_dir下的*.lib產生md5sum檔

# generate md5 checksum files
$(shell cd $(LOCAL_PATH)/$(data_dir) && { \
for f in *.lib; do \
  md5sum "$$f" > "$$f".md5sum; \
done;})

將檔案產生成列表

# gather list of relative filenames
in_files := $(wildcard $(LOCAL_PATH)/$(data_dir)/*.lib)
in_files += $(wildcard $(LOCAL_PATH)/$(data_dir)/*.md5sum)
in_files := $(patsubst $(LOCAL_PATH)/%,%,$(in_files))

搜尋目錄下的特定副檔名

可以用all-java-files-under使用all-named-files-under的方式
define all-java-files-under
$(call all-named-files-under,*.java,$(1))
endef

define all-named-files-under
$(call find-files-in-subdirs,$(LOCAL_PATH),"$(1)",$(2))
endef

留言