配置vscode阅读Android native 代码

在阅读android 源码时经常会有阅读native代码的场景,使用asfp有些代码跳转不是很准确,甚至有些无法跳转的情况,这篇文章将介绍如何配置vscode阅读native代码, 这里不介绍原理,直接介绍方法, 亲测有效,跳转准确

主要步骤

  1. 生成compile_commands.json
  2. 配置vscode
  3. 加载aosp项目native 代码

1. 生成compile_commands.json

在aosp工程中有对compile_commands.json生成方式进行介绍的文档。文档位置在:build/soong/docs/compdb.md

  1. 配置环境变量
ini 复制代码
$ export SOONG_GEN_COMPDB=1
$ export SOONG_GEN_COMPDB_DEBUG=1
  1. 编译生成compile_commands.json命令
shell 复制代码
$source build/envsetup.sh
$lunch xxxx
$make nothing
  1. 生成的compile_commands.json目录:
bash 复制代码
out/soong/development/ide/compdb/compile_commands.json

注意:这种方式生成的compile_commands.json包含了所有使用Android.bp定义的模块的编译数据库,使用Android.mk编译的模块并不包含在内。

Android16新方式: 在Android16工程中使用上述方法则不会生成我们想要的compile_commands.json文件,在android16需要使用下面方法。

  1. 在android.bp中添加全局配置: 在文件build/soong/cc/config/global.gocommonGlobalCflags中添加-v选项如下:
c 复制代码
commonGlobalCflags = []string{
    ........,
    "-v",
    }
  1. clear之前的编译, 可以直接删除.out 目录
  2. 重新编译
bash 复制代码
source build/envsetup.sh
lunch xxx
make -j32 | tee build_sys.log

这里把编译时,产生的日志输入到 build_sys.log 文件中。 或者不使用tee将编译的日志输入到 build_sys.log中也可以, 直接进行make 编译,编译完后也系统也会生成一个编译日志文件,使用这个文件也是可以的。 4. 使用编译日志文件生成compile_commands.json 使用下面脚本进行生成,创建文件build_cc_json_tools.py

css 复制代码
import json
import sys

def build_compile_commands(input_file: 'str', output_file: 'str', android_top: 'str', compiler='clang'):
    with open(input_file) as input:
        target_lines = []
        compile_command_list = []
        for line in input:
            if line.count(compiler) > 0 and ( line.count('.c') > 0 or line.count('.cpp') > 0 ):
                target_lines.append(line.strip())
        # print(len(target_lines))
        for rule in target_lines:
            if rule.count('"') >= 2:
                compile_command = {}
                compile_command['directory'] = android_top
                compile_command['arguments'] = []
                compile_command_file = ''
                items = rule.split(' ')
                for item in items:
                    item = item.replace('"', '')
                    if item.count(compiler) > 0:
                        item = android_top + '/' + item
                    compile_command['arguments'].append(item)
                    if item.count('.c') > 0 or item.count('.cpp') > 0:
                        if item.count('/') > 0:
                            compile_command_file = item
                if compile_command_file != '':
                    compile_command['file'] = compile_command_file
                    compile_command_list.append(compile_command)

        with open(output_file, 'w') as output:
            print(json.dumps(compile_command_list, indent=4), file=output)

if __name__ == '__main__':
    if len(sys.argv) < 4:
        print("Usage: python3 {} <input_file> <output_file> <android_top> [compiler]".format(sys.argv[0]))
        exit(1)
    else:
        input_file = sys.argv[1]
        output_file = sys.argv[2]
        android_top = sys.argv[3]
        compiler = 'clang'
        if len(sys.argv) > 4:
            compiler = sys.argv[4]
        build_compile_commands(input_file, output_file, android_top, compiler)

执行命令,这里需要注意使用python3 进行生成

bash 复制代码
python3 build_cc_json_tools.py build_sys.log compile_commands.json  /home/cuckoo/Adisk/aosp16

第一个参数:编译生成日志文件 第二个参数:生成的compile_commands.json名字 第三个参数:存放路径

2. 精简compile_commands.json

你可能会发现,编译后生成的compile_commands.json很大,如果打开整个Android目录会非常慢,一般来说,我们只会打开一个或几个仓库就可以,如frameworks,hardware 等几个仓库,所以我们需要精简compile_commands.json,然后打开特定仓库进行索引,以加快vscode的响应速度。

可以使用下面脚本精简compile_commands.json, 复制脚本创建文件streamline_project.py,

python 复制代码
#!/usr/bin/python3
import json
import sys
from typing import *


def simply_compile_commands_json(completed_json_file: 'str', simplified_json_file: 'str', repositories: 'List[str]'):
    with open(completed_json_file) as input_file:
        command_content = input_file.read()
        command_json = json.loads(command_content)
        target_command_list = []
        for command in command_json:
            file: 'str' = command['file']
            if any((file.startswith(repository) for repository in repositories)):
                target_command_list.append(command)

        with open(simplified_json_file, "w") as output_file:
            output_file.write(json.dumps(target_command_list, indent=4))


if __name__ == '__main__':
    if len(sys.argv) != 4:
        print('Usage: python3 {} <complete.json> <simply.json> <repo[,repo[,repo]...]>'.format(sys.argv[0]))
        print('Eg: python3 {} ./compile_commands.json.big ./compile_commands.json system,hardware,frameworks'.format(sys.argv[0]))
        exit(1)
    else:
        input_compile_commands = sys.argv[1]
        output_compile_commands = sys.argv[2]
        repositories = sys.argv[3].split(',')
        simply_compile_commands_json(input_compile_commands, output_compile_commands, repositories)

执行命令,这里需要注意使用python3 进行精简操作

bash 复制代码
$python3 streamline_project.py out/soong/development/ide/compdb/compile_commands.json ./compile_commands.json frameworks,hardware,kernel

第一个参数:生成的完整的compile_commands.json 第二个参数:精简后的compile_commands.json文件 第三个参数:需要保留的模块,用,隔开

到这里我们需要的compile_commands.json文件就制作好了

最后把生成的compile_commands.json文件放到aosp工程的根目录。

3. vscode 配置

clangd插件

  • clangd插件能根据提供的配置文件(compile_commands.json),来分析代码中每个函数在哪个头文件声明,在哪个文件中实现,十分准确
  • clangd插件和C/C++ IntelliSense 有些冲突,需要先禁掉这个插件,或者把C/C++ 插件卸载掉 参考:vscode c工程中抛弃C/C++ IntelliSense实现函数跳转

clangd插件分为两部分。

  1. vscode 中clangd 插件
  2. 你的电脑上需要安装

ubuntu 系统可以使用下面命令进行安装:

ruby 复制代码
$ sudo apt install clangd

打开vscode加载aosp项目。 clangd默认会在打开文件的当前目录下找compile_commands.json。等待扫描完成即可。 到这里导入的时候需要注意一点, 在vscode可能提示需要使用java17, 可能需要手动安装一下。

相关推荐
阿巴斯甜1 天前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker1 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95271 天前
Andorid Google 登录接入文档
android
黄林晴2 天前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab2 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿2 天前
Android MediaPlayer 笔记
android
Jony_2 天前
Android 启动优化方案
android
阿巴斯甜2 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇2 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_2 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android