编译数据库的生成

编译数据库是一个json格式,它提供了编译源文件时的命令、参数、源文件、工作目录等信息,可以基于编译数据库对C/C++代码进行分析。一般的生成文件名为compile_commands.json

这里包含对Compilation database — Sarcasm notebook的整理。

主流的支持基于编译数据库分析的工具有:clang-checkclang-docclang-include-fixerclang-renameclang-tidyclangd

如何获得项目的编译数据库

使用cmake构建项目

原来是cmake的地方替换成cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1

生成的编译数据库形如:

[{ "directory": "/home/user/llvm/build", "arguments": ["/usr/bin/clang++", "-Irelative", "-DSOMEDEF=With spaces, quotes and \\-es.", "-c", "-o", "file.o", "file.cc"], "file": "file.cc" }, { "directory": "/home/user/llvm/build", "command": "/usr/bin/clang++ -Irelative -DSOMEDEF=\"With spaces, quotes and \\-es.\" -c -o file.o file.cc", "file": "file2.cc" }, ]

注意到这里有argumentscommand两种输出形式,一般认为arguments结果要好。

使用bazel构建项目

使用ninja构建项目

使用如下格式生成。

ninja -t compdb > compile_commands.json

使用clang编译单个文件

使用类似 clang -MJ c_struct.o.json c_struct.c -o c_struct.o的选项生成。生成的格式形如下。注意如下几个细节:

  • 生成文件的末尾的,,这并不是标准的json;同时缺乏通常的编译数据库生成的[]。因此,基于这种方案生成的编译数据库文件需要手动调整(这里提供一个自动化脚本)。
  • argumentsclang的命令被替换成非软链接的绝对路径,且添加上了一些选项如-xc--target=x86_64-pc-linux-gnu。这样的编译数据库,是使用了clang编译器而不是driver。
  • 除了arguments还有output项,且/tmp/c_struct-d6903c.oc_struct.o并不一样。

{ "directory": "/root", "file": "c_struct.c", "output": "/tmp/c_struct-3faa5e.o", "arguments": ["/usr/lib/llvm-14/bin/clang", "-xc", "c_struct.c", "--target=x86_64-pc-linux-gnu"]},

使用bear进行wrap

使用bear build这个回复中提到不建议使用scan-build中的intercept-build

优势

  • 可以搞定任何构建命令的编译数据库生成问题。
  • 生成的编译数据库使用arguments而不是command,避免了转义的问题(但很多对编译数据库的分析工具可能仅支持command项)。

不足

  • 由于bear仅监控本次实际构建的命令,因此如果是项目的增量式构建则只会输出部分编译数据库结果,但全量构建可能会非常耗时。经常会出现,"全版本动辄近一个小时,很影响效率,大部分时间都浪费在等待编译结束"。

使用compiledb对make进行wrap(推荐)

compiledb有所有bear的优势,且弥补了bear的不足;性能方面也有优势。改进之处包括:

  1. 可以跳过时间构建而只生成compile_commands.json,如compiledb -n make

  2. 可以基于build-log来生成编译数据库。

    make -Bnwk > build-log.txt compiledb --parse build-log.txt # 或 compiledb < build-log.txt # 使用管道的方式也行 make -Bnwk | compiledb -o-
  3. 使用command风格的编译数据库:

    compiledb --command-style make # 根据我的实验,在已经构建完成之后使用该命令,仍然能够得到编译数据库
    

不足:

  • 仅能够对make指令进行wrap。
    bash

    复制代码

    # 可编译 > gcc testnum.c main.c # bear可wrap > bear -- gcc testnum.c main.c #compiledb不可wrap > compiledb gcc testnum.c main.c Usage: compiledb [OPTIONS] COMMAND [ARGS]... Try 'compiledb -h' for help. Error: No such command 'gcc'.

TODO:

  • 补全citnamesintercept命令行的使用(bear相关)。
  • 补全交叉编译时的问题。
  • 补全编译数据库供基于clang的分析工具时的局限性。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Bear 编译数据库是一个用于帮助开发生成和维护代码编辑器的编译数据库的工具。编译数据库是一组描述代码文件的元数据,包括每个文件的编译指令、编译选项、头文件和源代码之间的依赖关系等。 Bear 编译数据库的目的是为了帮助开发者通过为编辑器提供准确的编译数据库来改善代码的智能功能,如自动补全、代码导航、语法检查和重构等。通过使用编译数据库,编辑器能够更好地理解代码,并提供更准确和有用的代码建议。 使用 Bear 编译数据库的步骤大致如下: 1. 首先,需要安装 Bear 编译数据库工具。可以通过在终端中运行相应的命令,使用包管理器(如apt、yum、brew等)安装该工具。 2. 安装完成后,运行 bear make 命令,该命令会在当前工作目录中执行 make 命令,并生成编译数据库。可以根据具体需求,使用不同的编译器选项来生成数据库,如 -C (--clean) 参数可以清除现有数据库,重新生成新的。 3. 生成编译数据库文件默认为 compile_commands.json,它是一个 JSON 格式的文件,描述了项目中所有源代码文件的编译相关信息。 4. 将生成编译数据库文件移动到编辑器所需的位置。不同的编辑器可能需要将数据库文件放置在不同的目录中,具体可以参考编辑器的文档。 通过以上步骤,开发者就可以使用 Bear 编译数据库来改善代码编辑体验。需要注意的是,由于生成编译数据库中包含了源代码文件的路径信息,因此在将数据库文件与他人共享或在不同的机器上使用时,需要注意路径的一致性,以避免编辑器无法正确解析编译数据库的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值