如何为内核和设备 driver 开发设置 YouCompleteMe?
How to setup YouCompleteMe for kernel and device driver development?
我想为内核破解设置 vim,所以我安装了 YouCompleteMe 以自动完成。但是,无论我做什么,看起来我都无法正确配置它。它没有正确地完成语义;它只建议当前文件中已经使用的语义,甚至不包括 headers 或其他翻译单元中的语义,如果这不可能,那么 ycm 就没用了。有谁知道如何为特定目的做这件事?如果有必要包括我的 .vimrc
或 .ycm_extra_conf.py
请在评论中询问。另外,如果我需要额外的工具,请指定它们,这样我也可以设置它们。
你想要cscope。有关设置说明,请参阅此处:
http://cscope.sourceforge.net/large_projects.html
内核非常庞大和复杂。 Cscope 在合理的时间内搜索它的性能非常好。
不过,这仍然是一个难题,因为内核大量使用 C 宏的方式对于工具来说并不总是很容易遵循。跟踪内核代码可能是一门艺术,需要练习。
这里有一些其他工具的更多提示:
以下是我使用 vim.
设置内核编程环境的方法
使用的工具:
- OmniCompletion:vim 的集成功能(无需额外插件)用于自动完成
- ctags:创建代码索引数据库,这是 OmniCompletion(和其他一些 vim 插件)所需要的
- cscope:用于导航代码的工具(例如,您可以立即跳转到光标下的函数定义等)。创建它自己的代码索引数据库(不同于 ctags)。
1。安装工具
首先,安装vim、ctags和cscope:
$ sudo aptitude install vim vim-gtk cscope exuberant-ctags
2。创建索引数据库
现在创建 cscope 和 ctags 数据库。在你的内核源代码根目录 运行 下一个脚本(我使用 this tutorial 作为参考):
#!/bin/bash
list_sources() {
echo "---> Listing sources..."
find . \
-path "./arch*" -prune -o \
-path "./tmp*" -prune -o \
-path "./Documentation*" -prune -o \
-path "./scripts*" -prune -o \
-type f -name "*.[chsS]" -print >cscope.files
find arch/arm/include/ \
arch/arm/kernel/ \
arch/arm/common/ \
arch/arm/boot/ \
arch/arm/lib/ \
arch/arm/mm/ \
arch/arm/mach-omap2/ \
arch/arm/plat-omap/ \
-type f -name "*.[chsS]" -print >>cscope.files
}
create_cscope_db() {
echo "---> Creating cscope DB..."
cscope -k -b -q
}
create_ctags_db() {
echo "---> Creating CTags DB..."
ctags -L cscope.files
}
cleanup() {
echo "---> Removing garbage..."
rm -f cscope.files
}
list_sources
create_cscope_db
create_ctags_db
cleanup
此脚本用于处理 ARM 体系结构代码(使用 OMAP 平台)。如果您需要使用其他架构(例如 x86),则需要适当更改脚本中的 find
行。
正如您从上面的脚本中看到的那样,接下来它会执行以下操作:
- 创建要索引的文件列表 (
cscope.files
),使用 find
命令。
为内核创建 cscope 数据库(默认使用 cscope.files
文件)(参见 man cscope 中的 -k
选项),使用下一个命令:
$ cscope -b -q -k
创建 ctags 文件 (tags
),使用 cscope.files
文件(参见 man ctags):
$ ctags -L cscope.files
删除 cscope.files
文件,因为不再需要它。
3。为 cscope
配置 vim
下载 cscope_maps.vim file to your ~/.vim/plugin
directory (see this link 了解详情)。
现在您可以使用 Ctrl+\, g
、Ctrl+\, s
等内容在 vim 中导航您的内核代码。有关详细信息,请参阅 this。 vim 中的 :help cscope-find
命令也很有用。
4。为 OmniCompletion
配置 vim
要使用 OmniCompletion,您需要编辑 ~/.vimrc
文件。例如,这是我的 OmniCompletion 配置(将这些行添加到您的 ~/.vimrc
):
"-------------------------------------------------------------------------------
" OmniCppCompletion plugin
"-------------------------------------------------------------------------------
" Enable OmniCompletion
" http://vim.wikia.com/wiki/Omni_completion
filetype plugin on
set omnifunc=syntaxcomplete#Complete
" Configure menu behavior
" http://vim.wikia.com/wiki/VimTip1386
set completeopt=longest,menuone
inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
inoremap <expr> <C-n> pumvisible() ? '<C-n>' :
\ '<C-n><C-r>=pumvisible() ? "\<lt>Down>" : ""<CR>'
inoremap <expr> <M-,> pumvisible() ? '<C-n>' :
\ '<C-x><C-o><C-n><C-p><C-r>=pumvisible() ? "\<lt>Down>" : ""<CR>'
" Use Ctrl+Space for omni-completion
"
inoremap <expr> <C-Space> pumvisible() \|\| &omnifunc == '' ?
\ "\<lt>C-n>" :
\ "\<lt>C-x>\<lt>C-o><c-r>=pumvisible() ?" .
\ "\"\<lt>c-n>\<lt>c-p>\<lt>c-n>\" :" .
\ "\" \<lt>bs>\<lt>C-n>\"\<CR>"
imap <C-@> <C-Space>
" Popup menu hightLight Group
highlight Pmenu ctermbg=13 guibg=LightGray
highlight PmenuSel ctermbg=7 guibg=DarkBlue guifg=White
highlight PmenuSbar ctermbg=7 guibg=DarkGray
highlight PmenuThumb guibg=Black
" enable global scope search
let OmniCpp_GlobalScopeSearch = 1
" show function parameters
let OmniCpp_ShowPrototypeInAbbr = 1
" show access information in pop-up menu
let OmniCpp_ShowAccess = 1
" auto complete after '.'
let OmniCpp_MayCompleteDot = 1
" auto complete after '->'
let OmniCpp_MayCompleteArrow = 1
" auto complete after '::'
let OmniCpp_MayCompleteScope = 0
" don't select first item in pop-up menu
let OmniCpp_SelectFirstItem = 0
OmniCompletion 将使用您的 ctags 文件 (tags
)。您现在可以使用 Ctrl+Space
(由上面的 vim 配置添加)来使用补全。
5。一些额外的东西
另请查看下一个插件:
请原谅我将这个死去已久的 post 从永恒的安息中唤醒,但我一直在与同样的问题作斗争,而接受的答案并没有回答这个问题。
问题是使用 YouCompleteMe 插件 为内核和设备 driver 开发设置 Vim。虽然接受的答案很有帮助,但它让我走上了错误的道路,因为我想让 YouCompleteMe 工作。
我就是这样解决的
我将在下面概述我是如何解决它的,以防其他人遇到这个问题,希望它能帮助他们。我不是任何这些技术的专家,所以它可能不是最好的方法,但我没能找到解决问题的任何其他方法。
工具
- 安装Vim
- 安装YouCompleteMe
- 安装BEAR
密码
我跟进了 Linux Device Drivers, Third Edition 并且我相信许多在这个问题上跌跌撞撞的人可能会尝试同样的事情。
在第 2 章中,作者为设备 driver 展示了一个简单的 "Hello, world!",我将其复制如下:
// hello.c
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void){
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void){
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
问题
在 Vim 中打开它可能会让 YCM 抱怨 #include <linux/init.h>
。
得到linuxheaders
显然,内核编译比一般 gcc hello.c
难一些,您需要在计算机上安装 linux header 文件。我使用 arch(顺便说一句),所以我使用 pacman -S linux-headers
获取它们,但其他发行版应该有类似的方法来使用包管理器获取它们。如果一切都失败了,您可以下载 Linux 内核源代码,包括来自 Website 的 header 文件。
如果您使用包管理器安装,您的 /lib/modules/$(uname -r)/build/include
目录中应该有 headers。如果您已经安装了内核源代码,header 位于 /path/to/source/include/
.
获取 Makefile
此外,您需要一个 Makefile,它可以将您的 hello.c 和 link 所有依赖项一起构建。为此,我使用了 the Makefile for the book。
但是请注意,此 Makefile 指向 /lib/modules/$(uname -r)/build
,因此如果您使用内核源代码进行构建,则必须更改它。
此外,Makefile 将尝试构建一堆其他示例,因此您可以删除它们。 obj-m := hello.o
应该是此示例的全部内容。
测试生成文件
如果此时你 运行 make
,它应该编译并且你可以 insmod 和 rmmod 新创建的 hello.ko 模块。然而你的Vim还是会抱怨。
创建编译数据库
除此之外,首先 运行 make clean
因为 BEAR demands a clean directory. Then run bear make
and it should generate a 'compile_commands.json' for you. This is what the YCM guide was referring to here.
终点线
现在,如果您在 vim 中重新打开 hello.c,它应该不会再抱怨 init.h
,并且一切都应该按预期工作。
你可能 运行 进入 this issue 尽管我已经通过将以下内容添加到我的 .vimrc 文件中解决了一堆 YCM 投诉:
let g:ycm_filter_diagnostics = {
\ "c": {
\ "regex": [
\ "-mno-fp-ret-in-387",
\ "-mpreferred-stack-boundary=3",
\ "-mskip-rax-setup",
\ "-mindirect-branch=thunk-extern",
\ "-mindirect-branch-register",
\ "-fno-allow-store-data-races",
\ "-fplugin-arg-structleak_plugin-byref-all",
\ "-fno-var-tracking-assignments",
\ "-fconserve-stack",
\ "-mrecord-mcount"
\ ]
\ }
\}
需要比我更有资格的人来解释为什么必须过滤掉这些。我对上面 link 编辑的 github 问题中的解释感到满意。
但是无论如何,现在 Vim 中您应该不会再收到错误或警告了,因为 YouCompleteMe 为内核和设备 driver 开发提供了全方位的服务。
我希望这个答案能找到并帮助仍在为这个问题苦苦挣扎的任何人!
我想为内核破解设置 vim,所以我安装了 YouCompleteMe 以自动完成。但是,无论我做什么,看起来我都无法正确配置它。它没有正确地完成语义;它只建议当前文件中已经使用的语义,甚至不包括 headers 或其他翻译单元中的语义,如果这不可能,那么 ycm 就没用了。有谁知道如何为特定目的做这件事?如果有必要包括我的 .vimrc
或 .ycm_extra_conf.py
请在评论中询问。另外,如果我需要额外的工具,请指定它们,这样我也可以设置它们。
你想要cscope。有关设置说明,请参阅此处:
http://cscope.sourceforge.net/large_projects.html
内核非常庞大和复杂。 Cscope 在合理的时间内搜索它的性能非常好。
不过,这仍然是一个难题,因为内核大量使用 C 宏的方式对于工具来说并不总是很容易遵循。跟踪内核代码可能是一门艺术,需要练习。
这里有一些其他工具的更多提示:
以下是我使用 vim.
设置内核编程环境的方法使用的工具:
- OmniCompletion:vim 的集成功能(无需额外插件)用于自动完成
- ctags:创建代码索引数据库,这是 OmniCompletion(和其他一些 vim 插件)所需要的
- cscope:用于导航代码的工具(例如,您可以立即跳转到光标下的函数定义等)。创建它自己的代码索引数据库(不同于 ctags)。
1。安装工具
首先,安装vim、ctags和cscope:
$ sudo aptitude install vim vim-gtk cscope exuberant-ctags
2。创建索引数据库
现在创建 cscope 和 ctags 数据库。在你的内核源代码根目录 运行 下一个脚本(我使用 this tutorial 作为参考):
#!/bin/bash
list_sources() {
echo "---> Listing sources..."
find . \
-path "./arch*" -prune -o \
-path "./tmp*" -prune -o \
-path "./Documentation*" -prune -o \
-path "./scripts*" -prune -o \
-type f -name "*.[chsS]" -print >cscope.files
find arch/arm/include/ \
arch/arm/kernel/ \
arch/arm/common/ \
arch/arm/boot/ \
arch/arm/lib/ \
arch/arm/mm/ \
arch/arm/mach-omap2/ \
arch/arm/plat-omap/ \
-type f -name "*.[chsS]" -print >>cscope.files
}
create_cscope_db() {
echo "---> Creating cscope DB..."
cscope -k -b -q
}
create_ctags_db() {
echo "---> Creating CTags DB..."
ctags -L cscope.files
}
cleanup() {
echo "---> Removing garbage..."
rm -f cscope.files
}
list_sources
create_cscope_db
create_ctags_db
cleanup
此脚本用于处理 ARM 体系结构代码(使用 OMAP 平台)。如果您需要使用其他架构(例如 x86),则需要适当更改脚本中的 find
行。
正如您从上面的脚本中看到的那样,接下来它会执行以下操作:
- 创建要索引的文件列表 (
cscope.files
),使用find
命令。 为内核创建 cscope 数据库(默认使用
cscope.files
文件)(参见 man cscope 中的-k
选项),使用下一个命令:$ cscope -b -q -k
创建 ctags 文件 (
tags
),使用cscope.files
文件(参见 man ctags):$ ctags -L cscope.files
删除
cscope.files
文件,因为不再需要它。
3。为 cscope
配置 vim下载 cscope_maps.vim file to your ~/.vim/plugin
directory (see this link 了解详情)。
现在您可以使用 Ctrl+\, g
、Ctrl+\, s
等内容在 vim 中导航您的内核代码。有关详细信息,请参阅 this。 vim 中的 :help cscope-find
命令也很有用。
4。为 OmniCompletion
配置 vim要使用 OmniCompletion,您需要编辑 ~/.vimrc
文件。例如,这是我的 OmniCompletion 配置(将这些行添加到您的 ~/.vimrc
):
"-------------------------------------------------------------------------------
" OmniCppCompletion plugin
"-------------------------------------------------------------------------------
" Enable OmniCompletion
" http://vim.wikia.com/wiki/Omni_completion
filetype plugin on
set omnifunc=syntaxcomplete#Complete
" Configure menu behavior
" http://vim.wikia.com/wiki/VimTip1386
set completeopt=longest,menuone
inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
inoremap <expr> <C-n> pumvisible() ? '<C-n>' :
\ '<C-n><C-r>=pumvisible() ? "\<lt>Down>" : ""<CR>'
inoremap <expr> <M-,> pumvisible() ? '<C-n>' :
\ '<C-x><C-o><C-n><C-p><C-r>=pumvisible() ? "\<lt>Down>" : ""<CR>'
" Use Ctrl+Space for omni-completion
"
inoremap <expr> <C-Space> pumvisible() \|\| &omnifunc == '' ?
\ "\<lt>C-n>" :
\ "\<lt>C-x>\<lt>C-o><c-r>=pumvisible() ?" .
\ "\"\<lt>c-n>\<lt>c-p>\<lt>c-n>\" :" .
\ "\" \<lt>bs>\<lt>C-n>\"\<CR>"
imap <C-@> <C-Space>
" Popup menu hightLight Group
highlight Pmenu ctermbg=13 guibg=LightGray
highlight PmenuSel ctermbg=7 guibg=DarkBlue guifg=White
highlight PmenuSbar ctermbg=7 guibg=DarkGray
highlight PmenuThumb guibg=Black
" enable global scope search
let OmniCpp_GlobalScopeSearch = 1
" show function parameters
let OmniCpp_ShowPrototypeInAbbr = 1
" show access information in pop-up menu
let OmniCpp_ShowAccess = 1
" auto complete after '.'
let OmniCpp_MayCompleteDot = 1
" auto complete after '->'
let OmniCpp_MayCompleteArrow = 1
" auto complete after '::'
let OmniCpp_MayCompleteScope = 0
" don't select first item in pop-up menu
let OmniCpp_SelectFirstItem = 0
OmniCompletion 将使用您的 ctags 文件 (tags
)。您现在可以使用 Ctrl+Space
(由上面的 vim 配置添加)来使用补全。
5。一些额外的东西
另请查看下一个插件:
请原谅我将这个死去已久的 post 从永恒的安息中唤醒,但我一直在与同样的问题作斗争,而接受的答案并没有回答这个问题。 问题是使用 YouCompleteMe 插件 为内核和设备 driver 开发设置 Vim。虽然接受的答案很有帮助,但它让我走上了错误的道路,因为我想让 YouCompleteMe 工作。
我就是这样解决的
我将在下面概述我是如何解决它的,以防其他人遇到这个问题,希望它能帮助他们。我不是任何这些技术的专家,所以它可能不是最好的方法,但我没能找到解决问题的任何其他方法。
工具
- 安装Vim
- 安装YouCompleteMe
- 安装BEAR
密码
我跟进了 Linux Device Drivers, Third Edition 并且我相信许多在这个问题上跌跌撞撞的人可能会尝试同样的事情。 在第 2 章中,作者为设备 driver 展示了一个简单的 "Hello, world!",我将其复制如下:
// hello.c
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void){
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void){
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
问题
在 Vim 中打开它可能会让 YCM 抱怨 #include <linux/init.h>
。
得到linuxheaders
显然,内核编译比一般 gcc hello.c
难一些,您需要在计算机上安装 linux header 文件。我使用 arch(顺便说一句),所以我使用 pacman -S linux-headers
获取它们,但其他发行版应该有类似的方法来使用包管理器获取它们。如果一切都失败了,您可以下载 Linux 内核源代码,包括来自 Website 的 header 文件。
如果您使用包管理器安装,您的 /lib/modules/$(uname -r)/build/include
目录中应该有 headers。如果您已经安装了内核源代码,header 位于 /path/to/source/include/
.
获取 Makefile
此外,您需要一个 Makefile,它可以将您的 hello.c 和 link 所有依赖项一起构建。为此,我使用了 the Makefile for the book。
但是请注意,此 Makefile 指向 /lib/modules/$(uname -r)/build
,因此如果您使用内核源代码进行构建,则必须更改它。
此外,Makefile 将尝试构建一堆其他示例,因此您可以删除它们。 obj-m := hello.o
应该是此示例的全部内容。
测试生成文件
如果此时你 运行 make
,它应该编译并且你可以 insmod 和 rmmod 新创建的 hello.ko 模块。然而你的Vim还是会抱怨。
创建编译数据库
除此之外,首先 运行 make clean
因为 BEAR demands a clean directory. Then run bear make
and it should generate a 'compile_commands.json' for you. This is what the YCM guide was referring to here.
终点线
现在,如果您在 vim 中重新打开 hello.c,它应该不会再抱怨 init.h
,并且一切都应该按预期工作。
你可能 运行 进入 this issue 尽管我已经通过将以下内容添加到我的 .vimrc 文件中解决了一堆 YCM 投诉:
let g:ycm_filter_diagnostics = {
\ "c": {
\ "regex": [
\ "-mno-fp-ret-in-387",
\ "-mpreferred-stack-boundary=3",
\ "-mskip-rax-setup",
\ "-mindirect-branch=thunk-extern",
\ "-mindirect-branch-register",
\ "-fno-allow-store-data-races",
\ "-fplugin-arg-structleak_plugin-byref-all",
\ "-fno-var-tracking-assignments",
\ "-fconserve-stack",
\ "-mrecord-mcount"
\ ]
\ }
\}
需要比我更有资格的人来解释为什么必须过滤掉这些。我对上面 link 编辑的 github 问题中的解释感到满意。 但是无论如何,现在 Vim 中您应该不会再收到错误或警告了,因为 YouCompleteMe 为内核和设备 driver 开发提供了全方位的服务。
我希望这个答案能找到并帮助仍在为这个问题苦苦挣扎的任何人!