内核目录下可以使用make cscope快速生成对应架构的数据库, 仅这点就把渣渣si甩了一条街. 其实实现原理很简单, cscope是通过读取cscope.files中文件列表建立的数据库, 因此只要控制cscope.files的输入即可实现不同架构下建立的不同cscope.out.
我们先来看看内核是怎么做的. 主目录Makefile中cscope目标会调用scripts/tags.sh脚本, 后者根据传参会生成tags, cscope等, 我们就看下cscope.
1 docscope()
2 {
3 (echo \-k; echo \-q; all_target_sources) > cscope.files
4 cscope -b -f cscope.out
5 }
-k是使用kernel mode, 即不包含/usr/include的头文件.
-q是使用反转索引, 开启后会额外生成两个文件, 但可以加快索引效率.
-b是建立交叉引用.
-f是指定文件名.
以上选项均可以通过man cscope获取说明.
all_target_sources是关键, 它通过find命令将所需的源文件名输入cscope.files中. 这里有个地方没看懂记录下: $tree是怎么赋值成内核目录树的.
可以根据不同架构生成不同名字的cscope.out然后在需要时载入对应的cscope.out文件, 这样查看工程远比si等ide方便.
注意反汇编的文件不要以*.S命名, 否则被当做汇编加入数据库会导致cscope.out剧烈膨胀, 曾经一个工程生成上G的文件, 而内核的cscope.out才400M.
再补充下ctags的生成方式, 由于ctags命令较多, 因此比cscope稍微复杂一点. 首先ctags有两种版本, Exuberant版与Emacs版. 由于当前服务器使用Exuberant版, 就以前者为例, 内核目录下的tags.sh有对两种版本的不同处理.
因为ctags是根据字符串匹配原理来生成tag文件, 因此它不能很好的处理预处理宏, 对于内核或第三方库中使用的特殊宏需要我们手动修改它的定义. 说下tags.sh中用到的常用选项:
-a 以append方式将生成的tags添加到tag文件尾部.
-I 标识符列表, 一些属性宏(i.e. attribute)会影响ctags对函数/变量的判断, 需要将它们加入标识符列表中避免误判.
--regex-
--extra=[+|-]flags flags可以为f或g.
--
小结: ctags是根据字符串匹配的, 因此不能很好的识别宏及c++的扩展. 但是它生成方便, 在没有ycm情况下做为临时索引还是很好用的. 另外同样不要包含反汇编的文件, 否则生成10G的tags也不是不可能.
1 #!/bin/sh
2 SH_DIR=$PWD/$(dirname $0)
3 TOP_DIR=$SH_DIR/../../../../
4 PRODUCT_DIR=$TOP_DIR/product/
5 src_dirs=$TOP_DIR/build/drv_pub/
6 src_dirs+=\ $TOP_DIR/product/compile/
7 src_dirs+=\ $TOP_DIR/product/drv_src/kernel_src/
8 src_dirs+=\ $TOP_DIR/product/drv_src/usr_src/
9 DEBUG_PATH=
10 if [ -n "$DEBUG_PATH" ]; then
11 touch test && chmod +x test && echo > test
12 PRINT_FILE="-fprint $SH_DIR/test"
13 else
14 PRINT_FILE="-print"
15 fi
16 find_c_sources()
17 {
18 find $src_dirs -name "*.[chS]" -a -not -regex ".*x86_sdk.*" -not -type l $PRINT_FILE
19 }
20 find_makefile()
21 {
22 find $src_dirs -name Makefile -not -type l $PRINT_FILE
23 find $src_dirs -name *.config -not -type l $PRINT_FILE
24 find $src_dirs -name *.mk -not -type l $PRINT_FILE
25 }
26 find_sources()
27 {
28 find_c_sources
29 find_makefile
30 }
31 make_ctags()
32 {
33 if [ -f tags ]; then
34 rm tags
35 fi
36 if ! ctags --version | grep -iq exuberant ; then
37 echo "ctags version mismatch!"
38 exit 1
39 fi
40 find_sources | xargs ctags -a -I --extra=+f --c-kinds=+px \
41 --regex-c='/^#?[ \t]?CONFIG_([a-zA-Z0-9_]+)/\1/'
42 }
43 make_cscope()
44 {
45 if [ -f cscope.out ]; then
46 rm cscope.*
47 fi
48 (echo \-k; echo \-q; find_sources) > cscope.files
49 if [ ! -n "$DEBUG_PATH" ]; then
50 cscope -b -f cscope.out -i cscope.files
51 fi
52 }
53 target_check()
54 {
55 CHECK_BASE=$(basename -a $PWD)
56 if [ "$CHECK_BASE" != "product" ]; then
57 echo "wrong path!"
58 exit 1
59 fi
60 BUILD_LIST=$(cat $PWD/Makefile | \
61 awk -F "\n" 'BEGIN{temp[2] = 0;} {match($1, /^(.+):$/, temp); print temp[1];}'
62 )
63 for i in $BUILD_LIST;
64 do
65 if [ "$i" == "$1" ]; then
66 BUILD_TARGET=$i
67 break
68 fi
69 done
70 if [ "$BUILD_TARGET" == "" ]; then
71 echo "wrong target!"
72 exit 1
73 fi
74 BUILD_CLEAN=$(echo $BUILD_TARGET | sed -r 's/(.*)[_].+/\1_clean/')
75 echo $BUILD_CLEAN
76 CLEAN_FIND=0
77 for i in $BUILD_LIST;
78 do
79 if [ "$i" == "$BUILD_CLEAN" ]; then
80 CLEAN_FIND=1
81 break
82 fi
83 done
84 if [ $CLEAN_FIND -eq 0 ]; then
85 BUILD_CLEAN=clean
86 fi
87
88 echo "BUILD_TARGET is" $BUILD_TARGET
89 echo "BUILD_CLEAN is" $BUILD_CLEAN
90 }
91 make_check()
92 {
93 target_check $1
94 TYPE=$(cat $TOP_DIR/build/Compatible_Device_List | \
95 awk -F "\n" 'BEGIN{temp[2] = 0;} {match($1, /^COMPATIBLE_DEVICE_LIST_([^=]+)=.*/, temp); print temp[1];}'
96 )
97 for i in $TYPE;
98 do
99 FILE=./temp_build.$i
100 SKIP=$(echo $i | \
101 awk 'BEGIN{temp[2] = 0;} {match($1, /V([0-9]+)R.+/, temp); if(temp[1] > 2){print $0;}else{print 1};}'
102 )
103 if [ "$SKIP" == "1" ]; then
104 echo "board type" $i "too old to build. SKIP!"
105 continue
106 fi
107 echo "============================"
108 echo "Begin to make on board" $i
109 echo "log file on" $FILE
110 echo "============================"
111 make $BUILD_CLEAN DEVICE_TYPE=$i >> $FILE 2>&1
112 make $BUILD_TARGET DEVICE_TYPE=$i >> $FILE 2>&1
113 if [ $ -ne 0 ]; then
114 echo "*********************************************"
115 echo "End make" $i "with FAILUEEEEEEEEEEEEEEEE!!!"
116 echo "*********************************************"
117 break
118 else
119 echo "End make" $i "with SUCCESS"
120 rm $FILE
121 fi
122 done
123 }
124 usage()
125 {
126 echo "usage:"
127 echo "$0 ctags"
128 echo "$0 cscope"
129 echo "$0 check [target]"
130 echo "$0 sdk"
131 }
132 if [ $# -eq 0 ]; then
133 usage;
134 else
135 case "$1" in
136 "ctags")
137 make_ctags
138 ;;
139 "cscope")
140 cd $TOP_DIR
141 make_cscope
142 ;;
143 "check")
144 cd $PRODUCT_DIR
145 make_check $2
146 ;;
147 "sdk")
148 make_sdk
149 ;;
150 esac
151 fi
原文链接: https://www.cnblogs.com/Five100Miles/p/9060214.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/274321
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!