prc 发表于 2015-11-23 14:53

帮助你阅读内核源码

本帖最后由 prc 于 2015-11-26 16:34 编辑

在阅读大型C/C++工程源码的过程中常常遇到以下问题

[*]源码中存在的条件编译语句;有的甚至很长,超出了屏幕的高度
[*]工程中存在大量同名的符号
这些都会打断思维过程,使得我不得不停下来花费时间精力去判断哪个代码块为“真”,哪个为“假”。 CL针对这个问题提供了一套简单的解决方案,在编译过程中模仿预处理器计算条件编译语句的值,然后删除“假”的代码块, 仅剩下有效代码。

运行环境

[*]Ubuntu (其它的linux发行版应该也可以,但是没做过测试)
[*]Python 2
[*]Gnu awk
[*]Bash
[*]Gnu make

运行
以linux为例,依次执行下列命令:

[*] git clone https://github.com/panruochen/codeless.git
[*] 编译CL,假设代码目录为${CL_DIR}
[*] make defconfig CROSS_COMPILE=${CROSS_COMPILE} ARCH=${ARCH}
[*] ${CL_DIR}/y-Make --yz-cc=${CROSS_COMPILE}gcc --yz-postprocess=${YOUR_DIR} --yz-server-addr=${ANY_VALID_PATH} -j8
--yz开头的参数传给CL的;--yz-cc表示编译器,--yz-postprocess表示先编译后清理源文件;一般来说只需要这两个参数就可以了。 --yz-server-addr表示启动server并指定server的地址(该地址可以是任何有效的路径)。启动server可以减少临时文件的大小, 并对程序的性能有轻微的改善。而其它的参数如-j8则是传给make的。
编译完成后,在linux目录下会发现大量的.bak文件,它们都是被清理过的同名的.c/.cpp/.h文件的备份。通过比较.bak与原文件,可以发现源文件中的条件编译代码已经被删除:
https://cloud.githubusercontent.com/assets/1546040/4838205/0377bfea-5fe5-11e4-83d9-f0c20679ba7c.png
为了方便恢复代码,建议使用git或者其它的版本管理工具。
为了保证目标文件vmlinux与源代码的一致性,还需要再次编译linux。

限制
只能使用下列编译器(其它的编译器未经测试)

[*]gcc
[*]clang
并且${CROSS_COMILE}gcc展开后只能包含字母,数字,下划线_和减号-

副产品
${YOUR_DIR}目录下的projlist.txt列出了本次编译涉及到的所有.c/.cpp/.h文件,我们可以利用它来生成一个更精确的cscope或者ctags的数据库。
cscope -bkq -i <(tail -n +2 projlist.txt)
通过这个数据库查找可以避免大量重名的符号。
https://cloud.githubusercontent.com/assets/1546040/11395831/68b82500-93a8-11e5-94d3-27b56225ac58.png

y-Make的命令行参数
--yz-cc=CC               指定编译器
--yz-postprocess=DIR       开启后处理模式,并使用DIR为其工作目录
--yz-save-dep=FILE         将所有依赖关系保存在文件FILE中
--yz-save-cl=FILE          将所有命令行保存在文件FILE中
--yz-save-condvals=FILE    将所有条件编译语句的计算结果保存在文件FILE中
--yz-save-proj=FILE      将编译中所涉及到的文件保存在文件FILE中
--yz-server-addr=FILE      启动server,并以FILE作为server的地址
--yz-runtime-dir=DIR       指定server的工作目录为DIR;默认为/var/tmp
--yz-xcc=FILE            指定FILE为parser;默认为${CL_DIR}/cl.exe
--yz-server-program=FILE   指定FILE为server;默认为${CL_DIR}/cl-server.exe
Post Process(后处理)
后处理模式是为了解决编译过程中的实际问题而引入的,即一个.c/.cpp文件有可能被多次编译。如果在编译之前清理文件(这是默认模式), 被删除掉的代码很可能在第二次编译时应该被引用,从而导致整个编译过程失败。 并且,.h文件几乎100%会被多次引用,如果未开启后处理模式,清理.h文件是不可能的。

适用范围
下列开源项目经过测试

[*]linux-3.6
[*]linux-2.6.27.29
[*]llvm-3.5.0
[*]u-boot
[*]make-4.0

Godbach 发表于 2015-11-23 16:39

回复 1# prc

感谢分享。


   

nswcfd 发表于 2015-11-25 14:52

应该会有很多网友需要这样的工具。3x

amarant 发表于 2015-11-26 14:18

这个diao

yihect 发表于 2015-11-28 12:05

有动态 开启/关闭 功能否?
有时候确实想知道走的是哪个预处理块,但如果写死,难免会起一些纠结

prc 发表于 2015-11-30 19:24

这个需求可以通过git完成
git checkout YOUR_FILE #恢复文件
CL_DIR/tool/cl-tool strip -f TMP_DIR/tmp.pp YOUR_FILE #清理文件
回复 5# yihect

firocu 发表于 2015-12-01 12:46

Cool!
It seems very useful!
Thanks for share!

hnwyllmm 发表于 2015-12-10 10:17

../codeless/y-Make --yz-cc=gcc --yz-postprocess=cl

我使用上面的命令处理zeromq,出现这样的异常:

../libtool: line 1:4300 Segmentation fault      (core dumped) /home/bm186/codeless/cl.exe --yz-no-output --yz-save-dep=/home/bm186/zeromq-wangyl11/cl/depends.txt --yz-save-cl=/home/bm186/zeromq-wangyl11/cl/commands.txt --yz-save-condvals=/home/bm186/zeromq-wangyl11/cl/condvals.txt --yz-top-dir=/home/bm186/zeromq-wangyl11 --yz-cc=gcc --yz-verbose=0 "$@"

我的系统环境是
186_bm186%uname -a
Linux rhel13160 2.6.32-131.0.15.el6.x86_64 #1 SMP Tue May 10 15:42:40 EDT 2011 x86_64 x86_64 x86_64 GNU/Linux

楼主见过这个错误吗?

prc 发表于 2015-12-10 11:33

回复 8# hnwyllmm
这个可能是个BUG,请给出zeromq的下载路径

   

hnwyllmm 发表于 2015-12-10 12:51

回复 9# prc
github.com/zeromq/zeromq4-1(抱歉没有URL权限)
这是官方版本的下载地址,但是我自己测试的是4.0.4版本代码
另外,我把gcc改成g++就不会core了,但是却没有发现任何结果。
页: [1] 2
查看完整版本: 帮助你阅读内核源码