返回顶部
首页 > 资讯 > 移动开发 >详谈Android编译命令
  • 115
分享到

详谈Android编译命令

Android 2022-06-06 08:06:43 115人浏览 泡泡鱼
摘要

工欲善其事,必先利其器,对于想要深入学习Android源码,必须先掌握Android编译命令. 一、引言 关于Android Build系统,这个话题很早就打算整理下,迟迟

工欲善其事,必先利其器,对于想要深入学习Android源码,必须先掌握Android编译命令.

一、引言

关于Android Build系统,这个话题很早就打算整理下,迟迟没有下笔,决定跟大家分享下。先看下面几条指令,相信编译过Android源码的人都再熟悉不过的。


source /opt/android1204_17.conf 
source setenv.sh
lunch
make -j12

记得最初刚接触Android时,同事告诉我用上面的指令就可以编译Android源码,指令虽短但过几天就记不全或者忘记顺序,每次编译时还需要看看自己的云笔记,冰冷的指令总是难以让我记忆。后来我决定认真研究下这个指令的含义。知其然还需知其所以然,这样能更深层次的理解并记忆,才能与自身的知识体系建立强连接,或许还能有意外收获,果然如此,接下来跟大家分享一下在研究上述几条指令含义的过程中,深入了解到的Android Build(编译)系统。

二、编译命令

准备好编译环境后,编译Android源码的第一步是 source build/envsetup.sh,其中source命令就是用于运行shell脚本命令,功能等价于".",因此该命令也等价于. build/envsetup.sh。在文件envsetup.sh声明了当前会话终端可用的命令,这里需要注意的是当前会话终端,也就意味着每次新打开一个终端都必须再一次执行这些指令。起初并不理解为什么新开的终端不能直接执行make指令,到这里总算明白了。

接下来,解释一下本文开头的引用的命令:

source /opt/android1204_17.conf  //初始化jdk环境变量(这个不是必需的,因厂商而异)
source setenv.sh  //初始化编译环境,包括后面的lunch和make指令
lunch  //指定此次编译的目标设备以及编译类型
make  -j12 //开始编译,默认为编译整个系统,其中-j12代表的是编译的job数量为12。
所有的编译命令都在envsetup.sh文件能找到相对应的function,比如上述的命令lunch,make,在文件一定能找到


function lunch(){
  ...
}
function make(){
  ...
}

具体实现这里就不展开说明,下面精炼地总结了一下各个指令用法和功效。

2.1 代码编译

编译指令 解释
m 在源码树的根目录执行编译
mm 编译当前路径下所有模块,但不包含依赖
mmm [module_path] 编译指定路径下所有模块,但不包含依赖
mma 编译当前路径下所有模块,且包含依赖
mmma [module_path] 编译指定路径下所有模块,且包含依赖
make [module_name] 无参数,则表示编译整个Android代码
下面列举部分模块的编译指令:

模块 make命令 mmm命令
init make init mmm system/core/init
zyGote make app_process mmm frameworks/base/cmds/app_process
system_server make services mmm frameworks/base/services
java framework make framework mmm frameworks/base
framework资源 make framework-res mmm frameworks/base/core/res
jni framework make libandroid_runtime mmm frameworks/base/core/jni
binder make libbinder mmm frameworks/native/libs/binder

上述mmm命令同样适用于mm/mma/mmma,编译系统采用的是增量编译,只会编译发生变化的目标文件。当需要重新编译所有的相关模块,则需要编译命令后增加参数-B,比如make -B [module_name],或者 mm -B [module_path]。

Tips:

对于m、mm、mmm、mma、mmma这些命令的实现都是通过make方式来完成的。
mmm/mm编译的效率很高,而make/mma/mmma编译较缓慢;
make/mma/mmma编译时会把所有的依赖模块一同编译,但mmm/mm不会;

建议:首次编译时采用make/mma/mmma编译;当依赖模块已经编译过的情况,则使用mmm/mm编译。

2.2 代码搜索

搜索指令 解释
cgrep 所有C/C++文件执行搜索操作
jgrep 所有Java文件执行搜索操作
ggrep 所有Gradle文件执行搜索操作
mangrep [keyWord] 所有AndroidManifest.xml文件执行搜索操作
sepgrep [keyword] 所有sepolicy文件执行搜索操作
resgrep [keyword] 所有本地res/*.xml文件执行搜索操作
sgrep [keyword] 所有资源文件执行搜索操作

上述指令用法最终实现方式都是基于grep指令,各个指令用法格式:

xgrep [keyword]  //x代表的是上表的搜索指令
例如,搜索所有AndroidManifest.xml文件中的launcher关键字所在文件的具体位置,指令

mangrep launcher
再如,搜索所有system_app的selinux权限信息

sepgrep system_app
Tips: Android源码非常庞大,直接采用grep来搜索代码,不仅方法笨拙、浪费时间,而且搜索出很多无意义的混淆结果。根据具体需求,来选择合适的代码搜索指令,能节省代码搜索时间,提高搜索结果的精准度,方便定位目标代码。

2.3 导航指令

导航指令 解释
croot 切换至Android根目录
cproj 切换至工程的根目录
godir [filename] 跳转到包含某个文件的目录
Tips: 当每次修改完某个文件后需要编译时,执行cproj后会跳转到当前模块的根目录,也就是Android.mk文件所在目录,然后再执行mm指令,即可编译目标模块;当进入源码层级很深后,需要返回到根目录,使用croot一条指令完成;另外cd - 指令可用于快速切换至上次目录。

2.4信息查询

查询指令 解释
hmm 查询所有的指令help信息
findmakefile 查询当前目录所在工程的Android.mk文件路径
print_lunch_menu 查询lunch可选的product
printconfig 查询各项编译变量值
gettop 查询Android源码的根目录
gettargetarch 获取TARGET_ARCH值
Tips: 当忘了前面的所有指令时,可以执行一个hmm便可输出这些指令的帮助信息。

其他指令:

make clean:执行清理操作,等价于 rm -rf out/
make update-api:更新API,在framework API改动后需执行该指令,Api记录在目录frameworks/base/api;

三、编译系统

Android 编译系统是Android源码的一部分,用于编译Android系统,Android SDK以及相关文档。该编译系统是由Make文件、Shell以及python脚本共同组成,其中最为重要的便是Make文件。关于编译系统可参考 理解 Android Build 系统。

3.1 Makefile分类

整个Build系统的Make文件分为三大类:

系统核心的Make文件:定义了Build系统的框架,文件全部位于路径/build/core,其他Make文件都是基于该框架编写的;
针对产品的Make文件:定义了具体某个型号手机的Make文件,文件路径位于/device,该目录下往往又以公司名和产品名划分两个子级目录,比如/device/qcom/msm8916;
针对模块的Make文件:整个系统分为各个独立的模块,每个模块都一个专门的Make文件,名称统一为"Android.mk",该文件定义了当前模块的编译方式。Build系统会扫描整个源码树中名为"Android.mk"的问题,并执行相应模块的编译工作。

3.2 编译产物

经过make编译后的产物,都位于/out目录,该目录下主要关注下面几个目录:

/out/host:Android开发工具的产物,包含SDK各种工具,比如adb,dex2oat,aapt等。
/out/target/common:通用的一些编译产物,包含Java应用代码和Java库;
/out/target/product/[product_name]:针对特定设备的编译产物以及平台相关C/c++代码和二进制文件;
在/out/target/product/[product_name]目录下,有几个重量级的镜像文件:

system.img:挂载为根分区,主要包含Android OS的系统文件;
ramdisk.img:主要包含init.rc文件和配置文件等;
userdata.img:被挂载在/data,主要包含用户以及应用程序相关的数据;
当然还有boot.img,reocovery.img等镜像文件,这里就不介绍了。

3.3 Android.mk解析

在源码树中每一个模块的所有文件通常都相应有一个自己的文件夹,在该模块的根目录下有一个名称为“Android.mk”
的文件。编译系统正是以模块为单位进行编译,每个模块都有唯一的模块名,一个模块可以有依赖多个其他模块,模块间的依赖关系就是通过模块名来引用的。也就是说当模块需要依赖一个jar包或者apk时,必须先将jar包或apk定义为一个模块,然后再依赖相应的模块。

对于Android.mk文件,通常都是以下面两行


LOCAL_PATH := $(call my-dir) //设置当编译路径为当前文件夹所在路径
include $(CLEAR_VARS) //清空编译环境的变量(由其他模块设置过的变量)

为方便模块编译,编译系统设置了很多的编译环境变量,如下:

LOCAL_SRC_FILES:当前模块包含的所有源码文件;
LOCAL_MODULE:当前模块的名称(具有唯一性);
LOCAL_PACKAGE_NAME:当前APK应用的名称(具有唯一性);
LOCAL_C_INCLUDES:C/C++所需的头文件路径;
LOCAL_STATIC_LIBRARIES:当前模块在静态链接时需要的库名;
LOCAL_SHARED_LIBRARIES:当前模块在运行时依赖的动态库名;
LOCAL_STATIC_JAVA_LIBRARIES:当前模块依赖的Java静态库;
LOCAL_JAVA_LIBRARIES:当前模块依赖的Java共享库;
LOCAL_CERTIFICATE:签署当前应用的证书名称,比如flatfORM
LOCAL_MODULE_TAGS:当前模块所包含的标签,可以包含多标签,可能值为debgu,eng,user,development或optional(默认值)

针对这些环境变量,编译系统还定义了一些便捷函数,如下:

$(call my-dir):获取当前文件夹路径;
$(call all-java-files-under, <src>):获取指定目录下的所有Java文件;
$(call all-c-files-under, <src>):获取指定目录下的所有C文件;
$(call all-Iaidl-files-under, <src>) :获取指定目录下的所有AIDL文件;
$(call all-makefiles-under, <folder>):获取指定目录下的所有Make文件;
示例:


 LOCAL_PATH := $(call my-dir) 
 include $(CLEAR_VARS) 
 # 获取所有子目录中的Java文件
 LOCAL_SRC_FILES := $(call all-subdir-java-files) 
 # 当前模块依赖的动态Java库名称
 LOCAL_JAVA_LIBRARIES := com.gityuan.lib 
 # 当前模块的名称
 LOCAL_MODULE := demo 
 # 将当前模块编译成一个静态的Java库
 include $(BUILD_STATIC_JAVA_LIBRARY)
您可能感兴趣的文章:单独编译Android 源代码中的模块实现方法Android内核源码 在ubuntu上下载,编译,安装Android源码 在Ubuntu上下载,编译和安装为Android的apk应用程序文件加壳以防止反编译的教程Android APK反编译图文教程Android开发apk反编译和二次打包教程Android应用程序的编译流程及使用Ant编译项目的攻略从源码编译Android系统的Java类库和JNI动态库的方法利用源码编译Android系统的APK和可执行命令的方法使用Android studio创建的AIDL编译时找不到自定义类的解决办法Android 源码如何编译调试


--结束END--

本文标题: 详谈Android编译命令

本文链接: https://lsjlt.com/news/25367.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 详谈Android编译命令
    工欲善其事,必先利其器,对于想要深入学习Android源码,必须先掌握Android编译命令. 一、引言 关于Android Build系统,这个话题很早就打算整理下,迟迟...
    99+
    2022-06-06
    Android
  • 使用cache加快编译速度的命令详解
    目录Ubuntu 安装ccache使用libzmq测试ccacheUbuntu 安装ccache sudo apt-get install ccache安装完后确认安装执行which...
    99+
    2024-04-02
  • C++编译器命令有哪些
    这篇文章给大家分享的是有关C++编译器命令有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。快要被VC6.0的编译器给搞疯了,按照自己的编码速度,今天因该把驱动通讯模块基本通过编译,但是没有想到的是,VC6.0...
    99+
    2023-06-17
  • Ubuntu上怎么编译gcc命令
    这篇文章主要讲解了“Ubuntu上怎么编译gcc命令”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Ubuntu上怎么编译gcc命令”吧!打开终端,输入以下命令编辑hello.cpp文件。vi...
    99+
    2023-07-04
  • android开发实践之ndk编译命令简单示例
    前言Android提供了NDK工具,用来编译native代码(c/c++),该工具配置好了相关的交叉编译环境和工具链,只需要你简单地编写几个.mk文件即可将你的c/c++代码编译为Android的java工程/Android手机可以识别、加...
    99+
    2023-05-31
    android ndk编译 命令
  • yum命令详解,配置本地yum源,编译安装
    一、yum简介 Yum(全称为 Yellow dogUpdater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动...
    99+
    2023-08-31
    linux 服务器 centos
  • 如何在Ubuntu上编译gcc命令
    在Ubuntu上编译gcc命令的示例:打开终端,输入以下命令编辑hello.cpp文件。vim hello.cpp输入如下代码:#include using namespace std;int main(){cout...
    99+
    2024-04-02
  • Java编译器命令行的功能
    这篇文章主要讲解了“Java编译器命令行的功能”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java编译器命令行的功能”吧!Java编译器Java编译器读取Java源代码,并将其编译成字节代...
    99+
    2023-06-17
  • 命令行编译java文件方式
    目录命令行编译java文件java在命令行编译Java源码总结命令行编译java文件 import java.util.*; public class shuchu{ pub...
    99+
    2023-05-15
    命令行编译java文件 java命令行 java编译命令行
  • Android Sqlite命令详解(基本命令)
    在Android开发中SQLite起着很重要的作用,网上SQLite的教程有很多很多,不过那些教程大多数都讲得不是很全面。本人总结了一些SQLite命令,借着论坛的大赛,跟大家...
    99+
    2022-06-06
    SQLite Android
  • 如何配置C#命令行编译器
    这篇文章主要介绍了如何配置C#命令行编译器,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.配置C#命令行编译器:我的电脑 —〉高级 —〉环境变量 —〉Path —〉添加&q...
    99+
    2023-06-17
  • java反编译class命令如何使用
    要使用Java反编译class命令,你需要安装并配置Java的反编译工具,比如JD-GUI或Jad。然后,可以按照以下步骤使用反编译...
    99+
    2023-10-20
    java
  • linux系统的编译命令怎么用
    本篇内容介绍了“linux系统的编译命令怎么用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!linux系统的编译命令是“Make”。在lin...
    99+
    2023-07-04
  • 怎么用命令行编译java文件
    这篇“怎么用命令行编译java文件”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么用命令行编译java文件”文章吧。命令行...
    99+
    2023-07-06
  • 详谈Win10命令提示符的改进
    如果你是一路从DOS走来的老用户,那么你一定对命令提示符不陌生。不过从WindowsXP时代开始一直到前不久Windows10发布,我们的老朋友命令提示符(CMD)才稍稍算跟上了时代。 全新的属性页面 点击CMD命令提示...
    99+
    2023-06-08
    Win10 命令提示符 改进
  • 用cmd命令行编译运行Java文件的方法详解
    在windows下利用cmd命令行,可以调用jdk里的javac.exe和java.exe,从而对java文件进行编译和执行,前提是jdk已成功安装并正确配置相关环境变量。下面,我们一起学习如何用cmd命令行编译运行一个Java程序。在wi...
    99+
    2019-05-06
    java入门 cmd Java
  • C语言预处理预编译命令及宏定义详解
    目录程序翻译环境和执行环境翻译环境:详解编译+链接1. 编译 — 预处理/预编译 test.c ---- test.i2. 编译 — 编译 test.i ---- test.s3. ...
    99+
    2024-04-02
  • 关于androidstudio通过命令行运行gradle编译命令的问题
    报错:Could not resolve all dependencies for configuration ':classpath'  打开android-studio的ter...
    99+
    2024-04-02
  • 浅谈Android编码规范及命名规范
    前言:   目前工作负责两个医疗APP项目的开发,同时使用LeanCloud进行云端配合开发,完全单挑。   现大框架已经完成,正在进行细节模块上的开发   抽空总结一下And...
    99+
    2022-06-06
    Android
  • Linux下c mysql程序的编译命令(转)
    Linux下c mysql程序的编译命令(转)[@more@]最好用 #gcc -o test test.c `mysql_config --cflags --libs`其它的编译命令: #gcc -o t...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作