Linux Kernel Source Auto Complete

Table of Contents

lsp

To use lsp mode, we can use a file called compile_commands.json to tell lsp backends about file compile information.

Generate compile_commands.json

Either of following methods can generate compile_commands.json, Select as you like.

  • kernel script from scripts directory
    # after build kernel
    curl -fsSL https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/scripts/gen_compile_commands.py\?h\=v5.3 | python
    
  • make bear
    1. install bear (Build EAR)
    2. compile you project
      • use bear to wrapper make command
    bear make -C kernel/msm-4.9 O=../../out/target/product/grus/obj/kernel/msm-4.9 DTC_EXT=dtc  ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- KCFLAGS=-mno-android grus_debug_defconfig
    sed 's/..\/..\/..\/..\/..\/..\/..\/kernel\/msm-4.9\///g' compile_commands.json > kernel/msm-4.9/compile_commands.json
    

auto complete setup for Emacs

  • install ccls from
  • setup your emacs
    • default c-mode-hook will execute before local-variables loaded.
    • In the fellowing settings, we use hack-local-variables-hook to execute lsp-mode setting after local variables setting.
    • For some project, like Linux Kernel, we must exclude some args unrecognizable by clang.
    (use-package ccls
      :ensure t
      :config
      ;; https://github.com/maskray/ccls/blob/master/src/config.h
      (setq
       ccls-initialization-options
       `(:clang
         (:excludeArgs
          ;; Linux's gcc options. See ccls/wiki
          ["--param=allow-store-data-races=0" "-W*" "-f*" "-m*"]
          :extraArgs ["--gcc-toolchain=/usr"])
         :completion
         (:include
          (:blacklist
           ["^/usr/(local/)?include/c\\+\\+/[0-9\\.]+/(bits|tr1|tr2|profile|ext|debug)/"
           "^/usr/(local/)?include/c\\+\\+/v1/"
           ]))))
      )
    
    (use-package lsp-mode
      :commands lsp
      :init
      (setq lsp-auto-guess-root t)    ; 我習慣自動選project root
      (setq lsp-enable-indentation nil)
      (setq lsp-enable-file-watchers nil)
      ;; (setq lsp-prefer-flymake t)  ; 預設t。flymake替代flycheck
      :config
      (require 'lsp-clients)          ; ocaml,css,python,bash,...
      :hook
      (hack-local-variables . (lambda ()
                                (cond ((derived-mode-p 'c-mode 'c++-mode 'objc-mode)
                                       (progn
                                         (require 'ccls)
                                         (lsp)))
                                      ))))
    (use-package lsp-ui
      :commands lsp-ui-mode
      :ensure t
      :config
      :hook (lsp-mode . lsp-ui-mode))
    
    (use-package company-lsp
      :ensure t
      :config
      ;; 设置 company-lsp 为后端
      (push 'company-lsp company-backends))
    
    
  • dir-locals setting
    ;;; Directory Local Variables
    ;;; For more information see (info "(emacs) Directory Variables")
    ((nil .
          ((ccls-initialization-options . (:clang
                                           (:excludeArgs
                                            ;; Linux's gcc options. See ccls/wiki
                                            ["--param=allow-store-data-races=0" "-W*" "-f*" "-m*"])
                                           :compilationDatabaseDirectory "../out/target/product/qemu/KERNEL_OBJ"
                                           )))
          ))
    
    

clangd

~/.config/clangd/config.yaml

CompileFlags:
  Add: [ -Wall, -Wunused-function, -Wno-unknown-warning-option]
  Remove: [-w, -fmax-errors, -mabi=lp64, -W, -f*, -m*]

If:
  PathMatch: [.*\.h, .*\.c, .*\.cc, .*\.cpp]
  PathExclude: []

Diagnostics:
  ClangTidy:
    Add: [misc-*,modernize*,bugprone*, clang-analyzer*]
    Remove: [modernize-use-trailing-return-type]
    CheckOptions:
      readability-identifier-naming.NamespaceCase: lower_case
      readability-identifier-naming.ClassCase: CamelCase
      readability-identifier-naming.StructCase: CamelCase
      readability-identifier-naming.TemplateParameterCase: CamelCase
      readability-identifier-naming.FunctionCase: CamelCase
      readability-identifier-naming.VariableCase: lower_case
      readability-identifier-naming.ClassMemberCase: lower_case
      readability-identifier-naming.ClassMemberSuffix: _
      readability-identifier-naming.PrivateMemberSuffix: _
      readability-identifier-naming.ProtectedMemberSuffix: _
      readability-identifier-naming.EnumConstantCase: CamelCase
      readability-identifier-naming.EnumConstantPrefix: k
      readability-identifier-naming.ConstexprVariableCase: CamelCase
      readability-identifier-naming.ConstexprVariablePrefix: k
      readability-identifier-naming.GlobalConstantCase: CamelCase
      readability-identifier-naming.GlobalConstantPrefix: k
      readability-identifier-naming.MemberConstantCase: CamelCase
      readability-identifier-naming.MemberConstantPrefix: k
      readability-identifier-naming.StaticConstantCase: CamelCase
      readability-identifier-naming.StaticConstantPrefix: k
      readability-implicit-bool-conversion.AllowIntegerConditions: 1
      readability-implicit-bool-conversion.AllowPointerConditions: 1

https://github.com/clangd/clangd/issues/662

(use-package lsp-mode
  :commands lsp
  :init
  (setq lsp-auto-guess-root t)    ; 我習慣自動選project root
  (setq lsp-enable-indentation nil)
  (setq lsp-enable-file-watchers nil)
  ;; (setq lsp-prefer-flymake t)  ; 預設t。flymake替代flycheck
  :hook
  (hack-local-variables
   . (lambda ()
       (cond ((derived-mode-p 'c-mode 'c++-mode 'objc-mode)
              (progn
                (lsp)))
             ))))

enjoy codeing with emacs

Contact me via :)
虚怀乃若谷,水深则流缓。