header

2014年9月2日火曜日

RustのインストールとEmacs用の設定

Rust に興味があって、インストールした。この記事はそのときにした設定とか迷ったところのメモ

普通に試すだけなら、tar形式でダウンロードするか、rustbyexample ってサイト(tour of Go風)で試すのが一番お手軽っぽい。。。


Rustのインストール

自分は最初はtar形式で試したあとコード補完とかしたいかったのでgit cloneした(自分はghqを使っているのでghq getした)

git clone https://github.com/rust-lang/rust.git

Ubuntu12.04を利用しているので、ビルドするのにgccのバージョンが違かったのでppaからgcc/g++の4.7をインストールした(必要なバージョンは変わるので随時rustのページを確認したほうがいい)
参考: http://mortenvp.com/installing-a-newer-gccg-on-ubuntu-12-04-lts/

コンパイラがupdate alternativesでうまくかえれなかったのでCC, CXXでコンパイラを指定した。あと、clangのオプションをgcc/g++がうまくうけとってくれなかったので、COVERED_SWITCH_DEFAULT変数を書きかえた。

COVERED_SWITCH_DEFAULT=`$CXX -Werror -fsyntax-only -xc /dev/null 2>/dev/null`; CC=gcc-4.7; CXX=g++-4.7; ./configure
make && make install

これでrustcとrustdocコマンドが使えるようになる(はず)。


Emacsの設定

エラーチェックにとくに設定なしでflycheckがつかえた。
Rust用のauto-completeに racer というパッケージがあったので利用した。(この記事を書いていて力つきたのでインストールはリンク先をみてください)
ソースコードのタグジャンプにGNU globalを利用した。


GNU globalの設定

Rust用の設定をするのが結構手間だったので、項をわける。
GNU globalはデフォルトでは、Rustに対応してないのでexuberant-ctagsをパーサーにしてctagsにRust用の設定を追加する方法を利用した。

なので最初にexuberant-ctagsをインストールする
注意点として、自分はctags, etagsをコマンドが存在しているときは、exuberant-ctagsコマンドがうまくインストールされていないようだったのでsudo rm /usr/bin/etags sudo rm /usr/bin/ctagsをしたあとにexuberant-ctagsをインストールした。

# インストールするときはexuberant-ctags、コマンドはctags-exuberant
sudo apt-get install exuberant-ctags

Rust用の設定を ~/.ctags に貼りつける(rustのsrc/etc/にctags.rustという名前で入っている)

--langdef=Rust
--langmap=Rust:.rs
--regex-Rust=/^[ \t]*(#\[[^\]]\][ \t]*)*(pub[ \t]+)?(extern[ \t]+)?("[^"]+"[ \t]+)?(unsafe[ \t]+)?fn[ \t]+([a-zA-Z0-9_]+)/\6/f,functions,function definitions/
--regex-Rust=/^[ \t]*(pub[ \t]+)?type[ \t]+([a-zA-Z0-9_]+)/\2/T,types,type definitions/
--regex-Rust=/^[ \t]*(pub[ \t]+)?enum[ \t]+([a-zA-Z0-9_]+)/\2/g,enum,enumeration names/
--regex-Rust=/^[ \t]*(pub[ \t]+)?struct[ \t]+([a-zA-Z0-9_]+)/\2/s,structure names/
--regex-Rust=/^[ \t]*(pub[ \t]+)?mod[ \t]+([a-zA-Z0-9_]+)/\2/m,modules,module names/
--regex-Rust=/^[ \t]*(pub[ \t]+)?static[ \t]+([a-zA-Z0-9_]+)/\2/c,consts,static constants/
--regex-Rust=/^[ \t]*(pub[ \t]+)?trait[ \t]+([a-zA-Z0-9_]+)/\2/t,traits,traits/
--regex-Rust=/^[ \t]*(pub[ \t]+)?impl([ \t\n]*<[^>]*>)?[ \t]+(([a-zA-Z0-9_:]+)[ \t]*(<[^>]*>)?[ \t]+(for)[ \t]+)?([a-zA-Z0-9_]+)/\4 \6 \7/i,impls,trait implementations/
--regex-Rust=/^[ \t]*macro_rules![ \t]+([a-zA-Z0-9_]+)/\1/d,macros,macro definitions/

この時点でctags-exuberantを試すにはrustのsrcディレクトリ以下で以下のようにする。(あとから思いだしながらかいてるので、あってないかも。。。)

# cd path/to/rust-lang/src/
ctags-exuberant -e -f TAGS.emacs --language-force=Rust -R ./

たぶん、TAGS.emacsというのができてるのでなかをみればrustの関数の情報が入っていれば成功

GNU global はapt-getではなくリンク先のdownloadからtarを解凍したものを利用した。
GNU globalのplugin-factory/PLUGIN_HOWTOに書いてあるが、configureオプションにちょっと追加した。ctagsにはemacsのものもあるけど–with-exuberant-ctagsにはctags-exuberantを指定した。

./configure --with-exuberant-ctags=/usr/bin/ctags-exuberant
make
sudo make install

GNU globalのルートディレクトリにgtags.confがあるのでこれをコピペして.globalrcとして$HOMEにはりつけた。
その貼りつけた.globalrcのexuberant-ctagsの設定の中にRust用のlangmap, gtags_parserを追加した。(下のRustに関係ある行だけ追加した)

exuberant-ctags|plugin-example|setting to use Exuberant Ctags plug-in parser:\
...
:langmap=Ruby\:.rb.ruby:\
:langmap=Rust\:.rs:\
:langmap=Scheme\:.SCM.SM.sch.scheme.scm.sm:\
...
:gtags_parser=Ruby\:/usr/local/lib/gtags/exuberant-ctags.la:\
:gtags_parser=Rust\:/usr/local/lib/gtags/exuberant-ctags.la:\
:gtags_parser=Scheme\:/usr/local/lib/gtags/exuberant-ctags.la:\
...

Rustのソースコードがcppとrust自体のコードが混在していて、gtagsコマンドを実行した場合、混ざったものがでてきてしまったので.globalrcにRust用のラベルを作った。ほかにいい方法があればおしえてください。。。

default:\
:tc=native:
native:\
:tc=gtags:tc=htags:
user:\
:tc=user-custom:tc=htags:
ctags:\
:tc=exuberant-ctags:tc=htags:
rust:\
:tc=common:\
:langmap=Rust\:.rs:\
:gtags_parser=Rust\:/usr/local/lib/gtags/exuberant-ctags.la:

bashrcとかzshrcに以下を貼りつける。GTAGSCONFは設定ファイルの場所、GTAGSLABELはデフォルトのパーサーの設定なのでGNU globalのgtags.confを貼り付けていればctagsを設定しておけばctags-exuberantに対応する言語にも対応できるようになる。
GTAGSLIBPATHは:区切りでディレクトリを指定でき、globalで検索するソースを追加できる。Rustにしかglobalを使わないのであればしたの設定でいいかもしれないけど、Emacsからmajor-modeごとに変更したほうがよさそう。環境変数の説明のため(自分のメモとしても)に書いたので、これは別に設定しなくても大丈夫です。

export GTAGSCONF=$HOME/.globalrc
export GTAGSLABEL=ctags
export GTAGSLIBPATH="$HOME/.ghq/github.com/rust-lang/rust/src"

これで通常のRustのソースコードはそのソースのルートディレクトリで

gtags

でそのままタグファイルがつくれるはず。。ただ上でちょこっと書いたとおりRustのソースはcppとrustのコードが混ざってるので、rust用のラベルを指定してタグを作った

cd path/to/rust/src/
gtags --gtagslabel rust

EmacsからGNU globalを使う

自分が調べた感じだと、Emacsでglobalを使うなら以下のがよさげだった。

ggtags.el
helm-gtags.el

Githubのページの機能をみるとggtags.elはglobalで作ったタグから、eldocに表示できる機能があるらしい。試してみたがRustは表示できなかった。(他の言語は試してない)時間がたったら違う言語でまた試してみたい。

helm-gtags.elはglobalの結果をhelmでいい感じに表示してくれる。

まだあんまり試してないけど、下のようにしたらrust-modeの時helm-gtags-dwimで
Rustのソースコードも見れるようなった。

(require 'cl-lib)
(defadvice helm-gtags-dwim
(around update-libpath activate)
(setenv "GTAGSLIBPATH"
(cl-case major-mode
(rust-mode (file-truename
;; rustのソースコードへのパスを指定する
"~/.ghq/github.com/rust-lang/rust/src"))
(t nil)))
ad-do-it)

Rustを試してみた

普通にquickrunで実行できた。(quickrunすごい!)

type Rune = u8;
fn main () {
for c in range('a' as Rune, 'z' as Rune + 1) {
print!("{}", c as char);
}
}
// => abcdefghijklmnopqrstuvwxyz

まだRustそんな理解してないけど、基本的なところは書きやすそう。


おわり

なんか読みかえすと、GNU globalの導入記事っぽくなってる。。。


Popular Posts

Blogger templates

Blogger news