配置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, 可能需要手动安装一下。

相关推荐
tangweiguo030519872 小时前
Android OpenGL ES 2.0 完整开发指南:从零到三维旋转立方体
android
龚礼鹏2 小时前
AndroidStudio module编译aar混淆文件处理
android
程序员阿鹏5 小时前
MySQL中给字段添加唯一约束的方式有哪些?
android·数据库·mysql
三少爷的鞋6 小时前
Android Data 层设计的四条红线:为什么必须坚持、如何落地
android
猫豆~6 小时前
zabbix实战——3day
android
知行合一。。。7 小时前
Python--01--核心基础
android·java·python
汤米粥7 小时前
Android简单易用的视频压缩
android
怀君8 小时前
Uniapp——Android离线打包自定义基座教程
android·uni-app
ellis19708 小时前
Unity出安卓包知识点汇总
android·unity