使用mm/mmm 准备工作

本文深入解析Android源码目录下build/envsetup.sh文件中的m、mm、mmm命令的使用方法,通过具体实例展示如何快速编译特定模块,并解决在执行mm命令时遇到的错误提示。

source build/envsetup.sh

在这个shell脚本中定义了 help, croot, m, mm, mmm等

1. 问题 
有时我们只修改了个别文件,如何将修改快速地加进Image. 比如我们在RK2918的项目中修改了文件: 
/frameworks/base/services/java/com/android/server/ WindowManagerService.java 那我们只要执行以下命令即可: 
cd frameworks/base/services/java/com/android/server/ mm 
 ./mkimage.sh 
2. 但我们在执行命令mm时,出现了以下错误提示: The program 'mm' can be found in the following packages:  * mountmanager  * multimail 
Try: apt-get install <selected package>  
2.1 android
下m、mm、mmm编译命令的使用 
通过查看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下的libjpeg模块,当前目录为源码根目录,方法如下: 
 
1、. build/envsetup.sh 2、mmm external/jpeg/  
或者 : 
 
1、. build/envsetup.sh 2、cd external/jpeg 3、mm 
 
最后说明一下,envsetup.sh只要source一次就够了,source之后还可以用croot命令返回到源码根目录,很好用。

## 1、数据处理 #### (1)定义样例类 数据源准备完毕后,就可以编写 Flink 程序连接 Kafka,消费其中的日志数据了。为了在程序中便捷地处理日志信息,首先定义样例类,用于表示日志信息,代码如下: ```scala case class NginxLog( ip: String, // 客户端 IP 地址 timestamp: Long, // 日志时间戳 method: String, // 请求方法 url: String, // 请求的 URL status: Int, // 请求的 HTTP 状态码 userAgent: String, // 客户端的 User-Agent referer: String // 客户端的 Referer ) ``` #### (2)解析日志(程序入口对象) 为了后续能够分析日志中的各项指标,需要提取日志中的字段。接下来,定义解析日志的函数,代码如下: ```scala def parseLogLine(logLine: String): NginxLog = { val pattern = """^(\S+) - - \[(.+)\] "(\S+) (\S+) HTTP/1.1" (\d+) (\d+) "(.+)""(.+)"$""".r logLine match { case pattern(ip, timestamp, method, url, status, bytes, referer, userAgent) => val dateFormat = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss", Locale.ENGLISH) val eventTime = dateFormat.parse(timestamp).getTime NginxLog(ip, eventTime, method, url, status.toInt, userAgent, referer) case _ => throw new RuntimeException(s"Cannot parse log line: $logLine") } } ``` 这段代码定义了一个 parseLogLine ()函数,它接收一个字符串类型的 Nginx 日志行,并将其解析为一个 NginxLog 类型的对象。具体实现如下: 首先,定义一个正则表达式模式 pattern,用于匹配 Nginx 日志行中的各个字段。模式包含多个用于匹配具体字段的分组,例如,(\S+)匹配一个或多个非空白字符,(.+)匹配一个或多个任意字符。 然后,使用 match 关键字对 logLine 进行模式匹配。如果 logLine 能够匹配 pattern,则将匹配结果中的各个字段提取出来,并使用 SimpleDateFormat 将时间戳字符串 timestamp 解析为时间戳数值 eventTime。最后,将提取出来的字段构造成一个 NginxLog 对象并返回。如果 logLine 无法匹配 pattern,则会抛出一个运行时异常,表示无法解析该行日志。 #### (3)生成水位线(程序入口对象-main方法) 这里连接 Kafka 消费数据,并在数据流中生成水位线,具体代码如下: ```scala val env = StreamExecutionEnvironment.getExecutionEnvironment env.setParallelism(1) val source: KafkaSource[String] = KafkaSource .builder() .setBootstrapServers("192.168.200.131:9092") .setTopics("nginx_logs") .setGroupId("test-group") .setStartingOffsets(OffsetsInitializer.earliest()) .setValueOnlyDeserializer(new SimpleStringSchema()) .build() // 使用 KafkaSource val kafkaStream: DataStream[String] = env.fromSource( source, WatermarkStrategy.noWatermarks(), "Kafka Source" ) val nginxLogs: DataStream[NginxLog] = kafkaStream .map(parseLogLine(_)) .assignTimestampsAndWatermarks( WatermarkStrategy //(log: NginxLog, _) => log.timestamp .forBoundedOutOfOrderness[NginxLog](Duration.ofSeconds(10)) .withTimestampAssigner(new SerializableTimestampAssigner[NginxLog] { override def extractTimestamp(element: NginxLog, recordTimestamp: Long): Long = element.timestamp }) ) ``` 上述代码使用 Flink Kafka Connector 中的 KafkaSource 从 Kafka Topic"nginx_logs"中读取数据。首先,使用 StreamExecutionEnvironment. getExecutionEnvironment 获取 Flink 执行环境。接着,创建 KafkaSource 实例,设置 Kafka Broker 地址、Topic 名称、消费者组 ID、反序列化器等属性。然后,使用 env. fromSource () 方法将 KafkaSource 转换为 DataStream,同时指定水印策略为 noWatermarks (),即不引入水印。随后,通过. map (parseLogLine (_)) 对 DataStream 中的符串格式的日志信息进行解析,转换为 NginxLog 样例类的对象。最后,使用 assignTimestamp sAndWatermarks ()方法指定水印策略,使用 forBoundedOutOfOrderness 指定延迟上界,即允许数据最多延迟 10s,并使用 extractTimestamp ()方法指定时间戳字段。
06-09
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值