Skip to content

Instantly share code, notes, and snippets.

Last active March 17, 2022 08:50
  • Star 16 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?

How to Setup emacs irony-mode in Ubuntu-12.04

I recently found a nice emacs-mode, irony-mode, which can be used with company-mode, flycheck-mode, and eldoc-mode. It works nicely with CMake-based projects. The document contains a list of instructions for setting things up. I assume that you're using a fresh-installed Ubuntu-12.04.5 (64-bit). It uses Lean theorem prover as an example project.

irony-mode-company irony-mode-eldoc irony-mode-flycheck

Install Ubuntu Packages

  1. emacs (24.4 or higher)

sudo apt-get install python-software-properties # for add-apt-repository sudo add-apt-repository ppa:ubuntu-elisp/ppa sudo apt-get update sudo apt-get install emacs-snapshot ```

  1. g++-4.8, clang-3.4 and libclang-3.4-dev

sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y sudo apt-get install g++-4.8 clang-3.4 libclang-3.4-dev ```

  1. Required packages for compiling lean (optional)

sudo apt-get install git cmake liblua5.2-dev libmpfr-dev libgmp-dev make ```

Install emacs packages

  1. Setup MELPA

Have the following lines in your emacs setup (.emacs or .emacs.d/init.el): el (require 'package) ;; You might already have this line (add-to-list 'package-archives '("melpa" . "") t) (when (< emacs-major-version 24) ;; For important compatibility libraries like cl-lib (add-to-list 'package-archives '("gnu" . ""))) (package-initialize) ;; You might already have this line

  1. Install irony, irony-eldoc, flycheck-irony, company-irony
  • M-x package-install irony
  • M-x package-install irony-eldoc
  • M-x package-install flycheck-irony
  • M-x package-install company-irony
  1. Install irony-server
  • Open any .cpp file and make sure that irony-mode is on.
  • M-x irony-install-server
  • Important: To force irony-server to use llvm-3.4, you need to add cmake options -DLIBCLANG_INCLUDE_DIR=/usr/lib/llvm-3.4/include and -DLIBCLANG_LIBRARY=/usr/lib/llvm-3.4/lib/
  1. Setup irony-mode

Have the following lines in your emacs setup (.emacs or .emacs.d/init.el): el ;; ============= ;; irony-mode ;; ============= (add-hook 'c++-mode-hook 'irony-mode) (add-hook 'c-mode-hook 'irony-mode) ;; ============= ;; company mode ;; ============= (add-hook 'c++-mode-hook 'company-mode) (add-hook 'c-mode-hook 'company-mode) ;; replace the `completion-at-point' and `complete-symbol' bindings in ;; irony-mode's buffers by irony-mode's function (defun my-irony-mode-hook () (define-key irony-mode-map [remap completion-at-point] 'irony-completion-at-point-async) (define-key irony-mode-map [remap complete-symbol] 'irony-completion-at-point-async)) (add-hook 'irony-mode-hook 'my-irony-mode-hook) (add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options) (eval-after-load 'company '(add-to-list 'company-backends 'company-irony)) ;; (optional) adds CC special commands to `company-begin-commands' in order to ;; trigger completion at interesting places, such as after scope operator ;; std::| (add-hook 'irony-mode-hook 'company-irony-setup-begin-commands) ;; ============= ;; flycheck-mode ;; ============= (add-hook 'c++-mode-hook 'flycheck-mode) (add-hook 'c-mode-hook 'flycheck-mode) (eval-after-load 'flycheck '(add-hook 'flycheck-mode-hook #'flycheck-irony-setup)) ;; ============= ;; eldoc-mode ;; ============= (add-hook 'irony-mode-hook 'irony-eldoc) ;; ========================================== ;; (optional) bind TAB for indent-or-complete ;; ========================================== (defun irony--check-expansion () (save-excursion (if (looking-at "\\_>") t (backward-char 1) (if (looking-at "\\.") t (backward-char 1) (if (looking-at "->") t nil))))) (defun irony--indent-or-complete () "Indent or Complete" (interactive) (cond ((and (not (use-region-p)) (irony--check-expansion)) (message "complete") (company-complete-common)) (t (message "indent") (call-interactively 'c-indent-line-or-region)))) (defun irony-mode-keys () "Modify keymaps used by `irony-mode'." (local-set-key (kbd "TAB") 'irony--indent-or-complete) (local-set-key [tab] 'irony--indent-or-complete)) (add-hook 'c-mode-common-hook 'irony-mode-keys)

Compile Lean to generate compile_commands.json

irony-mode relies on compile_commands.json file to collect compilation information. This can be generated by using cmake option CMAKE_EXPORT_COMPILE_COMMANDS:

cd lean
mkdir -p build/debug-clang
cd build/debug-clang

Set up irony-mode for Lean

Make a symbolic link from lean/build/debug-clang/compile_commands.json to lean/src/compile_commands.json.

cd lean/src
ln -s ../build/debug-clang/compile_commands.json

If you find a better of doing this, please let me know.

Known Issues

  • eldoc-mode might gives you eldoc error: (void-function async-flag) or eldoc error: (void-function remove-if-not). This is due to the use of obsolete functions in ~/.emacs.d/elpa/irony-eldoc-20YYMMDD.HHMM/irony-eldoc.el file. To fix this problem,

    1. replace remove-if-not with cl-remove-if-not, and
    2. replace lexical-let with let.

    I submitted a bug report for this problem.

Copy link

For OSX configuration, you need to install llvm with --with-clang option. If you use homebrew, you can do it by running:

brew install --with-clang llvm

Then M-x irony-install-server and add the following extra cmake options:

  • -DCMAKE_CXX_COMPILER=/usr/local/opt/llvm/bin/clang++
  • -DCMAKE_C_COMPILER=/usr/local/opt/llvm/bin/clang
  • -DLIBCLANG_INCLUDE_DIR=/usr/local/opt/llvm/include
  • -DLIBCLANG_LIBRARY=/usr/local/opt/llvm/lib/libclang.dylib

Copy link

;; ==========================================
;; (optional) bind M-o for ff-find-other-file
;; ==========================================
(defvar my-cpp-other-file-alist
  '(("\\.cpp\\'" (".h" ".hpp" ".ipp"))
    ("\\.ipp\\'" (".hpp" ".cpp"))
    ("\\.hpp\\'" (".ipp" ".cpp"))
    ("\\.cxx\\'" (".hxx" ".ixx"))
    ("\\.ixx\\'" (".cxx" ".hxx"))
    ("\\.hxx\\'" (".ixx" ".cxx"))
    ("\\.c\\'" (".h"))
    ("\\.h\\'" (".cpp" "c"))))
(setq-default ff-other-file-alist 'my-cpp-other-file-alist)
(add-hook 'c-mode-common-hook (lambda ()
    (define-key c-mode-base-map [(meta o)] 'ff-get-other-file)))

Copy link

Have the following piece to support C++11 by default (and always?).

(setq irony-additional-clang-options '("-std=c++11"))

Copy link

I ended up having the following elisp in my configuration file to make irony-mode work on my Mac:

(setq irony--compile-options

As a result, it only works on a particular project. For me, this is fine because it's my main one.

Copy link

On Ubuntu:

cmake -DCMAKE_INSTALL_PREFIX=/usr0/home/soonhok/.emacs.d/irony/ \
/usr0/home/soonhok/.emacs.d/elpa/irony-20151016.1420/server \
-DLIBCLANG_INCLUDE_DIR=/usr/lib/llvm-3.7/include \
-DLIBCLANG_LIBRARY=/usr/lib/llvm-3.7/lib/ \
&& cmake --build . --use-stderr --config Release --target install

Copy link

soonhokong commented Oct 24, 2015

On mac

brew install llvm38
brew link llvm38
cmake -DCMAKE_CXX_COMPILER=ccache-clang++ -DCMAKE_C_COMPILER=ccache-clang -DCMAKE_INSTALL_PREFIX=/Users/soonhok/.emacs.d/irony/ \
~/.emacs.d/elpa/irony-20160506.955/server \
-DLIBCLANG_INCLUDE_DIR=/usr/local/Cellar/llvm38/3.8.0/lib/llvm-3.8/include/ \
-DLIBCLANG_LIBRARY=/usr/local/Cellar/llvm38/3.8.0/lib/llvm-3.8/lib/libclang.dylib \
&& cmake --build . --use-stderr --config Release --target install

Copy link

Thanks for this awesome guide!

Copy link

rileyrg commented Feb 28, 2019

Overly complex.

Copy link

brew install --with-clang llvm complains Error: invalid option: --with-clang

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment