android.mk 执行脚本,Android.mk的用法

(1)Android.mk是什么?

Android.mk是Android提供的一种makefile文件。Android.mk其实是把真正的Makefile包装起来,做成了一个对使用者来说很简单的东西。

你可以在每一个Android.mk file中定义一个或多个模块。每个模块属下列类型之一:

1)APK程序,一般的Android程序,编译打包生成apk文件

2)JAVA库,java类库,编译打包生成jar文件

3)  C\C++应用程序,可执行的C\C++应用程序

4)C\C++静态库,编译生成C\C++静态库,并打包成.a文件

5)C\C++共享库, 编译生成共享库(动态链接库),并打包成.so, 有且只有共享库才能被安装/复制到您的应用软件(APK)包中。

使用它来编译程序时,不管是动态库、可执行的二进制文件,还是Jar库、APK包,只要沿着一个简单的思路来做三大步就可以了:清除旧变量,设置新变量,调用编译函数。

(2)举例子

(一)BUILD_SHARED_LIBRARY——动态库

chris/superuser/su.cchris/superuser/Android.mk相应的Android.mk文件会像下面这样:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE

:= su

LOCAL_SRC_FILES := su.c

include $(BUILD_SHARED_LIBRARY)

1,

LOCAL_PATH := $(call my-dir): 一个Android.mk file首先必须定义好LOCAL_PATH变量.它用于在开发树中查找源文件。在这个例子中,宏函数‘my-dir’, 由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录)。

2,include $( CLEAR_VARS),CLEAR_VARS由编译系统提供((可以在 android 安装目录下的/build/core/config.mk 文件看到其定义,为 CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk)),指定让GNU MAKEFILE为你清除许多LOCAL_XXX变量(例如 LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 等等...) 。这是必要的,因为所有的编译控制文件都在同一个GNU MAKE执行环境中,所有的变量都是全局的

3,LOCAL_MODULE := su,LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的。注意编译系统会自动产生合适的前缀和后缀,换句话说,一个被命名为'foo'的共享库模块,将会生成'libfoo.so'文件

4,LOCAL_SRC_FILES := su.c,LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的C或C++源代码文件。注意,你不用在这里列出头文件和包含文件,因为编译系统将会自动为你找出依赖型的文件;仅仅列出直接传递给编译器的源代码文件就好。

5,LOCAL_C_INCLUDES:可选变量,表示头文件的搜索路径。默认的头文件的搜索路径是LOCAL_PATH目录。示例:LOCAL_C_INCLUDES := sources/foo或LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo

6,LOCAL_STATIC_LIBRARIES: 表示该模块需要使用哪些静态库,以便在编译时进行链接。

7,LOCAL_SHARED_LIBRARIES:  表示模块在运行时要依赖的共享库(动态库),在链接时就需要,以便在生成文件时嵌入其相应的信息

8,include $(call all-subdir-makefiles):返回一个位于当前'my-dir'路径的子目录中的所有Android.mk的列表。

(二)BUILD_EXECUTABLE——二进制文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES:= su.c

LOCAL_MODULE:= su

#LOCAL_C_INCLUDES :=

#LOCAL_STATIC_LIBRARIES :=

#LOCAL_SHARED_LIBRARIES :=

include $(BUILD_EXECUTABLE)

(三) BUILD_STATIC_LIBRARY——静态库

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:= /helloworld.cLOCAL_MODULE:= libtest_static#LOCAL_C_INCLUDES :=#LOCAL_STATIC_LIBRARIES :=#LOCAL_SHARED_LIBRARIES :=include $(BUILD_STATIC_LIBRARY)

BUILD_STATIC_LIBRARY表示编译一个静态库.a文件。静态库不会复制到的APK包中,但是能够用于编译共享库

补充:include $(BUILD_PACKAGE)则是编译出一个apk,include $(BUILD_STATIC_JAVA_LIBRARY)则是编译出jar包

(a)以上三者的生成结果分别在

out/target/product/generic/obj/EXECUTABLE

out/target/product/generic/obj/STATIC_LIBRARY

out/target/product/generic/obj/SHARED_LIBRARY

(b)每个模块的目标文件夹分别为:

可执行程序:XXX_intermediates

静态库:      XXX_static_intermediates

动态库:      XXX_shared_intermediates

(c)在Android.mk文件中,还可以指定最后的目标安装路径,用LOCAL_MODULE_PATH和LOCAL_UNSTRIPPED_PATH来指定。不同的文件系统路径用以下的宏进行选择:

TARGET_ROOT_OUT:表示根文件系统out/target/product/xxxxx/root。

TARGET_OUT:表示system文件系统out/target/product/xxxx/system。

TARGET_OUT_DATA:表示data文件系统out/target/product/xxxx/data。

TARGET_OUT_SHARED_LIBRARIES:表示out/target/product/xxxx/system/lib

TARGET_OUT_APPS:表示out/target/product/xxxx/system/app

ANDROID_PRODUCT_OUT:out/target/product/xxxx/

TARGET_OUT_JAVA_LIBRARIES:out/target/product/xxxx/system/framework

例如:LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/src

(3)相关的编译指令

android源码目录下的build/envsetup.sh文件,描述编译的命令

- m:       Makes from the top of the tree.

- mm:      Builds all of the modules in the current directory.

- mmm:     Builds all of the modules in the supplied directories.

所以要想使用这些命令,首先需要在android源码根目录执行build/envsetup.sh 脚本设置环境。

m:编译所有的模块

mm:编译当前目录下的模块,当前目录下要有Android.mk文件

mmm:编译指定路径下的模块,指定路径下要有Android.mk文件

下面举个例子说明,假设我要编译android下的\hardware\libhardware_legacy\power模块,当前目录为源码根目录,方法如下:

1、. build/envsetup.sh

2、mmm hardware/libhardware_legacy/power/

或者 :

1、. build/envsetup.sh

2、cd hardware/libhardware_legacy/power/

3、mm

实际开发中,并不需要每次都编译所有源代码,只需要编译自己修改的模块即可。Android的编译系统提供了强大的机制支持单独模块的编译,而且十分简单。Android提供三种方式用于编译单独模块:

make 模块名

mm (来自于envsetup.sh脚本中注册的函数)

mmm (来自于envsetup.sh脚本中注册的函数)

1.make 模块名

这种方法适合第一次编译,会把依赖模块一并编译。它需要在全部源代码中找到编译模块的Android.mk文件,并检查依赖模块是否有修改,因此编译时间较长。使用这种方法,我们只需要搜索源码目录下的Android.mk文件,找到模块名,然后指定给make即可。

对于应用层程序,需要查看Android.mk文件的LOCAL_PACKAGE_NAME变量

例如,要编译Phone应用程序的源码,先查看Phone的Android.mk文件

……(省略部分内容)

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE:=com.android.phone.common

……(省略部分内容)

LOCAL_PACKAGE_NAME:=Phone

……(省略部分内容)

得到编译参数后,在终端中运行如下命令便可单独编译Phone模块及其依赖模块:allong@android:~/android/.../***(Android.mk所在目录下编译)$

make Phone

2.mmm命令

该命令是envsetup.sh中注册的函数,用于在源码根目录编译指定模块,参数为模块的相对路径。只能在第一次编译后使用。比如要编译Phone部分源码,需要在终端中执行以下命令:

allong@android:~/android/jellybean$mmm packages/apps/phone

3.mm命令

该命令也是envsetup.sh中注册的函数,用于在模块根目录编译这个模块。只能在第一次编译后使用。例如要编译Phone部分源码,需要在终端中执行以下命令

注意 mmm和mm命令必须在执行“.build/envsetup.sh”之后才能使用,并且只编译发生变化的文件。

(4)Android 手工编译C程序的整个过程

1,先将你要编译的C代码模块 放入已经编译好的android源码目录下

b66f8e19b8ba2d98da13b844f98e3102.png

efdb6438aa0d2ecdb8f155faceab9cf3.png

有些头文件是android源码目录的,可能要在Android.mk中包含进来

62db97d959589f768c9831c9f8c75b5d.png

4ca9cebfe6356ad9c5a097d0dbee316b.png

2,初始化环境(每次编译模块前都要进行初始化环境!在这里耽误了一天时间才知道)

ade5a1b917e818696299415c4da1abb6.png

5fe71010fa3115fad62ee7afea716a8b.png

初始化之后进入你要编译的C模块目录,进行编译,编译成功会有提示

fa0e7e001e1b0e40a100b7f1c6c0360b.png

886fa666caa452c44328c3fd966b62f1.png

3,因为我编译的目标文件为include $(BUILD_EXECUTABLE),编译成功后默认路径为out/target/product/shamu/obj/EXECUTABLES/su(这里是相应的模块名称)_intermediates/su(相应的模块名称),在路径下可找到你的编译结果

8ac358476a20353aacb6167ae32792ee.png

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值