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.cpp

include $(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)

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.cpp

include $(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.cpp

LOCAL_STATIC_LIBRARIES := libhello_static
LOCAL_SHARED_LIBRARIES := libhello_shared

include $(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 #
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式wu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值