Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to setup YouCompleteMe for kernel and device driver development?

I would like to setup vim for kernel hacking so I have installed YouCompleteMe for auto completion. However, no matter what I do It looks like I can't configure it properly. It does not do semantic completion properly; It only suggests the semantics already used in the current file not even the ones in the headers or other translation units and if that's impossible then ycm is pretty useless. Does anyone know how to do it for the particular purpose? If it's necessary to include my .vimrc or .ycm_extra_conf.py please ask in the comments. Also if I need extra tools please specify them so I can set them up as well.

like image 293
moki Avatar asked Mar 16 '23 02:03

moki


1 Answers

Forgive me for waking this long dead post from its eternal rest, but I've been fighting this same problem and the accepted answer does not answer the question. The question was setting up Vim with the YouCompleteMe plugin for kernel and device driver development. And while the accepted answer is helpful, it sent me on a wrong path because I wanted to make YouCompleteMe work.

This is how I solved it

I'll outline below how I've solved it in case others come across this and hopefully it helps them. I am not an expert in any of these technologies so it may not be the best way, but I've failed to find any other solution to the problem.

Tools

  1. Install Vim
  2. Install YouCompleteMe
  3. Install BEAR

The code

I've followed along with Linux Device Drivers, Third Edition and I have no doubt that many stumbling on this question will likely be trying the same. In chapter 2, the author shows a simple "Hello, world!" for device drivers, which I'll copy below:

// 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);

The problem

Opening this in Vim will probably get YCM to complain about #include <linux/init.h>.

Get the linux headers

Apparently kernel compilation is a bit tougher than your average gcc hello.c and you'll need to have the linux header files on your machine. I use arch (btw) so I got them using pacman -S linux-headers but other distros should have similar ways of getting them using the package managers. If all else fails, you can download the Linux kernel source, including header files from their Website. If you installed using a package manager, you should have the headers in your /lib/modules/$(uname -r)/build/include directory. If you've installed the kernel source, the headers are in /path/to/source/include/.

Get a Makefile

Additionally you need a Makefile that can build your hello.c and link together all dependencies. For this I've used the Makefile for the book. Note however, that this Makefile points to /lib/modules/$(uname -r)/build so you'll have to change this if you're building using the kernel source. Additionally the Makefile will try to build a bunch of other examples so you can just remove these. obj-m := hello.o should be all that remains for this example.

Test Makefile

If you run make at this point, it should compile and you can insmod and rmmod the newly created hello.ko module. However your Vim will still complain.

Create the compilation database

In other to make this go away, first run make clean because 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.

The finish line

Now if you reopen hello.c in vim, it should not complain anymore about init.h and everything should work as expected. You might run into this issue though for a bunch of YCM complaints which I've solved by adding the following to my .vimrc file:

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"                                             
  \   ]                                                               
  \ }                                                                 
  \}       

It will take someone more qualified than me to explain why these have to be filtered out. I was content with the explanation in the github issue I linked above. But in any case, now you should have no more errors or warnings in Vim, with YouCompleteMe offering its full range of services for kernel and device driver development.

I hope this answer finds and helps anyone still struggling with this problem!

like image 140
Potential Guacamole Avatar answered Apr 06 '23 00:04

Potential Guacamole