拓冰建站拓冰建站
首页 / 资讯中心 / 正文

用 VSCode + ccls 高效阅读 OceanBase 源码:环境配置与索引原理全指南

用 VSCode ccls 高效阅读 OceanBase 源码环境配置与索引原理全指南【免费下载链接】oceanbaseOceanBase is the unified distributed database for the AI era — open-source, multi-model, one engine for your most demanding workloads.项目地址: https://gitcode.com/GitHub_Trending/oc/oceanbaseOceanBase 是一个代码量极为庞大的 C 分布式数据库项目仅src/下就有数千个源码文件并且默认采用 unity 编译方式构建这让传统的代码索引工具难以胜任。本文基于仓库官方文档 docs/docs/zh/ide-settings.md完整介绍如何通过VSCode ccls在远程 Linux 服务器上搭建 OceanBase 源码阅读环境包括 ccls 的安装、VSCode 插件配置、compile_commands.json的生成步骤并结合build.sh与cmake/下的构建脚本深入讲解 OceanBase unity 编译与 ccls 索引机制之间的关系。读完本文你将能够在一小时内搭建出一套可流畅跳转、全局检索 OceanBase 符号的阅读环境。背景为什么 OceanBase 需要专门的 IDE 索引方案为了更好的阅读 OceanBase 的代码我们建议使用一个可以方便索引 OceanBase 代码的 IDE。官方给出的推荐是Windows下推荐使用Source InsightMac 或 Linux下推荐使用VSCode ccls。由于Source Insight使用起来非常简单官方文档不单独介绍它的用法本文聚焦VSCode ccls这套组合。这里需要重点说明的是 ccls 的由来ccls 是基于 cquery 的 C/C/Objective-C LSPLanguage Server Protocol语言服务器协议实现之一。简单来说LSP 用于提供编程语言特定的功能如代码补全、语法高亮、警告和错误标记以及重构例程。VSCode 通过 LSP 与 ccls 通信从而获得代码跳转、查找引用、悬停提示等能力。由于 OceanBase 的代码量非常大而且OceanBase 不能在 Mac 或 Windows 下编译官方建议的典型工作流是在远程服务器上下载代码然后在本地使用 VSCode 通过 Remote 插件访问远程服务器上的代码。这样既绕开了操作系统限制又能利用远程服务器更强的算力完成索引构建。为什么选 ccls 而不是 clangd在 C/C LSP 领域比较有名的工具有clangd和ccls。官方文档推荐 ccls原因有二ccls 构建索引的速度比 clangd 慢但构建完成后ccls 访问索引的速度比 clangd 快。对于 OceanBase 这种千万行级别的代码库索引是一次性成本而日常的跳转、搜索是高频操作因此构建慢、访问快的取舍更合理。clangd 不支持 unity 编译而 OceanBase 是通过 unity 编译的clangd 无法通过compile_commands.json构建索引。第二点是关键。unity 编译Unity Build是将多个源文件合并成少数几个大的联合编译单元unity 文件后统一编译以此显著减少重复的头文件解析开销、加快整体编译速度。OceanBase 默认开启了 unity 编译这可以从构建脚本与 CMake 配置中得到印证build.sh 中的构建类型同时提供了release/debug与release_no_unity/debug_no_unity后者通过追加-DOB_ENABLE_UNITYOFF关闭 unity 编译见 build.sh 第 170-185 行cmake/Env.cmake 第 43-45 行定义了OB_ENABLE_UNITY ON以及默认的联合编译单元大小OB_MAX_UNITY_BATCH_SIZE 30cmake/Utils.cmake 第 101-107 行的config_target_unity函数通过UNITY_BUILD ON、UNITY_BUILD_MODE GROUP等 CMake 属性为每个 target 开启 unity 分组编译。unity 编译改变了源文件的聚合粒度而 clangd 对 unity 场景支持不佳无法据此还原正确的符号索引ccls 则通过项目方专门适配下文详述的OB_BUILD_CCLS分支能够正确处理 unity 编译产物因此成为官方推荐方案。在远程服务器上配置 ccls注意下面的/path/to只是一个路径示例请替换成你的实际路径。在 CentOS 上安装 ccls如果没有权限执行yum请使用sudo yum ...yum install epel-release yum install snapd # On centos8: yum install snapd --nobest systemctl enable --now snapd.socket ln -s /var/lib/snapd/snap /snap snap install ccls --classicCentOS 通过 snap 安装 ccls 后还需要把下面的命令添加到你的环境变量文件中例如~/.bashrc或者~/.bash_profileexport PATH/var/lib/snapd/snap/bin:$PATH然后刷新一下环境变量使配置立即生效source ~/.bashrc # or source ~/.bash_profile在 Ubuntu 上安装 cclsUbuntu 可以直接通过 apt 安装无需 snapapt-get -y install ccls注意如果没有权限执行apt-get请使用sudo apt-get ...。检查安装是否成功运行以下命令判断是否安装成功ccls --version看到 ccls 的版本信息输出即表示语言服务器安装成功。后续 VSCode 的 ccls 插件会自动调用该命令启动语言服务器。VSCode 配置远程插件Remote-SSH在远程主机上下载源代码后可以很容易地在远程主机上设置调试环境。同时由于远程主机更强大应用程序可以更快地运行。即使网络出现问题用户也可以很容易地访问远程主机上的源代码只需在重新连接远程服务器后等待重新加载即可。安装在 VSCode 的扩展商店中下载并安装Remote插件官方名称为 Remote - SSH由微软提供。使用注意确保本地机器和远程机器之间的连接正常。安装插件后VSCode 左下角会出现一个图标类似的蓝色图标。点击该图标选择Connect to Host或者按快捷键ctrlshiftp打开命令面板选择Remote-SSH: Connect to Host输入远程服务器的用户名IP地址然后输入密码VSCode 会连接到远程服务器准备打开远程机器的文件或目录如果需要指定 SSH 端口请选择Add New SSH Host然后输入形如ssh -p 端口号 用户名IP地址的 ssh 命令并选择一个配置文件来存储 ssh 配置之后配置好的机器就可以在Connect to Host中直接找到了。每次连接都需要输入密码如果想跳过这个步骤可以配置SSH 免密登录将本地公钥加入远程服务器的~/.ssh/authorized_keys。C/C 插件官方不推荐使用微软的 C/C 插件因为它无法为 OceanBase 提供良好的索引功能并且与 ccls 插件不兼容两者会抢占符号索引造成冲突。如果有一些简单的场景例如仅需要基础的代码补全和语法高亮可以在 VSCode 的扩展商店中下载并安装 C/C 插件但请注意C/C 插件可以自动完成代码补全和语法高亮却无法为 OceanBase 构建索引很难跳转到 OceanBase 的符号——这正是要使用 ccls 的原因。ccls 插件安装 ccls 插件在 VSCode 扩展商店中搜索并安装 ccls 插件要使用 ccls就建议卸载 C/C 插件避免两个插件在符号索引上互相干扰。配置 ccls 插件点击插件设置按钮然后选择Extension Settings扩展设置设置ccls.index.threads。ccls 默认使用系统 80% 的 CPU 核心作为默认的并行度我们可以在 VSCode 的配置页面中搜索threads并设置合适的数字重要默认情况下OceanBase 使用 unity 编译比普通情况消耗更多的内存。如果并行度太高例如 8 核 16G 的系统系统可能会挂起。建议在小内存机器上把ccls.index.threads调低例如 2~4并在索引期间关闭其他重负载进程。生成 compile_commands.jsonbash build.sh ccls --init的完整流程ccls 需要一份compile_commands.json编译命令数据库来知道每个源文件是如何被编译的从而建立准确的符号索引。OceanBase 的构建脚本为此专门提供了ccls构建类型。操作步骤使用 git 下载源码git clone https://github.com/oceanbase/oceanbase在源码根目录生成compile_commands.jsonbash build.sh ccls --init执行完成后可以在 OceanBase 源码目录下看到compile_commands.json文件。然后重启 VSCode让 ccls 插件加载该文件并开始构建索引。源码级解析build.sh 的 ccls 分支bash build.sh ccls --init中的--init会先执行依赖初始化deps/init/dep_create.sh见 build.sh 第 111-127 行随后ccls分支走 build.sh 第 187-191 行的逻辑xccls) do_build $ -DCMAKE_BUILD_TYPEDebug -DOB_USE_LLD$LLD_OPTION -DOB_BUILD_CCLSON # build soft link for ccls ln -sf ${TOPDIR}/build_ccls/compile_commands.json ${TOPDIR}/compile_commands.json ;;这段脚本做了三件事以 Debug 类型在build_ccls目录执行 CMake 配置并打开OB_BUILD_CCLSON开关由于CMAKE_COMMAND固定携带-DCMAKE_EXPORT_COMPILE_COMMANDS1见 build.sh 第 8 行CMake 会在build_ccls/目录下导出完整的compile_commands.json将build_ccls/compile_commands.json软链接到源码根目录方便 VSCode/ccls 直接定位。此外build.sh 第 146-151 行的do_clean函数在清理构建目录时特意通过grep -v build_ccls排除了build_ccls目录即清理其他构建产物不会破坏已经生成的 ccls 索引配置说明该目录被当作索引专用构建目录来维护。源码级解析unity 编译如何为 ccls 适配ccls 能处理 unity 编译离不开 CMake 侧的专门适配。相关逻辑集中在 cmake/Env.cmake 与 cmake/Utils.cmake默认情况下OB_BUILD_CCLS为OFFcmake/Env.cmake 第 26 行联合编译单元大小OB_MAX_UNITY_BATCH_SIZE为 30第 43 行当OB_BUILD_CCLSON时cmake/Env.cmake 第 392-398 行OB_MAX_UNITY_BATCH_SIZE被放大到200并为全局追加-DCCLS_LASY_ENABLE编译宏。注释解释了原因ccls 场景采用更大的 unity 联合编译单元因为 ccls 是非完整编译、调用 clang AST 接口单元的 size 和耗时呈指数衰减关系而-DCCLS_LASY_ENABLE启用 ccls 懒加载模式主要针对单测 case当添加上-DCCLS_LASY_OFF时首次将会进行完整检索在 cmake/Utils.cmake 的ob_set_subtarget函数中第 51-81 行当OB_BUILD_CCLS开启时unity 分组方式发生变化默认编译以target_group/group_id分组而 ccls 构建改为以 target 为单位、按 200 个一组进行UNITY_GROUP分组从而保证 ccls 索引到的每个联合编译单元规模可控、粒度一致第 109-113 行的config_ccls_flag函数还会为每个 target 追加CCLS_LASY_OFF编译定义用于控制懒加载模式下首次检索的行为。这也解释了官方文档中反复强调的内存警告unity 编译本就把大量源文件聚合在一起解析加上 ccls 使用 clang AST 构建索引内存峰值会明显高于普通项目。因此在 8 核 16G 这类配置的机器上务必调低ccls.index.threads避免系统因内存耗尽而挂起。使用索引构建与日常阅读执行完上述步骤后需要重启 VSCode然后在 VSCode 底部可以看到构建索引的过程索引构建完成后可以很容易地找到任何打开文件的函数引用和类成员。以打开任意源码文件为例将光标悬停在函数名或类名上即可获得签名与调用关系按住Ctrl点击即可跳转到定义右键即可查看所有引用效果如下图所示常用快捷键设置ccls 插件在 VSCode 中提供了丰富的快捷键官方文档给出的两组常用按键设置如下典型的用法包括Ctrl 左键/F12跳转到定义Shift F12查找所有引用Ctrl Shift O跳转到文件内的符号Ctrl T全局搜索符号跨文件。如果你有更顺手的按键习惯也可以直接在 VSCode 的keybindings.json中为 ccls 的相关命令绑定自定义快捷键。小结针对 OceanBase 这类使用 unity 编译、代码量巨大的 C 项目VSCode ccls是目前官方推荐的远程阅读方案。整个搭建链路可以归纳为四步安装语言服务器在远程 Linux 服务器上通过 snapCentOS或 aptUbuntu安装 ccls并用ccls --version验证配置 VSCode安装 Remote-SSH 插件连接远程服务器安装 ccls 插件并卸载 C/C 插件按机器内存调整ccls.index.threads生成索引数据在源码根目录执行bash build.sh ccls --init得到compile_commands.json——构建脚本会以OB_BUILD_CCLSON的方式生成 ccls 专用的 unity 分组与懒加载配置详见 build.sh 与 cmake/Env.cmake重启并索引重启 VSCode等待底部索引完成即可享受跨文件的符号跳转、引用查找与补全。这套环境不仅能显著提升日常阅读 OceanBase 源码从 src 下的存储引擎、SQL 引擎到 deps/oblib 的基础库的效率也是后续在 mittest、unittest 中定位和调试问题时的必备工具。【免费下载链接】oceanbaseOceanBase is the unified distributed database for the AI era — open-source, multi-model, one engine for your most demanding workloads.项目地址: https://gitcode.com/GitHub_Trending/oc/oceanbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门