Android 10 根文件系统和编译系统(七):Android.mk基本语法

 配套系列教学视频链接:

Android 10.0 AOSP源码编译:

        AOSP源码开发环境搭建教学视频-百问100ask   

       Android系统 10.0 AOSP源码编译--CSDN程序员研修院

 Android 10.0 根文件系统和编译系统:

        Android根文件系统和编译系统教学视频-百问100ask

        Android 10.0 根文件系统和编译系统-CSDN程序员研修院


说明

系统:AOSP Android10.0

设备:Android模拟器

前言

Android.mk是Android提供的一个makefile文件,对Android源码进行模块化编译, 基本语法都是基于Makfile, Android.mk可以控制编译C/C++, java等源文件,可以生成各种类型的目标文件, 如可执行程序, 动态库, 静态库, jar库, apk等,一个mk文件中可以定义一个或多个模块。本章节重点介绍Android系统中Android.mk的基本语法, 方便大家对模块进行控制编译。


一,基本语法

         Android.mk语法遵从Makefile, 所以可以在里面配置变量定义, 条件分支判断, 循环控制, 编译选项等逻辑. 

        在编写Makefile的过程中, 不同的目标文件, 编译方法会不同, 编写规则的方法也就不同, 如果需要直接编写一个Makefile来控制编译可执行程序, 动态库,静态库, jar, apk的话, 会有不同的写法,  而在Android系统中, Android.mk为我们提供一个通用的模板, 不管编译什么, 只要稍微修改一下模板即可。

Makefile的基本规则是:

目标 : 依赖

<tab> 编译方法

 而Android.mk也类似,并且更简单,类似填空, 最简单Android.mk只需要五行:

# 注释内容使用 "#" 号

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES := xxx.c

LOCAL_MODULE := xxx

include $(BUILD_EXECUTABLE)

为了让大家理解Android.mk中的各种变量, 我们通过GCC常见的命令来了解基本的编译选项。

gcc  -g  -Wall  -msoft-float  -D__KERNEL__ -I/home/peter/digilent/include -L./lib  -lpthread -lm -ltestlib      test1. c test2.c  -o mytest  

-Dmacro:相当于C语言中的#define macro

-Dmacro=defn:相当于C语言中的#define macro=defn

-Umacro :相当于C语言中的#undef macro

-Idir:指定头文件路径。

-llibrary:指定库

-Ldir:定制编译的时候,搜索库的路径。

-g:指示编译器,在编译的时候,产生调试信息。

-static:此选项将禁止使用动态库,所以,编译出来的东西,一般都很大。

-O0 -O1 -O2 -O3:编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高

-Wall:会打开一些很有用的警告选项,建议编译时加此选项。

-Werror:不区分警告和错误,遇到任何警告都停止编译

-std:指定C标准,如-std=c99使用c99标准,-std=gnu99,使用C99 再加上 GNU 的一些扩展。

二, Android.mk中各种变量解释

LOCAL_PATH

用来指定当前源码所在的目录,它不会被 CLEAR_VARS 清除,一般第一步就是定义该变量

include $(CLEAR_VARS)

CLEAR_VARS 清除很多除 LOCAL_PATH 外的变量。因为所有的 Makefile 都是在同一个编译环境在执行的,变量的定义理论上都是全局的,所以每个模块编译开始前进行清理工作是非常必要的。写法也很固定

LOCAL_SRC_FILES

此变量包含构建系统用于生成模块的源文件列表,可使用相对路径或绝对路径,但为了移植性应尽量选择使用相对路径

LOCAL_MODULE

模块名,整个编译系统中唯一存在,命名时中间不能有空格,针对编译动态库和静态库, 系统会帮你添加诸如 “lib” 前缀和 “.a” 或 “.so” 后缀等

LOCAL_PACKAGE_NAME

在编译内置app源码的时候,通过该变量来设置apk的文件名, 和LOCAL_MODULE作用一样。

LOCAL_MODULE_PATH

指定模块的输出路径

LOCAL_MODULE_RELATIVE_PATH

LOCAL_MODULE_RELATIVE_PATH := hw, 相对安装路径, 一般目标文件有默认的安装路径, 比如动态库安装路径为out/target/product/xx/system/lib,  加上 := hw就表示相对out/target/product/xx/system/lib这个路径, 加上hw, 完整路径为: out/target/product/xx/system/lib/hw

LOCAL_MODULE_TAGS

模块的一些标签,标签之间使用空格隔开,可以是optional, test, debug, user等

LOCAL_C_INCLUDES

指定引用头文件所在路径,类似gcc -Ixx

LOCAL_EXPORT_C_INCLUDES

导出当前模块的头文件路径,这样其他依赖当前模块的时候, 直接也自动拥有了当前模块指定的各种头文件路径。模板:

./external/libtextclassifier/Android.mk

在Android9上无效。

LOCAL_PROPRIETARY_MODULE

和LOCAL_VENDOR_MODULE一样, 设置为true就表示会编译到vendor分区

LOCAL_INIT_RC

编译可执行程序时,同时定义开机启动脚本, 一般放到/system/etc/init/或者/vendor/etc/init

LOCAL_CFLAGS

此可选变量为构建系统设置在构建 C 和 C++ 源文件时要传递的编译器标志。

此功能对于指定额外的宏定义或编译选项可能很有用, 如-D, -I, -L, -Werror

LOCAL_CPPFLAGS(LOCAL_CXXFLAGS)

仅当构建 C++ 源文件时才会传递一组可选的编译器标志。

它们将出现在编译器命令行中的 LOCAL_CFLAGS 后面

LOCAL_STATIC_LIBRARIES

编译所需的静态库列表, 只加载静态库中用到的函数

LOCAL_WHOLE_STATIC_LIBRARIES

在连接静态连接库的时候不会移除"daed code",何谓dead code呢,就是调用者模块永远都不会用到的代码段和变量

LOCAL_SHARED_LIBRARIES

指定c/c++代码链接所需要的动态库

LOCAL_JAVA_LIBRARIES

指定java代码链接所需要的动态库, 表示引用的外部Java库在编译时可以找到相关的东西,但并不打包到本模块,在runtime时需要从别的地方查找

LOCAL_LDLIBS

编译所需的其他链接器标志列表。它可让您使用 -l 前缀传递特定系统库的名称。例如,以下示例指示链接器生成在加载时链接到 /system/lib/libz.so 的模块:

LOCAL_LDLIBS := -lz

BUILD_XXX

一般以include $(BUILD_XXX)存在, 表示用什么规则来编译

BUILD_HOST_STATIC_LIBRARY

BUILD_HOST_SHARED_LIBRARY

BUILD_HOST_EXECUTABLE

BUILD_STATIC_LIBRARY

BUILD_SHARED_LIBRARY

BUILD_EXECUTABLE

三, Android.mk中涉及到的各种变量

TOPDIR

源码顶层目录

TARGET_OUT_ROOT

target目录,默认是out/target

PRODUCT_OUT

默认是out/target/product/{产品名},真正的编译生成文件的目录

TARGET_OUT_APPS

默认内置apk安装路径out/target/product/{产品名}/system/app

TARGET_OUT_SHARED_LIBRARIES

默认动态库安装路径out/target/product/{产品名}/system/lib64

OUT_DIR

out目录,默认情况下是源码目录下的out目录,如果指定

其实以上变量都是在build/core/envsetup.mk中定义的,同时通过命令get_build_var获取获取到。

四, Android.mk中涉及常见的函数

include $(call all-makefiles-under, subdir)

wildcard $(1)/*/Android.mk

包含某个目录下所有子目录中的Android.mk,subdir为指定某个目录,只包含一级目录,无递归

 路基格式为:  subdir/*/Android.mk

一般单独顶层目录的独立文件存在, 或者加载一个Android.mk的前面,原则: 在调用my-dir之前才能包含其他Makefile

include $(call all-subdir-makefiles)

$(call all-makefiles-under,$(call my-dir))

路基格式为:  ./*/Android.mk

包含当前目录下所有子目录的Android.mk,只包含一级目录,无递归,使用位置同上。

include $(call all-named-subdir-makefiles, subdir)

$(wildcard $(addsuffix /Android.mk, $(addprefix $(call my-dir)/,$(1))))

路基格式为:  ./subdir/Android.mk

包含当前目录中某个子目录下的Android.mk,subdir为指定某个子目录,只包含子目录一级,无递归

 使用位置同上。

$(call all-java-files-under,  main/src)

获取当前目录下main/src中所有的java文件名, 并且是递归子目录的,并返回所有java文件列表。

$(call all-c-files-under, src)

获取当前目录src中所有的c文件名, 并且是递归子目录的,并返回所有c文件列表。

总结

Android.mk中的变量特别多, 其实不需要记住, 很多东西根据经验, 都可以猜测是什么意思, 记住,你看的多就会学的多, 多看模板就会了。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

旗浩QH

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

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

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

打赏作者

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

抵扣说明:

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

余额充值