Android中转到定义怎么,Android中添加自己的模块 【转】

转:http://blog.csdn.net/yili_xie/archive/2009/12/09/4971736.aspx

这里我们向Android中添加自己的模块,只涉及到.so/*.a/elf source的编译,以及如何将prebuilt file添加进工程。对于APK以及jar的source暂时没有仔细研究,要添加进去的话可以参照/pacakge和/framework 里面的Android.mk ~~

首先是可能用得到的基础知识,必须了解基础Makefile的语法,然后下面是Andriod用来编译相应模块使用的核心makefile,当然如果要速成的话也可以不看这些东西,直接按照后面的例子添加就可以了:

1、prebuilt

/build/core/base_rules.mk

/build/core/prebuilt.mk

/build/core/multi_prebuilt.mk

2、.so/

/build/core/base_rules.mk

/build/core/shared_library.mk

/build/core/dynamic_library.mk

/build/core/binary.mk

3、.a

/build/core/base_rules.mk

/build/core/static_library.mk

/build/core/binary.mk

编写可执行文件基本上和.so是差不多的,现在分为两类来仔细讲一下,一类是prebuilt files的编译,另外就是.so/.a/elf的编译。

在所有这许makefile中最重要的是base_rules.mk,它是对module进行处理的核心过程,下面先看看这个文件的内容:

L3Byb3h5L2h0dHAvcC5ibG9nLmNzZG4ubmV0L2ltYWdlcy9wX2Jsb2dfY3Nkbl9uZXQveWlsaV94aWUvRW50cnlJbWFnZXMvMjAwOTEyMDkvYmFzZV9ydWxlcy5tay5wbmc=.jpg

每个模块在编译的时候都会产生一个编译目录和一个安装目录,编译目录就是这个模块编译以后生成的目标文件,安装目录就代表着这个模块是否会编译进文件系 统,就是是否编译进IMG啦~~在base_rules.mk提供了两个变量来定义你要输出的目录,仔细弄懂对你了解编译后的生成目录是很有帮助的~~

built_module_path := $(intermediates)

LOCAL_BUILT_MODULE := $(built_module_path)/$(LOCAL_BUILT_MODULE_STEM)

LOCAL_INSTALLED_MODULE := $(LOCAL_MODULE_PATH)/$(LOCAL_MODULE_SUBDIR)$(LOCAL_INSTALLED_MODULE_STEM)

built_module_path是编译生成的中间文件所在的目录,LOCAL_BUILT_MODULE_STEM就是你要生成的编译目标啦,如果 本地模块指定了LOCAL_MODULE_STEM的话,它的值就 是$(LOCAL_MODULE_STEM)$(LOCAL_MODULE_SUFFIX),如果没有指定了的话就 是$(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX)。由此可以看到LOCAL_MODULE的定义是很有讲究的,比如什 么*.so,一般*就用来作模块名。LOCAL_MODULE_SUFFIX在编译不同的模块时,GOOGLE内置会给你加上相应的值,如果你不了解的话 还是尽量自己来指定,不然可能编译出来的东西被篡改了文件名哦噢~~

将编译目录的文件拷贝到安装目录就是我们的LOCAL_INSTALLED_MODULE了,是否会安装就要看你定义的 LOCAL_MODULE_TAGS了,当然你也可以通过修改LOCAL_MODULE_PATH来自定义安装。LOCAL_MODULE_PATH是有 个很有用的变量,首先我们看看当我们在本地模块没有指定这个值的时候,它的值实际上是:LOCAL_MODULE_PATH := $($(my_prefix)OUT$(use_data)_$(LOCAL_MODULE_CLASS)),如果你的模块定义了TAGS := TESTS则user_data的值是DATA,这样的模块会被安装在data/目录下,那么通过替换我们就知道这个LOCAL_MODULE_PATH := TARGET_OUT_$(LOCAL_MODULE_CLASS)。这个LOCAL_MODULE_CLASS在特定的类型编译会被google赋值成 固定内容,但是在prebuilt的编译中它是由你自己来赋值的,它的值就会用来定义生成的目录,比如LOCAL_MODULE_CLASS := ETC的时候,则就会被安装在/system/etc目录。那么我们就知道如何来定义prebuilt模块里面的CLASS了,google还提供了一个 LOCAL_MODULE_SUBDIR可以让你来定义子目录,但是要记得的是在每个模块的最后要将这个值清空,因为默认CLEAR_VARS是不会清空 这个值的。

当然前面说的是LOCAL_MODULE_PATH的默认值,我们可以通过给它赋值来强制指定安装的目录,比如说要安装在system/etc /permissions目录,则可以强制指定它的值为$(TARGET_OUT_ETC)/permissions,这样模块就会被强制安装在这个目录 了,给LOCAL_MODULE_PATH赋值的情况主要应用在prebuilt模块的编译上,其他的应该尽量采用其默认值。

下面我们就具体看看我写的一个如何编译自己的.so *.a  elf的例子,具体能使用到的变量,和要注意的地方我都写出来了:

L3Byb3h5L2h0dHAvcC5ibG9nLmNzZG4ubmV0L2ltYWdlcy9wX2Jsb2dfY3Nkbl9uZXQveWlsaV94aWUvRW50cnlJbWFnZXMvMjAwOTEyMDkvYnVpbGQlMjB5b3VyJTIwb3duJTIwc28ucG5n.jpg

这里要说明的是这个prelink,prelinke只有在编译.so的时候才会有的选项,主要是通过预链接的方式来加快程序启动和执行的速度,如果你的 本地模块prelink是真的话,那你要在build/core/prelink-linux-arm.map中定义你的库需要使用的空间,空间不够的话 会报错(具体使用没仔细研究过)

下面再看看如何来将我们自己的prebuilt files编译进工程,先让我们和这个相关的最重要的两个makefile:

L3Byb3h5L2h0dHAvcC5ibG9nLmNzZG4ubmV0L2ltYWdlcy9wX2Jsb2dfY3Nkbl9uZXQveWlsaV94aWUvRW50cnlJbWFnZXMvMjAwOTEyMDkvcHJlYnVpbHQubWsucG5n.jpg

multi_prebuilt.mk只用来加入需要加入的各种库,仔细注意它里面的那个对加入文件进行处理的函数,尤其是 LOCAL_MODULE,LOCAL_MODULE_SUFFIX ,LOCAL_SRC_FILES这3个变量是如何得到的,使用multi_prebuilt编译进工程的文件都会自动打上USER的tag。而且它最后 还是会掉用prebuilt.mk来执行真正的编译操作。

prebuilt.mk实际上可以编译任何文件到我们的工程中,下面是我写的一个例子,可以自动将目录下相应格式的文件编译进工程:

L3Byb3h5L2h0dHAvcC5ibG9nLmNzZG4ubmV0L2ltYWdlcy9wX2Jsb2dfY3Nkbl9uZXQveWlsaV94aWUvRW50cnlJbWFnZXMvMjAwOTEyMDkvYWRkJTIwcHJlYnVpbHQlMjBmaWxlcy5wbmc=.jpg

此外添加prebuilt.mk也有一个粗暴的方式,可以通过下面的规则简单的将所有prebuilt files添加到你工程中去,必须一个一个添加:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# your prebuilt file name

LOCAL_MODULE := example.so

LOCAL_MODULE_TAGS := user eng

# your prebuilt file (must be relative directory )

LOCAL_SRC_FILES := lib/example.so

# the path your prebuilt file will be installed   $(TARGET_OUT) is the system directory

LOCAL_MODULE_PATH := $(TARGET_OUT)/lib

include (BUILD_PREBUILT)

在最后说一下Android对模块唯一性检测的规则,在base_rules.mk里面通过module_id里来检测这个模块是否已经存在,我们看看这个值是如何定义的:

module_id := MODULE.$(if \

$(LOCAL_IS_HOST_MODULE),HOST,TARGET).$(LOCAL_MODULE_CLASS).$(LOCAL_MODULE)

所以它是通过LOCAL_MODULE_CLASS和LOCAL_MODULE这两个变量来检测模块的唯一性,因此当你定义同一样的CLASS和 MODULE的时候,Android就会报错,提示模块必须是唯一的。因此如果你将LOCAL_MODULE_CALSS进行修改,使用 LOCAL_MODULE_PATH来指定安装目录的时候就会逃过Android对模块唯一性的检测,但是这样导致的问题就是同一个目标会有多个规则来实 现它,而且每个规则都是相同的命令。这样导致的结果就是MAKE会将所有的依赖放在一起,然后使用命令来将其生成目标,这样是非常危险的,会造成库的覆 盖,而且很多时候你不知道它就究竟使用的是哪个依赖来最终生成目标,只能用md5sum来检查。

因此当你使用prebuilt来覆盖系统原有的文件的时候应该特别小心,如果你确认你的文件在覆盖系统原有文件以后系统能正常运行的话,好的方法是还是打 开Android对module_id的检测,同时把原来生成这个文件的Makefile进行修改,让其不编译出这个文件~

最后补充一个Android如何来存放模块的编译中间文件:

1、如果你的LOCAL_MODULE_CLASS包含COMMON_MODULE_CLASS := JAVA_LIBRARIES NOTICE_FILES,则你编译出的中间文件会放在:

$(TARGET__OUT_COMMON_INTERMEDIATES)/$(LOCAL_MODULE_CLASS)/$(LOCAL_MODULE)_intermediates/

TARGET_OUT_COMMON_INTERMEDIATES := out/target/common/obj

2、如果你的LOCAL_MODULE_CLASS不包含COMMON_MODULE_CLASS,则你编译出的中间文件会放在:

$(TARGET__OUT_INTERMEDIATES)/$(LOCAL_MODULE_CLASS)/$(LOCAL_MODULE)_intermediates/

TARGET_OUT_INTERMEDIATES := out/target/product/msm7627_ffa/obj

在jekyll模板博客中添加网易云模块

最近使用GitHub Pages + Jekyll 搭建了个人博客,作为一名重度音乐患者,博客里面可以不配图,但是不能不配音乐啊. 遂在博客里面引入了网易云模块,这里要感谢网易云的分享机制,对开发者非 ...

android中添加背景音乐

方法一:这是使用java中的多线程,另外new出一个类,用类来启动音乐. 这个方法,就像当初写java的小游戏一样,不过是在电脑上运行的,可以控制每一个动作,比如你的触碰动作,但是,在我这个游戏中,我 ...

如何在Android中添加系统服务

一,在frameworks/base/core/java/android/content/Context.java中添加 public static final String RADIO_SERVIC ...

android中添加只有border-left的样式

如何在android中的边框添加只有左边边框有颜色的样式呢 1. 相应的drawable文件 <?xml version="1.0" encoding="utf-8 ...

idea中添加多级父子模块

在 IntelliJ IDEA 中,没有类似于 Eclipse 工作空间(Workspace)的概念,而是提出了Project和Module这两个概念. 在 IntelliJ IDEA 中Projec ...

ZYNQ原理图中添加RTL设计模块

前言 已有的RTL模块怎么添加到原理图中? 流程 (1)添加文件到设计中. (2)右键文件添加到block design中. (3)连线即可. 以上.

&lbrack;工作积累&rsqb; android 中添加libssl和libcurl

1. libssl https://github.com/guardianproject/openssl-android 然后执行ndk-build 2.libcurl 源代码组织结构, 下面的mak ...

如何在Pycharm中添加新的模块

在使用Pycharm编写程序时,我们时常需要调用某些模块,但有些模块事先是没有的,我们需要把模块添加上去. 最近在学习爬虫,写了下面几行代码: 结果出现错误 错误ModuleNotFoundError ...

如何在html中添加引用公共模块文件

1.首先需要修改apache的配置文件: 打开httpd.conf 搜索“AddType text/html .shtml” 搜索结果: AddType text/html .shtml .html ...

随机推荐

ASP&period;NET Core官方计划路线及需要废除的一些Framework技术

概述 下面是 ASP.NET Core的时间表和路线图. 注意日期和特性都可能更改. 作为.NET Core这么大的一个项目,很难准确预测每一个计划的是否有变动. 即便如此,我们还是计划公开和透明的实 ...

Java 中类型转换

int -> String int i=12345; String s=""; 第一种方法:s=i+""; 第二种方法:s=String.valueOf( ...

I帧 B帧 p帧 IDR帧的区别

转自:http://blog.csdn.net/sphone89/article/details/8086071 IDR(Instantaneous Decoding Refresh)--即时解码刷新 ...

ODB学习笔记之基础环境搭建

一,简介 ODB是应用于C++的一个开源.跨平台.跨数据库的对象关系映射(ORM)系统. 它可以让你持久化C++对象到关系数据库,而不必处理表.列或者SQL,无需手动编写任何映射代码. ODB支持 ...

Gson简要使用

哇,原来我已经潜水2年多了,还是需要养成习惯写写东西啊. 最近在做一个java web service项目,需要用到jason,本人对java不是特别精通,于是开始搜索一些java平台的json类库. ...

JqGrid自定义toolbar

1.设置toolbar参数为[true,"top"],其意思是toolbar显示在Grid顶部,且其id为t_+Grid的id.e.g.: Grid的id为myGrid,toolb ...

MResource

public class MResource { public static int getIdByName(Context context, String className, String nam ...

C、C&plus;&plus;中引用与指针的区别

1:引用的和指针在概念上的区别 引用是变量的别名,例如 int m; int &n=m; 引用作为一个别名.它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,而且其引用 ...

RSD和wlwmanifest是什么

今天小博发现header.php文件里<?php wp_head(); ?>显示有以下的两句代码,因为小博的网站打开速度实在太慢了,换空间怕麻烦,那就只有优化代码了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值