当前位置: 首页 > news >正文

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)

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 #
http://www.dtcms.com/a/344862.html

相关文章:

  • Electron 核心 API 全解析:从基础到实战场景
  • 从零开始搭 Linux 环境:VMware 下 CentOS 7 的安装与配置全流程(附图解)
  • openstack的novnc兼容问题
  • 【日常学习】2025-8-20 框架中控件子类实例化设计
  • FPGA学习笔记——简单的IIC读写EEPROM
  • LeetCode 3195.包含所有 1 的最小矩形面积 I:简单题-求长方形四个范围
  • 化工生产场景下设备状态监测与智能润滑预测性维护路径
  • 校园作品互评管理移动端的设计与实现
  • Boost库中boost::random::normal_distribution(正态分布)详解和实战示例
  • 腾讯云EdgeOne安全防护:快速上手,全面抵御Web攻击
  • 如何优雅的监听dom的变化(尺寸)
  • php apache无法接收到Authorization header
  • JDK17 升级避坑指南:技术原理与解决方案详解
  • 【学习记录】structuredClone,URLSearchParams,groupBy
  • 【大语言模型 14】Transformer权重初始化策略:从Xavier到GPT的参数初始化演进之路
  • 网络编程8.22
  • Python面试常考函数
  • 技术分析 剖析一个利用FTP快捷方式与批处理混淆的钓鱼攻击
  • RSS与今日头条技术对比分析
  • Unreal Engine UObject
  • 嵌入式-EXTI的工作原理和按钮实验-Day19
  • 6口千兆图像采集卡:突破多路高清视觉系统的传输瓶颈
  • DFS序与树链剖分入门
  • RORPCAP: retrieval-based objects and relations prompt for image captioning
  • 多元函数积分学
  • kafka生产者 消费者工作原理
  • 线性回归8.21
  • 椭圆、双曲线、抛物线总对比表
  • Java 对象内存布局详解
  • Docker容器化部署实战:Tomcat与Nginx服务配置指南