vim+cscope+ctags代码阅读工具使用说明

在远程一台老服务器时,由于存储空间有限,装远程vscode属实有点吃力,只能终端看,就把N年前写过的这篇草稿文找出来更新了一遍,个人还是建议使用界面话的工具阅读代码(例如vscode、sourceinsight等),但vim+cscope+ctags 阅读源码的方式也可以学习一下,毕竟有些场景用这个效率还是很高的。通过以下配置和技巧,实现高效、便捷的代码阅读体验:

一、准备工作

1. 安装必要工具

# Ubuntu/Debian
sudo apt-get install vim cscope universal-ctags

# CentOS/RHEL
sudo yum install vim cscope universal-ctags

# Arch Linux
sudo pacman -S vim cscope universal-ctags

cscopeuniversal-ctags 都是用于代码阅读和导航的工具,常与 Vim 搭配使用,但它们的功能侧重点不同,适合互补使用:


cscope 的功能

cscope 是一个交互式的代码浏览工具,主要用于 C/C++ 项目,支持以下功能:

功能说明
查找函数定义定位函数、变量、宏等的定义位置
查找函数调用查找调用某个函数的所有位置
查找被调用的函数查找某个函数内部调用了哪些函数
查找符号查找函数名、变量名、宏等符号出现的位置
查找字符串查找指定的字符串
查找包含文件查找包含某个头文件的所有文件
查找文件快速打开某个文件
支持正则表达式搜索类似 egrep,但速度更快

cscope 的优势在于函数调用关系的查找,这是 ctags 无法直接做到的。


universal-ctags 的功能

universal-ctagsctags 的现代维护版本,支持更多语言(如 C、C++、Python、Go、Rust 等),功能包括:

功能说明
跳转到定义快速跳转到函数、变量、类等的定义处
生成 tags 文件生成 tags 文件供 Vim 使用
支持多种语言cscope 更广泛的语言支持
支持结构体、类、成员等能识别复杂的语法结构
与 Vim 集成良好支持 Ctrl+] 跳转、Ctrl+o 返回等操作

ctags 的优势在于快速跳转到定义,但不能查找函数调用关系

2. 生成内核源码索引

进入内核源码目录,生成索引文件:

cd /path/to/linux-kernel-source

# 生成 cscope 索引
cscope -Rbq

# 生成 ctags 索引
ctags -R

✅ 生成的 cscope 索引内容如下:

  • cscope.out:主数据库文件,包含符号、函数、变量等信息。
  • cscope.in.outcscope.po.out:是 cscope 的辅助索引文件,用于加速查找

✅ 生成的 ctags索引内容如下:

  • tags 文件是代码的“目录”或“地图”,让你可以快速跳转到任何符号的定义处。

二、Vim 配置(~/.vimrc)

" 基本设置
"开启语法高亮,让不同类型的代码(如关键字、注释、字符串)显示不同颜色,提升可读性
syntax on 
"显示行号,方便定位、调试、跳转
set number 
"高亮当前光标所在行,更容易跟踪你正在查看的代码行
set cursorline 
"自动将当前工作目录切换为当前打开文件所在的目录,方便使用相对路径。
set autochdir
"Tab 键显示为 4 个空格宽度
set tabstop=4 
"自动缩进时使用 4 个空格
set shiftwidth=4 
"将 Tab 转换为空格,避免不同编辑器或环境下 Tab 显示不一致
set expandtab 

" 启用文件类型检测和插件,根据文件类型(如 .c、.py)自动加载对应的插件和缩进规则
filetype plugin indent on

" ctags 和 cscope 设置
"告诉 Vim 在当前目录查找 tags 文件,用于跳转到函数/变量定义
set tags=./tags 
"启用 cscope 支持,让 Vim 优先使用 cscope 数据库进行符号查找
set cscopetag 

" 添加 cscope 数据库,如果当前目录存在 cscope.out 文件,就加载它,用于函数调用、定义等查找
if filereadable("cscope.out")
    cs add cscope.out
endif

" 快捷键映射
" 查找函数定义(cs find g是 cscope 的查找定义命令)
nnoremap <F6> :cs find g <C-R><C-W><CR>

" 查找函数调用
nnoremap <F5> :cs find c <C-R><C-W><CR>
" 查找符号
nnoremap <F7> :cs find s <C-R><C-W><CR>
" 查找字符串
nnoremap <F8> :cs find t <C-R><C-W><CR>
" 返回上一个位置
nnoremap <C-o> <C-o>
" 代码折叠,根据语法结构自动折叠代码(如函数、类、结构体等)
set foldmethod=syntax
" 默认展开所有折叠,只有你手动折叠的代码才会收起
set foldlevel=99

三、常用操作技巧

1. 代码导航

  • 跳转到定义:将光标放在函数或变量上,按 Ctrl+]F6
  • 返回原位置:按 Ctrl+oCtrl+t
  • 查找调用:将光标放在函数名上,按 F5
  • 查找符号:按 F7

2. 代码搜索

  • 搜索当前单词:按 *#
  • 全局搜索:vimgrep /pattern/ **/*.c 然后 :copen

3. 窗口管理

  • 水平分割:split
  • 垂直分割:vsplit
  • 切换窗口Ctrl+w + 方向键(实际测试发现是按住ctrl点击两次w键便会自动跳,与方向键无关)

4. 代码折叠

  • 折叠代码zc,在大括号处执行
  • 展开代码zo
  • 全部折叠zM
  • 全部展开zR

四、推荐插件(可选)

使用插件管理器(如 vim-plug)安装:

call plug#begin('~/.vim/plugged')

" 文件浏览器
Plug 'scrooloose/nerdtree'

" 代码补全
Plug 'neoclide/coc.nvim', {'branch': 'release'}

" 语法高亮增强
Plug 'sheerun/vim-polyglot'

" 状态栏美化
Plug 'vim-airline/vim-airline'

call plug#end()

五、实用技巧

  1. 快速注释

    • 可视模式选中行,按 gc(需要插件支持)
  2. 快速跳转

    • :tag function_name 跳转到指定函数
  3. 查看调用栈

    • :cscope find c function_name
  4. 查看结构体定义

    • 将光标放在结构体名上,按 F6
  5. 查看宏定义

    • 将光标放在宏上,按 F6

六、示例工作流程

  1. 打开内核源码文件:

    vim init/main.c
    
  2. 查找 start_kernel 函数定义:

  • 将光标放在 start_kernel 上,按 F6
  1. 查看调用关系:
  • 在函数定义处按 F5 查看调用情况
  1. 查看相关结构体:
  • 将光标放在结构体名上,按 F6
  1. 返回原位置:

    • Ctrl+o

通过以上配置和技巧,你可以高效地使用 Vim 阅读和分析 Linux 内核源码。建议多加练习,熟练掌握这些操作后,阅读效率会大幅提升。


进阶优化建议

1. 使用 cscope 的增量更新(避免每次全量生成)

Linux 内核代码量巨大,全量生成 cscope.out 很慢。你可以使用 cscope -Rbkq 先生成一次,后续只更新变动的文件:

# 只更新变动的文件
find . -name "*.c" -o -name "*.h" | cscope -Rbkq -i-
2. 使用 cscope_maps.vim 插件增强体验

官方提供的 cscope_maps.vim 插件(GitHub 地址)可以更优雅地集成 cscope 到 Vim,支持:

  • 自动加载多个 cscope.out 文件(适合多模块内核)
  • 提供 :CscopeFind 命令,避免手动 cs find

安装方式(使用 vim-plug):

Plug 'brookhong/cscope.vim'
3. 结合 LSPcoc.nvim 实现智能跳转

虽然 ctagscscope 很快,但对复杂 C 语法(如宏、内联函数)支持有限。你可以用 coc.nvim + coc-clangd 实现更精确的跳转:

# 安装 clangd(需 LLVM)
sudo apt install clangd

# 安装 coc-clangd
:CocInstall coc-clangd

coc-settings.json 中配置内核头文件路径:

{
  "clangd.arguments": [
    "--compile-commands-dir=./",
    "--header-insertion=never"
  ]
}
4. 使用 vim-fugitive 查看 Git 历史

Linux 内核使用 Git 管理,安装 vim-fugitive 后可直接在 Vim 中查看代码历史:

Plug 'tpope/vim-fugitive'

常用命令:

  • :Gblame 查看某行代码的最后修改记录
  • :Glog 查看整个文件的提交历史
5. vim-tmuxvim-terminal 分屏调试

在阅读内核时,可能需要同时查看 dmesggdb 输出。用 Vim 8 的终端功能:

:terminal  # 在 Vim 内打开终端

或配合 tmux

tmux split-window -h  # 水平分屏

⚠️ 常见坑 & 解决方案

问题原因解决方案
F6 跳转失败未生成 tagscscope.out确认在源码根目录执行了 ctags -Rcscope -Rbq
Ctrl+] 跳转到错误定义多个同名符号:tselect 手动选择,或改用 coc.nvim 的 LSP 跳转
cscope 查找结果为空未包含 .h 文件find . -name "*.c" -o -name "*.h" > cscope.files 再生成索引
Vim 打开大文件卡顿语法高亮导致:syntax off 临时关闭,或安装 vim-fastfold 插件
coc.nvim 提示找不到头文件未配置 compile_commands.jsonbear -- make 生成,或手动指定 -I 路径

🎯 高效工作流示例(结合 LSP + cscope)

  1. 打开文件

    vim kernel/sched/core.c
    
  2. 跳转到 schedule() 定义

    • gd(LSP 跳转)或 F6(cscope)
    • 若 LSP 失败,自动 fallback 到 cscope
  3. 查看调用关系

    • :CocList references(LSP)
    • 或按 F5(cscope 查找调用)
  4. 查看 Git 历史

    • :Gblame 查看某行修改记录
    • :Glog 查看整个函数的演变
  5. 调试时

    • :terminal 打开 dmesg -w 实时查看日志
    • :make 编译内核,错误直接跳转到对应文件

📌 总结

工具适用场景
cscope查找函数调用、全局符号、文件依赖
ctags快速跳转到定义
LSP (coc.nvim)精确跳转、补全、诊断(需配置)
vim-fugitive查看 Git 历史、追溯代码变更
tmux/终端分屏调试、日志监控

如果你有特定需求(如调试驱动、追踪某个子系统),可以进一步优化配置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值