#author("2020-07-22T06:26:39+00:00","","")
#author("2020-07-23T23:59:04+00:00","","")
#topicpath

///////////////////////////////////////////////////////////////////////////////
* 目次 [#sec94d40]
#contents();


///////////////////////////////////////////////////////////////////////////////
* lctags [#lctags]
//==============================================================================
** 環境構築 [#mff5961f]
+ コードの取得
 $ git clone https://github.com/ifritJP/lctags.git
+ 追加パッケージのインストール
-- swig (ビルドに必要)
-- liblua50-dev
-- lua5.3
-- luajit
-- liblua5.3-dev
-- libssl-dev
+ 他モジュールのコードを取得・展開
 $ cd lctags/external
 $ curl http://lua.sqlite.org/index.cgi/zip/lsqlite3_fsl09x.zip?uuid=fsl_9x -o luasqlite3.zip
 $ unzip luasqlite3.zip
 $ cp -Rfdp lsqlite3_fsl09x/ luasqlite3/
 $ curl https://www.lua.org/ftp/lua-5.3.4.tar.gz -o lua/lua-5.3.4/src/lua.tar.gz
 $ tar -xvzf lua.tar.gz
 $ mv lua-5.3.4 lua/
+ ビルド
++ src/makefile の修正
 diff --git a/src/makefile b/src/makefile
 index d3dde80..9a92a49 100644
 --- a/src/makefile
 +++ b/src/makefile
 @@ -1,128 +1,152 @@
  NDIR=$(shell pwd)
  
 -INST_DIR=/usr/local/bin
 +INST_DIR := /usr/local/bin
  
 -PROXY=
 +PROXY :=
  
 -SWIG=swig
 +SWIG := swig
  
  INSTALL=/usr/bin/install -c
  
 -SO=so
 -## cygwin
 -#SO=dll
 +LUA_VER := 5.3
 +# LUA_VER := 5.2
 +# LUA_VER := 5.1
  
 -####### customize Lua environment ######
 +LUAJIT_VER := 2.0.4
 +# LUAJIT_VER := $(shell luajit -v | awk '{print $2;}')
 +
 +CLANG_VER := 7
 +# CLANG_VER=3.8
 +
 +UNAME := $(shell uname -a)
 +ifeq ($(filter Darwin,$(UNAME)),Darwin)
 +OS := mac
 +else
 +ifeq ($(filter Linux,$(UNAME)),Linux)
 +OS := linux
 +else
 +ifeq ($(filter MINGW,$(UNAME)),Cygwin)
 +OS := cygwin
 +else
 +$(info Your platform $(UNAME) is not supported.)
 +endif
 +endif
 +endif
  
 +ifeq ($(OS),cygwin)
  ## cygwin
 -# LUA_COMMAND=lua
 -# LUA_INC=/usr/include
 -# LUA_LDFLAGS=
 -# LUA_SO=-llua
 +SO := dll
 +else
 +SO := so
 +endif
  
 -# LUA_COMMAND=lua5.1
 -# LUA_INC=/usr/include/lua5.1
 -# LUA_LDFLAGS=
 -# LUA_SO=-llua5.1
 +####### customize Lua environment ######
 +ifeq ($(OS),cygwin)
 +## cygwin
 +LUA_COMMAND := lua
 +LUA_INC     := /usr/include
 +LUA_LDFLAGS :=
 +LUA_SO      := -llua
  
 -LUA_COMMAND=lua5.3
 -LUA_INC=/usr/include/lua5.3
 -LUA_LDFLAGS=
 -LUA_SO=-llua5.3
 +else
 +LUA_COMMAND := lua$(LUA_VER)
 +LUA_INC     := /usr/include/lua$(LUA_VER)
 +LUA_LDFLAGS :=
 +LUA_SO      := -llua$(LUA_VER)
 +endif
  
 -# LUA_COMMAND=luajit
 -# LUA_INC=/usr/include/luajit-2.0
 -# LUA_LDFLAGS=
 -# LUA_SO=-lluajit-5.1
 +# LUA_COMMAND  := luajit
 +# LUA_INC      := /usr/include/luajit-2.0
 +# LUA_LDFLAGS  := 
 +# LUA_SO       := -lluajit-5.1
  
 -# LUA_COMMAND=./clanglua
 -# LUA_CFLAGS=-fPIC -DLUA_COMPAT_5_1 -DLUA_COMPAT_5_2 -I$(NDIR)/$(LUA_DIR)
 -# LUA_DIR=../external/lua/lua-5.3.4/src
 -# LUA_INC=$(NDIR)/$(LUA_DIR)
 -# LUA_LIB=$(LUA_DIR)/liblua.a
 -# LUA_INST_DIR=/usr/local/bin
 -# LUA_LIB_DIR=/usr/local/lib/lua/5.3
 -# LUA_LDFLAGS=-lncursesw
 +# LUA_COMMAND  := ./clanglua
 +# LUA_CFLAGS   := -fPIC -DLUA_COMPAT_5_1 -DLUA_COMPAT_5_2 -I$(NDIR)/$(LUA_DIR)
 +# LUA_DIR      := ../external/lua/lua-5.3.4/src
 +# LUA_INC      := $(NDIR)/$(LUA_DIR)
 +# LUA_LIB      := $(LUA_DIR)/liblua.a
 +# LUA_INST_DIR := /usr/local/bin
 +# LUA_LIB_DIR  := /usr/local/lib/lua/5.3
 +# LUA_LDFLAGS  := -lncursesw
  
 -TEST_LUA_DIR=../external/lua/lua-5.3.4/src
 +TEST_LUA_DIR := ../external/lua/lua-5.3.4/src
  
 -LUA_URL="https://www.lua.org/ftp/lua-5.3.4.tar.gz"
 +LUA_URL := "https://www.lua.org/ftp/lua-5.3.4.tar.gz"
  
 -LUA_COMMAND_FULL:=$(shell python -c 'import os; print( os.path.abspath( "$(shell which $(LUA_COMMAND))" ) );' )
 +LUA_COMMAND_FULL := $(shell python -c 'import os; print( os.path.abspath( "$(shell which $(LUA_COMMAND))" ) );' )
  
  ####### customize libclang environment ######
  
 +ifeq ($(OS),cygwin)
  ## cygwin
 -# LIBCLANG_INC=/usr/include
 -# LIBCLANG_LIB=/lib
 -# LIBCLANG_STD_INC=/lib/clang/5.0.1/include
 -
 -
 -CLANG_VER=3.8
 -LIBCLANG_INC=/usr/lib/llvm-$(CLANG_VER)/include
 -LIBCLANG_LIB=/usr/lib/llvm-$(CLANG_VER)/lib
 -LIBCLANG_STD_INC=$(shell find /usr/lib/llvm-$(CLANG_VER)/lib/clang/ -maxdepth 1 -mindepth 1 | head -n 1)
 +LIBCLANG_INC     := /usr/include
 +LIBCLANG_LIB     := /lib
 +LIBCLANG_STD_INC := /lib/clang/5.0.1/include
  
 -# LIBCLANG_DIR=/proj/next/clang/r34-final
 -# LIBCLANG_INC=../external/clang/r390/llvm/tools/clang/include
 -# LIBCLANG_STD_INC=../external/clang/r390/build/lib/clang/3.9.0/include
 -# LIBCLANG_LIB=/usr/lib/llvm-$(CLANG_VER)/lib
 +else
 +LIBCLANG_INC     := /usr/lib/llvm-$(CLANG_VER)/include
 +LIBCLANG_LIB     := /usr/lib/llvm-$(CLANG_VER)/lib
 +LIBCLANG_STD_INC := $(shell find /usr/lib/llvm-$(CLANG_VER)/lib/clang/ -maxdepth 1 -mindepth 1 | head -n 1)
  
 -# LIBCLANG_SO=-lclang
 +# LIBCLANG_DIR     := /proj/next/clang/r34-final
 +# LIBCLANG_INC     := ../external/clang/r390/llvm/tools/clang/include
 +# LIBCLANG_STD_INC := ../external/clang/r390/build/lib/clang/3.9.0/include
 +# LIBCLANG_LIB     := /usr/lib/llvm-$(CLANG_VER)/lib
 +endif
  
 -LIBCLANG_SO=-lclang
 +LIBCLANG_SO := -lclang
  
  ####### customize luasqlite3 environment ######
  # If you don't have luasqlite3, you must customize this setting.
  # http://lua.sqlite.org/index.cgi/index
  
 -LUASQLITE3_WORKDIR=../external/luasqlite3
 -LUASQLITE3_DIR=$(LUASQLITE3_WORKDIR)/lsqlite3_fsl09x
 -#USE_BDB_SQLITE=y
 +LUASQLITE3_WORKDIR := ../external/luasqlite3
 +LUASQLITE3_DIR     := $(LUASQLITE3_WORKDIR)/lsqlite3_fsl09x
 +#USE_BDB_SQLITE    := y
  
 -LUASQLITE3_URL="http://lua.sqlite.org/index.cgi/zip/lsqlite3_fsl09x.zip?uuid=fsl_9x"
 +LUASQLITE3_URL := "http://lua.sqlite.org/index.cgi/zip/lsqlite3_fsl09x.zip?uuid=fsl_9x"
  
  
  
  ####### make rules ######
  
 -LUA_LIB_DIR=$(shell echo $(LUA_DIR_LIB) | $(LUA_COMMAND) )
 -LUA_MOD_DIR=$(shell echo $(LUA_DIR_SCRIPT) | $(LUA_COMMAND) )
 +LUA_LIB_DIR := $(shell echo $(LUA_DIR_LIB) | $(LUA_COMMAND) )
 +LUA_MOD_DIR := $(shell echo $(LUA_DIR_SCRIPT) | $(LUA_COMMAND) )
  
 -LCTAGS_LOG=4
 -JOBS=3
 +LCTAGS_LOG := 4
 +JOBS       := 3
  
  ifdef LCTAGS_PROF
 -LCTAGS_PROF_OP = --lctags-prof
 +LCTAGS_PROF_OP  :=  --lctags-prof
  endif
  
 -LCTAGS_LOCKLOG=y
 +LCTAGS_LOCKLOG := y
  ifdef LCTAGS_LOCKLOG
 -LOCKLOG = --lctags-lockLog
 +LOCKLOG  :=  --lctags-lockLog
  endif
  
  ifdef LCTAGS_SERVER_ON
 -LCTAGS_SERVER=--lctags-srv
 +LCTAGS_SERVER := --lctags-srv
  endif
  
 -LUA_LIB:=$(addprefix $(NDIR)/,$(LUA_LIB))
 +LUA_LIB    := $(addprefix $(NDIR)/,$(LUA_LIB))
  
 -LCTAGS_LUA=lctags/lctags.lua
 +LCTAGS_LUA := lctags/lctags.lua
  
 -#OPT_OP = -O3
 +#OPT_OP  :=  -O3
  
 -IF_LUA = libclanglua/if.lua
 -IFC_LUA = libclanglua/ifc.lua
 -COREBASE_SO = libclanglua/coreBase.$(SO)
 -CORE_SO = libclanglua/core.$(SO)
 +IF_LUA       :=  libclanglua/if.lua
 +IFC_LUA      :=  libclanglua/ifc.lua
 +COREBASE_SO  :=  libclanglua/coreBase.$(SO)
 +CORE_SO      :=  libclanglua/core.$(SO)
  
 -LUA_DIR_SCRIPT='for path in string.gmatch( package.path, "[^;]+" ) do if path:find( ".*lua.*%?%.lua" ) then print( (path:gsub( "/%?%.lua", "" )) ); break end end'
 -LUA_DIR_LIB="for path in string.gmatch( package.cpath, '[^;]+' ) do if path:find( \".*lua.*%?%.$(SO)\" ) then print( (path:gsub( \"/%?%.$(SO)\", '' ))); break end end"
 +LUA_DIR_SCRIPT := 'for path in string.gmatch( package.path, "[^;]+" ) do if path:find( ".*lua.*%?%.lua" ) then print( (path:gsub( "/%?%.lua", "" )) ); break end end'
 +LUA_DIR_LIB    := "for path in string.gmatch( package.cpath, '[^;]+' ) do if path:find( \".*lua.*%?%.$(SO)\" ) then print( (path:gsub( \"/%?%.$(SO)\", '' ))); break end end"
  
  
  
  ifneq ($(LUA_DIR),)
 -TARGET_LUA = $(LUA_COMMAND)
 +TARGET_LUA  :=  $(LUA_COMMAND)
  endif
  
  all:
 @@ -254,11 +278,11 @@ test-simple:
  
  
  ifdef BATCH
 -BATCH_OP=--lctags-only-reg
 +BATCH_OP := --lctags-only-reg
  endif
  
  ifeq ($(INDIV),y)
 -INDIV_OP=--lctags-indiv
 +INDIV_OP := --lctags-indiv
  endif
* TagSystem [#faa5a708]
- ソースコードを静的解析するツール。指定したシンボルの定義を参照したりするのに使われる。


++ ビルド(lctags のトップディレクトリに戻ってから)
 $ make build
成功すると、以下のファイルが出来る
 src/lsqlite3.so
 src/lctags/Helper
 src/lctags/Helper.so
 src/lctags/core.so
 src/lctags/coreBase.so

//==============================================================================
** 実行ファイルに PATH を通す [#g88cf93a]
- make で生成された実行ファイルと共有ライブラリを、1箇所に集めて環境変数 PATH と LD_LIBRARY_PATH に追加する。
-- 或いは、パッケージ管理システムで構築されている環境では、これらをパッケージ化してインストールする。

//==============================================================================
** emacs から使う [#a3d47aba]
+ lctags を emacs から使う為の lisp は、lctags のリポジトリ内に同梱されているので、これを load 出来るようにする。
++ リポジトリ内の src/lisp を、emacs が load 出来る場所にコピーするか、 load-path に追加する。
 (add-to-list 'load-path "hoge/lctags/src/lisp") t)
++ src/lisp/lctags.el を load する。
 (require 'lctags)
+ これらを使えるようにするために、 [[helm>Editor/emacsen#helm]] と [[gtags.el>Prog/TagSystem#gtags-global]] も使えるようにする必要がある。

//==============================================================================
** 参考リンク [#vb650226]
- [[ifritJP/lctags - GitHub>https://github.com/ifritJP/lctags]]
- [[lctags で C 言語の関数コールを簡単に - 公開技術情報>https://ifritjp.github.io/documents/lctags/callfunc/]]



///////////////////////////////////////////////////////////////////////////////
* Rtags [#Rtags]
//==============================================================================
** 環境構築 [#r8bf01af]
+ rtags をビルドする
 # apt-get install clang libclang-dev cmake
 $ git clone --recursive https://github.com/Andersbakken/rtags
 $ cd rtags
 $ git submodule init
 $ git submodule update
 $ mkdir build
 $ cd build
 $ cmake ..
 $ make
 $ sudo make install
~
+ rtags をインストールする
-- ビルドすると rtags/build/bin に以下の実行形式が生成されるので、環境変数 PATH の通っているところに配置する。
 $ ls rtags/build/bin
 rc  rdm  rp
* 各種 TagStstem [#y9fbb108]
#ls2(Prog/TagSystem/);

//==============================================================================
** タグを生成する [#ec89eba8]
+ まず、daemon を起動する
 $ rdm --daemon
+ タグを生成する方法は2つある

//------------------------------------------------------------------------------
*** 1. rc コマンドに直接渡す [#ec230bdd]
- 実際に compile するときのコマンドを rc に渡す。
 $ rc gcc $(CFLAGS) $(SRCS)

//------------------------------------------------------------------------------
*** 2. rc -Jコマンドで compile_commands.json を読み込ませる [#rfeb66d5]
- compile_commands.json は、cmake か bear で生成する。
-- bear を使う場合(cmake を使わない、Makefile のみのプロジェクトの場合)
--- bear コマンドがインストールされていない場合は、インストールする
 # apt-get install bear
--- bear コマンドの実行
 $ make bear
-- cmake で生成する場合
~
T.B.D.
- rc -Jコマンドで compile_commands.json を読み込ませる
 $ rc -J .



//==============================================================================
** emacs から rtags を使う [#w2d2547d]
- rtags.el を、 emacs の load-path の通っているところに置く。rtags.el は、rtag リポジトリの下記にある
 build/src/rtags.el
- init.el
 ;;; rtags.el の設定
 (require 'rtags)
 
 (when (require 'rtags nil 'noerror)
   (add-hook 'c-mode-common-hook
             (lambda ()
               (when (rtags-is-indexed)
                 (local-set-key (kbd "M-.") 'rtags-find-symbol-at-point)
                 (local-set-key (kbd "M-;") 'rtags-find-symbol)
                 (local-set-key (kbd "M-@") 'rtags-find-references)
 		(local-set-key (kbd "M-,") 'rtags-location-stack-back)))))
 
 (provide 'rtags.conf)




//==============================================================================
** 参考リンク [#l754c53c]
- [[最強のC/C++インデクサー "Rtags" を本気で使う>https://qiita.com/kota65535/items/39aa4d6e8adf6ab5f98c]]
- [[Rtags で BitVisor の開発を楽になるか?>https://qiita.com/deep_tkkn/items/eb24cb2f0713c7fc4162]]


///////////////////////////////////////////////////////////////////////////////
* cscope [#cscope]
- debian では、 cscope は cscope パッケージに入っている
- ソースコードは Linux ディストリビューションなどが配布しているもの、若しくは開発元の git repository から取得出来る
-- git repository
 https://github.com/welash/cscope.git
-- debian
 $ apt-get source cscope

//==============================================================================
** tag の生成 [#cscope-indexer]
- コンソールから
 $ cscope-indexer -r
- cscope-indexer のオプション
|~option |~description |
|-f <database-file> |出力先データベースのファイル名を指定する(default: cscope.out)|
|-i <list-file> |リストファイル(ファイルのインデックスを記録したファイル)の名前を指定する(default: cscope.files)|
|-l |データベースファイルの生成・更新を抑制する。&br;但し、リストファイルが生成済みであること |
|-r |再帰的にディレクトリを走査する。&br;このオプションがない場合、走査対象はカレントディレクトリに限定される。|
|-v |冗長モード |


//==============================================================================
** cscope で SymLink になっているファイルが扱えない問題について [#cscope-problem-symlink]
- ソースコード・ヘッダが SymLink になっている場合、cscope では正しく DB 化出来ない。これは、cscope が DB 作成処理の際、 SymLink を対象外とするように動作する実装になっているためである。
- SymLink も DB 化の対象にしたい場合は、ソースパッケージを取ってきて、以下のように修正する。
++ cscope-indexer で SymLink をリスト対象とするように変更する
 diff --git a/cscope-15.8a/contrib/xcscope/cscope-indexer b/cscope-15.8a/contrib/xcscope/cscope-indexer
 index 13c0ae2..31e3956 100644
 --- a/cscope-15.8a/contrib/xcscope/cscope-indexer
 +++ b/cscope-15.8a/contrib/xcscope/cscope-indexer
 @@ -134,7 +134,7 @@ fi
  	    echo "$DIR/$f"
  	done
      else
 -	find $DIR \( -type f -o -type l \)
 +	find -L $DIR \( -xtype f -o -xtype l \)
      fi
  ) | \
      egrep -i '\.([chly](xx|pp)*|cc|hh)$' | \
~
また、cscope-indexer は内部で環境変数 PATH を独自に設定している(起動したshell の環境変数変数PATHは引き継がれない)ため、下記で修正する cscope の配置先が cscope-indexer から見える場所にあるかどうかを確認しておくこと。
++ cscope の中で使われている lstat() を stat() に置き換える
--- ソース上の lstat() を全て置き換えてもいいが、configure を走らせる前に config.h.in を1行修正する方がスマート。 HAVE_LSTAT が定義されないようにすれば良い(下記)。
 diff --git a/cscope-15.8a/config.h.in b/cscope-15.8a/config.h.in
 index 2219be7..b0fff54 100644
 --- a/cscope-15.8a/config.h.in
 +++ b/cscope-15.8a/config.h.in
 @@ -53,7 +53,7 @@
  #undef HAVE_LONG_LONG_INT
  
  /* Define to 1 if you have the `lstat' function. */
 -#undef HAVE_LSTAT
 +// #undef HAVE_LSTAT
  
  /* Define to 1 if you have the `memcpy' function. */
  #undef HAVE_MEMCPY
~
但し、global.h も手直しが必要。
 diff --git a/cscope-15.8a/src/global.h b/cscope-15.8a/src/global.h
 index cda29aa..1919277 100644
 --- a/cscope-15.8a/src/global.h
 +++ b/cscope-15.8a/src/global.h
 @@ -189,6 +189,7 @@ int rpl_asprintf(char **, const char *, ...);
  
  /* This can happen on only vaguely Unix-ish platforms... */
  #ifndef HAVE_LSTAT
 +#include <sys/stat.h>
  # define	lstat(file,buf)	stat(file,buf)
  #endif

--- 修正後、ビルドする
 $ configure
 $ make
---  実行ファイルをパスの通った所へ配置する。
--- パッケージをインストールしている場合は、念の為削除しておいた方が良いだろう。


//==============================================================================
** xcscope.el [#xcscope]
- cscope を emacs で使用するのに xcscope.el を使う。そのために cscope-el パッケージを導入する
- emacs起動時に問題がなくても xcscope.el が正しく動作しない時は、''cscope-minor-mode'' に正しく入れていない可能性がある。その場合には
 (setq c++-mode-hook
       '(lambda ()
 		 (setq cscope-minor-mode t)
 		 ))
のように ${HOME}/.emacs などの適切な初期設定ファイルに記述しておく。 
- xcscope.el では、タグファイルを生成してあっても、リストを表示させるたびに grep が走る。そのため表示は速くない。速度が問題になる場合は、xcscope.el ではなく [[ascope>#ascope]] の使用を検討する余地がある。


- emacs 上の xcscope.el から tag ファイルを生成する
 C-c s L


//------------------------------------------------------------------------------
*** シンボルを探す [#xcscope-emacs]
|~key |~description |~remark |
|C-c s s |シンボルを指定して探す(定義・呼び出し箇所等の一覧をリストアップする)| |
|C-c s C |指定したシンボルの呼び出し箇所をリストアップ | |
|C-c s G |指定したシンボルの定義(宣言ではなく)、またはそれに関する定義をリストアップする | |
|C-c s n |次のシンボルへ Jump | |
|C-c s p |前のシンボルへ Jump | |




//------------------------------------------------------------------------------
*** xcscope のキーバインド一覧(xcscope.el ver.1.0) [#xcscope-emacs-binding]
 ;; * Keybindings:
 ;;
 ;; All keybindings use the "C-c s" prefix, but are usable only while
 ;; editing a source file, or in the cscope results buffer:
 ;;
 ;;      C-c s s         Find symbol.
 ;;      C-c s =         Find assignments to this symbol
 ;;      C-c s d         Find global definition.
 ;;      C-c s g         Find global definition (alternate binding).
 ;;      C-c s G         Find global definition without prompting.
 ;;      C-c s c         Find functions calling a function.
 ;;      C-c s C         Find called functions (list functions called
 ;;                      from a function).
 ;;      C-c s t         Find text string.
 ;;      C-c s e         Find egrep pattern.
 ;;      C-c s f         Find a file.
 ;;      C-c s i         Find files #including a file.
 ;;
 ;; These pertain to navigation through the search results:
 ;;
 ;;      C-c s b         Display *cscope* buffer.
 ;;      C-c s B         Auto display *cscope* buffer toggle.
 ;;      C-c s n         Next symbol.
 ;;      C-c s N         Next file.
 ;;      C-c s p         Previous symbol.
 ;;      C-c s P         Previous file.
 ;;      C-c s u         Pop mark.
 ;;
 ;; These pertain to setting and unsetting the variable,
 ;; `cscope-initial-directory', (location searched for the cscope database
 ;;  directory):
 ;;
 ;;      C-c s a         Set initial directory.
 ;;      C-c s A         Unset initial directory.
 ;;
 ;; These pertain to cscope database maintenance:
 ;;
 ;;      C-c s L         Create list of files to index.
 ;;      C-c s I         Create list and index.
 ;;      C-c s E         Edit list of files to index.
 ;;      C-c s W         Locate this buffer's cscope directory
 ;;                      ("W" --> "where").
 ;;      C-c s S         Locate this buffer's cscope directory.
 ;;                      (alternate binding: "S" --> "show").
 ;;      C-c s T         Locate this buffer's cscope directory.
 ;;                      (alternate binding: "T" --> "tell").
 ;;      C-c s D         Dired this buffer's directory.
 ;;

//------------------------------------------------------------------------------
*** xcscope のキーバインドが正しく動作しない場合 [#xcscope-problem-minor-mode]
- xcscope.el を組み込んだ後、
 C-c s
と打っても
 C-c s is undefined
とメッセージが出て動作しない場合は、xcscope.el が提供するマイナーモードに入れていない可能性がある。~
その場合は、c-mode-hook, c++-mode-hook に引っ掛けて ''cscope-minor-mode'' を呼び出すようにすると良い。
 ; c-mode での設定
 (setq c-mode-hook
       '(lambda ()
          (cscope-minor-mode)
          ))
 
 ; c++-mode でも同様に...
 (setq c++-mode-hook
       '(lambda ()
          (cscope-minor-mode)
          ))
//------------------------------------------------------------------------------
*** 参考リンク [#xcscope-link]
- [[cscope Home Page>http://cscope.sourceforge.net/]]
- [[Emacsからcscopeソースコードナビゲータを使ってみよう>http://prog.quarklink.org/linux/xcscope/]]
- [[[Emacs] id-utils と cscope 導入してみた>http://d.hatena.ne.jp/khiker/20071018/cscope]]


//==============================================================================
** acscope.el [#ascope]
- ascope.el は cscope の emacs 用 I/F の一つ。
- [[xcscope.el>#cscope]] と比べて
-- 機能は少ない
-- xcscope.el と違って毎回検索を行わない分、
--- 結果表示までの時間は早い
--- 対象のソースコードに変更があった場合、検索結果に正しく反映されない場合がある
- debian では、 cscope は cscope パッケージに入っている
- この他、 emacs で使用するのに acscope.el を使う。debian8 にはパッケージはない。

//------------------------------------------------------------------------------
*** 導入 [#qd41bf62]
- debian8 のようにディストリビューションからパッケージが提供されていない場合は、[[GitHub>https://github.com/ameyp/ascope/blob/master/ascope.el]] または [[EmacsWiki>https://www.emacswiki.org/emacs/ascope.el]] などから Download して組み込む。~
但し [[EmacsWiki>https://www.emacswiki.org/emacs/ascope.el]] に掲載されているものは、 GitHub の最新版より大分古いようなので注意が必要。
-- GitHub から取得する場合
 $ git clone https://github.com/ameyp/ascope
- キーバインドを設定する
-- ascope.el ではキーバインドが設定されてない一方、関数名が xcscope.el と同じなので、xcscope.el から流用して設定する。~
#ただ、xcscope.el にあって ascope.el にないものが多い。
 (setq load-path (cons (expand-file-name "~/.emacs.d/site-lisp/ascope")  load-path))
 (load-library "~/.emacs.d/site-lisp/ascope/ascope.el")
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Original is from xcscope.el
 (defvar cscope-minor-mode-keymap
   (let ((map (make-sparse-keymap)))
 
     ;; xemacs has various issues with (cscope-mouse-popup-menu-or-search), so I
     ;; don't use that function for xemacs. Its popup menu support won't be as
     ;; good (cscope will still prompt for the search term)
     ;(if cscope-running-in-xemacs
     ;    (progn
     ;      (define-key map [(shift button3)] 'cscope-mouse-search-again))
     ;  (define-key map [mouse-3]   'cscope-mouse-popup-menu-or-search)
     ;  (define-key map [S-mouse-3] 'cscope-mouse-search-again))
 
     ;; The following line corresponds to be beginning of the "Cscope" menu.
     (define-key map "\C-css" 'cscope-find-this-symbol)
     (define-key map "\C-csd" 'cscope-find-global-definition)
     (define-key map "\C-csg" 'cscope-find-global-definition)
     ; (define-key map "\C-csG" 'cscope-find-global-definition-no-prompting)
     ; (define-key map "\C-cs=" 'cscope-find-assignments-to-this-symbol)
     (define-key map "\C-csc" 'cscope-find-functions-calling-this-function)
     (define-key map "\C-csC" 'cscope-find-called-functions)
     (define-key map "\C-cst" 'cscope-find-this-text-string)
     ; (define-key map "\C-cse" 'cscope-find-egrep-pattern)
     (define-key map "\C-csf" 'cscope-find-this-file)
     (define-key map "\C-csi" 'cscope-find-files-including-file)
     ;; --- (The '---' indicates that this line corresponds to a menu separator.)
     ; (define-key map "\C-csb" 'cscope-display-buffer)
     ; (define-key map "\C-csB" 'cscope-display-buffer-toggle)
     ; (define-key map "\C-csn" 'cscope-history-forward-line-current-result)
     ; (define-key map "\C-csN" 'cscope-history-forward-file-current-result)
     ; (define-key map "\C-csp" 'cscope-history-backward-line-current-result)
     ; (define-key map "\C-csP" 'cscope-history-backward-file-current-result)
     ; (define-key map "\C-csu" 'cscope-pop-mark)
     ;; ---
     ; (define-key map "\C-csa" 'cscope-set-initial-directory)
     ; (define-key map "\C-csA" 'cscope-unset-initial-directory)
     ;; ---
     ; (define-key map "\C-csL" 'cscope-create-list-of-files-to-index)
     ; (define-key map "\C-csI" 'cscope-index-files)
     ; (define-key map "\C-csE" 'cscope-edit-list-of-files-to-index)
     ; (define-key map "\C-csW" 'cscope-tell-user-about-directory)
     ; (define-key map "\C-csS" 'cscope-tell-user-about-directory)
     ; (define-key map "\C-csT" 'cscope-tell-user-about-directory)
     ; (define-key map "\C-csD" 'cscope-dired-directory)
     ;; The previous line corresponds to be end of the "Cscope" menu.
 
 
 
     ;; (START Add) --------------------------------------
     ;; ここは xcscope.el にないものを追加
     (define-key map "\C-csa" 'cscope-setup)
     ;; (END   Add) --------------------------------------
 
     map)
   "The global cscope keymap")
 
 (require 'ascope)

//------------------------------------------------------------------------------
*** tagの生成 [#ascope-create-tag]
- emacs 上のインターフェースが異なるのみで、cscope を使うという意味では [[xcscope.el>#xcscope]]と変わりない。&br;
tag の生成については [[tag の生成(xcscope.el)>#cscope-indexer]] を参照のこと。

//------------------------------------------------------------------------------
*** 参考リンク [#ascope-link]
- [[Erlcscope and ascope.el>http://masayuki038.github.io/blog/2013/09/23/erlcscope-and-ascope-el/]]
- [[ascope.el@github>https://github.com/ameyp/ascope/blob/master/ascope.el]]
- [[EmacsWiki>https://www.emacswiki.org/emacs/ascope.el]]


//==============================================================================
** 参考リンク [#cscope-link]
- [[CscopeとSilentBobによるソースコードの解析>https://mag.osdn.jp/07/03/13/0115244]]
- [[Using Cscope on large projects (example: the Linux kernel)>http://cscope.sourceforge.net/large_projects.html]]




////////////////////////////////////////////////////////////////////////////////
* id-utils [#id-utils]
//==============================================================================
** 導入 [#ne99dcda]
- debian の場合は、以下のパッケージをインストールする
 id-utils elscreen
- emacs 

//==============================================================================
** emacs の設定 [#id-utils-emacs-config]
- ${HOME}/.emacs.d/init.el に以下を追記
 ; id-utils
 (require 'elscreen)
 (require 'elscreen-gf)

//==============================================================================
** DB の生成 [#id-utils-create-db]
- mkid コマンドで DB を生成する
-- コマンドラインから
 $ mkid
-- emacs から
 M-x: elscreen-gf-idutils-mkid

//==============================================================================
** symbol の検索 [#id-utils-search-symbol]
- 検索
 M-x: elscreen-gf-idutils-gid
で、検索したいパターンを入力する
- 検索結果から Jump
-- カーソルで見たいところを選択し、
 o
または
 O (read-only で Jump 先が開かれる)


////////////////////////////////////////////////////////////////////////////////
* gtags / global の利用 [#gtags-global]
- タグシステムの一つ
- debian では、 global パッケージに入っている

//==============================================================================
** tag の生成 [#gtags-global-create-tag]
 $ gtags [options] [path]
 $ gtags -f <files>
 $ gtags -v
- gtags には、etags と違って append mode が存在しないため、xargs でマルチスレッド化して実行するのは不可かもしれない。
- -f <file> を指定しない場合、gtags はカレント以下のディレクトリを走査してタグ情報を生成する。
- tag の生成処理が終わると、実行したディレクトリ配下に、下記4つのファイルが作られる:
 GPATH GTAGS GRTAGS GSYMS

//==============================================================================
** emacs の設定 [#gtags-global-emacs-config]
-- gtags.el を入手する
--- ディストリビューションによっては、下記のようなパスにインストールされる場合もある
 /usr/share/emacs/site-lisp/global/gtags.el
--- もしディストリビューションで用意されていない場合は、手動で取得し、library-path の通っている場所に配置する。
--- 大文字・小文字を区別するように設定する~
→ [[検索時に大文字・小文字を区別するかしないかの設定>Editor/emacsen#case-fold-search]]
-- キーバインドを設定する
 (autoload 'gtags-mode "gtags" "" t)
 (setq gtags-mode-hook
       '(lambda ()
          (local-set-key "\C-v" 'gtags-visit-rootdir)
          (local-set-key "\M-t" 'gtags-find-tag)    ;関数の定義元へ
          (local-set-key "\M-r" 'gtags-find-rtag)   ;関数の参照先へ
          (local-set-key "\M-s" 'gtags-find-symbol) ;変数の定義元/参照先へ
          (local-set-key "\C-t" 'gtags-pop-stack)
          ))




//==============================================================================
** vi での設定 [#n614fe8a]
+ vimのプラグインを ~/.vim/plugin にコピー
 $ mkdir ${HOME}/.vim/plugin
 $ cp /usr/share/doc/global/examples/gtags.vim.gz ${HOME}/.vim/plugin
 $ cd ${HOME}/.vim/plugin
 $ gunzip gtags.vim.gz
+ ~/.vimrc にgtagsの設定を追加
 map <C-h> :Gtags -f %<CR>
 map <C-j> :GtagsCursor<CR>
 map <C-n> :cn<CR>
 map <C-p> :cp<CR>

*** 操作 [#w26fce71]
|~binding |~ description |
|C-h      |そのソースの関数を表示 |
|C-n      |リストのカーソルを下に移動 |
|C-p      |リストのカーソルを上に移動 |
|C-j      |現在の関数の中にジャンプ |
|C-o      |ジャンプする前の位置に戻る |




//==============================================================================
** 参考リンク [#gtags-global-link]
- [[GNU GLOBAL(gtags)>http://cha.la.coocan.jp/doc/gnu_global.html]]
- [[新機能の御紹介>http://www.tamacom.com/handbook/new.html]]
- [[[Linux][開発] GNU GLOBALとvimで快適な開発環境を手に入れる>https://qiita.com/suzutsuki0220/items/1e755fd98e5b12af3e2d]]

////////////////////////////////////////////////////////////////////////////////
* etags (ctags for Emacs)の利用 [#etags]

//==============================================================================
** tag の生成 [#etags-create-tag]
- まずは、 Tag file を生成する。emacs パッケージには etags.emacs** なコマンドが付属している場合があるので、それがあればそちらを使う。
- Tag file は TAGS というファイル名で生成される。
 $ etags.emacs23 `find | grep -i "\.c$\|\.cc\|\.cpp$\|\.cxx$\|\.h$"
- ただ、ファイル数が多い場合にはコマンドラインバッファの上限を超えてしまい、全てのファイルを処理できないことが予想される。この問題は xargs を使って解消することが出来る。~
以下に、そのためのスクリプトを示す。~
下記の例では、 xargs の -P オプションも併用し、マルチスレッドで動作するようにしている。 THREAD_NUM は CPUの数もしくは Core 数に合わせる。
 #!/bin/bash
 TAGS_FILE=TAGS
 CMD_ETAGS=etags.emacs23
 THREAD_NUM=4
 rm -f ${TAGS_FILE};
 find | grep -i "\.c$\|\.cc\|\.cpp$\|\.cxx$\|\.h$" | xargs -P ${THREAD_NUM} -I {} ${CMD_ETAGS} -a {} # 対象となるソース・ヘッダを etags に引数で渡す
-- 全てのファイルを渡すのにコマンドバッファが足りなくなってしまう場合(=ファイル数が多い場合や個々のパス名が長い場合など)でも全てのファイルを渡せるよう、xargs を使って etags にファイル名を渡すようにしている。
-- コマンドバファが足りなくなった場合、 xargs は複数回 etags を呼ぶ。この場合、 etags が append モードで動作しないと etags は呼ばれる度に TAGS ファイルを上書きしてしまうので注意すること(そのため上記では append モードにするため "-a" を付けて etags を呼んでいる)。

//==============================================================================
** emacs に TAGS ファイルを読みこませる [#etags-emacs]
 M-x: tags-reset-tags-tables 一旦リセットする
 M-x: visit-tags-table 明示的に TAGS ファイルを読み込む
- emcs から操作する(下記)
|~Key binding  |~command |~description |
|M-.        |find-tag  |クラスや関数を探す |
|C-u M-.    | |次の検索結果候補を表示する |
|C-u – M-.  | |前の検索結果候補を表示する |
|M-*        |  |元の場所に戻る |
|C-x 4 .    |find-tag-other-window | 	タグ(名前)の定義箇所を探し別ウィンドウに表示 |
|C-x 5 .    |find-tag-other-frame  | 	タグ(名前)の定義箇所を探し別フレームに表示 |



////////////////////////////////////////////////////////////////////////////////
* ctags-exuberant [#ctags-exuberant]
- 正しくは、Exuberant ctags という。このページ名は、Debian のパッケージ名に合わせている。
- ctags の派生プログラムである。
- install 後、実行ファイルは /usr/bin/ctags-exuberant に配置される。システムによっては /usr/bin/ctags に symlink されることもある。
- %%debian 8 にはパッケージが存在しない。%% → exuberant-ctags というパッケージになっている。

//==============================================================================
** TAGS file の生成 [#ctags-exuberant-create-tag]
 $ ctags-exuberant -e -R [path]
- これにより、 'TAGS' という名前のファイルが生成される。
- emacs からの使い方は、[[etags>Prog/TagSystem#etags]] と基本的に同じ

//==============================================================================
** emacs から TAGS の生成を行えるようにする [#ctags-exuberant-emacs-config]
- ${HOME}/.emacs または ${HOME}/.emacs.d/init.el に下記の行を追加する:
 (setq path-to-ctags "/usr/bin/ctags-exuberant") ;; <- your ctags path here
 (defun create-tags (dir-name)
   "Create tags file."
   (interactive "DDirectory: ")
   (shell-command
    (format "ctags -f %s -e -R %s" path-to-ctags (directory-file-name dir-name)))
   )
- TAGS の生成を実行
 M-x: create-tags

//==============================================================================
** 参考リンク [#ctags-exuberant-link]
- [[BuildTags>http://www.emacswiki.org/emacs/BuildTags]]
- [[EmacsTags>http://www.emacswiki.org/emacs/EmacsTags]]


////////////////////////////////////////////////////////////////////////////////
* ebrowse (ebrowse for Emacs)の利用 [#ebrowse]
- etags/ctags 同様、C++ のコードから class のデータベースを作成し、それを emacs で読み込み、class 定義などに Jump 出来るというもの。
- まずは、 BROWSE file を生成する
 $ cd ${PROGRAM_TOP_DIR}
 $ find | grep "C$\|h$" | xargs ebrowse -f  # 対象となるソース・ヘッダを ebrowse に渡す
- emacs に BROWSE ファイルを読みこませる
 C-x C-f: ${PROGRAM_TOP_DIR}/BROWSE
- emacs から操作する
|~Key binding  |~command |~description |
|return        |ebrowse-find-class-declaration| 当該の class 定義に Jump |
|C-x 4 .       |find-tag-other-window  |- |
|C-x 5 .       |find-tag-other-frame   | - |

//==============================================================================
** Links [#ebrowse-link]
- [[A Class Browser for C++>http://www.sunsite.ualberta.ca/Documentation/Gnu/emacs-21.1/html_chapter/ebrowse.html]]


///////////////////////////////////////////////////////////////////////////////
* SilentBob [#silentbob]
- Debian 8 にはパッケージが存在しないので、使用する場合はコードを取ってきてビルドする必要がある。
- repository: 
 git://git.code.sf.net/p/silentbob/git

//=============================================================================
** tag の生成 [#silentbob-create-tag]
 $ bob --make-ctags
 $ bob --cfiles
 $ bob -L cfiles --call-tags
 
//=============================================================================
** 参考リンク [#silentbob-link]
- [[CscopeとSilentBobによるソースコードの解析>https://mag.osdn.jp/07/03/13/0115244]]
- http://silentbob.sourceforge.net/

///////////////////////////////////////////////////////////////////////////////
* 各システムでの解析速度 [#y0ec5d99]
- 各タグシステムで同一コードツリーを走査して、 DB を作り終わるまでの時間を計測した。
- 結果(2)
|~[[TagSystem>Prog/TagSystem]] |~command |~elapsed time [sec] |~remark |
|[[cscope>Prog/TagSystem#cscope]]             |cscope-indexer -r |13.65 | |
|[[id-utils>Prog/TagSystem#id-utils]]         |mkid              |16.61 | |
|[[gtags-global>Prog/TagSystem#gtags-global]] |gtags             |14.82 | |
|[[etags>Prog/TagSystem#etags]]               |find -name '*.h' -o -name '*.c' -o -name '*.cc' &#124; xargs -P ${THREAD_NUM} -I {} etags -a {} |8.30 |THREAD_NUM=8 |
|[[ctags-exuberant>Prog/TagSystem#ctags-xuberant]] |ctags-exuberant -e -R <path> |14.00 | |
// |[[Silent Bob>Prog/TagSystem#silent-bob]]  |bob --make-ctags&br;bob --cfiles&br;bob -L cfiles --call-tags|22.79 | |
-- 計測条件
--- 対象:linux-4.0.1
--- CPU:Core i7-7700HQ @ 2.8GHz (8Core)
--- Disk I/O:なし(tmpfs 上で計測)


- 結果(1)
|~[[TagSystem>Prog/TagSystem]] |~command |~elapsed time [sec] |~remark |
|[[cscope>Prog/TagSystem#cscope]]             |cscope-indexer -r |20.19 | |
|[[id-utils>Prog/TagSystem#id-utils]]         |mkid              |19.23 | |
|[[gtags-global>Prog/TagSystem#gtags-global]] |gtags             |25.24 | |
|[[etags>Prog/TagSystem#etags]]               |find &#124; grep -i "\.h$\&#124;\.c$&#124;\.cc$&#124;\.cxx$&#124;\.cpp" &#124; xargs -P ${THREAD_NUM} -I {} etags -a {} |35.69 |THREAD_NUM=4 |
|[[ctags-exuberant>Prog/TagSystem#ctags-xuberant]] |ctags-exuberant -e -R <path> |16.36 | |
|[[Silent Bob>Prog/TagSystem#silent-bob]]  |bob --make-ctags&br;bob --cfiles&br;bob -L cfiles --call-tags|22.79 | |
-- 計測条件
--- 対象:linux-3.16.36
--- CPU:Core i7-3520M @ 2.90GHz (4Core)
--- Disk I/O:あり(HDD 上で計測)



トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS