背景
在我平時用Emacs編寫C代碼時,經常需要進行代碼的跳轉,主要需求為函數定義的跳轉,某個具
體函數的調用查找,某個結構體的定義跳轉以及結構體中具體某一項的跳轉等,GNU Global就能
完全滿足我的這個需求,所以習慣了Emacs的人可以將Source Insight扔開了。
GNU Global簡介
GNU Global全稱為GNU Global source code tagging system,官方定義為GNU Global是一個可以跨越各
種環境的代碼標記系統,例如在Emacs,VI,Less Viewer,Bash Shell甚至在Web瀏覽器中使用。
可以通過GNU Global查找局部變量,函數,宏,結構體,類並且方便的跳轉到你想要的位置,在進行大型項
目開發時,GNUL Global可以包含許多子目錄,#ifdef語句和許多main函數,它有點向平時經常使用的ctags
和etags,但是有和這兩個tag工具比起來GNU Global有以下兩點更為強大:
- 和編輯器不具有強綁定關系,所以可以很方便的將其用於各種編輯環境,無論是Emacs的忠實使用者還是Vim的粉絲都可以盡情的使用它來進行代碼跳轉
- 具有比較強大的查找定義和引用的能力,對於代碼閱讀來說這個能力已經足夠了
GNU Global具有強大的跨平台能力,無論是在Linux還是在BSD系統還是Windows都可以使用。
GNU Global具有以下功能:
- 內置6種語法分析程序(定義和引用)C,C++,Yacc,Java,PHP4和匯編
- 通過Ctags的語法解析插件可以支持25中語言(定義和引用)Awk, Dos batch, COBOL, C, C++, C#, Erlang,Fortran, Java, JavaScript, Lisp, Lua, Pascal, Perl, PHP, Python, Ruby, Matlab, OCaml, Scheme, Tcl, TeX, Verilog, Vhdl and Vim
- 在各種不同的編輯環境中能夠以相同的方式工作,例如
- Shell命令行
- Bash Shell
- Vi編輯器(Vim)
- Less Viewer
- Emacs編輯器(Emacs,Mule,XEmacs)
- Web瀏覽器
- Doxygen文檔系統
- 通過特殊的符號表快速查找局部變量
- 不僅能夠查找定義還可以查找引用
- 允許重復的tags
- 給出匹配的路徑
- 默認分層查找
- 不僅僅實在代碼級別查找,還可以在庫中查找
- 生成補全列表
- 支持多種格式輸出
- 允許指定標記文件
- 支持POSIX 1003.2正則表達式
- 支持idutils作為外部搜索引擎
- 生成的tag文件獨立於各種體系結構
- 支持隨時更新tag文件
- 支持新語言的語法解析插件
- 支持自定義gtags.conf
- 使用壓縮格式來節省空間
- 支持C/S環境(TRAMP)
- 默認忽略可執行文件,隱藏文件和特殊文件
- 內置cscope程序(gtags-cscope)
- 內置grep命令(使用-g)
- 能夠很好的處理循環符號鏈
GNU Global使用
命令行下使用GLOBAL,在開始使用之前可以看一下FAQ
$more /your/gtags/path/FAQ
|
的代碼時,只需要執行以下命令
$cd ~/code/kernel/
$gtags -v
|
執行完之后會發現,在kernel目錄下產生了3個tag文件分別是GPATH,GRTAGS,GTAGS,
GTAGS是定義的數據庫,GRTAGS是引用的數據庫,GPATH是路徑的數據庫。
基本用法,加入下面的是我們的目錄樹
/home/user/ | |-ROOT/ <- the root of source tree (GTAGS,GRTAGS,...) | |- README ..... +---------------+ | |The function of| | +---------------+ |- DIR1/ | | | |- fileA.c ..... +---------------+ | | |main(){ | | | | func1();| | | | func2();| | | |} | | | +---------------+ | | | |- fileB.c ..... +---------------+ | |func1(){ ... } | | +---------------+ |- DIR2/ | |- fileC.c ..... +---------------+ |#ifdef X | |func2(){ i++; }| |#else | |func2(){ i--; }| |#endif | |func3(){ | | func1();| |} | +---------------+ |
相關函數,需要注意的是只能在生成TAG文件的目錄及其子目錄中搜索:
$ cd /home/user/ROOT $ global func1 DIR1/fileB.c # func1() is defined in fileB.c $ cd DIR1 $ global func1 fileB.c # relative path from DIR1 $ cd ../DIR2 $ global func1 ../DIR1/fileB.c # relative path from DIR2 |
使用global的-r選項獲取相關引用:
$ global -r func2 ../DIR1/fileA.c # func2() is referred from fileA.c |
$ cd /home/user/ROOT $ global 'func[1-3]' DIR1/fileB.c # func1, func2 and func3 are matched DIR2/fileC.c |
$ global func2 DIR2/fileC.c $ global -x func2 func2 2 DIR2/fileC.c func2(){ i++; } func2 4 DIR2/fileC.c func2(){ i--; } |
$ global -a func1 /home/user/ROOT/DIR1/fileB.c |
$ global -xs X X 1 DIR2/fileC.c #ifdef X |
$ global -xg '#ifdef' #ifdef 1 DIR2/fileC.c #ifdef X |
-l選項只在當前目錄搜索,使用-P選項可以搜索特定模式的路徑;
如果想在庫中搜索相關符號,則需要在每一個GTAGSLIBPATH中執行gtags
命令:
$ pwd /develop/src/mh # this is a source project $ gtags $ ls G*TAGS GRTAGS GTAGS $ global mhl uip/mhlsbr.c # mhl() is found $ global strlen # strlen() is not found $ (cd /usr/src/lib; gtags) # library source $ (cd /usr/src/sys; gtags) # kernel source $ export GTAGSLIBPATH=/usr/src/lib:/usr/src/sys $ global strlen ../../../usr/src/lib/libc/string/strlen.c # found in library $ global access ../../../usr/src/sys/kern/vfs_syscalls.c # found in kernel $ ln -s /usr/src/lib . $ ln -s /usr/src/sys . $ gtags $ global strlen lib/libc/string/strlen.c $ global access sys/kern/vfs_syscalls.c |
$ global -c kmem # maybe k..k.. kmem..
kmem_alloc
kmem_alloc_pageable
kmem_alloc_wait
kmem_free
kmem_free_wakeup
kmem_init
kmem_malloc
kmem_suballoc # This is what I need!
$ global kmem_suballoc
../vm/vm_kern.c
$ funcs()
> {
> local cur
> cur=${COMP_WORDS[COMP_CWORD]}
> COMPREPLY=(`global -c $cur`)
> }
$ complete -F funcs global
$ global kmem_<TAB><TAB>
kmem_alloc kmem_alloc_wait kmem_init
kmem_alloc_nofault kmem_free kmem_malloc
kmem_alloc_pageable kmem_free_wakeup kmem_suballoc
$ global kmem_s<TAB>
$ global kmem_suballoc
../vm/vm_kern.c
|
GNU Global在Emacs中的使用
- 安裝配置Emacs
$HOME/.emacs +------------------------------------------------------ |(setq load-path (cons "/home/owner/global" load-path)) |(autoload 'gtags-mode "gtags" "" t) (global-set-key (kbd "M-<f1>") 'gtags-find-file) (global-set-key (kbd "M-<f2>") 'gtags-find-tag) (global-set-key (kbd "M-<f3>") 'gtags-find-rtag) (global-set-key (kbd "M-<f4>") 'gtags-find-symbol) (global-set-key (kbd "M-<f5>") 'gtags-find-with-grep) |
- 安裝好之后在emacs中可以通過M-x使用如下命令
在瀏覽器中顯示當前屏幕 跳轉到輸入的文件處 通過grep命令搜索 在tag文件中搜索引用 在tag文件中搜索符號 在tag文件中搜索定義 從當前表達式獲得tag名並跳轉 以當前位置作為tag跳轉 在另一個窗口中打開tag跳轉 搜索文件並查詢 tag名字補全 開啟gtags mode 顯示當前文件的tag 從棧中移動到上一個點 從tag列表中選擇一個tag 選擇一個tag 通過某個事件選擇tag 在其他window中選擇tag 訪問tag文件根目錄 |
gtags-display-browser
gtags-find-file
gtags-find-pattern
gtags-find-rtag
gtags-find-symbol
gtags-find-tag
gtags-find-tag-by-event
gtags-find-tag-from-here
gtags-find-tag-other-window
gtags-find-with-grep
gtags-find-with-idutils
gtags-make-complete-list
gtags-mode
gtags-parse-file
gtags-pop-stack
gtags-select-mode
gtags-select-tag
gtags-select-tag-by-event
gtags-select-tag-other-window
gtags-visit-rootdir
|