Android.mk 基础
1. Android.mk 基本概念和结构
Android.mk 文件是 Android 构建系统中定义编译规则的配置文件,主要用于描述哪些源文件需要编译,以及如何编译它们。
常见的 Android.mk 文件结构:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)LOCAL_MODULE := libhello_shared
LOCAL_SRC_FILES := hello_shared.cppinclude $(BUILD_SHARED_LIBRARY)
1.1 LOCAL_PATH := $(call my-dir)
LOCAL_PATH := $(call my-dir)
- 含义:定义当前模块(当前 Android.mk 文件所在目录)的路径。
$(call my-dir)
是一个内置函数,返回当前 Android.mk 文件所在的目录路径。- 这样写的好处是,无论这个 Android.mk 文件被放到哪个目录,都能自动识别自己路径,而不用写死绝对路径。
- 举例:
如果 Android.mk 文件在路径:
external/project/static_lib/
,那么 LOCAL_PATH 的值就是:$(TOP)/external/project/static_lib
。$(TOP) 表示 Android 源码的根目录)
- 举例:
1.2 include $(CLEAR_VARS)
- 含义:清空上一个模块设置的所有
LOCAL_ 前缀变量
,确保不会相互影响。 - Android 构建系统是顺序执行的,一个 Android.mk 文件中可能定义多个模块。
- 如果不 CLEAR_VARS,之前的 LOCAL_SRC_FILES、LOCAL_MODULE 等变量可能会“污染”后续模块。
- 你可以把它理解成 重新初始化环境,类似 C 语言里每次函数调用前清理局部变量。
1.3 LOCAL_MODULE
- LOCAL_MODULE:定义模块的名称,即生成的目标文件名(例如 .so 文件或可执行文件)。
1.4 LOCAL_SRC_FILES
定义模块的源文件,支持 .c、.cpp、.java 等文件。
1.5 其它
- LOCAL_C_INCLUDES:指定 C/C++ 头文件路径(包括目录)。
- LOCAL_STATIC_LIBRARIES:指定静态链接的库。
- LOCAL_LDLIBS:指定链接时使用的库(例如 -llog 表示链接 liblog.so)。
- include $(BUILD_SHARED_LIBRARY):编译为共享库(.so)。
- include $(BUILD_STATIC_LIBRARY):编译为静态库(.a)。
- include $(BUILD_EXECUTABLE):编译为可执行文件。
- 编译预处理
- 可以通过 LOCAL_CFLAGS 和 LOCAL_CPPFLAGS 添加编译时的预处理宏、优化选项或警告级别等。
- 例如:
LOCAL_CFLAGS := -Wall -O2
LOCAL_CPPFLAGS := -DDEBUG=1
- 多文件编译
- 在 LOCAL_SRC_FILES 中可以指定多个源文件,分行书写或者以空格隔开:
LOCAL_SRC_FILES := file1.c file2.c file3.c
- 子目录中的 Android.mk
- 如果你的项目有多个子目录,可以在顶级 Android.mk 文件中使用 $(call all-subdir-makefiles) 来包含子目录中的 Android.mk:
include $(call all-subdir-makefiles)
- 如果你的项目有多个子目录,可以在顶级 Android.mk 文件中使用 $(call all-subdir-makefiles) 来包含子目录中的 Android.mk:
2. 实战开发:
目录结构:
aosp/external/project
├── executable
│ ├── Android.mk
│ └── main.cpp
├── shared_lib
│ ├── Android.mk
│ └── hello_shared.cpp
└── static_lib├── Android.mk└── hello_static.cpp
2.1 生成 C++ 静态库
- static_lib/hello_static.cpp
#include <iostream>
void print_static_hello(){std::cout << "Hello from static library!" << std::endl;
}
- static_lib/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)LOCAL_MODULE := libhello_static # 定义静态库名称
LOCAL_SRC_FILES := hello_static.cpp # 指定源文件include $(BUILD_STATIC_LIBRARY)
- 编译:
mmm external/project/static_lib
2.2 生成 C++ 动态库
- shared_lib/hello_shared.cpp
#include <iostream>
void print_shared_hello(){std::cout << "Hello from shared library!" << std::endl;
}
- shared_lib/Android.mk
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := libhello_shared
LOCAL_SRC_FILES := hello_shared.cppinclude $(BUILD_SHARED_LIBRARY)
- 编译
mmm external/project/shared_lib
2.3 生成可执行文件并依赖静态库和动态库
- executable/main.cpp
#include <iostream>extern void print_static_hello();
extern void print_shared_hello();int main(){print_static_hello();print_shared_hello();return 0;
}
- executable/Android.mk
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := hello_executable
LOCAL_SRC_FILES := main.cppLOCAL_STATIC_LIBRARIES := libhello_static
LOCAL_SHARED_LIBRARIES := libhello_sharedinclude $(BUILD_EXECUTABLE)
- 编译:
mmm external/project/executable
2.4 调试运行
adb push out/target/product/emulator_x86_64/system/bin/hello_executable /data/local/tmp
adb push out/target/product/emulator_x86_64/obj/STATIC_LIBRARIES/libhello_static_intermediates/libhello_static.a /data/local/tmp
adb push out/target/product/emulator_x86_64/obj/SHARED_LIBRARIES/libhello_shared_intermediates/libhello_shared.so /data/local/tmp
adb shell
emulator_x86_64:/data/local/tmp # ls
hello_exe libhello_shared.so libhello_static.a
emulator_x86_64:/data/local/tmp # chmod 777 *
emulator_x86_64:/data/local/tmp # export LD_LIBRARY_PATH="./:$LD_LIBRARY_PATH"
emulator_x86_64:/data/local/tmp # ./hello_executable
Hello from static library!
Hello from shared library!
emulator_x86_64:/data/local/tmp #