tqsheng

go.....
随笔 - 366, 文章 - 18, 评论 - 101, 引用 - 0
数据加载中……

wikidpad


项目MyBaseWikidPad备注
费用收费,可破解开源,免费 
中文支持OKOK 
全文搜索OKOK 
所见即所得OKNO 
链接及图片OKOK 
自动ToDoNOOK 
Tag及各种视图TagTag+视图 
分支&页面加密OKNO保密内容用附件加密
数学公式NOOK(Mimetex,插件) 
代码着色NOOK(Prettycode,插件) 
导出无法连附件导出,导出为一组文件可导出附件,且导出后仍为一个阅读系统 
文件格式私有TXT多文件可选为文件系统
附件管理数据库+链接链接 
文本格式丰富一般,可满足需求 
表格不好用满足需求 
节点管理节点方式子页面 
向量图NOOK(GraphVic,插件) 
函数图NOOK(GNUplot,插件) 

必备插件

http://trac.wikidpad2.webfactional.com/wiki/ListOfUserScripts
  • Prettycode: Syntax highlighting for many languages using Pygments.
  • Edit Extensions: Add some edit functionality to Wikidpad
  • TodoExtension: Collect todo item in a page. http://www.ziemski.net/wikidpad/todo_extension.html
  • Colorizer: Colorize text selection via font tags in different colors
  • InsertSymbols2: Pop-up window to insert user-defined symbols in Wikidpad editor 

外部程序

WikidPad的强大之处在于可以使用集成使用一些强大的工具,以丰富其功能。
  • 如何使用MimeTex:数学公式
  • 如何使用GrapViz:向量图和非向量图
  • 如何使用GNUplot:函数图

TIP

如何使用ToDo

<<
todo开始时,记录条目.
    * todo.项目名:[发起日期][预计完成日期][推迟次数]todo项目内容. 
 todo完成时,记录条目.
    * done.项目名:[发起日期][预计完成日期][实际完成日期][推迟次数]todo项目内容.
    * 完成过程与内容描述.
    * 相关链接.
>>

posted @ 2012-07-29 13:33 tqsheng 阅读(324) | 评论 (0)编辑 收藏

效率

http://blog.macro2.org/?p=644 

posted @ 2012-07-23 09:33 tqsheng 阅读(104) | 评论 (0)编辑 收藏

抓视频的图



要抓视频的图只需要把windows的显示设置硬件加速设无就可以了

posted @ 2012-07-22 20:28 tqsheng 阅读(121) | 评论 (0)编辑 收藏

一些软件

NoteExpress和Endnote文献管理软件Magic Notes 3.5 Build 10281
桌面提醒 Desktop-Reminder 2.54
ToDoList
GoodSync - 真正实用的本地双向文件同步工具 (自动备份利器,支持U盘/移动硬盘/FTP)
pnotes
Rainlendar
rednotebook
wikidpad

posted @ 2012-07-19 22:40 tqsheng 阅读(153) | 评论 (0)编辑 收藏

SE的按需显示----强啊,赞一个

SE的按需显示----强啊,赞一个

2006-06-02

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://birdnest.blogbus.com/logs/2626856.html

今天心情好,再加多一篇:
读过复杂代码的人都有这种体会:如果能够把一个函数或者一个文件里面已经看过的,或者不重要的部分隐藏起来,这样整个函数(文件)的结构就会看得更清晰,读起来也就更加容易。

SourceInsight号称代码查看之王,却没有这个功能,UE也是从11版以后才提供的。不过SE不仅有这个功能而且非常之强大,UE的那些在它面前只能算小儿科了。

1. 隐藏某个大括号内的内容
这个UE是有的,SE中的操作为:将光标放到所需隐藏的大括号内的任意位置,然后选择菜单View-> Hide Code Block即可。

2. 隐藏选中的某个区域
这个UE也是有的,SE中的操作为:先选取一块区域,然后选择菜单View-> Hide Selection

3. 隐藏注释内容
良好的注释虽然好,不过有时候太多的注释也会影响查看,让我们把它藏起来先。
UE也有这个,不过它的这个功能和它隐藏大括号是很类似的,那就是只能隐藏/*….*/的多行注释,对于连续的//单行注释就不成了,呵呵
SE就可以Handle这个啦,对于不论哪种方式的注释,都可以采用隐藏大括号的方法来隐藏,而且更加强悍的是,它可以一次性隐藏所有注释而不影响其他的查看,这个UE就只能流口水啦,呵呵
隐藏所有注释的方法:选择菜单View-> Hide All Comment

4. 函数头显示
如何轻松快速的在文件里面找到所需要的函数呢,当然是把所有的函数头列在那里让你挑啦。UE里面只能用“全部折叠”来勉强实现,但是还有很有多#define,全局变量,//的注释等等残留在那里,实在是。。。。。。
SE的函数头显示功能这时可就大派用场了,选择菜单View-> Function Heading,看看,
除了函数头以外,什么都没有了,干干净净,所有的函数实在是一目了然啊。

5. 有选择的显示
最后再来说说SE独一无二的也是最强大的功能Selective Display,定制显示内容。呵呵,看名字是不是就觉得很强呢?
选择菜单View-> Selective Display出现如下界面


这里列出了6种可选择的显示方式,我们一种种来:
Ⅰ. Search Text
只显示(或者隐藏)符合搜索内容的行。这个强啊,可以让我们用最快的速度找到我们所需要的东西所在的行。
下面的输入框可以输入要搜索的内容,下面还有几个复选框,左边3个是一般搜索常见的大小写吻合,整个词吻合,使用正则表达式。
右边第一个”Reset selective display”则是在这次搜索前先清除以前所隐藏的东西,恢复到完全显示状态再执行搜索操作。否则可以在上次的基础上再次隐藏新的内容。
第二个则是决定隐藏搜索到的行,抑或只显示搜索到的行。

Ⅱ. Function definitions

只显示所有的函数头(定义),这里和我们前面说的Function Heading类似,不过在这里可以追加显示每个函数上面的注释内容。使用了这个,我们的.c文件也可以变成.h文件了,^_^
下面有2个复选框,
“Show comments” 显示完整的函数头注释
“Collapse comments” 注释只显示第一行,想看完整的可自行点击展开

Ⅲ. Preproessor directives

这个超赞啊!!!!!!
根据你的预定义,只显示编译器能看到的部分。也就是说当你有很多功能模块分别都用#ifdef FEATURE_XXXX框起来的话,如果其中某个FEATURE没有被预定义的话,它将不会被显示出来!!!!!
用这个看那种预定义功能超多的操作系统代码,或者多模块的复杂代码实在是太方便了,我以前看代码就最烦里面N多多#ifdef XXXX的了,也不知道哪段代码才是真正有用了,有了这个,终于可以解放了啊,hoho。
在下面的输入框中,可以输入你要隐藏的预定义的内容,可以包含多个,如果你不记得定义的名字了,还可以用”Scan for Defines” 按钮来帮你搜索(作者实在太体贴啦)。
如果不指定的话,所有在#ifdef …#endif 中的内容都将被隐藏。

Ⅳ. Multi-level

这个则是按照嵌套层次进行隐藏,有2种选择Brace(大括号)和Indentation(缩进)。
选择大括号则是关闭所有的大括号,就跟UE的全部关闭类似,
缩进则是关闭所有的缩进,呵呵,这次连单行的if..else..语句的内容也可以隐藏了。
Limit levels可以指定关闭深度,当你的嵌套很深时,你如果要打开就得点很多次了,这里就可以指定一个深度,超过这个深度的就作为一个整体不会再被关闭了。

Ⅳ.Ⅴ 后面2个比较简单,就不仔细介绍了
Pragraphs:只显示所有段落的第一行
Hide Selection:和刚才最前面讲过的隐藏选区是一样的。

最后,下面3个单选框是用来指定你进行展开一个多重嵌套时的操作的
Expand:展开时自动展开所有的子项
Collapse:只展开下层中的第一层
Remember:恢复到关闭前的状态

看到这里,你对SE的强大是否又有了新的了解了呢,是否激起你更换编辑器的冲动了呢,呵呵,不要犹豫,赶快也去整一个来试用试用吧,你一定会爱上它的。

posted @ 2012-07-17 12:21 tqsheng 阅读(329) | 评论 (0)编辑 收藏

Doxygen + Graphviz + Htmlhelp, 成为文档好手

1 doxygen是大名鼎鼎代码文档工具。

下载地址:www.doxygen.org

安装它。http://www.stack.nl/~dimitri/doxygen/download.html 可下载.

 

2 Graphviz

这个工具配合doxygen使用,可以提取函数,模块之间的调用关,非常清晰。

下载地址:http://www.graphviz.org/Download..php 

下面是Graphviz提取出来的一些关系图:

    

 
  

 


3 htmlhelp

这个工具把doxygen生成的html文件,转化为一个CHM文件,看起来方便些。

 下载地址:

http://www.microsoft.com/downloads/details.aspx?FamilyID=00535334-c8a6-452f-9aa0-d597d16580cc&displaylang=en

安装它。

 

全部安装后就可以开始使用了。

运行doxygen wizard.exe

     运行doxywizard.exe,这时按照doxygen根目录下的文档(doxygen_manual-1.5.2.chm)中 Doxywizard usage一节的说明设置即可。主要包括,源码路径、工作路径、输出路径等。

点开始,即可生成文档

 

最后对文档生成过程中遇到的一些问题进行说明:

 

1 中文问题:中文注释在文档中是乱码。
解决:在expert中的INPUT选项页的
INPUT_ENCODEING中填入“GB2312”,这样基于GB的文本编辑器生成的代码就可以正常使用了。

 

2 图形问题:无法绘制类图协作图等图形。
首先确保安装了graphviz,注意不是wingraphviz,后者是一个graphviz的com封装,但是doxygen并不是基于它开发的,所以装了也没用。然后在 expert的Dot页
DOT_PATH中填入graphviz的安装路径。接着在wizard的diagram中选择需要生成的图形类别就可以了。

如果出现无法包含.map文件的错误,可以将工作目录设置成html,并将html中所有文件都清除再试。这个问题的原因还不太确定。

 

3 输出chm的问题:如何输出.chm文件
1. 你必须安装微软或其相兼容的chm编译系统。通常为HTML Help Workshop。

2. 首先在[Wizard]的Output页面中,选择HTML,然后选择到prepare for compressed HTML(.chm)。

3. 其次在[Expert]的HTML页面中,将HHC_LOCATION指向微软的hhc工具。通常为C:/Program Files/HTML Help Workshop/hhc.exe。然后点击OK,保存,编译即可。

 

HHC_LOCATION中输入hhc.exe文件的路径。hhc.exe可以通过安装HTML Help Workshop获得。

 

4 如何像MSDN那样在左边的树中显示函数列表?
打开[Expert]的HTML页面,然后选中
TOC_EXPAND即可。

 

5 如何去掉CHM附带的CHI文件?
注 意在默认情况下,CHM会有一个CHI文件,似乎是用来加速索引的。我本人也遇到过很多用户仅仅上传了CHM,而没有上传CHI文件,导致无法正常显示的 情况。我不知道是否可以通过工具重建CHI文件,但是我觉得关闭这个功能即可。打开[Expert]的HTML页面,取消
GENERATE_CHI 即可。

 

6 如何像MSDN那样右边每页显示一个函数?

这 个问题其实比较棘手,在[Expert]中的 Project页面,下面有一个选项叫做SEPARATE_MEMBER_PAGES,把这个选项选中,这样每个函数就是一个页。但是会有一个问题,那就 是右边页面的旁边多了所有函数的列表。很遗憾,经过研究,这个确实无法去掉。我的解决方法就是自己编译一下doxygen,在 memberlist.cpp的writeDocumentationPage函数中将 container->writeQuickMemberLinks(ol,md);连同附近几行屏蔽掉即可。

 

7 如何在CHM中去掉当选择SUBGROUPING后去掉分组的组信息?

这 个功能就是在chm的左边树中直接列出函数列表,而不用点击看右边页面了。这个功能需要修改源代码。在index.cpp中,屏蔽 writeGroupIndexItem函数的 Doxygen::indexList.addContentsItem,Doxygen::indexList.incContentsDepth和 Doxygen::indexList.decContentsDepth();即可。

 

8 如何修改或者去掉右下脚Generated at ...的文字?

打 开[Expert...]的HTML页面,然后在HTML_FOOTER中指定相应的HTML文件即可。注意HTML_FOOTER中至少包含BODY和 HTML结束标记。即一个最小的尾部HTML至少是这样</BODY></HTML>。同理,如果你要指定了 HTML_HEADER,他至少包含<HTML><HEAD></HEAD><BODY>

 

9 如何生成组?

组 就是可以把同类的函数放到一个根下的显示方式。doxygen支持grouping,即你可以把相关的代码通过标志,放到同一个组中,便于查看。这主要是 通过几个内置语法命令。首先通过@defgroup定义一个组,然后要把分组的函数或者类等,通过标志@ingroup加入相应的组。这样,相应的函数就 被放置在同一个组中。

 

10 如何生成中文帮助?

点击[Expert],在页Project 的OUTPUT_LANGUAGE,选择Chinese,这样输出的帮助提示信息就是中文。具体中文提示信息的文字在源代码中。

 

11 如何彻底解决DoxyGen的输出中文chm的乱码问题?
DoxyGen的实现中大概有三处编码的设置。首先是,doxyfile,也就是配置文件。其次,INPUT_ENCODING,也就是DoxyGen需要解析的输入文件的编码。最后,就是输出的编码。譬如CHM左边的索引编码。

首先是chm的标题乱码,这个比较好解决,因为DoxyWizard使用QT做的界面,它内部做了转换,所以在DoxyWizard中输入中文,在保存的时 候,他自己做了转码,导致doxyfile中的最终的保存信息不正确。这个时候只需要用记事本打开doxyfile配置文件,输入相应中文即可。注意保存 的时候保存成ANSI编码即可。保存成其他格式的话可能需要去掉BOM,比较麻烦,没研究了。这个相应的编码设置在[Expert...]中,页 Project 的 DOXYFILE_ENCODING,不输入或者默认为UTF-8都行。

其次是右边内容乱码,这个多半是因为你没有配置好输入的文件编码类型造成的。在[Expert...]的Input页面中,有一个 INPUT_ENCODING,这个选项表示输入文件的编码方式,这要和你处理的源文件格式一致。对于我们来说(使用vs的人),一般设置为 GB2312。当然,再次声明,编码方式取决于源文件的编码方式。如果文件编码已经是UTF-8了,然而你还将其设置成GB2312,那么DoxyGen 会将UTF-8当成ANSI再进行一次UTF-8转换,自然会出错了。

最后也是经常遇到的问题就是DoxyGen生成的CHM文件的左边树目录的中文变成了乱码。这个只需要将chm索引的编码类型修改为GB2312即可。在 HTML的CHM_INDEX_ENCODING中输入GB2312即可。然而这种方法下,还有一个瑕疵之处,就是chm的搜索页的搜索结果中显示的中文 文字却变成乱码了。这是因为DoxyGen默认开启了HTML Help Workshop的Full-text search全文搜索选项,他在进行全文搜索的时候,应该是打开文件然后按照ANSI进行搜索的,(资料表示HHW不支持UTF-8,仅支持ISO- 8859-1或者windows-1252编码。)而Doxygen生成的右边界面统一是UTF-8,这自然出现了问题。而在这种情况下做全文搜索,理论 上只能搜索英文。

        我们的解决方案只能是重新编译DoxyGen代码,为了满足搜索,只要保证右边的页面文件不是UTF-8即可。我们首先修改 writeDefaultHeaderFile这个函数的代码,将其charset=GB2312。然后在 TranslatorDecoder的构造函数中修改m_toUtf8 = (void*)-1;即屏蔽文本写入时最终的转换函数。最后删除INPUT_ENCODING的设置或者输入UTF-8。这样会使DoxyGen认为我们 的文本是UTF-8的,从而不用进行转换。生成替换原始的DoxyGen即可。

另外需要补充的是,还有一种方案是不用修改作者的源代码,但是需要将DoxyGen生成的右边的HTML文件使用工具(如iconv)手工转换成GB2312,然后再使用HTML Help Workshop生成,网上有篇文章介绍过,我测试一下,也是没有问题的。

     

  最后,doxygen是一个开源项目,并且支持vs2005项目,这样一来,如果你觉得哪里不顺手,完全可以把代码下载后自行编译。

        这样,基本上就能够用doxygen生成漂亮的文档了。代码方面,doxygen支持多种格式的注释风格,根据manual选择自己喜欢的就好。

1 doxygen是大名鼎鼎代码文档工具。

下载地址:www.doxygen.org

安装它。http://www.stack.nl/~dimitri/doxygen/download.html 可下载.

 

2 Graphviz

这个工具配合doxygen使用,可以提取函数,模块之间的调用关,非常清晰。

下载地址:http://www.graphviz.org/Download..php 

下面是Graphviz提取出来的一些关系图:

    

 
  

 


3 htmlhelp

这个工具把doxygen生成的html文件,转化为一个CHM文件,看起来方便些。

 下载地址:

http://www.microsoft.com/downloads/details.aspx?FamilyID=00535334-c8a6-452f-9aa0-d597d16580cc&displaylang=en

安装它。

 

全部安装后就可以开始使用了。

运行doxygen wizard.exe

     运行doxywizard.exe,这时按照doxygen根目录下的文档(doxygen_manual-1.5.2.chm)中 Doxywizard usage一节的说明设置即可。主要包括,源码路径、工作路径、输出路径等。

点开始,即可生成文档

 

最后对文档生成过程中遇到的一些问题进行说明:

 

1 中文问题:中文注释在文档中是乱码。
解决:在expert中的INPUT选项页的
INPUT_ENCODEING中填入“GB2312”,这样基于GB的文本编辑器生成的代码就可以正常使用了。

 

2 图形问题:无法绘制类图协作图等图形。
首先确保安装了graphviz,注意不是wingraphviz,后者是一个graphviz的com封装,但是doxygen并不是基于它开发的,所以装了也没用。然后在 expert的Dot页
DOT_PATH中填入graphviz的安装路径。接着在wizard的diagram中选择需要生成的图形类别就可以了。

如果出现无法包含.map文件的错误,可以将工作目录设置成html,并将html中所有文件都清除再试。这个问题的原因还不太确定。

 

3 输出chm的问题:如何输出.chm文件
1. 你必须安装微软或其相兼容的chm编译系统。通常为HTML Help Workshop。

2. 首先在[Wizard]的Output页面中,选择HTML,然后选择到prepare for compressed HTML(.chm)。

3. 其次在[Expert]的HTML页面中,将HHC_LOCATION指向微软的hhc工具。通常为C:/Program Files/HTML Help Workshop/hhc.exe。然后点击OK,保存,编译即可。

 

HHC_LOCATION中输入hhc.exe文件的路径。hhc.exe可以通过安装HTML Help Workshop获得。

 

4 如何像MSDN那样在左边的树中显示函数列表?
打开[Expert]的HTML页面,然后选中
TOC_EXPAND即可。

 

5 如何去掉CHM附带的CHI文件?
注 意在默认情况下,CHM会有一个CHI文件,似乎是用来加速索引的。我本人也遇到过很多用户仅仅上传了CHM,而没有上传CHI文件,导致无法正常显示的 情况。我不知道是否可以通过工具重建CHI文件,但是我觉得关闭这个功能即可。打开[Expert]的HTML页面,取消
GENERATE_CHI 即可。

 

6 如何像MSDN那样右边每页显示一个函数?

这 个问题其实比较棘手,在[Expert]中的 Project页面,下面有一个选项叫做SEPARATE_MEMBER_PAGES,把这个选项选中,这样每个函数就是一个页。但是会有一个问题,那就 是右边页面的旁边多了所有函数的列表。很遗憾,经过研究,这个确实无法去掉。我的解决方法就是自己编译一下doxygen,在 memberlist.cpp的writeDocumentationPage函数中将 container->writeQuickMemberLinks(ol,md);连同附近几行屏蔽掉即可。

 

7 如何在CHM中去掉当选择SUBGROUPING后去掉分组的组信息?

这 个功能就是在chm的左边树中直接列出函数列表,而不用点击看右边页面了。这个功能需要修改源代码。在index.cpp中,屏蔽 writeGroupIndexItem函数的 Doxygen::indexList.addContentsItem,Doxygen::indexList.incContentsDepth和 Doxygen::indexList.decContentsDepth();即可。

 

8 如何修改或者去掉右下脚Generated at ...的文字?

打 开[Expert...]的HTML页面,然后在HTML_FOOTER中指定相应的HTML文件即可。注意HTML_FOOTER中至少包含BODY和 HTML结束标记。即一个最小的尾部HTML至少是这样</BODY></HTML>。同理,如果你要指定了 HTML_HEADER,他至少包含<HTML><HEAD></HEAD><BODY>

 

9 如何生成组?

组 就是可以把同类的函数放到一个根下的显示方式。doxygen支持grouping,即你可以把相关的代码通过标志,放到同一个组中,便于查看。这主要是 通过几个内置语法命令。首先通过@defgroup定义一个组,然后要把分组的函数或者类等,通过标志@ingroup加入相应的组。这样,相应的函数就 被放置在同一个组中。

 

10 如何生成中文帮助?

点击[Expert],在页Project 的OUTPUT_LANGUAGE,选择Chinese,这样输出的帮助提示信息就是中文。具体中文提示信息的文字在源代码中。

 

11 如何彻底解决DoxyGen的输出中文chm的乱码问题?
DoxyGen的实现中大概有三处编码的设置。首先是,doxyfile,也就是配置文件。其次,INPUT_ENCODING,也就是DoxyGen需要解析的输入文件的编码。最后,就是输出的编码。譬如CHM左边的索引编码。

首先是chm的标题乱码,这个比较好解决,因为DoxyWizard使用QT做的界面,它内部做了转换,所以在DoxyWizard中输入中文,在保存的时 候,他自己做了转码,导致doxyfile中的最终的保存信息不正确。这个时候只需要用记事本打开doxyfile配置文件,输入相应中文即可。注意保存 的时候保存成ANSI编码即可。保存成其他格式的话可能需要去掉BOM,比较麻烦,没研究了。这个相应的编码设置在[Expert...]中,页 Project 的 DOXYFILE_ENCODING,不输入或者默认为UTF-8都行。

其次是右边内容乱码,这个多半是因为你没有配置好输入的文件编码类型造成的。在[Expert...]的Input页面中,有一个 INPUT_ENCODING,这个选项表示输入文件的编码方式,这要和你处理的源文件格式一致。对于我们来说(使用vs的人),一般设置为 GB2312。当然,再次声明,编码方式取决于源文件的编码方式。如果文件编码已经是UTF-8了,然而你还将其设置成GB2312,那么DoxyGen 会将UTF-8当成ANSI再进行一次UTF-8转换,自然会出错了。

最后也是经常遇到的问题就是DoxyGen生成的CHM文件的左边树目录的中文变成了乱码。这个只需要将chm索引的编码类型修改为GB2312即可。在 HTML的CHM_INDEX_ENCODING中输入GB2312即可。然而这种方法下,还有一个瑕疵之处,就是chm的搜索页的搜索结果中显示的中文 文字却变成乱码了。这是因为DoxyGen默认开启了HTML Help Workshop的Full-text search全文搜索选项,他在进行全文搜索的时候,应该是打开文件然后按照ANSI进行搜索的,(资料表示HHW不支持UTF-8,仅支持ISO- 8859-1或者windows-1252编码。)而Doxygen生成的右边界面统一是UTF-8,这自然出现了问题。而在这种情况下做全文搜索,理论 上只能搜索英文。

        我们的解决方案只能是重新编译DoxyGen代码,为了满足搜索,只要保证右边的页面文件不是UTF-8即可。我们首先修改 writeDefaultHeaderFile这个函数的代码,将其charset=GB2312。然后在 TranslatorDecoder的构造函数中修改m_toUtf8 = (void*)-1;即屏蔽文本写入时最终的转换函数。最后删除INPUT_ENCODING的设置或者输入UTF-8。这样会使DoxyGen认为我们 的文本是UTF-8的,从而不用进行转换。生成替换原始的DoxyGen即可。

另外需要补充的是,还有一种方案是不用修改作者的源代码,但是需要将DoxyGen生成的右边的HTML文件使用工具(如iconv)手工转换成GB2312,然后再使用HTML Help Workshop生成,网上有篇文章介绍过,我测试一下,也是没有问题的。

     

  最后,doxygen是一个开源项目,并且支持vs2005项目,这样一来,如果你觉得哪里不顺手,完全可以把代码下载后自行编译。

        这样,基本上就能够用doxygen生成漂亮的文档了。代码方面,doxygen支持多种格式的注释风格,根据manual选择自己喜欢的就好。

posted @ 2012-07-15 15:58 tqsheng 阅读(521) | 评论 (0)编辑 收藏

用 Graphviz 可视化函数调用

用 Graphviz 可视化函数调用

使用开源软件来简化复杂调用结构

M. Tim Jones, 资深软件工程师, Emulex

简介: 花一些时间遍历一下源代码,可以向您展现所有的函数调用过程;但是如果函数指针非常复杂,或者代码太长且晦涩难懂,那么这个过程就可能更加困难了。本文将向您介绍如何使用开源软件和一些定制的代码来构建一个动态的图形函数调用生成器。

本文的标签:  代码库图形化开放源码调试

发布日期: 2005 年 7 月 11 日 
级别: 初级 
访问情况 : 12381 次浏览 
评论: 1 (查看 | 添加评论 - 登录)

平均分 5 星 共 19 个评分 平均分 (19个评分)
为本文评分

可以将以图形形式查看应用程序的调用过程看作是一个学习经历。这样做可以帮助您理解应用程序的内部行为,并获得有关程序优化方面的信息。例如,通过对那些经常调用的函数进行优化,您就可以用最少的努力来获得最佳的性能。另外,调用跟踪还可以判断用户函数的最大调用深度,这可以用来对调用栈使用的内存进行有效限制(在嵌入式系统中,这是非常重要的一个考虑因素)。

为了捕获并显示调用图,您需要 4 个元素:GNU 编译器工具链、Addr2line 工具、定制的中间代码和一个名为 Graphviz 的代码。Addr2line 工具可以识别函数、给定地址的源代码行数和可执行映像。定制的中间代码是一个非常简单的工具,它可以减少对图形规范的地址跟踪。Graphviz 工具可以生成图形映像。整个过程如图 1 所示。


图 1. 搜集、简化和可视化跟踪路径的过程
跟踪过程 

数据搜集:捕获函数调用路径

要收集一个函数调用的踪迹,您需要确定每个函数在应用程序中调用的时间。在过去,都是通过在函数的入口处和退出处插入一个惟一的符号来手工检测每个函数的。这个过程非常繁琐,而且很容易出错,通常需要对源代码进行大量的修改。

幸运的是,GNU 编译器工具链(也称为 gcc)提供了一种自动检测应用程序中的各个函数的方法。在执行应用程序时,就可以收集相关的分析数据。您只需要提供两个特殊的分析函数即可。其中一个函数在每次执行想要跟踪的函数时都会调用;而另外一个函数则在每次退出想要跟踪的函数时调用(参见清单 1)。这两个函数都是特别指定的,因此,编译器可以识别它们。


清单 1. GNU 的入口和出口配置函数
				 void __cyg_profile_func_enter( void *func_address, void *call_site )                                 __attribute__ ((no_instrument_function)); void __cyg_profile_func_exit ( void *func_address, void *call_site )                                 __attribute__ ((no_instrument_function)); 

避免使用特殊的检测函数

您或许会产生疑惑,如果 gcc 就是我们需要的检测函数,那么为什么它不检测__cyg_* 分析函数呢?gcc 的开发者曾思考过这个问题,他们提供了一个名为no_instrument_function 的函数属性,这个函数属性可以应用于函数原型,禁止对它们进行检测。不要将这个函数属性应用到分析函数上,这样会导致无限递归分析循环和大量的无用数据。

在调用一个检测函数时,__cyg_profile_func_enter 同时也会被调用,并以 func_address 形式传递调用的函数地址,以及从中调用该函数的 call_site 形式的地址。反之,当一个函数退出时,也会调用__cyg_profile_func_exit 函数,并传递 func_address 形式的函数地址,以及函数从中退出的真实地址,该地址的表示形式为 call_site

在这些分析函数中,您可以记录下地址对,以供以后再进行分析使用。要请求 gcc 所有的检测函数,每个文件都必须使用 -finstrument-functions 和 -g选项进行编译,这样可以保留调试符号。

因此,现在您就可以为 gcc 提供一些分析函数了,这些函数可以透明地插入应用程序中的函数入口点和函数退出点。但在调用分析函数时,又应该怎样处理所提供的地址呢?您有很多选择,但是为了简便起见,可以将这个地址简单地写入一个文件,要注意哪个地址是函数的入口地址,哪个地址是函数的出口地址(参见清单 2)。

注意:在清单 2 中并没有使用调用 Callsite 信息,因为这些信息对于分析程序来说是不必要的。


清单 2. 分析函数
				 void __cyg_profile_func_enter( void *this, void *callsite ) {   /* Function Entry Address */   fprintf(fp, "E%p\n", (int *)this); } void __cyg_profile_func_exit( void *this, void *callsite ) {   /* Function Exit Address */   fprintf(fp, "X%p\n", (int *)this); } 

现在您可以搜集分析数据了,但是您应该在什么地方打开或关闭您的跟踪输出文件呢?到现在为止,还不需要为了进行分析而对源程序进行任何修改。因此,您该如何检测整个应用程序(包括 main 函数)而不用对分析数据的输出结果进行初始化呢?gcc 的开发者也考虑过这个问题,它们为 main 函数的 constructor 函数和 destructor 函数提供了一些碰巧能够满足这个要求一些方法。constructor 函数是在调用 main 函数之前调用的,而 destructor 函数则是在应用程序退出时调用的。

要创建 constructor 和 destructor 函数,则需要声明两个函数,然后对这两个函数应用constructor 和 destructor 函数属性。在 constructor 函数中,会打开一个新的跟踪文件,分析数据的地址跟踪就是写入这个文件的;在 destructor 函数中,会关闭这个跟踪文件(参见清单 3)。


清单 3. 分析 constructor 和 destructor 函数
				 /* Constructor and Destructor Prototypes */ void main_constructor( void ) 	__attribute__ ((no_instrument_function, constructor)); void main_destructor( void ) 	__attribute__ ((no_instrument_function, destructor)); /* Output trace file pointer */ static FILE *fp; void main_constructor( void ) {   fp = fopen( "trace.txt", "w" );   if (fp == NULL) exit(-1); } void main_deconstructor( void ) {   fclose( fp ); } 

如果编译分析函数(在 instrument.c)并将它们与目标应用程序链接在一起,然后再执行目标应用程序,结果会生成一个应用程序的调用追踪,追踪记录被写入 trace.txt 文件。跟踪文件与调用的应用程序处于相同的目录中。最终结果是,您可能会得到一个其中满是地址的非常大的文件。为了能够让这些数据更有意义,您可以使用一个不太出名的叫做 Addr2line 的 GNU 工具。

回页首

使用 Addr2line 将函数地址解析为函数名

Addr2line 工具(它是标准的 GNU Binutils 中的一部分)是一个可以将指令的地址和可执行映像转换成文件名、函数名和源代码行数的工具。这种功能对于将跟踪地址转换成更有意义的内容来说简直是太棒了。

要了解这个过程是怎样工作的,我们可以试验一个简单的交互式的例子。(我直接从 shell 中进行操作,因为这是最简单地展示这个过程的方法,如清单 4 所示。)这个示例 C 文件(test.c)是通过 cat 一个简单的应用程序实现的(也就是说,将标准输出的文本重定向到一个文件中)。然后使用 gcc 来编译这个文件,它会传递一些特殊的选项。首先,要(使用 -Wl选项)通知链接器生成一个映像文件,并(使用 -g 选项)通知编译器生成调试符号。最终生成可执行文件 test。得到新的可执行应用程序之后,您就可以使用 grep 工具在映像文件中查找 main 来寻找它的地址了。使用这个地址和 Addr2line 工具,就可以判断出函数名(main)、源文件(/home/mtj/test/test.c)以及它在源文件中的行号(4)。

在调用 Addr2line 工具时,要使用 -e 选项来指定可执行映像是 test。通过使用 -f 选项,可以告诉工具输出函数名。


清单 4. addr2line 的一个交互式例子
				 $ cat >> test.c #include <stdio.h> int main() {   printf("Hello World\n");   return 0; } <ctld-d> $ gcc -Wl,-Map=test.map -g -o test test.c $ grep main test.map 	0x08048258		__libc_start_main@@GLIBC_2.0 	0x08048258		main $ addr2line 0x08048258 -e test -f main /home/mtj/test/test.c:4 $ 

Addr2line 和调试器

Addr2line 工具提供了基本的符号调试信息,不过 GNU Debugger (GDB)使用的是其他一些内部方法。

回页首

精简函数跟踪数据

现在您有了一个可以搜集函数函数地址的追踪数据的方法,还可以使用 Addr2line 工具将地址转换为函数名。然而,从应用程序中产生大量的跟踪数据之后,如何对这些数据进行精简,从而使其更有意义呢?这就是使用一些定制的中间代码在开源工具之间建立联系的地方。本文提供了这个工具(Pvtrace)的带有注释的完整代码,包括如何编译和使用该工具的一些说明。(有关的更多信息,请参阅 下载 一节。)

回想一下图 1 中的内容,在执行设置了检测函数的应用程序时,会创建一个名为 trace.txt 的文本文件。这个人们可以读取的文件中包含了一系列地址信息 —— 每行一个地址,每行都有一个前缀字符。如果前缀是 E,那么这个地址就是一个函数的入口地址(也就是说,您正在调用这个函数)。如果前缀是一个 X 字符,那么这个地址就是一个出口地址(也就是说,您正在从这个函数中退出)。

因此,如果在跟踪文件中有一个入口地址(A)紧跟着另外一个入口地址(B),那么您就可以推断是 A 调用了 B。如果一个入口地址(A)后面跟着一个出口地址(A),那么就说明这个函数(A)被调用后就直接返回了。当涉及大量的调用链时,就很难分析究竟是谁调用了谁,因此,一种简单的解决方案是维护一个整个地址的堆栈。每次在跟踪文件中碰到一个入口地址时,就将其压入堆栈。栈顶的地址就代表最后一次被调用的函数(也就是当前的活动函数)。如果后面紧接着是另外一个入口地址,这说明堆栈中的地址调用了这个刚从跟踪文件处读出的地址。在碰到退出函数时,当前的活动函数就会返回,并释放栈顶元素。这会将上下文返到回前一个函数,由此,就可以产生正确的调用链过程。

图 2 介绍了这个概念,以及精简数据的方法。在分析跟踪文件中的调用链时,会构建一个连通矩阵,用来表示哪个函数调用了其他哪些函数。这个矩阵的行表示调用函数的地址,列表示被调用的地址。对于每个调用对来说,行与列的交叉点不断进行累加(调用次数)。当处理完整个跟踪文件时,其结果是该应用程序的整个调用历史的一个非常简单的表示,其中包含了调用的次数。


图 2. 对跟踪数据进行处理和精简,并生成矩阵格式
精简过程 

编译并安装工具

在下载并解压 Pvtrace 工具之后,只需在子目录中输入 make 命令,就可以编译 Pvtrace 工具了。也可以使用下面的代码将这个工具安装到 /usr/local/bin 目录中:

$ unzip pvtrace.zip -d pvtrace

$ cd pvtrace

$ make

$ make install

现在我们已经构建了简化的函数连通性矩阵,接下来应该构建图形的表示了。让我们深入研究 Graphviz,了便理解如何从连通矩阵生成一个调用图。

回页首

使用 Graphviz

Graphviz 或 Graph Visualization 是由 AT&T 开发的一个开源的图形可视化工具。它提供了多种画图能力,但是我们重点关注的是它使用 Dot 语言直连图的能力。在本文中,我们将简单介绍如何使用 Dot 来创建一个图形,并展示如何将分析数据转换成 Graphviz 可以使用的规范。(请参阅 参考资料 一节,以获得有关下载这个开源软件的信息。)

Dot 使用的图形规范

使用 Dot 语言,您可以指定三种对象:图、节点和边。为了让您理解这些对象的含义,我们将构建一个例子来展示这些元素的用法。

清单 5 给出了一个简单的定向图(directed graph),其中包含 3 个节点。第一行声明这个图为 G,并且声明了该图的类型(digraph)。接下来的三行代码用于创建该图的节点,这些节点分别名为 node1node2 和 node3。节点是在它们的名字出现在图规范中时创建的。边是在在两个节点使用边操作(->)连接在一起时创建的,如第 6 行到第 8 行所示。我还对边使用了一个可选的属性 label,用它来表示边在图中的名称。最后,在第 9 行完成对该图规范的定义。


清单 5. 使用 Dot 符号表示的示例图(test.dot)
				 1:  digraph G { 2:    node1; 3:    node2; 4:    node3; 5: 6:    node1 -> node2 [label="edge_1_2"]; 7:    node1 -> node3 [label="edge_1_3"]; 8:    node2 -> node3 [label="edge_2_3"]; 9:  } 

要将这个 .dot 文件转换成一个图形映像,则需要使用 Dot 工具,这个工具是在 Graphviz 包中提供的。清单 6 介绍了这种转换。


清单 6. 使用 Dot 来创建 JPG 映像
				 $ dot -Tjpg test.dot -o test.jpg $ 

在这段代码中,我告诉 Dot 使用 test.dot 图形规范,并生成一个 JPG 图像,将其保存在文件 test.jpg 中。所生成的图像如图 3 所示。在此处,我使用了 JPG 格式,但是 Dot 工具也可以支持其他格式,其中包括 GIF、PNG 和 postscript。


图 3. Dot 创建的示例图
Dot 创建的示例图 

Dot 语言还可以支持其他一些选项,包括外形、颜色和很多属性。但是就我们想要实现的功能而言,这个选项就足够了。

回页首

综合

现在我们已经看到了整个过程的各个阶段了,下面可以采用一个例子来展示如何将这些阶段合并在一起了。现在,您应该已经展开并安装了 Pvtrace 工具,然后还需要将 instrument.c 文件复制到工作源代码目录中。

在这个例子中,我使用了一个源文件 test.c 进行检测。清单 7 给出了整个过程。在第 3 行中,我使用检测源(instrument.c)来构建(编译并连接)应用程序。然后在第 4 行执行test,再使用 ls 命令验证已经生成了 trace.txt 文件。在第 8 行,我调用了 Pvtrace 工具,并提供这个映像文件作为它惟一的参数。映像名是必需的,这样 Addr2line(在 Pvtrace 中调用)就可以访问这个映像中的调试信息。在第 9 行中,我又执行了一次 ls 命令,以确保 Pvtrace 生成了 graph.dot 文件。最后,在第 12 行,使用 Dot 将这个图形规范转换成一个 JPG 图形映像。


清单 7. 创建调用跟踪图的整个过程
				  1:  $ ls  2:  instrument.c    test.c  3:  $ $ gcc -g -finstrument-functions test.c instrument.c -o test  4:  $ ./test  5:  $ ls  6:  instrument.c     test.c  7:  test             trace.txt  8:  $ pvtrace test  9:  $ ls 10:  graph.dot        test           trace.txt 11:  instrument.c     test.c 12:  $ dot -Tjpg graph.dot -o graph.jpg 13:  $ ls 14:  graph.dot        instrument.c   test.c 15:  graph.jpg        test           trace.txt 16:  $ 

这个过程的示例输出如图 4 所示。这个示例图是从使用 Q 学习的一个简单增强式学习应用程序中得到的。


图 4. 示例应用程序的跟踪结果
示例应用程序的跟踪结果 

您也可以使用这种方法对更大的应用程序进行分析。我要展示的最后一个例子是 Gzip 工具。我简单地将 instrument.c 加入 Gzip 的 Makefile 中,作为其依赖的一个源文件,然后编译 Gzip,并使用它生成一个跟踪文件。这个图形太大了,不太容易进行更详细的分析,但是下图表示了 Gzip 对一个小文件进行压缩时的处理过程。


图 5. Gzip 跟踪结果
Gzip 跟踪结果 

回页首

结束语

使用开源软件和少量的中间代码,只需要花很少的时间就可以开发出非常有用的项目。通过使用对应用程序进行分析的几个 GNU 编译器扩展,可以使用 Addr2line 工具进行地址转换,并对 Graphviz 应用程序进行图形可视化,然后您就可以得到一个程序,该程序可以对应用程序进行分析,并展示一个说明调用链的定向图。通过图形来查看一个应用程序的调用链对于理解应用程序的内部行为来说非常重要。在正确了解调用链及其各自的频率之后,这些知识可能对调试和优化应用程序非常有用。


回页首

下载

描述名字大小下载方法
Instrumentation source and Pvtrace sourcepvtrace.zip4 KBHTTP

posted @ 2012-07-15 14:58 tqsheng 阅读(860) | 评论 (0)编辑 收藏

关于「Proxy Switchy Plus 汉化版」和「豆瓣助手 for Chrome」这两个扩展你应该知道的事情


关于「Proxy Switchy Plus 汉化版」和「豆瓣助手 for Chrome」这两个扩展你应该知道的事情

1、根据微博网友 @老王2012A 的爆料(via @月光博客),Chrome Web Store 中的「Proxy Switchy Plus 汉化版」扩展存在流氓行为。该扩展会自动修改淘宝购物链接,并在淘宝购物链接中加入了一个淘宝客广告推广ID,从而获得利益。而用户对此并不知情!

2、关于「豆瓣助手 for Chrome」这个扩展也有类似的行为,这个扩展小编一直在使用,每当点击淘宝中的链接,会发现浏览器中的地址会经过一个 data:text/html 开头的 DATA URL 进行跳转,然后才会打开目标链接。而正是有了这一跳转,原作者就能你购买的商品中获利。虽然作者曾经有在豆瓣发帖说明此事(文末),并在被网友质疑之后加入了一个可以取消该功能的选项,但说老实话,我用了很长时间这个扩展,到今天晚上才知道该插件还有设置并关闭这一流氓行为的功能(因为只能进入豆瓣网才能设置,采用的并非 Chrome 扩展标准的选项接口)。

进入「豆瓣助手 for Chrome」设置界面的方法为:打开豆瓣网,按快捷键 alt+Q 打开设置界面,然后切换到“其他功能”标签,取消勾选“通过在卓越、淘宝商城上买书支持豆瓣助手”

其实早在今年2月份的时候就有网友曝光该扩展,链接在此:http://www.douban.com/group/topic/17667748/

从我个人角度来讲,对开发者从扩展中谋取一定收入没有任何意见,但前提是你必须清楚的告知用户(因为这还涉及到隐私方面的问题,同时淘宝卖家也会因此遭受损失)。既然作者不愿意告知用户,那么我就来告诉大家,希望大家注意。

关于「Proxy Switchy Plus 汉化版」和「豆瓣助手 for Chrome」这两个扩展你应该知道的事情

1、根据微博网友 @老王2012A 的爆料(via @月光博客),Chrome Web Store 中的「Proxy Switchy Plus 汉化版」扩展存在流氓行为。该扩展会自动修改淘宝购物链接,并在淘宝购物链接中加入了一个淘宝客广告推广ID,从而获得利益。而用户对此并不知情!

2、关于「豆瓣助手 for Chrome」这个扩展也有类似的行为,这个扩展小编一直在使用,每当点击淘宝中的链接,会发现浏览器中的地址会经过一个 data:text/html 开头的 DATA URL 进行跳转,然后才会打开目标链接。而正是有了这一跳转,原作者就能你购买的商品中获利。虽然作者曾经有在豆瓣发帖说明此事(文末),并在被网友质疑之后加入了一个可以取消该功能的选项,但说老实话,我用了很长时间这个扩展,到今天晚上才知道该插件还有设置并关闭这一流氓行为的功能(因为只能进入豆瓣网才能设置,采用的并非 Chrome 扩展标准的选项接口)。

进入「豆瓣助手 for Chrome」设置界面的方法为:打开豆瓣网,按快捷键 alt+Q 打开设置界面,然后切换到“其他功能”标签,取消勾选“通过在卓越、淘宝商城上买书支持豆瓣助手”

其实早在今年2月份的时候就有网友曝光该扩展,链接在此:http://www.douban.com/group/topic/17667748/

从我个人角度来讲,对开发者从扩展中谋取一定收入没有任何意见,但前提是你必须清楚的告知用户(因为这还涉及到隐私方面的问题,同时淘宝卖家也会因此遭受损失)。既然作者不愿意告知用户,那么我就来告诉大家,希望大家注意。

posted @ 2012-07-15 09:24 tqsheng 阅读(255) | 评论 (0)编辑 收藏

记事本

c在保存一篇新建的文档时,如果没有指定编码类型,会使用缺省的ANSI类型(对于中文版来说,对应的就是GB码)。
而在打开一篇已创建的文档时,它会分析文档的编码类型,它首先判断文档头部有无BOM(Byte Order Mark,字节序标记,长
度为(2-3字节),如有则根据其内容判断编码类型,FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8) 
因为事实上有很多非ANSI编码的文档是没有任何BOM的“纯文本”,所以对这些文档不能简单的判断为ANSI编码。
而需要使用一系列的统计学算法根据文档内容来猜测文档编码。记事本使用了 IsTextUnicode 函数来判断是否为 
Unicode/Unicode big endian 编码,使用 IsTextUTF8 判断是否为 UTF8 编码。但既然是统计学算法,就难免存在误判
,尤其在文档内容过短时,由于样本的容量太小,这种误判的概率会显著增大。比如那个有名的微软与联通有仇的笑话,
就是记事本在打开只有"联通"二字的ANSI编码文档时,IsTextUTF8 函数将其误判为UTF8编码[2];同样的误判也发生在 
IsTextUnicode 函数上,比如具有 “this app can break”这种具有4335结构的文档,会被误判为 Unicode 编码[3][4]。
需要说明的是,这种误判的可能性是建立在文本较短且其字节位特征不被干扰的前提上的。如果将上述的文本做稍许修改(即使只是增加一个回车),则误判很难再发生。
而这种方法的特殊性在于,它的字节串不但具有Unicode特征,而且很长达到了1288字节,也就是说它的Unicode特征性很强,所以可以抵抗一 些较短的不具有Unicode特征串的干扰,这是由统计学的规律所决定的。但是在干扰串稍长时,Unicode的特征将会受到显著干扰,直至被 IsTextUnicode 函数认定为非 Unicode。所以,有些朋友总是无法测试成功,应该是与附加的批处理代码长度和内容相关。
因为其他的编辑器(比如 Word / Wordpad / EditPlus / UltraEdit)使用了更新的编码类型判断算法,所以在 Unicode 判断上改进了不少,而 UTF8 的判断仍然不尽如人意。但因为理论上来说完全准确地算法并不存在,所以我们只能依靠避免使用无BOM的非ANSI文档,或者打开文档时手动指定编码类型。
   另外,如果使用记事本保存了这些误判了编码类型的文件,则将难以恢复。如果使用误判编码保存,则将给原文档加上BOM标记,则使用其他编辑器也再无法 观察到原文档。如果使用 ANSI 编码保存,则原文档将会被当作 Unicode 文档而被转换,还原的可能性接近于零

posted @ 2012-07-13 20:59 tqsheng 阅读(146) | 评论 (0)编辑 收藏

build 中文乱码

SE貌似有自己的shell,可以通过Build窗口访问,是一个很方便的功能,在工程中点击Compile或是Build,编译的输出信息都会显示在Build窗口中,如果编译出现错误,双击Error或是Warning就可以在源文件中定位,是一个十分方便的功能,不过我一直被乱码所困扰,原因大概是shell默认是用的语言是zh_CN-UTF8,和SE的默认编码方式不同,所以我们需要在SE初始化的时候修改环境变量,方法如下:

  1. gedit ~/.slickedit/14.0.2/vslick.ini
  2. 添加以下内容:
    [Enviroment]
    LANG = en_US.UTF-8
  3. Ctrl + S
  4. 重启SE

我们还可以在这里添加其它环境变量,SE下Ctrl + Space切换输入法的设置貌似也可以在这设置,不过还没成功过。

posted @ 2012-07-13 20:09 tqsheng 阅读(316) | 评论 (0)编辑 收藏

BABYBJORN

BABYBJORN 

posted @ 2012-07-13 12:47 tqsheng 阅读(102) | 评论 (0)编辑 收藏

makefile下$(wildcard $^),$^,$@,$?,$<,$(@D),$(@F)

makefile下$(wildcard $^),$^,$@,$?,$<,$(@D),$(@F)代表的不同含义


$(filter-out $(PHONY) $(wildcard $^),$^)
常用用法为$(wildcard *.c)
表示列举当前目录下的所有.c文件
这里$^因为会包含依赖的文件名,如果包含的该文件存在,那么将返回其含路径的文件名
所以$(wildcard $^)就是用来过滤$^包含的所有文件并且该文件确实在本地存在.

自动化变量$?代表依赖文件列表中被改变过的所有文件。
自动化变量$^代表所有通过目录搜索得到的依赖文件的完整路径名(目录 + 一般文件名)列表。
自动化变量$@代表规则的目标。
自动化变量$<代表规则中通过目录搜索得到的依赖文件列表的第一个依赖文件。
自动化变量$(@D) 
The directory part of the file name of the target, 
with the trailing slash removed. If the value of ‘$@’ is dir/foo.o 
then ‘$(@D)’ is dir. This value is . if ‘$@’ does not contain a slash.
http://www.gnu.org/software/make/manual/make.html
自动化变量$(@F)
The file-within-directory part of the file name of 
the target. If the value of ‘$@’ is dir/foo.o then ‘$(@F)’ is foo.o. 
‘$(@F)’ is equivalent to ‘$(notdir $@)’. 

4.12 静态模式
静态模式规则是这样一个规则:
规则存在多个目标,
并且不同的目标可以根据目标
文件的名字来自动构造出依赖文件。
静态模式规则比多目标规则更通用,
它不需要多个
目标具有相同的依赖。
但是静态模式规则中的依赖文件必须是相类似的而不是完全相同
的。
4.12.1
静态模式规则的语法
首先,我们来看一下静态模式规则的基本语法:
TARGETS ...: TARGET-PATTERN: PREREQ-PATTERNS ...
COMMANDS
...
“TAGETS”
列出了此规则的一系列目标文件。
像普通规则的目标一样可以包含通
配符。关于通配符的使用可参考 4.4 文件名使用通配符 一节
“TAGET-PATTERN”和“PREREQ-PATTERNS”说明了如何为每一个目标文件
生成依赖文件。从目标模式(TAGET-PATTERN)的目标名字中抽取一部分字符串(称
为“茎”。使用“茎”替代依赖模式(PREREQ-PATTERNS)中的相应部分来产生对
)
应目标的依赖文件。下边详细介绍这一替代的过程。
首 先 在目标模式和依赖模式中 ,一般需要包含模式字符“% ”
。在目标模式
(TAGET-PATTERN)中“%”可以匹配目标文件的任何部分,模式字符“%”匹配的
部分就是“茎”
。目标文件和目标模式的其余部分必须精确的匹配。看一个例子:目标
“foo.o”符合模式“%.o”
,其“茎”为“foo”
。而目标“foo.c”和“foo.out”就不符
合此目标模式。
每一个目标的依赖文件是使用此目标的“茎”代替依赖模式
(PREREQ-PATTERNS)中的模式字符“%”而得到。例如:上边的例子中依赖模式
(PREREQ-PATTERNS)为“%.c”
,那么使用“茎”
“foo”替代依赖模式中的“%”
得到的依赖文件就是“foo.c”
。需要明确的一点是:在模式规则的依赖列表中使用不包
含模式字符“%”也是合法的。代表这个文件是所有目标的依赖文件。
在模式规则中字符‘%’可以用前面加反斜杠“\”方法引用。引用“%”的反斜杠
也可以由更多的反斜杠引用。引用“%”“\”的反斜杠在和文件名比较或由“茎”代

替它之前会从模式中被删除。反斜杠不会因为引用“%”而混乱。如,模式
“the\%weird\\%pattern\\”是“the%weird\”+“%”+“pattern\\”构成。最后的两个
反斜杠由于没有任何转义引用“%”所以保持不变。
我们来看一个例子,它根据相应的.c 文件来编译生成“foo.o”和“bar.o”文件:
objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
例子中,规则描述了所有的.o文件的依赖文件为对应的.c文件,对于目标“foo.o”
,取
其茎“foo”替代对应的依赖模式“%.c”中的模式字符“%”之后可得到目标的依赖文
件“foo.c”
。这就是目标“foo.o”的依赖关系“foo.o: foo.c”
,规则的命令行描述了如
何完成由“foo.c”编译生成目标“foo.o”
。命令行中“$<”和“$@”是自动化变量,
“$<”
表示规则中的第一个依赖文件,
“$@”
表示规则中的目标文件
(可参考 10.5.3 自
动化变量 一小节)
。上边的这个规则描述了以下两个具体的规则:
foo.o : foo.c
$(CC) -c $(CFLAGS) foo.c -o foo.o
bar.o : bar.c
$(CC) -c $(CFLAGS) bar.c -o bar.o
在使用静态模式规则时,指定的目标必须和目标模式相匹配,否则执行make时将
会得到一个错误提示。
如果存在一个文件列表,
其中一部分符合某一种模式而另外一部
分符合另外一种模式,这种情况下我们可以使用“filter”函数(可参考 第八章 make
的内嵌函数)来对这个文件列表进行分类,在分类之后对确定的某一类使用模式规则。
例如:
files = foo.elc bar.o lose.o
$(filter %.o,$(files)): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
$(filter %.elc,$(files)): %.elc: %.el
emacs -f batch-byte-compile $<
其中;$(filter %.o,$(files))的结果为“bar.o lose.o”“filter”函数过滤不符合“%.o”

模式的文件名而返回所有符合此模式的文件列表。
第一条静态模式规则描述了这些目标
文件是通过编译对应的.c 源文件来重建的。同样第二条规则也是使用这种方式。
我们通过另外一个例子来看一下自动环变量“$*”在静态模式规则中的使用方法:
bigoutput littleoutput : %output : text.g
generate text.g -$* > $@
当执行此规则的命令时,
自动环变量
“$*”
被展开为
“茎” 在这里就是

“big” “little”


静态模式规则对一个较大工程的管理非常有用。
它可以对整个工程的同一类文件的
重建规则进行一次定义,而实现对整个工程中此类文件指定相同的重建规则。比如,可
以用来描述整个工程中所有的.o 文件的依赖规则和编译命令。通常的做法是将生成同
一类目标的模式定义在一个 make.rules 的文件中。在工程各个模块的 Makefile 中包含
此文件。

  1. 静态模式makefile中$(cobjs): $(obj)/%.o: $(src)/%.c

  2. http://www.gnu.org/software/make/manual/make.html
  3. 4.12.1 Syntax of Static Pattern Rules

  4. Here is the syntax of a static pattern rule:

  5.      targets ...: target-pattern: prereq-patterns ...
  6.              recipe
  7.              ...

  8. The targets list specifies the targets that the rule applies to. The targets can contain wildcard characters, just like the targets of ordinary rules (see Using Wildcard Characters in File Names).

  9. The target-pattern and prereq-patterns say how to compute the prerequisites of each target. Each target is matched against the target-pattern to extract a part of the target name, called the stem. This stem is substituted into each of the prereq-patterns to make the prerequisite names (one from each prereq-pattern).

  10. Each pattern normally contains the character ‘%’ just once. When the target-pattern matches a target, the ‘%’ can match any part of the target name; this part is called the stem. The rest of the pattern must match exactly. For example, the target foo.o matches the pattern ‘%.o’, with ‘foo’ as the stem. The targets foo.and foo.out do not match that pattern.

  11. The prerequisite names for each target are made by substituting the stem for the ‘%’ in eachprerequisite pattern. For example, if one prerequisite pattern is %.c, then substitution of the stem ‘foo’ gives the prerequisite name foo.c. It is legitimate to write a prerequisite pattern that does not contain ‘%; then this prerequisite is the same for all targets.

  12. %’ characters in pattern rules can be quoted with preceding backslashes (\). Backslashes that would otherwise quote ‘%’ characters can be quoted with more backslashes. Backslashes that quote ‘%’ characters or other backslashes are removed from the pattern before it is compared to file names or has a stem substituted into it. Backslashes that are not in danger of quoting ‘%’ characters go unmolested. For example, the pattern the\%weird\\%pattern\\ has ‘the%weird\’ preceding the operative ‘%’ character, and ‘pattern\\’ following it. The final two backslashes are left alone because they cannot affect any ‘%’ character.

  13. Here is an example, which compiles each of foo.and bar.o from the corresponding .c file:

  14.      objects = foo.o bar.o
  15.      
  16.      all: $(objects)
  17.      
  18.      $(objects): %.o: %.c
  19.              $(CC) -c $(CFLAGS) $< -o $@

  20. Here ‘$<’ is the automatic variable that holds the name of the prerequisite and ‘$@’ is the automatic variable that holds the name of the target; see Automatic Variables.

  21. Each target specified must match the target pattern; a warning is issued for each target that does not. If you have a list of files, only some of which will match the pattern, you can use the filter function to remove nonmatching file names (see Functions for String Substitution and Analysis):

  22.      files = foo.elc bar.o lose.o
  23.      
  24.      $(filter %.o,$(files)): %.o: %.c
  25.              $(CC) -c $(CFLAGS) $< -o $@
  26.      $(filter %.elc,$(files)): %.elc: %.el
  27.              emacs -f batch-byte-compile $<

  28. In this example the result of ‘$(filter %.o,$(files))’ is bar.o lose.o, and the first static pattern rule causes each of these object files to be updated by compiling the corresponding C source file. The result of ‘$(filter %.elc,$(files))’ is foo.elc, so that file is made from foo.el.

  29. Another example shows how to use $* in static pattern rules:

  30.      bigoutput littleoutput : %output : text.g
  31.              generate text.-$* > $@

  32. When the generate command is run, $* will expand to the stem, either ‘big’ or ‘little’.

posted @ 2012-07-13 10:30 tqsheng 阅读(689) | 评论 (0)编辑 收藏

Unix网络API

     摘要: 索引: 1.字节序函数2.字节操作函数3.地址转换函数4.readn、writen和readline5.测试描述符类型6.socket函数7.connect函数8.bind函数9.listen函数10.accept函数11.close函数12.getsockname和getpeername13.select函数14.shutdown函数15.pselect函数16.poll函数17.ge...  阅读全文

posted @ 2012-07-13 10:28 tqsheng 阅读(314) | 评论 (0)编辑 收藏

Code Navigation Tools

Code Navigation Tools

副标题: Ctags, Doxygen, Class Browser, Slickedit, Cscope, Source Insight, Understand
出版社: Books LLC
出版年: 2010-9-15
页数: 34
定价: USD 14.14
装帧: Paperback
ISBN: 9781157307280

posted @ 2012-07-12 16:11 tqsheng 阅读(171) | 评论 (0)编辑 收藏

推荐一个不错的flex ajax javascript资源网站http://ntt.cc/

推荐一个不错的flex ajax javascript资源网站http://ntt.cc/ 

posted @ 2012-07-12 12:42 tqsheng 阅读(161) | 评论 (0)编辑 收藏

仅列出标题
共25页: First 6 7 8 9 10 11 12 13 14 Last