Skip to content

Instantly share code, notes, and snippets.

@soonhokong
Last active March 17, 2022 08:50
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save soonhokong/7c2bf6e8b72dbc71c93b to your computer and use it in GitHub Desktop.
Save soonhokong/7c2bf6e8b72dbc71c93b to your computer and use it in GitHub Desktop.
irony-mode

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" . "http://melpa.org/packages/") t) (when (< emacs-major-version 24) ;; For important compatibility libraries like cl-lib (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/"))) (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/libclang-3.4.so
  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
cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ../../src

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.

@soonhokong
Copy link
Author

;; ==========================================
;; (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)))

@soonhokong
Copy link
Author

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

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

@soonhokong
Copy link
Author

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

(setq irony--compile-options
      '("-std=c++11"
        "-stdlib=libc++"
        "-I/System/Library/Frameworks/Python.framework/Headers"
        "-I/Users/soonhok/work/dreal3/build/debug-clang/include"
        "-I/Users/soonhok/work/dreal3/build/debug-clang/include/ibex"
        "-I/Users/soonhok/work/dreal3/src"
        "-I/Users/soonhok/work/dreal3/src/opensmt"
        "-I/Users/soonhok/work/dreal3/build/debug-clang/"))

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

@soonhokong
Copy link
Author

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/libclang-3.7.so \
&& cmake --build . --use-stderr --config Release --target install

@soonhokong
Copy link
Author

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

@rb-personal
Copy link

Thanks for this awesome guide!

@rileyrg
Copy link

rileyrg commented Feb 28, 2019

Overly complex.

@pyang-1981
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