﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客- 驭风万里无垠</title><link>http://www.cppblog.com/skyscribe/</link><description /><language>zh-cn</language><lastBuildDate>Tue, 07 Apr 2026 18:29:51 GMT</lastBuildDate><pubDate>Tue, 07 Apr 2026 18:29:51 GMT</pubDate><ttl>60</ttl><item><title>转移到github</title><link>http://www.cppblog.com/skyscribe/archive/2012/02/29/move-to-octopress.html</link><dc:creator>skyscribe</dc:creator><author>skyscribe</author><pubDate>Wed, 29 Feb 2012 14:52:00 GMT</pubDate><guid>http://www.cppblog.com/skyscribe/archive/2012/02/29/move-to-octopress.html</guid><wfw:comment>http://www.cppblog.com/skyscribe/comments/166817.html</wfw:comment><comments>http://www.cppblog.com/skyscribe/archive/2012/02/29/move-to-octopress.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/skyscribe/comments/commentRss/166817.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/skyscribe/services/trackbacks/166817.html</trackback:ping><description><![CDATA[接触了octopress之后，才发现真的是神器；用vim写东西然后rake generate;rake deploy;的方式就是好啊。<br />
<br />
感兴趣的请移步:
<a target="_blank" href="http://skyscribe.github.com">http://skyscribe.github.com</a>
<img src ="http://www.cppblog.com/skyscribe/aggbug/166817.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/skyscribe/" target="_blank">skyscribe</a> 2012-02-29 22:52 <a href="http://www.cppblog.com/skyscribe/archive/2012/02/29/move-to-octopress.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ruby学习笔记《二》</title><link>http://www.cppblog.com/skyscribe/archive/2012/02/19/ruby-study-1.html</link><dc:creator>skyscribe</dc:creator><author>skyscribe</author><pubDate>Sun, 19 Feb 2012 11:29:00 GMT</pubDate><guid>http://www.cppblog.com/skyscribe/archive/2012/02/19/ruby-study-1.html</guid><wfw:comment>http://www.cppblog.com/skyscribe/comments/165993.html</wfw:comment><comments>http://www.cppblog.com/skyscribe/archive/2012/02/19/ruby-study-1.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/skyscribe/comments/commentRss/165993.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/skyscribe/services/trackbacks/165993.html</trackback:ping><description><![CDATA[ruby的blocks和closure特性明显有别于其它的语言，其closure本身是real closure，所绑定的context是共享的而非copy，其设计思路和lisp的相同；blocks本身则可以用于实现closure。二者的关系如下所述 （<a href="http://www.artima.com/intv/closures2.html">来源</a>）<br />
<blockquote><br />
<div><strong>Yukihiro Matsumoto</strong>: You can reconvert a closure back into a block, so a closure can be used anywhere a block can be used. Often, closures are used to store the status of a block into an instance variable, because once you convert a block into a closure, it is an object that can by referenced by a variable. And of course closures can be used like they are used in other languages, such as passing around the object to customize behavior of methods. If you want to pass some code to customize a method, you can of course just pass a block. But if you want to pass the same code to more than two methods -- this is a very rare case, but if you really want to do that -- you can convert the block into a closure, and pass that same closure object to multiple methods.<br />
</div>
</blockquote>
<div>
<ul>
     <li>
     <h2>7种结构</h2>
     </li>
</ul>
<blockquote>
<ul>
     <li>block方式3种</li>
</ul>
<blockquote>
<ul>
     <li>隐式传入，内部用yield调用</li>
</ul>
<blockquote>&nbsp;&nbsp;
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">def</span><span style="color: #000000; ">&nbsp;thrice<br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">yield</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">yield</span><span style="color: #000000; "><br />
&nbsp;&nbsp;</span><span style="color: #0000FF; ">yield</span><span style="color: #000000; "><br />
end<br />
<br />
x</span><span style="color: #000000; ">=</span><span style="color: #000000; ">1</span><span style="color: #000000; "><br />
thrice&nbsp;{x</span><span style="color: #000000; ">+=</span><span style="color: #000000; ">2</span><span style="color: #000000; ">}</span></div>
<span style="color: #000000; "></span></div>
</blockquote>
<ul>
     <li>&amp;block参数传入，内部直接操作&amp;block</li>
</ul>
<blockquote>
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">def</span><span style="color: #000000; ">&nbsp;six_times(</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">block)<br />
&nbsp;&nbsp;thrice(</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">block)<br />
&nbsp;&nbsp;thrice(</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">block)<br />
end<br />
&nbsp;<br />
x&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">4</span><span style="color: #000000; "><br />
six_times&nbsp;{&nbsp;x&nbsp;</span><span style="color: #000000; ">+=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">10</span><span style="color: #000000; ">&nbsp;}</span></div>
</blockquote>
<ul>
     <li>&amp;block传入，保存block为变量，然后调用block.call</li>
</ul>
<blockquote>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">def</span><span style="color: #000000; ">&nbsp;save_for_later(</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">b)<br />
&nbsp;&nbsp;@saved&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;b&nbsp;&nbsp;</span><span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;Note:&nbsp;no&nbsp;ampersand!&nbsp;This&nbsp;turns&nbsp;a&nbsp;block&nbsp;into&nbsp;a&nbsp;closure&nbsp;of&nbsp;sorts.</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">end<br />
&nbsp;<br />
save_for_later&nbsp;{&nbsp;puts&nbsp;</span><span style="color: #800000; ">"</span><span style="color: #800000; ">Hello!</span><span style="color: #800000; ">"</span><span style="color: #000000; ">&nbsp;}<br />
puts&nbsp;</span><span style="color: #800000; ">"</span><span style="color: #800000; ">Deferred&nbsp;execution&nbsp;of&nbsp;a&nbsp;block:</span><span style="color: #800000; ">"</span><span style="color: #000000;"><br />
@saved.call<br />
@saved.call<br />
</span></div>
</blockquote><blockquote>这里的saved保存为main对象的一个成员，后边实现延迟调用。<br />
</blockquote></blockquote>
<ul>
     <li>Proc.new/proc</li>
</ul>
<blockquote>
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000; ">@saved_proc_new&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;Proc.new&nbsp;{&nbsp;puts&nbsp;</span><span style="color: #800000; ">"</span><span style="color: #800000; ">I'm&nbsp;declared&nbsp;with&nbsp;Proc.new.</span><span style="color: #800000; ">"</span><span style="color: #000000; ">&nbsp;}<br />
@saved_proc&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;proc&nbsp;{&nbsp;puts&nbsp;</span><span style="color: #800000; ">"</span><span style="color: #800000; ">I'm&nbsp;declared&nbsp;with&nbsp;proc.</span><span style="color: #800000; ">"</span><span style="color: #000000; ">&nbsp;}<br />
<br />
@saved_proc_new.call<br />
@saved_proc.call</span></div>
</blockquote>
<ul>
     <li>lambda</li>
</ul>
<blockquote>
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000; ">@saved_lambda&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">lambda</span><span style="color: #000000; ">&nbsp;{&nbsp;puts&nbsp;</span><span style="color: #800000; ">"</span><span style="color: #800000; ">I'm&nbsp;declared&nbsp;with&nbsp;lambda.</span><span style="color: #800000; ">"</span><span style="color: #000000; ">&nbsp;}<br />
@saved_lambda.call</span></div>
</blockquote>
<ul>
     <li>method</li>
</ul>
<blockquote>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">def</span><span style="color: #000000; ">&nbsp;some_method<br />
&nbsp;&nbsp;puts&nbsp;</span><span style="color: #800000; ">"</span><span style="color: #800000; ">I'm&nbsp;declared&nbsp;as&nbsp;a&nbsp;method.</span><span style="color: #800000; ">"</span><span style="color: #000000; "><br />
end<br />
@method_as_closure&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000;">&nbsp;method(:some_method)<br />
<br />
</span></div>
</blockquote></blockquote>
<ul>
     <li>
     <h2>特点和差异</h2>
     </li>
     <ul>
         <li>
         <h2>return行为</h2>
         </li>
     </ul>
</ul>
<blockquote><blockquote>当对应的block里边包含return的时候，上述7中方式有些许的不同：<br />
<ul>
     <li>lambda/method表现出真正的closure行为，仅仅返回closure本身；外部调用控制流不受影响，继续yield或者call的下一语句执行</li>
     <li>其它几种会跳出外部调用者的控制流，即return出调用者，yield/call之后的也不会再执行，直接跳出到最近的end外</li>
</ul>
<p><br />
</p>
</blockquote>
<ul>
     <li>
     <h3>arity - 参数个数校验</h3>
     </li>
</ul>
<blockquote>对于调用点的参数检查，呈现如下行为：<br />
<ul>
     <li>lambda/method严格校验参数的个数，如果不匹配回抛出异常</li>
     <li>其它几个不检查参数个数</li>
</ul>
<p><br />
</p>
</blockquote></blockquote>
<ul>
     <li>
     <h2>总结</h2>
     </li>
</ul>
<blockquote>lambda/method方式呈现完备的closure行为，return之后继续下一流程，对于实际传入参数个数会在调用点检查；proc/blocks方式在return的时候直接返回了外部的函数或者block，对于传入的参数个数也没有执行检查。<br />
<br />
</blockquote>参考：<a href="http://innig.net/software/ruby/closures-in-ruby">http://innig.net/software/ruby/closures-in-ruby</a>
<br />以上结论验证于最新的ruby1.9.3，和链接中的结论有些许不同；ruby1.8中的proc函数可能有不同的行为。<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><span style="color: #000000;"></span></div>
</div><img src ="http://www.cppblog.com/skyscribe/aggbug/165993.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/skyscribe/" target="_blank">skyscribe</a> 2012-02-19 19:29 <a href="http://www.cppblog.com/skyscribe/archive/2012/02/19/ruby-study-1.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ruby学习笔记《一》</title><link>http://www.cppblog.com/skyscribe/archive/2012/02/19/ruby-study-0.html</link><dc:creator>skyscribe</dc:creator><author>skyscribe</author><pubDate>Sun, 19 Feb 2012 07:58:00 GMT</pubDate><guid>http://www.cppblog.com/skyscribe/archive/2012/02/19/ruby-study-0.html</guid><wfw:comment>http://www.cppblog.com/skyscribe/comments/165976.html</wfw:comment><comments>http://www.cppblog.com/skyscribe/archive/2012/02/19/ruby-study-0.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/skyscribe/comments/commentRss/165976.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/skyscribe/services/trackbacks/165976.html</trackback:ping><description><![CDATA[看得再多也不如自己动手试，最近有闲就打算认真研究一下ruby语言了。<a href="http://pragprog.com/the-pragmatic-programmer">Pragmatic programmer</a>中说，需要一年学一门新语言一遍改造思想，去年浅浅的学了javascript的皮毛，今年可以看看ruby这
个有lisp之风的OO语言了。<br />
<br />
<ul>
     <li>安装环境</li>
</ul>
第一个想到的是apt-get来下载了，得到的是一个交互式解析器和编译器。和python的比较类似，不过ruby的交互程序是个单独的程序叫做irb。<br />
<blockquote>
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000; ">skyscribe:</span><span style="color: #000000; ">~</span><span style="color: #000000; ">$&nbsp;ruby&nbsp;</span><span style="color: #000000; ">--</span><span style="color: #000000; ">version<br />
ruby&nbsp;</span><span style="color: #000000; ">1.8</span><span style="color: #000000; ">.</span><span style="color: #000000; ">7</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">2011</span><span style="color: #000000; ">-</span><span style="color: #000000; ">06</span><span style="color: #000000; ">-</span><span style="color: #000000; ">30</span><span style="color: #000000; ">&nbsp;patchlevel&nbsp;</span><span style="color: #000000; ">352</span><span style="color: #000000; ">)&nbsp;[i686</span><span style="color: #000000; ">-</span><span style="color: #000000; ">linux]<br />
skyscribe:</span><span style="color: #000000; ">~</span><span style="color: #000000; ">$&nbsp;irb<br />
irb(main):</span><span style="color: #000000; ">001</span><span style="color: #000000; ">:</span><span style="color: #000000; ">0</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;puts&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">hello</span><span style="color: #000000; ">"</span><span style="color: #000000; "><br />
hello<br />
</span><span style="color: #000000; ">=&gt;</span><span style="color: #000000;">&nbsp;nil<br />
<br />
</span></div>
</blockquote>可惜得到的不是比较新的版本。<br />
<br />
不
过很快想起翻翻<a href="http://en.wikipedia.org/wiki/Ruby_%28programming_language%29">
wiki</a>，还是用rvm方便的多。教程比较简单，参考它的<a href="http://beginrescueend.com/">quick installation guide</a>就可。第一次尝试的时候用apt-get安装了没有purge，导致总是安装到root用户造
成&#8220;permission denied"的问题。<br />
<br />
安装好之后，所有的东西都在$HOME/.rvm下边，比较干脆。<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;"><br />
</span><blockquote><span style="color: #000000; ">skyscribe:</span><span style="color: #000000; ">~</span><span style="color: #000000; ">$&nbsp;rvm&nbsp;install&nbsp;</span><span style="color: #000000; ">1.9</span><span style="color: #000000; ">.</span><span style="color: #000000; ">3</span><span style="color: #000000;"></span><br />
<span style="color: #000000; ">skyscribe:</span><span style="color: #000000; ">~</span><span style="color: #000000;">$&nbsp;rvm&nbsp;list</span><br />
<span style="color: #000000;"></span><br />
<span style="color: #000000;">rvm&nbsp;rubies</span><br />
<span style="color: #000000;"></span><br />
<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;ruby</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1.9</span><span style="color: #000000; ">.</span><span style="color: #000000; ">3</span><span style="color: #000000; ">-</span><span style="color: #000000;">p125&nbsp;[&nbsp;i686&nbsp;]</span><br />
<span style="color: #000000;"></span><br />
<span style="color: #000000; ">#&nbsp;Default&nbsp;ruby&nbsp;not&nbsp;</span><span style="color: #0000FF; ">set</span><span style="color: #000000; ">.&nbsp;Try&nbsp;</span><span style="color: #000000; ">'</span><span style="color: #000000; ">rvm&nbsp;alias&nbsp;create&nbsp;default&nbsp;&lt;ruby&gt;</span><span style="color: #000000; ">'</span><span style="color: #000000;">.</span><br />
<span style="color: #000000;"></span><br />
<span style="color: #000000; ">#&nbsp;</span><span style="color: #000000; ">=&gt;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000;">&nbsp;current</span><br />
<span style="color: #000000; ">#&nbsp;</span><span style="color: #000000; ">=*</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;current&nbsp;</span><span style="color: #000000; ">&amp;&amp;</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">default</span><span style="color: #000000;"></span><br />
<span style="color: #000000; ">#&nbsp;&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">default</span><span style="color: #000000;"></span><br />
<span style="color: #000000;"></span><br />
<span style="color: #000000; ">skyscribe:</span><span style="color: #000000; ">~</span><span style="color: #000000; ">$&nbsp;rvm&nbsp;alias&nbsp;create&nbsp;</span><span style="color: #0000FF; ">default</span><span style="color: #000000; ">&nbsp;ruby</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1.9</span><span style="color: #000000; ">.</span><span style="color: #000000; ">3</span><span style="color: #000000; ">-</span><span style="color: #000000;">p125</span><br />
<span style="color: #000000; ">Creating&nbsp;alias&nbsp;</span><span style="color: #0000FF; ">default</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;ruby</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1.9</span><span style="color: #000000; ">.</span><span style="color: #000000; ">3</span><span style="color: #000000; ">-</span><span style="color: #000000;">p125.</span><br />
<span style="color: #000000; ">Recording&nbsp;alias&nbsp;</span><span style="color: #0000FF; ">default</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">&nbsp;ruby</span><span style="color: #000000; ">-</span><span style="color: #000000; ">1.9</span><span style="color: #000000; ">.</span><span style="color: #000000; ">3</span><span style="color: #000000; ">-</span><span style="color: #000000;">p125.</span><br />
<span style="color: #000000; ">Creating&nbsp;</span><span style="color: #0000FF; ">default</span><span style="color: #000000; ">&nbsp;links</span><span style="color: #000000; ">/</span><span style="color: #000000;">files</span><br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; "></span><span style="color: #000000; "><div>skyscribe:~$ cat &gt;&gt; ~/.bashrc <br />[[ -s "$HOME/.rvm/scripts/rvm" ]] &amp;&amp; . "$HOME/.rvm/scripts/rvm" # This loads RVM into a shell session.<br />^C<br />skyscribe:~$ bash<br />skyscribe:~$ rvm use 1.9.3<br />Using /home/skyscribe/.rvm/gems/ruby-1.9.3-p125<br />skyscribe:~$ ruby -v<br />ruby 1.9.3p125 (2012-02-16 revision 34643) [i686-linux]</div></span></div><br />
<span style="color: #000000; "></span></blockquote></div>
<br />
<ul>
     <li>熟悉和上手</li>
</ul>
官方的文档是最好的参考，推荐<a href="http://rubykoans.com/">ruby koans</a>,下载下来，解压后，是个典型的TDD学习材料，不断运行<br />
<blockquote>
<div>
<div>&nbsp;ruby path_to_enlightenment.rb</div></div></blockquote><div><div>koans 会遍历每一个test case直到全部完毕，大概需要2个小时以上的时间方可全部完工。中间的注释和THINK ABOUT的部分比较有意思，感悟比较深刻的是以下一些点：<br /><blockquote><ul><li>完完全全的OO，所有东西皆为对象</li><li>两种基本的collection，hash和array基本对应于python的dict和array</li><li>函数调用可以不必添加括号，除非可能引发歧义或者解析错误</li><li>函数参数可以包含block，支持lambda和closure<br /></li><li>bool类型更简单，只有false和nil与false等价，其余全部是true</li><li>控制结构有unless</li><li>类定义是开放式的，便于非侵入式设计，当然也可以允许修改builtin</li><li>每一个对象都有object id</li><li>symbol和string可以互相转化构造</li><li>method的调用可以用send 的方法发送message - proxy变得极度容易</li><li>module可以被class include从而包含方法， 便于mixin设计</li><li>instance variable和class variable 定义方便快捷</li><li>regular expresion的和python极为相似<br /></li></ul></blockquote></div></div><blockquote><div>
</div>
</blockquote><img src ="http://www.cppblog.com/skyscribe/aggbug/165976.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/skyscribe/" target="_blank">skyscribe</a> 2012-02-19 15:58 <a href="http://www.cppblog.com/skyscribe/archive/2012/02/19/ruby-study-0.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Unix文本处理之利器－awk/gawk</title><link>http://www.cppblog.com/skyscribe/archive/2011/01/02/awk.html</link><dc:creator>skyscribe</dc:creator><author>skyscribe</author><pubDate>Sun, 02 Jan 2011 12:32:00 GMT</pubDate><guid>http://www.cppblog.com/skyscribe/archive/2011/01/02/awk.html</guid><wfw:comment>http://www.cppblog.com/skyscribe/comments/137894.html</wfw:comment><comments>http://www.cppblog.com/skyscribe/archive/2011/01/02/awk.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/skyscribe/comments/commentRss/137894.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/skyscribe/services/trackbacks/137894.html</trackback:ping><description><![CDATA[日常在shell中使用awk基本是家常便饭了，但是详细的写一些小程序还是第一次，总体是下来，还是深深得被这门年龄比自己都要大的工具语言的魅力所折服（<a  href="http://groups.engin.umd.umich.edu/CIS/course.des/cis400/awk/awk.html#history">since 1977</a>）。作者中最引人注目的当属鼎鼎大名的<a  href="https://secure.wikimedia.org/wikipedia/en/wiki/Brian_Kernighan">Brian W. Kernighan</a> (即K的简称来源）。目前所用的版本大多是gawk或者nawk.<br><br>作为一门微型且完整的编程语言，awk可以用数行代码就完成其他语言需要数倍的LOC才能完成的工作。其设计哲学也是比较特殊的，核心是data－driven的，并且采用了和C类似的语法来组织。它最核心的思想应该是如下两点：<br>
<ul>
    <li>pattern-action 结构 借由强大的正则表达式来匹配pattern，然后执行pattern对应的操作</li>
    <li>Record/Field 处理模型&nbsp; 所有的输入数据都根据制定的record separator 分割成 record, 然后没一个record再根据field separator 分割为fields. POSIX 定义的 field separator可以为正则表达式，而gawk可以允许record separator同时为正则表达式</li>
</ul>
引发我花点时间来仔细研究awk的起因是这样的，我们的程序在做profiling的时候，发现原来用shell写的脚本分析一次话费的时间太长。初看了下那个脚本，大概的逻辑是要扫名所有的log文件，按照时间戳将关注的时间所耗费的时间提取出来，计算平均值，波动等最终画出曲线图。<br><br>整体的脚本有几个部分（python＋bash），处理一次40MB的log文件需要耗费40分钟～1个小时，这显然超出了预期；中间一个处理很长的部分是grep某个时间段的信息然后按照报表格式写入到中间文件中。在想能否优化这一节的时候，忽然就想起了模式匹配来（学习Haskell的最深印象），于是大致翻了一下awk，发现很容易通过模式匹配使得按行处理，同时记录中间的信息，而一个时间段恰好和awk的record概念吻合。<br><br>花了2个小时研读了下awk的函数语法，自定义自己的时间截取函数（gawk的strftime很有用，尤其我们发现记录有跳跃要自动补全中间的数据记录时），通过三个pattern截取需要的信息，30分钟写出来awk的代码来。<br><br>所幸的是，其它的shell脚本都不需要任何改动，重新跑一次，3s就处理完了原来40MB的文件，看来这点时间投入还是相当值得的。<br><br>有兴趣的可参考：<br>&nbsp;&nbsp;&nbsp;&nbsp; <a  href="http://www.gnu.org/manual/gawk/gawk.html">http://www.gnu.org/manual/gawk/gawk.html</a><br><br>PS：awk的另一作者<a  href="https://secure.wikimedia.org/wikipedia/en/wiki/Peter_J._Weinberger">Winberger</a> 供职于google。<br>&nbsp;<br><br><img src ="http://www.cppblog.com/skyscribe/aggbug/137894.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/skyscribe/" target="_blank">skyscribe</a> 2011-01-02 20:32 <a href="http://www.cppblog.com/skyscribe/archive/2011/01/02/awk.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GCC4.5的profile mode</title><link>http://www.cppblog.com/skyscribe/archive/2010/05/09/GCC4_5ProfileMode.html</link><dc:creator>skyscribe</dc:creator><author>skyscribe</author><pubDate>Sun, 09 May 2010 07:16:00 GMT</pubDate><guid>http://www.cppblog.com/skyscribe/archive/2010/05/09/GCC4_5ProfileMode.html</guid><wfw:comment>http://www.cppblog.com/skyscribe/comments/114920.html</wfw:comment><comments>http://www.cppblog.com/skyscribe/archive/2010/05/09/GCC4_5ProfileMode.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/skyscribe/comments/commentRss/114920.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/skyscribe/services/trackbacks/114920.html</trackback:ping><description><![CDATA[GCC最近发布了4.5版本，对于C++的支持除了更为丰富的0x特性支持外（参考<a href="http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.200x">这里</a>），<br>还增加了一个新的profile模式（尚处于试验阶段），可以根据程序运行状态给出关于STL使用的一些优化建议。<br><br>参看如下的描述：<br>
<div style="margin-left: 40px;">
<ul>
    <li>
    <p>An experimental <a href="http://gcc.gnu.org/onlinedocs/libstdc++/manual/profile_mode.html">
    profile mode </a> has been added. This is an implementation of
    many C++ standard library constructs with an additional analysis
    layer that gives performance improvement advice based on
    recognition of suboptimal usage patterns. For example,
    </p>
    <pre>#include &lt;vector&gt;<br>int main() <br>{<br>  std::vector&lt;int&gt; v;<br>  for (int k = 0; k &lt; 1024; ++k) <br>    v.insert(v.begin(), k);<br>}<br></pre>
    <p>
    When instrumented via the profile mode, can return suggestions about
    the initial size and choice of the container used as follows:
    </p>
    <pre>vector-to-list: improvement = 5: call stack = 0x804842c ...<br>    : advice = change std::vector to std::list<br>vector-size: improvement = 3: call stack = 0x804842c ...<br>    : advice = change initial container size from 0 to 1024<br></pre>
    <p>
    These constructs can be substituted for the normal libstdc++
    constructs on a piecemeal basis, or all existing components can be
    transformed via the <code>-D_GLIBCXX_PROFILE</code> macro.
    </p>
    </li>
</ul>
</div>
这个profile mode的主要作用就是根据代码实际运行状况给出关于STL的使用优化建议。有点遗憾的是，该profile方法是intrusive的，必须添加-D_GLBCXX_PROFILE来重新编译所有的代码。<br><br>Profile mode的提出源于09年CGO的一篇<a href="http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?reload=true&amp;arnumber=4907670">paper</a>，作者里边出现了华人的名字（根据拼音来判断）;作者地址填的显然是Purdue大学的：<br>&nbsp;&nbsp;&nbsp; Dept. of Comput. Sci., Purdue Univ., West。<br><br>GCC的Profiler对C++的支持一贯停留在和C同样的水平；由于C++模板机制和OO的存在使得很多时候分析profiling结果的意义被大大削弱。<br>这个针对STL的profile mode还是很值得期待的。<br><br><br>  <img src ="http://www.cppblog.com/skyscribe/aggbug/114920.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/skyscribe/" target="_blank">skyscribe</a> 2010-05-09 15:16 <a href="http://www.cppblog.com/skyscribe/archive/2010/05/09/GCC4_5ProfileMode.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>boost.cmake: 方便解决boost的升级问题</title><link>http://www.cppblog.com/skyscribe/archive/2010/05/09/114919.html</link><dc:creator>skyscribe</dc:creator><author>skyscribe</author><pubDate>Sun, 09 May 2010 06:59:00 GMT</pubDate><guid>http://www.cppblog.com/skyscribe/archive/2010/05/09/114919.html</guid><wfw:comment>http://www.cppblog.com/skyscribe/comments/114919.html</wfw:comment><comments>http://www.cppblog.com/skyscribe/archive/2010/05/09/114919.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/skyscribe/comments/commentRss/114919.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/skyscribe/services/trackbacks/114919.html</trackback:ping><description><![CDATA[以前常用boost的一些库，由于项目自身用cmake组织build。<br>boost每次升级之后，重新用bjam编译一次都很是不便（某些平台，用默认选项编译有些问题，基本安装不成功）。<br><br>最近才发现boost的cmake版本已经独立出来了，对于使用cmake的用户而言，这里是个不错的选择。<br>项目<a  href="http://sodium.resophonic.com/boost-cmake/current-docs/">主页</a>的文档很是清晰，最新的版本是1.41 (版本号对应的基本就是其upstream的boost版本号)。<br>源代码是用git组织的，对于Linux用户而言更加方便。<br><br>引用其主页上的一句话：<br>
<div style="margin-left: 40px;">Boost.<a class="reference external" href="http://www.cmake.org/">CMake</a>
(or <a class="reference internal" href="http://sodium.resophonic.com/boost-cmake/current-docs/#alt-boost"><em> alt.boost</em> </a>)
is the boost distribution that all the cool kids are
using.
</div>
<br>CMake + <a  href="http://gitorious.org/boost/cmake.git">GIT</a> +<a  href="http://sphinx.pocoo.org/">Spinx</a> 确实够酷了。<br><br><span style="font-family: 微软雅黑;">编译起来可以充分利用强大的CMake了：</span><br>
<div style="margin-left: 40px;">
<pre>git clone git://gitorious.org/boost/cmake.git src<br>cd src<br>git checkout &lt;TAG&gt; &nbsp; &nbsp;//TAG==1.41.0.cmake0<br>mkdir bld<br>cd bld/<br>cmake ../<br></pre>
</div>
<pre>如果需要按需编译某些库，只需用make edit_cache修改cache即可。<br></pre>
<div style="margin-left: 40px;">
</div><img src ="http://www.cppblog.com/skyscribe/aggbug/114919.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/skyscribe/" target="_blank">skyscribe</a> 2010-05-09 14:59 <a href="http://www.cppblog.com/skyscribe/archive/2010/05/09/114919.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VIM下实现对C++ STL的IntelliSense</title><link>http://www.cppblog.com/skyscribe/archive/2010/01/10/105346.html</link><dc:creator>skyscribe</dc:creator><author>skyscribe</author><pubDate>Sun, 10 Jan 2010 10:28:00 GMT</pubDate><guid>http://www.cppblog.com/skyscribe/archive/2010/01/10/105346.html</guid><wfw:comment>http://www.cppblog.com/skyscribe/comments/105346.html</wfw:comment><comments>http://www.cppblog.com/skyscribe/archive/2010/01/10/105346.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/skyscribe/comments/commentRss/105346.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/skyscribe/services/trackbacks/105346.html</trackback:ping><description><![CDATA[<p>以前尝试过在vim下配置STL的Intellisense曾经没有成功；最近有空刚好仔细看了下vim的一些相对高级的manual，</p> <p>总算将<a href="http://www.vim.org/scripts/script.php?script_id=1520">OmniCppComplete</a>主页上的效果给弄了出来（<a href="http://vissale.neang.free.fr/Vim/OmniCppComplete/ScreenShots/screenshots.htm">这里</a>）。</p> <p>根据其help提示一步一步来(装完了omnicppcomplete之后，可以:help omnicppcomplete)：</p> <ul> <li> <h1>首先需要有ctags，并且必须是<a href="http://ctags.sourceforge.net/">Exuberant ctags</a>，我的Ubuntu上已经是最新版了：</h1></li><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">skyscribe@skyscribe:~/study/vim/pics$ ctags --version
</pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
</pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">  Compiled: Aug  6 2009, 17:06:22
</pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">  Addresses: &lt;dhiebert@users.sourceforge.net&gt;, http:<span style="color: #008000">//ctags.sourceforge.net</span>
</pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">  Optional compiled features: +wildcards, +regex
</pre></pre></pre></pre></pre></pre>
<li>
<h1>在 ~/.vimrc 里边加入autoload taglist功能，为了方便自动更新当前tags，设置一个快捷键（<a href="http://design.liberta.co.za/articles/code-completion-intellisense-for-cpp-in-vim-with-omnicppcomplete/">这里</a>）：</h1></li></ul>
<blockquote><pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">map &lt;C-F12&gt; :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .&lt;CR&gt;
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">source ~/.vim/my.vim
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"></pre></pre>
<p>&nbsp;</p>
<p>这里的自动加载已有vim的功能，就用一个vim脚步来实现 (参考 vim :help glob给的例子)：</p><pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">cat ~/.vim/my.vim 
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">let tagfiles = glob("<span style="color: #8b0000">`find ~/.vim/tagfiles -name tags -print`</span>")
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">let &amp;tags = substitute(tagfiles, "<span style="color: #8b0000">\n</span>", "<span style="color: #8b0000">,</span>", "<span style="color: #8b0000">g</span>")
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"></pre></pre>
<p>&nbsp;</p>
<p>以后需要新的taglist，只需要放在~/.vim/tagfiles目录下就好了。</p>
<p>vim启动的时候，会自动执行~/.vimrc，从而调用my.vim，将事先准备好的taglist更新进去；这里一般放一些不太变化的静态头文件tag就可以了。</p></blockquote>
<ul>
<p></p>
<li>
<h1>要有STL的intelliSense，自然要有STL C++的tags database了，这里需要生成之。</h1></li></ul>
<blockquote>
<p>根据上一步的惯例，需要生成一个tags文件，放在~/.vim/tagfiles/的某个子目录下：</p><pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 650px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">mkdir -p ~/.vim/tagfiles/gcc&lt;ver&gt;/
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">ls –l /usr/include/c++/</pre></pre>
<p>&nbsp;</p>
<p>这里需要将ver换成当前系统的libstdc++版本，Ubuntu 9.10上的是4.4.1.</p></blockquote>
<ul>
<p></p>
<li>
<h1>用上边的命令生成对应的tags文件：</h1></li></ul>
<blockquote><pre class="csharpcode">ctags -R --c++-kinds=+p --fields=+iaS --extra=+q . -o ~/.vim/tagfiles/gcc4.4/tags /usr/include/c++/4.4</pre>
<p>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</p>
<p>写一个简单的c++程序，在Insert Mode下，Ctrl+X， Ctrl+P，发现并不能工作，什么提示也没有；初步怀疑是对应的tag文件不对。</p>
<p>幸好早有人尝试过了，给出了一种办法(<a href="http://design.liberta.co.za/articles/code-completion-intellisense-for-cpp-in-vim-with-omnicppcomplete/">还是这里</a>），可惜他的方法我试了不行，不过已经可以借用他的思路了：</p></blockquote>
<ul>
<ul>
<li>将/usr/include/c++/4.4.1/的内容全部拷贝到一个目录下：</li><pre class="csharpcode">mkdir gcc4.4
cp -R /usr/include/c++/4.4 ./</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<li>写一个脚步替换所有的NAMESPACE宏定义(这里用sed完成宏替换，为了避免过于晦涩，还是放在一个临时的脚步文件里边来，便于调试吧)：</li></ul></ul>
<blockquote><pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 800px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">cat generate_sed.sh 
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">#!/bin/bash
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"><span style="color: #0000ff">if</span> [ $# -eq 0 ];then
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">    dir=.
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"><span style="color: #0000ff">else</span>
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">    dir=$1
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">fi
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">#Substitute scripts
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">cat &gt; .edit.sed &lt;&lt;- EOF
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">s/\b_GLIBCXX_BEGIN_NAMESPACE\b\s*\(\s*(\w+)\s*\)/namespace \1{/g
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">s/_GLIBCXX_BEGIN_NESTED_NAMESPACE\s*\(\s*std\s*,\s*_GLIBCXX_STD_[DP]\s*\)/namespace std{/g
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">s/\b_GLIBCXX_END_NAMESPACE\b/}/g
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">s/\b_GLIBCXX_END_(NESTED_\?NAMESPACE\b/}/g
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">EOF
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"><span style="color: #0000ff">count</span>=0
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">cols=`tput cols`
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">cols=`echo "<span style="color: #8b0000">$cols - 8</span>"|bc`
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">for file in `<span style="color: #0000ff">find</span> $dir -type f`;do
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">    <span style="color: #0000ff">if</span> [ "<span style="color: #8b0000">T</span>"$file != "<span style="color: #8b0000">T</span>"$0 ];then
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">        sed -nf "<span style="color: #8b0000">.edit.sed</span>" $file
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">        <span style="color: #0000ff">count</span>=`echo "<span style="color: #8b0000">$count+1</span>"|bc`
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">        echo -ne "<span style="color: #8b0000">=</span>"
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">        <span style="color: #0000ff">if</span> [ `echo "<span style="color: #8b0000">$count%$cols</span>"|bc` -eq 0 ];then
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">            echo "<span style="color: #8b0000"> $count</span>"
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">        fi
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">    fi
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">done
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">echo "<span style="color: #8b0000">Processed $count files!</span>"
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">rm -fr .edit.sed
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"># Generate ctag file
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">ctags -R --c++-kinds=+p --fields=+iaS --extra=+q 
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">echo "<span style="color: #8b0000">generated tag file!</span>"
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"></pre></pre></blockquote>
<h6></h6>
<ul>
<ul>
<li>再生成tag：</li></ul></ul>
<blockquote><pre style="border-right: #cecece 1px solid; padding-right: 5px; border-top: #cecece 1px solid; padding-left: 5px; min-height: 40px; padding-bottom: 5px; overflow: auto; border-left: #cecece 1px solid; width: 800px; padding-top: 5px; border-bottom: #cecece 1px solid; background-color: #fbfbfb"><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">skyscribe@skyscribe:~/libstdc++/gcc4.4$ ./generate_sed.sh . 
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">==================================================================================================== 100
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">==================================================================================================== 200
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">==================================================================================================== 300
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">==================================================================================================== 400
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">==================================================================================================== 500
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">==================================================================================================== 600
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">===============================================================Processed 663 files!
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">generated tag file!
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb">ls tags -lh
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"><p>-rw-r--r-- 1 skyscribe skyscribe 4.2M 2010-01-10 18:21 tags</p><p>cp tags ~/.vim/tagfiles/gcc4.4/</p></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #fbfbfb"></pre></pre></blockquote>
<p>&nbsp;</p>
<p></p>
<ul>
<li>
<h1>到这里效果终于出来了：</h1></li></ul>
<blockquote>
<p>上边的review窗口显示当前调用的函数信息,输入./-&gt;/:: 的时候会自动提示，也可以用CTRL+X CTRL+O 来调出提示窗口，方向键则可以选择。</p></blockquote>
<blockquote>
<p><a href="http://www.cppblog.com/images/cppblog_com/skyscribe/WindowsLiveWriter/VIMCSTLIntelliSense_F87E/omni_comp_2.png"><img title="omni_comp" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="568" alt="omni_comp" src="http://www.cppblog.com/images/cppblog_com/skyscribe/WindowsLiveWriter/VIMCSTLIntelliSense_F87E/omni_comp_thumb.png" width="839" border="0"></a> </p>
<p><a href="http://www.cppblog.com/images/cppblog_com/skyscribe/WindowsLiveWriter/VIMCSTLIntelliSense_F87E/vec_insert_2.png"><img title="vec_insert" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="572" alt="vec_insert" src="http://www.cppblog.com/images/cppblog_com/skyscribe/WindowsLiveWriter/VIMCSTLIntelliSense_F87E/vec_insert_thumb.png" width="845" border="0"></a> </p>
<p><a href="http://www.cppblog.com/images/cppblog_com/skyscribe/WindowsLiveWriter/VIMCSTLIntelliSense_F87E/vec_insert_sel_2.png"><img title="vec_insert_sel" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="571" alt="vec_insert_sel" src="http://www.cppblog.com/images/cppblog_com/skyscribe/WindowsLiveWriter/VIMCSTLIntelliSense_F87E/vec_insert_sel_thumb.png" width="843" border="0"></a> </p></blockquote>
<p>&nbsp;</p>
<p>&nbsp;</p><pre>&nbsp;</pre><pre>&nbsp;</pre><pre>&nbsp;</pre><pre>&nbsp;</pre><pre>&nbsp;</pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre></pre><img src ="http://www.cppblog.com/skyscribe/aggbug/105346.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/skyscribe/" target="_blank">skyscribe</a> 2010-01-10 18:28 <a href="http://www.cppblog.com/skyscribe/archive/2010/01/10/105346.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>cmake的一些小经验</title><link>http://www.cppblog.com/skyscribe/archive/2009/12/14/103208.html</link><dc:creator>skyscribe</dc:creator><author>skyscribe</author><pubDate>Mon, 14 Dec 2009 12:39:00 GMT</pubDate><guid>http://www.cppblog.com/skyscribe/archive/2009/12/14/103208.html</guid><wfw:comment>http://www.cppblog.com/skyscribe/comments/103208.html</wfw:comment><comments>http://www.cppblog.com/skyscribe/archive/2009/12/14/103208.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/skyscribe/comments/commentRss/103208.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/skyscribe/services/trackbacks/103208.html</trackback:ping><description><![CDATA[<p><font face="微软雅黑" size="4">初用CMake或者对其了解不太深的人，可能经常会被路径包含、库搜索路径、链接路径、RPath这些问题所绊倒，因为这些东西在手工执行gcc或者编写makefile的时候是很轻而易举的任务。</font></p> <p><font face="微软雅黑" size="4">其实我当初也有不少疑惑，不过通过较长时间的实践和阅读manual，总算有了个相对很清晰的认识。</font></p> <ul> <li><strong><font face="微软雅黑" size="4">如何使用其manual</font></strong></li></ul> <blockquote> <p><font size="4">cmake的帮助组织的还是很有规律的，了解了其规律，找自己想要的东西就会很简单，所以个人觉得这一点可能是最重要的。其help系统大概是这么几类：</font></p></blockquote> <ul> <ul> <li><font face="微软雅黑" size="4"><strong>command</strong></font></li></ul></ul> <blockquote> <p><font size="4">这个是实用过程中最长用到的，相当于一般脚步语言中的基本语法，包括定义变量，foreach，string，if，builtin command都在这里。</font></p> <p><font size="4">可以用如下这些命令获取帮助：</font></p><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">cmake --help-commands
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"><p>这个命令将给出所有cmake内置的命令的详细帮助，一般不知道自己要找什么或者想随机翻翻得时候，可以用这个。</p><p>我一般更常用的方法是将其重定向到less里边，然后在编辑器里边搜索关键字。</p><p>&nbsp;</p><p>另外也可以用如下的办法层层缩小搜索范围：</p></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">cmake --help-command-list
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"><p>cmake --help-command-list | grep find</p><p>skyscribe@skyscribe:~/program/ltesim/bld$ cmake --help-command-list | grep find<br>find_file<br>find_library<br>find_package<br>find_path<br>find_program</p></pre></pre></blockquote>
<blockquote><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"><p>cmake --help-command find_library</p><p>cmake version 2.6-patch 4<br>------------------------------------------------------------------------------<br>SingleItem <p>&nbsp; find_library<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Find a library. <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; find_library(&lt;VAR&gt; name1 [path1 path2 ...]) <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This is the short-hand signature for the command that is sufficient in<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; many cases.&nbsp; It is the same as find_library(&lt;VAR&gt; name1 [PATHS path1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; path2 ...]) <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; find_library(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;VAR&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name | NAMES name1 [name2 ...]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [HINTS path1 [path2 ... ENV var]]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [PATHS path1 [path2 ... ENV var]]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [PATH_SUFFIXES suffix1 [suffix2 ...]]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [DOC "cache documentation string"]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [NO_DEFAULT_PATH]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [NO_CMAKE_ENVIRONMENT_PATH]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [NO_CMAKE_PATH]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [NO_SYSTEM_ENVIRONMENT_PATH]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [NO_CMAKE_SYSTEM_PATH]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [CMAKE_FIND_ROOT_PATH_BOTH |<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ONLY_CMAKE_FIND_ROOT_PATH |<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NO_CMAKE_FIND_ROOT_PATH]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )</p></pre></pre></blockquote>
<ul>
<ul>
<li><font size="4"><strong>variable</strong></font></li></ul></ul>
<blockquote>
<p><font size="4">和command的帮助比较类似，只不过这里可以查找cmake自己定义了那些变量你可以直接使用，譬如OSName，是否是Windows，Unix等。</font></p>
<p><font size="4">我最常用的一个例子：</font></p><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">cmake --help-variable-list  | grep CMAKE | grep HOST
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">CMAKE_HOST_APPLE
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">CMAKE_HOST_SYSTEM
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">CMAKE_HOST_SYSTEM_NAME
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">CMAKE_HOST_SYSTEM_PROCESSOR
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">CMAKE_HOST_SYSTEM_VERSION
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">CMAKE_HOST_UNIX
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">CMAKE_HOST_WIN32
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"><p>这里查找所有CMake自己定义的builtin变量；一般和系统平台相关。</p></pre></pre></blockquote>
<blockquote>
<p>如果希望将所有生成的可执行文件、库放在同一的目录下，可以如此做：</p>
<p>这里的target_dir是一个实现设置好的绝对路径。（CMake里边绝对路径比相对路径更少出问题，如果可能尽量用绝对路径）</p><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"># Targets directory
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${target_dir}/lib)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${target_dir}/lib)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${target_dir}/bin)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre></pre></blockquote>
<ul>
<ul>
<li><font size="4"><strong>property</strong></font></li></ul></ul>
<blockquote>
<p><font size="4">Property一般很少需要直接改动，除非你想修改一些默认的行为，譬如修改生成的动态库文件的soname等。</font></p>
<p><font size="4">譬如需要在同一个目录下既生成动态库，也生成静态库，那么默认的情况下，cmake根据你提供的target名字自动生成类似的libtarget.so, libtarget.a，但是同一个project只能同时有一个，因为target必须唯一。</font></p>
<p><font size="4">这时候，就可以通过修改taget对应的文件名，从而达到既生成动态库也产生静态库的目的。</font></p>
<p><font size="4">譬如：</font></p><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">cmake --help-property-list | grep NAME
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">GENERATOR_FILE_NAME
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">IMPORTED_SONAME
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">IMPORTED_SONAME_&lt;CONFIG&gt;
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">INSTALL_NAME_DIR
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">OUTPUT_NAME
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">VS_SCC_PROJECTNAME
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">skyscribe@skyscribe:~$ cmake --help-property OUTPUT_NAME
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">cmake version 2.6-patch 4
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">------------------------------------------------------------------------------
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">SingleItem
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">  OUTPUT_NAME
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       Sets the real name of a target when it is built.
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       Sets the real name of a target when it is built and can be used to
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       help create two targets of the same name even though CMake requires
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       unique logical target names.  There is also a &lt;CONFIG&gt;_OUTPUT_NAME
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       that can set the output name on a per-configuration basis.
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre></pre></blockquote>
<ul>
<ul>
<li><font size="4"><strong>module</strong></font></li></ul></ul>
<blockquote>
<p><font size="4">用于查找常用的模块，譬如boost，bzip2, python等。通过简单的include命令包含预定义的模块，就可以得到一些模块执行后定义好的变量，非常方便。</font></p>
<p><font size="4">譬如常用的boost库，可以通过如下方式：</font></p><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"># Find boost 1.40
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">INCLUDE(FindBoost)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">find_package(Boost 1.40.0 COMPONENTS thread unit_test_framework)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"><span style="color: #0000ff">if</span>(NOT Boost_FOUND)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">    message(STATUS "<span style="color: #8b0000">BOOST not found, test will not succeed!</span>")
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">endif()
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">一般开头部分的解释都相当有用，可满足80%需求：
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">cmake --help-module FindBoost | head -40
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">cmake version 2.6-patch 4
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">------------------------------------------------------------------------------
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">SingleItem
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">  FindBoost
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       Try to find Boost include dirs and libraries
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       Usage of this module as follows:
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       == Using Header-Only libraries from within Boost: ==
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">          find_package( Boost 1.36.0 )
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">          <span style="color: #0000ff">if</span>(Boost_FOUND)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">             include_directories(${Boost_INCLUDE_DIRS})
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">             add_executable(foo foo.cc)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">          endif()
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       == Using actual libraries from within Boost: ==
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">          set(Boost_USE_STATIC_LIBS   ON)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">          set(Boost_USE_MULTITHREADED ON)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">          find_package( Boost 1.36.0 COMPONENTS date_time filesystem <span style="color: #0000ff">system</span> ... )
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">          <span style="color: #0000ff">if</span>(Boost_FOUND)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">             include_directories(${Boost_INCLUDE_DIRS})
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">             add_executable(foo foo.cc)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">             target_link_libraries(foo ${Boost_LIBRARIES})
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">          endif()
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       The components list needs to contain actual names of boost libraries
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre></pre></blockquote>
<ul>
<li><strong>如何根据其生成的中间文件查看一些关键信息</strong></li></ul>
<blockquote>
<p>CMake相比较于autotools的一个优势就在于其生成的中间文件组织的很有序，并且清晰易懂，不像autotools会生成天书一样的庞然大物（10000+的不鲜见）。</p>
<p>一般CMake对应的Makefile都是有层级结构的，并且会根据你的CMakeLists.txt间的相对结构在binary directory里边生成相应的目录结构。</p>
<p>譬如对于某一个target，一般binary tree下可以找到一个文件夹:&nbsp; CMakeFiles/&lt;targentName&gt;.dir/,比如：</p><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">skyscribe@skyscribe:~/program/ltesim/bld/dev/simcluster/CMakeFiles/SIMCLUSTER.dir$ ls -l
</pre></pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">total 84
</pre></pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">-rw-r--r-- 1 skyscribe skyscribe 52533 2009-12-12 12:20 build.make
</pre></pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">-rw-r--r-- 1 skyscribe skyscribe  1190 2009-12-12 12:20 cmake_clean.cmake
</pre></pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">-rw-r--r-- 1 skyscribe skyscribe  4519 2009-12-12 12:20 DependInfo.cmake
</pre></pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">-rw-r--r-- 1 skyscribe skyscribe    94 2009-12-12 12:20 depend.make
</pre></pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">-rw-r--r-- 1 skyscribe skyscribe   573 2009-12-12 12:20 flags.make
</pre></pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">-rw-r--r-- 1 skyscribe skyscribe  1310 2009-12-12 12:20 link.txt
</pre></pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">-rw-r--r-- 1 skyscribe skyscribe   406 2009-12-12 12:20 progress.make
</pre></pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">drwxr-xr-x 2 skyscribe skyscribe  4096 2009-12-12 12:20 src
</pre></pre><pre>这里，每一个文件都是个很短小的文本文件，内容相当清晰明了。build.make一般包含中间生成文件的依赖规则，DependInfo.cmake一般包含源代码文件自身的依赖规则。</pre><pre>比较重要的是flags.make和link.txt，前者一般包含了类似于GCC的-I的相关信息，如搜索路径，宏定义等；后者则包含了最终生成target时候的linkage信息，库搜索路径等。</pre><pre>这些信息在出现问题的时候是个很好的辅助调试手段。</pre><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre></pre></blockquote>
<ul>
<li><strong>文件查找、路径相关</strong></li>
<ul>
<li><strong>include</strong></li></ul></ul>
<blockquote>
<p>一般常用的是：</p><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">include_directories（）用于添加头文件的包含搜索路径
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">cmake --help-command include_directories
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">cmake version 2.6-patch 4
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">------------------------------------------------------------------------------
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">SingleItem
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">  include_directories
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       Add include directories to the build.
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">         include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       Add the given directories to those searched by the compiler <span style="color: #0000ff">for</span>
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       include files.  By <span style="color: #0000ff">default</span> the directories are appended onto the
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       current list of directories.  This <span style="color: #0000ff">default</span> behavior can be changed by
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       setting CMAKE_include_directories_BEFORE to ON.  By using BEFORE or
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       AFTER you can select between appending and prepending, independent
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       from the <span style="color: #0000ff">default</span>.  If the SYSTEM option is given the compiler will be
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       told that the directories are meant as <span style="color: #0000ff">system</span> include directories on
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       some platforms.
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">link_directories()用于添加查找库文件的搜索路径
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">cmake --help-command link_directories
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">cmake version 2.6-patch 4
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">------------------------------------------------------------------------------
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">SingleItem
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">  link_directories
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       Specify directories in which the linker will look <span style="color: #0000ff">for</span> libraries.
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">         link_directories(directory1 directory2 ...)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       Specify the paths in which the linker should search <span style="color: #0000ff">for</span> libraries.
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       The command will apply only to targets created after it is called.
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       For historical reasons, relative paths given to this command are
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       passed to the linker unchanged (unlike many CMake commands which
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">       interpret them relative to the current source directory).
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre></pre></blockquote>
<ul>
<ul>
<li><strong>library search</strong></li></ul></ul>
<blockquote>
<p>一般外部库的link方式可以通过两种方法来做，一种是显示添加路径，采用link_directories()， 一种是通过find_library()去查找对应的库的绝对路径。</p>
<p>后一种方法是更好的，因为它可以减少不少潜在的冲突。</p></blockquote>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一般find_library会根据一些默认规则来搜索文件，如果找到，将会set传入的第一个变量参数、否则，对应的参数不被定义，并且有一个xxx-NOTFOUND被定义；可以通过这种方式来调试库搜索是否成功。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于库文件的名字而言，动态库搜索的时候会自动搜索libxxx.so (xxx.dll),静态库则是libxxx.a（xxx.lib），对于动态库和静态库混用的情况，可能会出现一些混乱，需要格外小心；一般尽量做匹配连接。</p>
<ul>
<ul>
<li><strong>rpath</strong></li></ul></ul>
<blockquote>
<p>所谓的rpath是和动态库的加载运行相关的。我一般采用如下的方式取代默认添加的rpath：</p><pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"># RPATH and library search setting
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">SET(CMAKE_INSTALL_RPATH "<span style="color: #8b0000">${CMAKE_INSTALL_PREFIX}/nesim/lib</span>")
</pre><pre style="font-size: 15px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) </pre></pre>
<p>&nbsp;</p></blockquote>
<p><font size="4"></font></p><img src ="http://www.cppblog.com/skyscribe/aggbug/103208.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/skyscribe/" target="_blank">skyscribe</a> 2009-12-14 20:39 <a href="http://www.cppblog.com/skyscribe/archive/2009/12/14/103208.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pipeline会启动多少个进程？</title><link>http://www.cppblog.com/skyscribe/archive/2009/12/14/103205.html</link><dc:creator>skyscribe</dc:creator><author>skyscribe</author><pubDate>Mon, 14 Dec 2009 11:46:00 GMT</pubDate><guid>http://www.cppblog.com/skyscribe/archive/2009/12/14/103205.html</guid><wfw:comment>http://www.cppblog.com/skyscribe/comments/103205.html</wfw:comment><comments>http://www.cppblog.com/skyscribe/archive/2009/12/14/103205.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/skyscribe/comments/commentRss/103205.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/skyscribe/services/trackbacks/103205.html</trackback:ping><description><![CDATA[<p>最近在TL的<a href="http://groups.google.com/group/pongba/browse_thread/thread/1da7464331b9a3fd/7cf9c637ad0ef8cf">讨论中</a>忽然有人挑起了perl和python（一场关于c++的讨论扯到脚步上还有不少的碰撞，倒是挺有意思），我则有感而发的想起了前几天面试的时候问别人的一个基本的shell问题：</p> <blockquote><pre><pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"><p><font size="4">cat xxx.txt | grep "<span style="color: #8b0000">yyy</span>" | wc –l</font></p></pre></pre></blockquote>
<p>问题是这个常见的pipeline操作一般最少会起多少个进程？结果那位老兄倒是愣了半天然后目无表情。</p>
<p>我只好继续唠叨的解释了一下一般pipe的操作需要读取一个进程的输入，然后将输出送给下一个进程；其实我希望对方干脆利落的回答是有3个，这个问题就算是可以了；我们主要不是用脚本开发，但是如果有这个技能是能得到额外的认可的。</p>
<p>&nbsp;</p>
<p>TL上的大虾们果然是想法众多，立马有人站出来问：我想知道答案是几个？直接让我怀疑是不是我的脑袋有问题。后来有人给出了可能是2个的情形：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 某个变态的shell可能内置了cat,使其成为一个builtin，然后自己越俎代庖的读取标准输入，并且将内容文本输出，那么进程就少一个。</p>
<p>起初我觉得这个解释并不能成立，但是经过几个老大的解释还是明白了他所说的情况是shell的builtin。</p>
<p>&nbsp;</p>
<p>中间又讨论起那些可能是builtin的command，举出的例子是cd/kill/time，但是我查了一下Solaris上的，后两个都是executable，cd找到一个/usr/bin/cd 的ksh，内容如下：</p><pre><pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">#!/bin/ksh
</pre><pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"></pre><pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">command = `basename $0`
</pre><pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">$command $@</pre></pre><pre>这个结果本来还是挺出乎我的意料的，于是我也想当然的认为，shell里边不能直接调用syscall；</pre><pre>很快就得证这个揣测纯粹是错误的；以前还真没想过这个问题，查了下wikipedia、google之后得到很多意料之外的收获。</pre><pre>&nbsp;</pre><pre>最后居然有人搬出了busybox这个大旗（做过嵌入式的大多都知道些），并声称它把vi也builtin了。</pre><pre>这下也很出乎我的意料，不顾我没有仔细研究过，没有什么发言权。</pre><pre>不过最后有人站出来说，busybox并没有内置这些想当然的vi，而是大部分也单独起进程了；在Unix的哲学里边，做这些大而全的东西其实是不被鼓励的，因为它违反unix的哲学。</pre><pre>&nbsp;</pre><pre>话说回来，面试的时候，我之所以会问到这样的问题，也是有很真实的background的。曾经我们查过的一个很诡异的performance bottleneck就是由于shell脚步的问题引起的。</pre><pre>====================================================================================================</pre><pre>问题本身也是比较直观的（当然是“事后诸葛”了）：</pre><pre>     某段程序的启动脚本使用如下的东东来检测环境：</pre><pre><pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">exists=`netstat -rn | grep "<span style="color: #8b0000">xx.xx.xx.xx</span>" | wc -l`
</pre><pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff"><span style="color: #0000ff">if</span> [ $exists -eq 0 ];then
</pre><pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">     idx=`ifconfig -an | grep bge0 | awk -F"<span style="color: #8b0000">:</span>" '{print $2}' | uniq | sort | tail`"<span style="color: #8b0000">
</span></pre><pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">     ifconfig bge0:`echo $idx + 1 | bc` plumb up
</pre><pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">     ifconfig bge0:`echo $idx + 1 | bc` xx.xx.xx.xx netmask 255.255.255.0
</pre><pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">fi
</pre><pre style="font-size: 12px; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; background-color: #ffffff">  </pre></pre>
<p>当有很多个同样的进程（&gt;500)恰好于同一时刻跑到这个初始化点的时候，如果系统上已经存在的IP地址很多（当时的场景大概有2000+），那么netstat、ifconfig本身都变得非常耗时，加上多个进程的原因，系统中会有N多个进程在消耗着资源；</p>
<p>后果的严重程度是任何shell都停止响应，数十分钟都陷入假死，不得不重启电源了事。</p>
<p>当然的分析结果发现，真正占用的CPU都是处于kernel状态的，并且使用率超过99%，长长的pipeline带来的开销，相当一部分可能来源于互相等待CPU的进程的互相抢占。</p>
<p>解决的方法自然也很简单，这里不赘述了。</p>
<p>=========================================================================</p>
<p>当时以为对这个问题搞得算是比较明白了，结果拿出来一讨论，发现自己不了解的还真不少。</p><img src ="http://www.cppblog.com/skyscribe/aggbug/103205.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/skyscribe/" target="_blank">skyscribe</a> 2009-12-14 19:46 <a href="http://www.cppblog.com/skyscribe/archive/2009/12/14/103205.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Popen中奇怪的OSError：too many open files</title><link>http://www.cppblog.com/skyscribe/archive/2009/10/19/98970.html</link><dc:creator>skyscribe</dc:creator><author>skyscribe</author><pubDate>Mon, 19 Oct 2009 11:31:00 GMT</pubDate><guid>http://www.cppblog.com/skyscribe/archive/2009/10/19/98970.html</guid><wfw:comment>http://www.cppblog.com/skyscribe/comments/98970.html</wfw:comment><comments>http://www.cppblog.com/skyscribe/archive/2009/10/19/98970.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/skyscribe/comments/commentRss/98970.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/skyscribe/services/trackbacks/98970.html</trackback:ping><description><![CDATA[<p><font face="微软雅黑" size="3">近来用Python的unittest框架来做一个regression test 工具，验证一些复杂的程序功能，期望做到自动化测试完成一部分需要繁琐的界面点击和等待才能完成的验证工作。</font></p>
<p><font face="微软雅黑" size="3">其中核心的部分是通过python的subproces module中的Popen来调用shell脚步完成功能性请求，并抓取执行的结果。</font></p>
<p><font face="微软雅黑" size="3"></font>&nbsp;</p>
<p><font face="微软雅黑" size="3">初一开始，test case比较少的时候（100个以内）都没有任何问题；但从某一刻起，当超过120个的时候，最后一个test case执行的时候，总是报告</font></p>
<p><font face="微软雅黑" size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>OSError： too many open files</strong></font></p>
<p><font face="微软雅黑" size="3">给出的stack trace指向了Popen的communicate方法。</font></p>
<p><font face="微软雅黑" size="3"></font>&nbsp;</p>
<p><font face="微软雅黑" size="3">最简单的怀疑自然是打开文件数的限制了， ulimit&nbsp; -a 发现默认的Shell的确只有256，虽然感觉应该也够用了（因为每一个case都是用单独的Popen来执行操作,完毕就应该被回收了），但还是自然将其开大一些； </font></p>
<p><font face="微软雅黑" size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#800080">ulimit &#8211;n 1024 </font></font></p>
<p><font face="微软雅黑" size="3">重新执行，还是最后一个case失败，错误依然。</font></p>
<p><font face="微软雅黑" size="3"></font>&nbsp;</p>
<p><font face="微软雅黑" size="3">Google了一下，暂时没有头绪，只有待有时间再详细盘查一下原委了。不过在搜索答案的过程中发现了一个有意思的现象：</font></p>
<p><font face="微软雅黑" size="3">&nbsp;&nbsp; 有人在询问怎样将python的字符串quote成为一个可以再shell中安全使用的字符串，就有人回复说Subprocess中有一个类似的方法可以完成类似的工作为什么不用；马上有牛人站出来说，这个模块的作者大概不想维护过多的东西，因而将其隐藏了起来，而不是放开了给大家用，因为它的doc里边都没有直接说明，用的人是看了他的代码才知道有这个函数（参考</font><a href="http://code.activestate.com/recipes/498202/"><font face="微软雅黑" size="3">这里</font></a><font face="微软雅黑" size="3">）</font></p><img src ="http://www.cppblog.com/skyscribe/aggbug/98970.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/skyscribe/" target="_blank">skyscribe</a> 2009-10-19 19:31 <a href="http://www.cppblog.com/skyscribe/archive/2009/10/19/98970.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>