为嵌入式MCU工程建立完整的cscope和ctags索引
这几天深入了解了一下vim的神级插件YouCompleteMe,果然厉害,但是在MCU工程中函数跳转和语义补全就歇菜了,研究了几天也没找到很好的使用方法,最终还是无法在MCU嵌入式工程中跳转函数定义,这是无法忍受的,在PC或mac上的c/c++/clang工程可以完美使用。所以我还是老实的使用cscope和ctags吧,本篇文章就简单说一下,如何为MCU工程建立完整的索引,完成完美跳转!
MCU工程
现状
- macOS平台
- mcu为siliconlab的EFM32单片机,EFM32JG1B200
- 编辑器vim
安装了Silicon Labs官方的开发环境simplicity studio为EFM32的开发带来很大的方便,是很棒的开发工具,同时可以很方便的管理SDK和toolchain,十里却希望可以用vim完成代码编写和阅读,为了实现向开发环境中的各种跳转,十里决定使用cscope和ctags。建立工程依旧使用Simplicity Studio,建立好的工程会生成相应的makefile,这就免去了自己写makefile的麻烦!
SDK和Toolchains目录
- SDK
- “/Applications/Simplicity Studio.app/Contents/Eclipse/developer/sdks/gecko_sdk_suite/v1.1/”
- toolchain
- “/Applications/Simplicity Studio.app/Contents/Eclipse/developer/toolchains/gnu_arm/4.9_2015q3”
思路
先用find命令查找源文件和头文件,并建立索引文件cscope.files,然后通过索引文件创建数据库,这里要注意的是生成的索引文件中,每行代表一个文件的路径,如果路径中包含空格cscope会无法识别正确路径,所以需要用sed命令添加双引号进行处理,而ctags读取索引文件时会自动添加双引号所以应该在sed处理索引文件前先建立ctags数据库。
上述过程可以shell脚本的方式实现。
shell脚本
最终脚本如下:
#!/bin/bash
list_sources() {
echo "---> Listing sources..."
find "/Applications/Simplicity Studio.app/Contents/Eclipse/developer/toolchains/gnu_arm/4.9_2015q3/arm-none-eabi/include" \
-path "/Applications/Simplicity Studio.app/Contents/Eclipse/developer/toolchains/gnu_arm/4.9_2015q3/arm-none-eabi/include/c++" -prune -o \
-type f -name "*.[chsS]" -print > cscope.tmp
find "/Applications/Simplicity Studio.app/Contents/Eclipse/developer/sdks/gecko_sdk_suite/v1.1/platform/emlib/inc" \
"/Applications/Simplicity Studio.app/Contents/Eclipse/developer/sdks/gecko_sdk_suite/v1.1/platform/CMSIS/Include" \
"/Applications/Simplicity Studio.app/Contents/Eclipse/developer/sdks/gecko_sdk_suite/v1.1/platform/Device/SiliconLabs/EFM32JG1B/Include" \
"/Applications/Simplicity Studio.app/Contents/Eclipse/developer/sdks/gecko_sdk_suite/v1.1/hardware/kit/common/bsp" \
"/Applications/Simplicity Studio.app/Contents/Eclipse/developer/sdks/gecko_sdk_suite/v1.1/hardware/kit/common/drivers" \
"." \
-type f -name "*.[chsS]" -print >> cscope.tmp
}
create_cscope_db() {
#因为目录中包含空格,所以需要将生成的文件索引中每行文件路径放到双引号中
sed 's/^/"/;s/$/"/' cscope.tmp > cscope.files
echo "---> Creating cscope DB..."
cscope -k -b -q -R -i cscope.files
}
create_ctags_db() {
echo "---> Creating CTags DB..."
ctags -L cscope.tmp
}
cleanup() {
echo "---> Removing garbage..."
rm -f cscope.files cscope.tmp
}
list_sources
# 因为ctags读取文件索引的时候会对每一行加上引号解决路径包含空格的问题,所以建立ctags库应该直接用加引号前的文件cscope.tmp
create_ctags_db
create_cscope_db
cleanup
结语
在相应的工程下运行这个脚本,就会建立完整文件的cscope和ctags索引,就可以happy地各种跳转了,包括SDK中的源码。
因为不可能就只用到EFM32这一个MCU平台,所以十里又写了一个脚本mktags,其还可以建立Renesas平台的工程索引,这里只加了这一个,其实可以参考十里写的脚本很容易添加其他平台的,十里将其置于/usr/local/bin
目录下,重启终端后就可以为所欲为的构建MCU工程的cscope和ctags索引了。
mktags帮助信息如下:
Usage: /usr/local/bin/mktags SUB_COMMAND [MCU_NAME]
1. SUB_COMMAND:
build: build the cscope database for MCU_NAME
clean: no need MCU_NAME, clean the old cscope database
help: no need MCU_NAME, show the help tips
info: show the infomation of MCU_NAME
2. MCU_NAME:
rx21a -> renesas RX mcu
efm32jg -> Silicon labs efm32 mcu
Example:
/usr/local/bin/mktags build efm32jg
This can build cscope database at current dir for efm32jg