I am starting to develop a ROS (Robot Operating System) application for the first time using Emacs. Here is my ~/.emacs.d/init.el configuration for Flycheck and company packages:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Flycheck
;;;;;;;; Description: code linting (particularly C/C++ for me)
(require 'cc-mode)
(add-hook 'c++-mode-hook 'flycheck-mode)
(add-hook 'c-mode-hook 'flycheck-mode)
;; Check buffer on save, new line and immediately after anbling flycheck-mode
(setq flycheck-check-syntax-automatically '(mode-enabled save)) ;; new-line also possible
;; Add include paths
(add-hook 'c++-mode-hook
          (lambda () (setq flycheck-clang-include-path
                           (list (expand-file-name "/opt/ros/kinetic/include/")))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; company-mode
;;;;;;;; Description: text completion framework
(require 'company)
;; Use company-mode in all buffers
(add-hook 'after-init-hook 'global-company-mode)
;; Use company-mode with Clang
(setq company-backends (delete 'company-semantic company-backends))
(set 'company-clang-arguments (list "-std=c++11")) ;; enable C++11 code completion

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Irony
;;;;;;;; Description: asynchronous completion capability for company-mode
(add-hook 'c++-mode-hook 'irony-mode)
(add-hook 'c-mode-hook 'irony-mode)
(add-hook 'objc-mode-hook 'irony-mode)

(defun my-irony-mode-hook ()
  (define-key irony-mode-map [remap completion-at-point]
  (define-key irony-mode-map [remap complete-symbol]

(add-hook 'irony-mode-hook 'my-irony-mode-hook)
(add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)
;; Use comapny-mode with Irony
(add-hook 'irony-mode-hook 'company-irony-setup-begin-commands)
(setq company-backends (delete 'company-semantic company-backends))
;; Enable tab-completion with no delay
(setq company-idle-delay 0)
(define-key c-mode-base-map (kbd "<S-SPC>") 'company-complete)
;; Add support for completing C/C++ headers
(require 'company-irony-c-headers)
(eval-after-load 'company
    'company-backends '(company-irony-c-headers company-irony)))
;;(add-to-list 'company-c-headers-path-system "/usr/include/c++/5.4.0/")
;; Integrate Irony with Flycheck
(eval-after-load 'flycheck
  '(add-hook 'flycheck-mode-hook #'flycheck-irony-setup))
;; Set cppcheck standard to C++11
(setq irony-additional-clang-options '("-std=c++11"))

My problem is that it seems like Flycheck is not recognizing where the ROS header files are located. On my system, they are all in /opt/ros/kinetic/include/ and I tried to include this path in the above code with the command:

;; Add include paths
(add-hook 'c++-mode-hook
          (lambda () (setq flycheck-clang-include-path
                           (list (expand-file-name "/opt/ros/kinetic/include/")))))

However, this seems to not fix things. I still get the error:

enter image description here

Please help me with an answer on the best practice of adding custom include paths for projects for both Flycheck and company-mode to use, with the include path in this particular case being /opt/ros/kinetic/include. Thank you!

1 Answer 1


Irony-mode maintainer's here.

Also using ROS at work.

If you use catkin, then you can get along with irony-mode easily.

I do not have ROS at my disposal right now but you should be able to do something along these lines.

With catkin_make:

# create build/compile_commands.json

emacs src/my_packages/src/foo.cpp

If I explain a bit more:

First step, tells CMake (which catkin uses under the hoot) to generate a compilation database. You can read more about the compilation database here:

If I got the command right, you will have a new file in you build directory: build/compile_commands.json.

Second step, when you open Emacs on the file. irony-autosetup-compile-options will look if there is a compilation database in a parent directory of your file, or in a subdirectory build/ in a parent path of your file, which should be the case with the command we typed earlier. Type C-h v irony-cdb-search-directory-list RET for more information.

With catkin_tools:

# create ~/catkin_ws/build/xxx/compile_commands.json
# for all the packages located in ~/catkin_ws/src/xxx
catkin config --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

# in emacs, type:
#     M-x irony-cdb-json-add-compile-commands-path RET
# you will be prompted with the compile_commands.json to add, in this case,
# set the "Project root" to ~/catkin_ws/src/xxx/
# and set the "Compile commands" to ~/catkin_ws/build/xxx/compile_commands.json
emacs src/my_packages/src/foo.cpp
  • I use catkin_tools, running catkin -DCMAKE_EXPORT_COMPILE_COMMANDS=ON produces Error: No verb provided. Any idea what to do? Nov 7, 2016 at 20:00
  • I managed to get the first command to work by first running catkin config --append-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON, then I can run catkin build and the .json databases are created under catkin_ws/build/my_package/compile_commands.json. What do I do from there? Nov 7, 2016 at 20:08
  • Oups, there is a typo in my answer, does it work if you use catkin_make: catkin_make -DCMAKE_EXPORT_COMPILE_COMMANDS=ON. But since you are not using catkin_make, it looks like you can do: catkin build --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON. If the compile_commands.json is in such paths, you have to tell irony-mode about the location: M-x irony-cdb-json-add-compile-commands-path RET. Nov 7, 2016 at 20:15
  • As I said in my second comment, the compile_commands.json files are in ~/catkin_ws/build/my_package/compile_commands.json for package my_package which, itself, is located in ~/catkin_ws/src/my_package/. Are these the correct paths for Irony? Because as I understood from the docs, Irony will look in ~/catkin_ws/build but not in ~/catkin_ws/build/my_package for the json database... Nov 7, 2016 at 20:17
  • 1
    That's right, irony-mode will not look but you can use M-x irony-cdb-json-add-compile-commands-path RET to add non-standard paths like this. Nov 7, 2016 at 20:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.