本文示例如下:
https://github.com/hanyuhang-hz/android-demos
externalTest/test.zip
Android.mk的编译可按编程语言分为:
(1)C/C++
可编译为可执行文件,动态库或静态库文件。
(2)Java
可编译为jar包或apk。
1 一个简单的Android.mk例子
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_SRC_FILES := test.c
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_EXECUTABLE)
test.c:
#include <stdio.h>
int main() {
printf("hyh test! \n");
return 0;
}
mmm external/test/1
...
[100% 3/3] Install: external/test/test
#### build completed successfully (19 seconds) ####
查看生成可执行文件的格式:file test
external/test/test: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, BuildID[md5/uuid]=f2b0744bf9b392b2100f5dc43c9b112f, stripped
下面来分析这个简单的Android.mk:
(1)LOCAL_PATH:=$(call my-dir)
LOCAL_PATH是指Android.mk所在的目录。
(2)include $(CLEAR_VARS)
CLEAR_VARS是指清空所有环境变量,除了LOCAL_PATH。
为什么"include $(CLEAR_VARS)"要放在"LOCAL_PATH:=$(call my-dir)"之后?是因为如果放在之前,clear_vars.mk的路径会被作为LOCAL_PATH!!!
(3)LOCAL_MODULE:=test
编译生成的模块名
(4)LOCAL_SRC_FILES:=test.c
指定源文件
(5)LOCAL_MODULE_PATH := $(LOCAL_PATH)
指定生成目标文件的目录
(6)include $(BUILD_EXECUTABLE)
设置目标文件格式,这里是可执行文件。
2 Android.mk基本语法
2.1 多源码文件编译
(1)每个文件添加到Android.mk中
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_SRC_FILES := test.c \
call.c
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_EXECUTABLE)
call.c:
void call() {
return ;
}
test.c:
#include <stdio.h>
// extern:可置于变量或者函数前,以表示变量或者函数的定义在其他的文件中
extern void call();
int main() {
call();
printf("hyh test! \n");
return 0;
}
(2)使用系统提供的函数
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test
#LOCAL_SRC_FILES := test.c \
call.c
LOCAL_ALL_C_FILES := $(call all-c-files-under)
LOCAL_SRC_FILES := $(LOCAL_ALL_C_FILES)
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_EXECUTABLE)
注意:all-c-files-under定义在build/core/definitions.mk,my-dir也定义在该文件
2.2 一个mk中编译多个目标文件
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_ALL_C_FILES := $(call all-c-files-under)
LOCAL_SRC_FILES := $(LOCAL_ALL_C_FILES)
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_MODULE := test1
LOCAL_ALL_C_FILES := $(call all-c-files-under)
LOCAL_SRC_FILES := $(LOCAL_ALL_C_FILES)
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_EXECUTABLE)
test.c:
#include <stdio.h>
int main() {
printf("hyh test! \n");
return 0;
}
注意:目录下更新所有文件,touch externel/test/*
2.3 编译动态库
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libcall
LOCAL_ALL_C_FILES := $(call all-c-files-under)
LOCAL_SRC_FILES := $(LOCAL_ALL_C_FILES)
#LOCAL_SRC_FILES := call.c
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_SHARED_LIBRARY)
编译类型为:BUILD_SHARED_LIBRARY
call.c:
void call() {
return ;
}
2.4 编译静态库
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libtest
LOCAL_ALL_C_FILES := $(call all-c-files-under)
LOCAL_SRC_FILES := $(LOCAL_ALL_C_FILES)
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_STATIC_LIBRARY)
编译类型为:BUILD_STATIC_LIBRARY
call.c:
void call() {
return ;
}
2.5 引用系统库
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_SRC_FILES := test.c
LOCAL_SHARED_LIBRARIES += liblog
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_EXECUTABLE)
LOCAL_SHARED_LIBRARIES += liblog
test.c:
#include <stdio.h>
#define LOG_TAG "HYH"
#include <utils/Log.h>
int main() {
printf("hyh test! \n");
ALOGE("test!");
return 0;
}
2.6 引用第三方库
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libcall
LOCAL_SRC_FILES := call.c
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_SRC_FILES := test.c
LOCAL_SHARED_LIBRARIES += liblog
LOCAL_LDFLAGS := -L./ -lcall
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_EXECUTABLE)
LOCAL_LDFLAGS := -L/Path -lxxx
call.c:
void call() {
return ;
}
test.c:
#include <stdio.h>
#define LOG_TAG "HYH"
#include <utils/Log.h>
// extern:可置于变量或者函数前,以表示变量或者函数的定义在其他的文件中
extern void call();
int main() {
call();
printf("hyh test! \n");
ALOGE("test!");
return 0;
}
2.7 引用第三方头文件
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libcall
LOCAL_SRC_FILES := call.c
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_SRC_FILES := test.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/inc/
LOCAL_SHARED_LIBRARIES += liblog
LOCAL_LDFLAGS := -L./ -lcall
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_EXECUTABLE)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/inc/
注意:LOCAL_C_INCLUDES需要绝对路径。
inc/call.h:
#ifndef CALL_H
#define CALL_H
extern void call();
#endif
call.c:
void call() {
return ;
}
test.c:
#include <stdio.h>
#define LOG_TAG "HYH"
#include <utils/Log.h>
#include <call.h>
int main() {
call();
printf("hyh test! \n");
ALOGE("test!");
return 0;
}
2.8 引用静态库
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libcall
LOCAL_SRC_FILES := call.c
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_STATIC_LIBRARY)
#include $(CLEAR_VARS)
#LOCAL_MODULE := test
#LOCAL_SRC_FILES := test.c
#LOCAL_C_INCLUDES := $(LOCAL_PATH)/inc/
#LOCAL_SHARED_LIBRARIES += liblog
#LOCAL_LDFLAGS := $(LOCAL_PATH)/lib/libcall.a
#LOCAL_MODULE_PATH := $(LOCAL_PATH)
#include $(BUILD_EXECUTABLE)
注意:静态库生成在如下目录,需要手动拷贝到当前目录。
out/target/product/xxx/obj/STATIC_LIBRARIES/libcall_intermediates/libcall.a
call.c:
void call() {
return ;
}
test.c:
#include <stdio.h>
#define LOG_TAG "HYH"
#include <utils/Log.h>
#include <call.h>
int main() {
call();
printf("hyh test! \n");
ALOGE("test!");
return 0;
}
call.h:
#ifndef CALL_H
#define CALL_H
extern void call();
#endif
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libcall
LOCAL_SRC_FILES := call.c
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_SRC_FILES := test.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/inc/
LOCAL_SHARED_LIBRARIES += liblog
LOCAL_LDFLAGS := $(LOCAL_PATH)/libcall.a
LOCAL_MODULE_PATH := $(LOCAL_PATH)
include $(BUILD_EXECUTABLE)
注意:LOCAL_LDFLAGS需要绝对路径。
2.9 编译生成apk
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := TestPackage
include $(BUILD_PACKAGE)
BUILD_PACKAGE:表示编译生成apk
LOCAL_PACKAGE_NAME:表示编译生成的apk名字
2.10 编译生成jar包
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE := com.test.jar
include $(BUILD_STATIC_JAVA_LIBRARY)
#include $(BUILD_JAVA_LIBRARY)
jar包分类:
(1)静态jar包:
include $(BUILD_STATIC_JAVA_LIBRARY)
编译时使用.class文件打包而成的jar文件,可以在任何java虚拟机上运行
(2)动态jar包:
include $(BUILD_JAVA_LIBRARY)
编译时在静态jar包的基础上,使用.dex打包而成的jar文件,只能在android系统上运行
2.11 apk引用jar包
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_STATIC_JAVA_LIBRARIES := static-library
#LOCAL_JAVA_LIBRARIES := share-library
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := TestPackage
include $(BUILD_PACKAGE)
2.12 预编译jar包
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_MODULE := com.test.share
LOCAL_SRC_FILES := com.test.static
include $(BUILD_PREBUILT)
将静态jar包预编译为动态jar包。
LOCAL_MODULE_CLASS:表示预编译的文件类型
(1)JAVA_LIBRARIES:动态jar包
(2)APPS:apk
(3)SHARED_LIBRARIES:动态库文件so
(4)EXECUTABLES:二进制文件
(5)ETC:其他文件
2.13 Android.mk判断语法
ifeq ($(VALUE, x))
...
else
...
endif
USED_SHARE := true
ifeq ($(USED_SHARE), true)
LOCAL_LDFLAGS := -L./ -ltest
else
LOCAL_LDFLAGS := $(LOCAL_PATH)/lib/libcall.a
endif