暗无天日

=============>DarkSun的个人博客

TIL-etags扫描外部库头文件

现在写代码基本都靠 LSP 做跳转和补全,但 LSP 有时不省心:每种语言得装对应的服务器,有些小众语言还没有像样的实现,大项目启动也慢。etags 是 Emacs 自带的,跑一遍命令生成一个 TAGS 文件就能用,零依赖。

vannilla.org 有一篇 短文 指出了 etags 的一个短板:默认只扫项目源码,外部库(比如 libpng)的头文件不在 TAGS 里,Xref 跳转找不到,补全也用不了。补上这一块就好用了。

怎么做

两步:先找头文件在哪,再让 etags 扫。

第一步,用 pkg-config 找到头文件路径:

pkg-config --cflags-only-I libpng

输出类似:

-I/usr/include/libpng16

第二步,把头文件追加到项目的 TAGS 文件里:

etags.emacs --declarations --append -o TAGS /usr/include/libpng16/*.h

--declarations 是关键。头文件里只有函数声明(原型),没有完整定义。不加这个标志,etags 会跳过它们。注意:有些系统上 etags 指向 Universal Ctags(不支持这个标志),Debian/Ubuntu 上需要用 etags.emacs

--append 在已有的 TAGS 文件上追加,不覆盖项目源码的索引。

批量处理多个库

如果项目依赖多个外部库,可以写个 Shell 函数一次搞定:

addlib() {
    local inc=$(pkg-config --cflags-only-I "$1" | sed 's/-I//g; s/ //g')
    etags.emacs --declarations --append -o TAGS "${inc}"/*.h
}
addlib libpng
addlib zlib

注意:这个函数只适用于 pkg-config 返回单个 include 路径的情况。如果返回多个路径(如 -I/path1 -I/path2 ),需要额外处理。

把这段加到 Makefile 里,每次 make tags 自动更新:

tags: TAGS

TAGS:
        etags.emacs --declarations -o $$(find . -name "*.c" -o -name "*.h")
        addlib libpng
        addlib zlib

TAGS 文件生成后,Emacs 通过 M-x visit-tags-table 加载,之后 xref-find-definitions (默认 M-. )就能跳转到外部库头文件了。

Emacs : etags : Xref : 代码导航