Using gtags.el or ggtags.el.
I have a project A depending on project B. While in a buffer belonging to A, I want to jump to a definition in B. How do I do this with ggtags-mode
? M-.
simply lists the occurences in project A.
Emacs Stack Exchange is a question and answer site for those using, extending or developing Emacs. It only takes a minute to sign up.
Sign up to join this communityUsing gtags.el or ggtags.el.
I have a project A depending on project B. While in a buffer belonging to A, I want to jump to a definition in B. How do I do this with ggtags-mode
? M-.
simply lists the occurences in project A.
I would create a symbolic link to project B in one of the directories on project A and run gtags
in both the projects (as you might also need to use tags for Project B only).
There's also another way to solve this problem; here's more info from global
documentation:
If you want to locate symbols that are not defined in the source tree, then you can specify library directories with GTAGSLIBPATH environment variable.
You should execute gtags(1) at each directory in the GTAGSLIBPATH. If ‘GTAGS’ is not found there, global ignores such directories.
$ 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
Or, you can take a more straightforward way to do the same thing. In the following example, we treat as if the system library and the kernel are part of our project.
$ 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
[Source]
kaushalmodi's answer is almost perfect, but it doesn't solve the problem at hand. I suggest you to run gtags on each project directory say ~/projects/{a,b}
cd ~/projects/a
gtags
cd ../b
gtags
Now the trick is t use the GTAGSLIBPATH variable as shown in Global documentation so you can use global -T
global -T <function_symbol>
You should see global references to both repositories, if so you can proceed to set this variable in emacs.
Unfortunately the GTAGSLIBPATH variable is not enough for ggtags to show the definition in both modules; you need to force the '-T' option in global.
To force the '-T' option you have to set the environment variable GTAGSTHROUGH to any value (such as true) directly in emacs or as part of the environment when you launch it
;; You can set this in your .emacs
(setenv "GTAGSTHROUGH" "true")
Now you should be able to see the definitions from both projects using ggtags
The GTAGSLIBPATH
solution here requires that project B has a GTAGS
file, when you may only want tags from project A always. You may then temporarily set the current directory to be in project A
(defun ggtags-find-definition-projectA ()
"Find global tags in project A from anywhere"
(interactive)
(let ((default-directory "/path/to/project/A"))
(call-interactively 'ggtags-find-definition)))
and assign a shortcut to it.