linuxemacsflycheck

Using flycheck/flymake on kernel source tree


Is there a easy/automated way to configure flycheck or flymake to show error annotations while writing on a file in the linux kernel source tree? Assuming I am working on fs/proc/cmdline.c I would like flycheck to go down two directories and do a "make fs/proc/cmdline.o" and then annotate the result. Assuming ARCH and CROSS_COMPILE is set externally.


Solution

  • I'd been thinking of doing this myself - here's what I've got:

    You need to find the base of the kernel source tree, so the default flymake deal of looking for Makefile is counter productive. We'll add our own file which doubles for locating the source base, and for wrapping the normal kernel makefile:

    Add a file flymake.mk to the base of the kernel source tree (configure for your own cross-compilation needs):

    ARCH=mips
    CROSS_COMPILE=mips-linux-gnu-
    
    export ARCH
    export CROSS_COMPILE
    
    .PHONY: check-syntax
    check-syntax:
        make -f Makefile $(patsubst %_flymake.o,%.o,$(patsubst %.c,%.o,$(CHK_SOURCES)))
    

    The gist is to strip out "_flymake.c" and only compile the real file, and build the file for real, rather than just for syntax. This avoids us accidentally creating file_flymake.o

    We'll need to convince flymake to look for flymake.mk and run check-syntax against it - add these to your .emacs:

    ;; Build a custom command-line using flymake.mk
    (defun flymake-get-kernel-make-cmdline (source base-dir)
      (list "make"
        (list "-s"
                  "-f"
                  "flymake.mk"
              "-C"
              base-dir
              (concat "CHK_SOURCES=" source)
              "SYNTAX_CHECK_MODE=1"
              "check-syntax")))
    
    ;; Search for flymake.mk to locate kernel tree base
    (defun flymake-kernel-make-init ()
      (flymake-simple-make-init-impl 'flymake-create-temp-inplace t t "flymake.mk" 'flymake-get-kernel-make-cmdline))
    
    ;; Register against .c files under /linux/ or /kernel/
    ;; Since the list is parsed in order use `push`
    (push '(".+/\\(linux\\|kernel\\)/.+\\.c$" flymake-kernel-make-init) flymake-allowed-file-name-masks)
    

    Limitations:

    The header, temp and external modules limitations could be overcome by patching the kernel Makefile itself, which for now I wanted to avoid.