web-dev-qa-db-ja.com

Linuxカーネル開発用のVim設定

カーネル開発は、実際には従来のCプロジェクト開発とは異なります(私の見たところ、初心者として)。だから、私はいつもカーネルハッカーのvim設定は何だろうと思っています。

最も重要なことは、vimでカーネルソースツリーをナビゲートする方法です。私はctagsを試しましたが、ひどく動作します。

誰かが私に手がかりを与えることができますか?

21
Douglas Su

Linuxカーネルと通常のCプロジェクトの主な違い(開発者の観点から)は次のとおりです。

  • カーネルは非常に大きなプロジェクトです(したがって、インデックスを作成するコードを選択する必要があります)
  • アーキテクチャに依存するコードがあります(そして、一度に1つの特定のアーキテクチャにのみ興味があります;他のアーキテクチャはインデックス化されるべきではありません)
  • 非常に具体的です コーディングスタイル に固執する必要があります(それに応じてコードを表示するようにvimを構成する必要があります)
  • c標準ライブラリを使用しませんが、代わりに独自の同様のルーチンを使用します(したがって、インデックスツールはlibcヘッダーのインデックスを作成しないでください)

インデックス作成ツールのインストール

カーネルコードをナビゲートするには、cscopeおよびctagsツールを使用することをお勧めします。それらをインストールするには、次のコマンドを実行します。

$ Sudo aptitude install cscope exuberant-ctags

少し説明:

  • cscope:は、コードをナビゲートするために使用されます(関数間の切り替えなど)
  • ctagsTagbarプラグイン(さらに説明します)およびOmni completion(vimの自動補完メカニズム)に必要です。ナビゲーションにも使用できます

インデックスデータベースの作成

次に、カーネルソースファイルのインデックスを作成する必要があります。ここには2つのアプローチがあります。手動でインデックスを作成するか、カーネルで利用可能なスクリプトを使用します。どちらの方法が最適かわからない場合は、カーネルスクリプトを使用することをお勧めします。これは、舞台裏で多くの巧妙なトリックを行うためです(ビルドされていないソースを無視したり、ヘッダーファイルを結果リストの上に移動するなど)。

ただし、最初に、構築されたファイルを後で使用してインデックス作成プロセスを改善できるため、アーキテクチャ/ボード用のカーネルを構成および構築します。

scripts/tags.shを使用したインデックス作成

カーネルには、カーネルインデックスデータベースを作成するための非常に優れたスクリプト(scripts/tags.sh)があります。インデックスを作成するには、そのスクリプトを直接実行する代わりに、make cscopeおよびmake tagsルールを使用する必要があります。

例:

$ make O=. Arch=arm SUBARCH=omap2 COMPILED_SOURCE=1 cscope tags

どこ

  • O=.-絶対パスを使用します(作成されたcscope/ctagsインデックスファイルをカーネルディレクトリの外部にロードする場合、たとえばツリー外カーネルモジュールの開発に役立ちます)。相対パスを使用する場合(つまり、カーネルdirでのみ開発を行う場合)、そのパラメーターを省略します。
  • Arch=...-インデックスを作成するCPUアーキテクチャを選択します。参考のため、Arch/の下のディレクトリを参照してください。たとえば、Arch=armの場合、Arch/arm/ディレクトリのインデックスが作成され、残りのArch/*ディレクトリは無視されます
  • SUBARCH=...-インデックスを作成するサブアーキテクチャ(つまり、ボード関連ファイル)を選択します。たとえば、SUBARCH=omap2Arch/arm/mach-omap2/およびArch/arm/plat-omap/ディレクトリのみがインデックス付けされる場合、残りのマシンとプラットフォームは無視されます。
  • COMPILED_SOURCE=1-コンパイルされたファイルのみにインデックスを付けます。通常、ビルドで使用されるソースファイルにのみ関心があります(したがってコンパイルされます)。ビルドされていないファイルもインデックス化する場合は、このオプションを省略します。
  • cscope-cscopeインデックスを作成するルール
  • tags-ctagsインデックスを作成するルール

手動でインデックスを作成する

カーネルスクリプト(tags.sh)が正常に動作しないか、インデックス作成プロセスをより詳細に制御したい場合があります。これらの場合、カーネルソースに手動でインデックスを付ける必要があります。

手動インデックス付けに関する洞察は、 here から得られました。

最初に、インデックスを作成するすべてのファイルをリストするcscope.filesファイルを作成する必要があります。たとえば、次のコマンドを使用して、ARM architecture(Arch/arm)]、特にOMAPプラットフォーム(ナビゲーションを簡単にするための残りのプラットフォームを除く)のファイルを一覧表示しています。

find    $dir                                          \
        -path "$dir/Arch*"               -Prune -o    \
        -path "$dir/tmp*"                -Prune -o    \
        -path "$dir/Documentation*"      -Prune -o    \
        -path "$dir/scripts*"            -Prune -o    \
        -path "$dir/tools*"              -Prune -o    \
        -path "$dir/include/config*"     -Prune -o    \
        -path "$dir/usr/include*"        -Prune -o    \
        -type f                                       \
        -not -name '*.mod.c'                          \
        -name "*.[chsS]" -print > cscope.files
find    $dir/Arch/arm                                 \
        -path "$dir/Arch/arm/mach-*"     -Prune -o    \
        -path "$dir/Arch/arm/plat-*"     -Prune -o    \
        -path "$dir/Arch/arm/configs"    -Prune -o    \
        -path "$dir/Arch/arm/kvm"        -Prune -o    \
        -path "$dir/Arch/arm/xen"        -Prune -o    \
        -type f                                       \
        -not -name '*.mod.c'                          \
        -name "*.[chsS]" -print >> cscope.files
find    $dir/Arch/arm/mach-omap2/                     \
        $dir/Arch/arm/plat-omap/                      \
        -type f                                       \
        -not -name '*.mod.c'                          \
        -name "*.[chsS]" -print >> cscope.files

X86アーキテクチャ(Arch/x86)の場合、次のようなものを使用できます。

find    $dir                                          \
        -path "$dir/Arch*"               -Prune -o    \
        -path "$dir/tmp*"                -Prune -o    \
        -path "$dir/Documentation*"      -Prune -o    \
        -path "$dir/scripts*"            -Prune -o    \
        -path "$dir/tools*"              -Prune -o    \
        -path "$dir/include/config*"     -Prune -o    \
        -path "$dir/usr/include*"        -Prune -o    \
        -type f                                       \
        -not -name '*.mod.c'                          \
        -name "*.[chsS]" -print > cscope.files
find    $dir/Arch/x86                                 \
        -path "$dir/Arch/x86/configs"    -Prune -o    \
        -path "$dir/Arch/x86/kvm"        -Prune -o    \
        -path "$dir/Arch/x86/lguest"     -Prune -o    \
        -path "$dir/Arch/x86/xen"        -Prune -o    \
        -type f                                       \
        -not -name '*.mod.c'                          \
        -name "*.[chsS]" -print >> cscope.files

dir変数には、次の値のいずれかを指定できます。

  • .:カーネルソースコードディレクトリでのみ作業する場合。この場合、これらのコマンドはカーネルソースコードのルートディレクトリから実行する必要があります
  • カーネルソースコードディレクトリへの絶対パス:ツリー外カーネルモジュールを開発する場合;この場合、スクリプトはどこからでも実行できます

ツリー外モジュールを開発していないため、最初のオプション(dir=.)を使用しています。

cscope.filesファイルの準備ができたら、実際のインデックス作成を実行する必要があります。

$ cscope -b -q -k

-kパラメータは、C標準ライブラリのインデックスを作成しないように(カーネルが使用しないため)cscopeに指示します。

次は、ctagsインデックスデータベースを作成します。この段階を加速するために、すでに作成されたcscope.filesを再利用します。

$ ctags -L cscope.files

OK、cscopeおよびctagsインデックスデータベースが構築されます。cscope.filesファイルは不要になったため、削除できます。

$ rm -f cscope.files

次のファイルには、インデックスデータベースが含まれています(cscopeおよびctagsの場合):

- cscope.in.out
- cscope.out
- cscope.po.out
- tags

カーネルソースディレクトリのルートに保存します。

vimプラグイン

[〜#〜] note [〜#〜]:さらにpathogenの使用方法を示しますVimプラグインの処理。しかし、Vim 8がリリースされたので、同じ目的で ネイティブパッケージロード を使用できます。

次に、vimのプラグインをインストールします。理解を深めるために、pathogenプラグインを使用することをお勧めします。 git cloneディレクトリにあるさまざまなプラグインのファイルを混合するのではなく、~/.vim/bundle/ vimプラグインを~/.vimに隔離し、それらを隔離したままにすることができます。

説明されているようにpathogenをインストールします here

次のことを忘れないでください(同じリンクで説明されています):

これをvimrcに追加します:

execute pathogen#infect()

Vimが初めてで、vimrcvim ~/.vimrcがない場合は、次の超最小限の例を貼り付けます。

execute pathogen#infect()
syntax on
filetype plugin indent on

Vim用のcscopeマップのインストール

Vimは既にcscopeをサポートしています(:help cscopeを参照)。 :cs f g kfreeなどのコマンドを使用して、シンボルまたはファイルにジャンプできます。しかし、それほど便利ではありません。物事を加速するために、代わりにショートカットを使用することができます(したがって、カーソルを機能に置き、キーの組み合わせを押して機能にジャンプできます)。 cscopeのショートカットを追加するには、cscope_maps.vimファイルを取得する必要があります。

pathogenを使用してインストールする場合は、 this~/.vim/bundleにレポするだけです:

$ git clone https://github.com/joe-skb7/cscope-maps.git ~/.vim/bundle/cscope-maps

これで、ショートカットを使用してvimの関数とファイル間を移動できるようになります。いくつかのカーネルソースファイルを開き、キーボードカーソルを関数呼び出しに合わせて押します Ctrl+\ に続く g。関数を実装する必要があります。または、使用可能なすべての関数実装を表示してから、使用するものを選択できます。 cscope-struct

キーマッピングの残りについては、 cscope_maps.vim ファイルを参照してください。

次のようなコマンドをvimで使用することもできます。

:cs f g kmalloc

詳細については、:help cscopeを参照してください。

ctags note

ctagsは、たとえば#define宣言を検索するときなど、ナビゲーションに役立ちます。これにカーソルを置いて使用方法を定義し、を押すことができます g に続く Ctrl+]。詳細については、 this answer を参照してください。

cscope note

次のトリックを使用して、カーネル内の構造宣言を見つけることができます。

:cs f t struct device {

上記のコマンドは特定の構造体宣言スタイル(カーネルで使用)に依存しているため、構造体宣言の形式は常にstruct some_stuct {であることがわかっています。このトリックは、別のコーディングスタイルのプロジェクトでは機能しない場合があります。

アウトオブツリーモジュール開発ノート

アウトオブツリーモジュールを開発している場合は、おそらくカーネルディレクトリからcscopeおよびctagsデータベースをロードする必要があります。 vimの次のコマンド(コマンドモード)で実行できます。

外部cscopeデータベースをロードします。

:cs add /path/to/your/kernel/cscope.out

外部ctagsデータベースをロードします。

:set tags=/path/to/your/kernel/tags

vimrc

カーネル開発をよりよくサポートするために、~/.vimrcにもいくつかの変更を行う必要があります。

まず、81行目を垂直線で強調表示します(カーネルコーディングでは行の長さを最大80文字に維持する必要があるため)。

" 80 characters line
set colorcolumn=81
"execute "set colorcolumn=" . join(range(81,335), ',')
highlight ColorColumn ctermbg=Black ctermfg=DarkRed

80列以上も強調表示する場合は、2行目のコメントを解除します。

末尾のスペースはカーネルコーディングスタイルによって禁止されているため、強調表示することができます。

" Highlight trailing spaces
" http://vim.wikia.com/wiki/Highlight_unwanted_spaces
highlight ExtraWhitespace ctermbg=red guibg=red
match ExtraWhitespace /\s\+$/
autocmd BufWinEnter * match ExtraWhitespace /\s\+$/
autocmd InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
autocmd InsertLeave * match ExtraWhitespace /\s\+$/
autocmd BufWinLeave * call clearmatches()

カーネルコーディングスタイル

Vimがカーネルコーディングスタイルを尊重するようにするには、プラグイン vim-linux-coding-style を使用する準備ができています。

便利なプラグイン

次のプラグインは一般的に使用されるため、同様に便利です。

また、これらは興味深いプラグインですが、カーネル用に設定する必要がある場合があります。

オムニ完了

Vim 7(およびそれ以降)には、すでに自動補完サポートが組み込まれています。 Omni completionを呼び出します。詳細については :help new-omni-completion をご覧ください。

カーネルなどの大きなプロジェクトでは、オムニ補完はかなり遅くなります。それでも必要な場合は、次の行を~/.vimrcに追加して有効にすることができます。

" 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
" https://stackoverflow.com/questions/510503/ctrlspace-for-omni-and-keyword-completion-in-vim
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

そして使用する Ctrl+Space 自動補完用。

目の保養

256色

まず、端末が256色をサポートしていることを確認します。たとえば、 rxvt-256 terminalを使用して実現できます。 gnome-terminalの場合、次の行を~/.bashrcに追加するだけです。

export TERM="xterm-256color"

完了したら、次の行を~/.vimrcに追加します。

set t_Co=256

カラースキーム

~/.vim/colorsにしたいスキームをダウンロードし、~/.vimrcで選択してください:

set background=dark
colorscheme hybrid

どの配色を使用するかは、意見に強く依存します。 mrkn256hybridsolarized を推奨します。

フォント

プログラミング用の優れたフォントがたくさんあります。 Linuxの多くのプログラマーは Terminus フォントを使用しています。初心者向けに試してみてください。

既知の欠点

Vimにはまだいくつかの機能がありません。

  1. cscope/ctagsはinclude/generated/autoconf.hの定義を使用できず、ビルドされていないコードを無視できません。コーディング時に参照として使用するために、すべてのコードにインデックスを付けることは依然として有用です。
  2. マクロ展開はありません(まあ、そこisいくつか 関数 そこ(gcc -Eに基づいて)ですが、カーネルで動作するかどうかわかりません)。

唯一のIDEこれらの問題を処理することがわかっているのは Eclipse with CDT です。

65
Sam Protsenko