如果想弄清楚一个文件的作用,要知道三个方面的内容:
- 文件的输入
- 文件的输出
- 文件内部执行的原理
就我目前接触到的aosp的soong系统,这三个对我而言并不是特别的清晰。当然,如果
真要说这块的大体位置,我可以绝对保证,相关的中间文件位于out/.相关的目录
。
soong有一个自带的logger,可以看一下下面这个目录:
vimer@host:~/src/aosp$ ls build/soong/ui/
build logger metrics status terminal tracer
看一下 build\soong\cmd\soong_ui\main.go 这个文件中如何使用logger.
package main
import (
"context"
"flag"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"android/soong/ui/build"
"android/soong/ui/logger"
"android/soong/ui/metrics"
"android/soong/ui/status"
"android/soong/ui/terminal"
"android/soong/ui/tracer"
)
这里先铺垫一下go的基本使用方法。 关键词 package main
是指定了
由这个main.go文件生成了一个main的包,这样,在其他go文件中,只要
使用import命令,就比如android/soong/ui/logger
的引用方式,我们
就可以直接使用main.xx()的方式使用main文件定义的方法。
很明显,main.go把logger模块(感觉包不如模块熟悉些)引入到main.go 中,比如:
...
writer := terminal.NewWriter(stdio)
defer writer.Finish()
log := logger.New(writer)
defer log.Cleanup()
.....
if start, ok := os.LookupEnv("TRACE_BEGIN_SOONG"); ok {
if !strings.HasSuffix(start, "N") {
if start_time, err := strconv.ParseUint(start, 10, 64); err == nil {
log.Verbosef("Took %dms to start up.",
time.Since(time.Unix(0, int64(start_time))).Nanoseconds()/time.Millisecond.Nanoseconds())
buildCtx.CompleteTrace(metrics.RunSetupTool, "startup", start_time, uint64(time.Now().UnixNano()))
}
}
...
我们可以看到log.verbosef()方法已经生效,那么这个log文件位于什么地方呢?具体应该可以在代
码中定位到的,不过我现在没有去查找,据我了解的是在out/soong.log
文件下。
问题: 无法导入logger
但是这个方法对于某些文件并不能凑效,比如,我想调试下build/soong/cc/cmakelists.go
的某些具体量,但是不知道为什么根本加不进去logger模块,报错的:
build/soong/cc/cmakelists.go:25:2: can't find import: "android/soong/ui/logger"
解决方案
非常简答,只能是作为过渡方法:
...
f_1, _ := os.Create("out/yubo_soong_include.log")
defer f_1.Close()
f_1.WriteString("yubo\n")
f_1.WriteString(fmt.Sprintf("project(%s)\n", ccModule.ModuleBase.Name()))
...
这样自定义输出log文件的好处是: 清晰 只打印自己想要的内容,但缺点是输出的内容难以控制, 需要适配,比如:某个模块的某个方法到底能返回什么样类型的值,还需要看代码去确定。
但是,先这样凑合着使用吧。