web-dev-qa-db-fra.com

Configuration de Vim pour le développement du noyau Linux

Le développement du noyau est en fait différent d'un développement de projet C traditionnel (à mon avis, en tant que débutant). Donc, je me demande toujours quelle est la configuration vim d'un pirate du noyau.

Le plus important est de savoir comment naviguer dans l'arborescence des sources du noyau dans vim .. J'ai essayé ctags, cependant, cela fonctionne terriblement.

Quelqu'un peut-il me donner un indice?

21
Douglas Su

Les principales différences entre le noyau Linux et le projet C normal (du point de vue du développeur) sont les suivantes:

  • le noyau est un très gros projet (vous devez donc choisir le code à indexer)
  • il a un code dépendant de l'architecture (et vous n'êtes intéressé que par une architecture spécifique à la fois; les autres architectures ne doivent pas être indexées)
  • il a très spécifique style de codage vous devez vous en tenir à (et vim doit être configuré pour afficher le code en conséquence)
  • il n'utilise pas la bibliothèque standard C, mais a à la place ses propres routines similaires (donc votre outil d'indexation ne devrait pas indexer les en-têtes libc)

Installation d'outils d'indexation

Pour naviguer dans le code du noyau, je conseillerais les outils cscope et ctags. Pour les installer, exécutez la commande suivante:

$ Sudo aptitude install cscope exuberant-ctags

Une petite explication:

  • cscope: sera utilisé pour naviguer dans le code (basculer entre les fonctions, etc.)
  • ctags: nécessaire pour le plugin Tagbar (sera discuté plus loin) et pour Omni completion (mécanisme de complétion automatique dans vim); peut également être utilisé pour la navigation

Création d'une base de données d'index

Vous devez maintenant indexer vos fichiers source du noyau. Il y a 2 approches ici: créer un index manuellement ou utiliser le script disponible dans le noyau. Si vous n'êtes pas sûr de la meilleure façon pour vous, je recommande d'utiliser le script du noyau, car il fait beaucoup d'astuces en coulisses (comme ignorer les sources non construites et déplacer les fichiers d'en-tête en haut de la liste des résultats).

Mais tout d'abord, configurez et construisez le noyau de votre architecture/carte, car les fichiers construits peuvent être utilisés plus tard pour améliorer le processus d'indexation.

Indexation avec scripts/tags.sh

Le noyau a un assez bon script (scripts/tags.sh) Pour créer la base de données d'index du noyau. Il faut utiliser les règles make cscope Et make tags Pour créer un index, au lieu d'exécuter directement ce script.

Exemple:

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

  • O=. - utilisez des chemins absolus (utile si vous voulez charger les fichiers d'index cscope/ctags créés en dehors du répertoire du noyau, par exemple pour le développement de modules du noyau hors de l'arborescence). Si vous souhaitez utiliser des chemins relatifs (c'est-à-dire que vous ne ferez du développement que dans le répertoire du noyau), omettez simplement ce paramètre
  • Arch=... - sélectionnez l'architecture CPU à indexer. Voir les répertoires sous Arch/ Pour référence. Par exemple, si Arch=arm, Alors le répertoire Arch/arm/ Sera indexé, le reste des répertoires Arch/* Sera ignoré
  • SUBARCH=... - sélectionnez la sous-architecture (c'est-à-dire les fichiers liés à la carte) à indexer. Par exemple, si SUBARCH=omap2, Seuls les répertoires Arch/arm/mach-omap2/ Et Arch/arm/plat-omap/ Seront indexés, le reste des machines et des plates-formes sera ignoré.
  • COMPILED_SOURCE=1 - indexe uniquement les fichiers compilés. Vous n'êtes généralement intéressé que par les fichiers source utilisés dans votre build (donc compilés). Si vous souhaitez indexer également des fichiers qui n'ont pas été créés, omettez simplement cette option.
  • cscope - règle pour faire l'index cscope
  • tags - règle pour créer un index ctags

Indexation manuelle

Le script du noyau (tags.sh) Peut ne pas fonctionner correctement ou vous pouvez avoir plus de contrôle sur le processus d'indexation. Dans ces cas, vous devez indexer manuellement les sources du noyau.

Les informations sur l'indexation manuelle proviennent de ici .

Vous devez d'abord créer un fichier cscope.files Qui répertoriera tous les fichiers que vous souhaitez indexer. Par exemple, j'utilise les commandes suivantes pour répertorier les fichiers pour ARM (Arch/arm), Et en particulier pour la plate-forme OMAP (à l'exclusion du reste des plates-formes pour faciliter la navigation):

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

Pour l'architecture x86 (Arch/x86), Vous pouvez utiliser quelque chose comme ceci:

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

Où la variable dir peut avoir l'une des valeurs suivantes:

  • .: Si vous ne travaillez que dans le répertoire du code source du noyau; dans ce cas, ces commandes doivent être exécutées à partir du répertoire racine du code source du noyau
  • chemin absolu vers votre répertoire de code source du noyau : si vous allez développer un module de noyau hors arbre; dans ce cas, le script peut être exécuté de n'importe où

J'utilise la première option (dir=.), Car je ne développe aucun module hors arborescence.

Maintenant, lorsque le fichier cscope.files Est prêt, nous devons exécuter l'indexation réelle:

$ cscope -b -q -k

Où le paramètre -k Indique à cscope de ne pas indexer la bibliothèque standard C (car le noyau ne l'utilise pas).

Il est maintenant temps de créer la base de données d'index ctags. Pour accélérer cette étape, nous allons réutiliser déjà créé cscope.files:

$ ctags -L cscope.files

Ok, les bases de données d'index cscope et ctags sont construites, et vous pouvez supprimer le fichier cscope.files, Car nous n'en avons plus besoin:

$ rm -f cscope.files

Les fichiers suivants contiennent des bases de données d'index (pour cscope et ctags):

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

Gardez-les à la racine du répertoire des sources du noyau.

plugins vim

[~ # ~] note [~ # ~] : Ensuite, je montre comment utiliser pathogen pour la gestion des plugins Vim . Mais maintenant que Vim 8 est sorti, on peut utiliser chargement de paquet natif dans le même but.

Ensuite, nous allons installer des plugins pour vim. Pour mieux le comprendre, je vous encourage à utiliser le plugin pathogène . Il vous permet de simplement git clone Vim plugins à votre ~/.vim/bundle/ Et de les garder isolés, plutôt que de mélanger les fichiers de différents plugins dans le répertoire ~/.vim.

Installez l'agent pathogène comme il est décrit ici .

N'oubliez pas de faire les choses suivantes (comme cela est décrit sur le même lien):

Ajoutez ceci à votre vimrc:

execute pathogen#infect()

Si vous êtes nouveau sur Vim et que vous n'avez pas de vimrc, vim ~/.vimrc Et collez dans l'exemple super-minimal suivant:

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

Installation de cartes cscope pour vim

Vim prend déjà en charge cscope (voir :help cscope). Vous pouvez passer au symbole ou au fichier à l'aide de commandes comme :cs f g kfree. Ce n'est pas si pratique cependant. Pour accélérer les choses, vous pouvez utiliser des raccourcis à la place (pour placer votre curseur sur une fonction, appuyez sur une combinaison de touches et passez à la fonction). Afin d'ajouter des raccourcis pour cscope, vous devez obtenir le fichier cscope_maps.vim.

Pour l'installer en utilisant l'agent pathogène , vous pouvez simplement cloner this repo dans votre ~/.vim/bundle:

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

Vous devriez maintenant pouvoir naviguer entre les fonctions et les fichiers dans vim à l'aide de raccourcis. Ouvrez un fichier source du noyau, placez le curseur de votre clavier sur un appel de fonction et appuyez sur Ctrl+\ suivi par g. Cela devrait vous amener à la mise en œuvre de la fonction. Ou il peut vous montrer toutes les implémentations de fonctions disponibles, alors vous pouvez choisir celle à utiliser: cscope-struct .

Pour le reste des mappages de clés, voir cscope_maps.vim fichier.

Vous pouvez également utiliser des commandes dans vim comme:

:cs f g kmalloc

Voir :help cscope Pour plus de détails.

ctags note

les ctags peuvent toujours être utiles pour la navigation, par exemple lorsque vous recherchez une déclaration #define. Vous pouvez placer le curseur sur cette définition d'utilisation et appuyer sur g suivi par Ctrl+]. Voir cette réponse pour plus de détails.

cscope note

L'astuce suivante peut être utilisée pour trouver la structure de la déclaration dans le noyau:

:cs f t struct device {

Notez que la commande ci-dessus repose sur un style de déclaration de structure spécifique (utilisé dans le noyau), nous savons donc que la déclaration de structure a toujours cette forme: struct some_stuct {. Cette astuce peut ne pas fonctionner dans les projets avec un autre style de codage.

note de développement des modules hors arborescence

Si vous développez un module hors arborescence, vous devrez probablement charger les bases de données cscope et ctags à partir de votre répertoire du noyau. Cela peut être fait par les commandes suivantes dans vim (en mode commande).

Charger la base de données cscope externe:

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

Charger la base de données ctags externe:

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

vimrc

Certaines modifications doivent également être apportées à votre ~/.vimrc, Afin de mieux prendre en charge le développement du noyau.

Tout d'abord, soulignons la 81e colonne avec une ligne verticale (car le codage du noyau nécessite que vous gardiez la longueur de vos lignes à 80 caractères maximum):

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

Décommentez la deuxième ligne si vous souhaitez également mettre en évidence plus de 80 colonnes.

Les espaces de fin sont interdits par le style de codage du noyau, vous pouvez donc les mettre en évidence:

" 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()

Style de codage du noyau

Pour que vim respecte le style de codage du noyau, vous pouvez tirer le plugin prêt à l'emploi: vim-linux-coding-style .

Plugins utiles

Les plugins suivants sont couramment utilisés, vous pouvez donc les trouver utiles également:

Ce sont également des plugins intéressants, mais vous devrez peut-être les configurer pour le noyau:

Achèvement Omni

Vim 7 (et versions ultérieures) dispose déjà d'un support de complétion automatique. Il appelle Omni completion. Voir : help new-omni-complétement pour plus de détails.

L'achèvement Omni fonctionne plutôt lentement sur un projet aussi important que le noyau. Si vous le souhaitez toujours, vous pouvez l'activer en ajoutant les lignes suivantes à votre ~/.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

Et utilise Ctrl+Space pour l'achèvement automatique.

Apparence de bonbons pour les yeux

256 couleurs

Tout d'abord, vous voulez être sûr que votre terminal prend en charge 256 couleurs. Par exemple, cela peut être réalisé en utilisant rxvt-256 terminal. Pour gnome-terminal, Vous pouvez simplement ajouter la ligne suivante à votre ~/.bashrc:

export TERM="xterm-256color"

Une fois cela fait, mettez la ligne suivante dans votre ~/.vimrc:

set t_Co=256

Schéma de couleur

Téléchargez maintenant les schémas que vous préférez ~/.vim/colors Et sélectionnez-les dans ~/.vimrc:

set background=dark
colorscheme hybrid

Le jeu de couleurs à utiliser est une question fortement basée sur l'opinion. Je peux recommander mrkn256 , hybride et solarized pour les débutants.

Police de caractère

Il existe de nombreuses bonnes polices pour la programmation. De nombreux programmeurs sous Linux utilisent la police Terminus , vous pouvez l'essayer pour commencer.

Lacunes connues

Certaines fonctionnalités manquent toujours dans vim.

  1. cscope/ctags ne peut pas utiliser les définitions de include/generated/autoconf.h et ignorer le code qui n'a pas été construit. Il est toujours utile d'indexer tout le code pour l'utiliser comme référence lors du codage.
  2. Il n'y a pas d'extension de macro (enfin, il y a certains fonction là-bas (basé sur gcc -E)), mais je ne sais pas si ça va fonctionner pour le noyau).

Le seul IDE que je connais pour gérer ces problèmes est Eclipse avec CDT .

65
Sam Protsenko