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) # 模組編譯成執行檔
這功能比較常用的是增加Macro定義的功能
LOCAL_CFLAGS += -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION)
LOCAL_CFLAGS += -DPLATFORM_VERSION=$(PLATFORM_VERSION)
只針對C++編譯時加入flag使用CXXFLAGS
LOCAL_CXXFLAGS += -Wall
libstagefright_nuplayer \
libstagefright_rtsp
libbinder \
libcamera_client
一些常用的目錄:
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
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原始碼並編譯
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_PRIVILEGED_MODULE := true
如果要用特殊簽章, 可以用LOCAL_CERTIFICATE指定成media,platform,shared,testkey等
LOCAL_CERTIFICATE := platform
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 #如果模組名稱和檔案不一樣,這裡請改成檔案名稱
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)
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 filenamesin_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
留言