cmake

我以前总说 autotools sucks,以为只用 make 就能解决一切问题。

最近终于开始做一套比较实用的 (或者说 Insdustrial-strength) 的程序,涉及好几个平台和库,于是 make 的局限性就显现出来了,为了在几个不同的平台下都编译使用,不得不在 Makefile 里写大量判断。

于是开始找跨平台的编译工具,其中最有名的两个是 [cmake](http://www.cmake.org) 和 [scons](http://www.scons.org),cmake 之所以出名估计是因为 KDE 4 从 autotools 转向用 cmake 来编译。而 scons 则是 [lighttpd](http://www.lighttpd.net) 原来用的编译工具,它现在也转向 Python 了。cmake 和 python 大概代表了新一代跨平台编译工具的两种方向。第一种 (cmake) 是延续并改良传统 automake, autoconf 工具链,将之合为一体,但最终仍然生成 Makefile, Visual Studio 的 .sln,Xcode 的 .xcodebuild 文件,依赖现有编译工具 (make, nmake, vcbuild, xcodebuild) 来编译;第二种则是完全消除现有编译工具的调用,直接调用编译器,scons 就属于这一类 (scons 还有一个特点是完全不用专门的语言,控制编译的脚本就是 Python)。

从[人气](www.googlefight.com/index.php?lang=fr_FR&word1=scons&word2=cmake)上来说,反倒是走改良路线的 cmake 比 scons 好一些,有几个原因:scons 基于 Python,可能有些代码不是很照顾速度,于是类似 KDE 这样的大项目编译起来会很慢;scons 开发比较慢,最近一直只是 bugfix。不过相对 cmake,scons 的优点是文档非常细致可读,而 cmake 的文档则非常少,可以在网上找到的只有几篇介绍性的文章和参考手册,不像 scons 有一本 User Guide。

与之相关的工具还有 Jam (包括它的变体 FTJam, Boost.Build), [Waf](http://www.freehackers.org/~tnagy/bksys.html), [Bakefile](http://bakefile.sourceforge.net) 等。其中比较新的 Waf 是一个 scons 的改进,在它的提供的 [benchmark](http://www.freehackers.org/~tnagy/bench.txt) 中,显示通过缓存方式可以大大改进编译的速度。不过因为这个项目还很新,目前没有什么软件用它作为编译系统。

Bakefile 走的则是 cmake 的路子,从名称上也可以看出,它最终也是通过生成 Makefile 一类的文件来完成编译的。不过不同的地方在于 cmake 用的语法很像 autotools 用的 m4 的传统语法,而 bakefile 则完全用 XML 来定义编译规则了,这一点倒很像 [ant](http://ant.apache.org/)。Bakefile 倒是有不少著名的项目使用,比如 wxWidgets, WebKit, VCF, libxml。

我自己挑来选去,最终决定用 cmake,不过选择的过程写下来,希望能对遇上同样问题的朋友有用。

说说 TextMate 的不开源

Rands In Repose 上有一篇 TextMate 主创者 Allan Odgaard 的 [Interview](http://www.randsinrepose.com/archives/2007/01/26/interview_allan_odgaard.html),提及了一个敏感的话题:TextMate 会开放源代码吗?Allan 的答复是,他最终还是决定开公司,不开源,他的观点是:

1. TextMate 已经是部分开放源代码的 (Bundle 部分)。
2. 他本人喜欢设定一个确定的目标,得到一个确定的结果的方式,如果采用开源软件的开发方式,他无法要求参与的开发者都按照他的意愿工作,所以他宁可开个公司。
3. 他还是担心开源了就赚不到钱。

虽然让人有点失望,但这也是正常的思路,你不可能指望所有的编辑器作者都像 Bram Moolenaar 那样去救助乌干达的可怜儿童,所以 InType 早在没有出 Alpha 之前就说他们是[肯定要卖钱](http://intype.info/faq/#faq-basic-3)的,而虽然早有人说靠 TextMate 40 欧元每份的价格,Allan 早已赚得盆满钵满,但还是舍不得开源。

作为一个购买了 TextMate 的用户,我关心的是什么呢?

1. 我提的问题是不是有人回复
2. 如果没有人回复,我能不能自己去改进它

我最热爱开源软件的地方正是第二点,我可以完完全全地按照自己的意愿去改进它,如果我的改进能被主干接受当然更好,如果不接受也没关系。就拿 TextMate 为例,我被它处理正则表达式的问题困扰,但因为 Allan 去旅行了两个半月,没有人能回答我的问题,结果我只能坐着等 (事实上,Allan 今天刚刚从旅行回来,我甚至根本不知道我两个月前提的问题他会不会看,一想到这一点我就抓狂),如果困扰我的是 Smultron, Vim, 这样的问题早就解决了。

如果开公司,是可以保证比较稳定的客户服务,但无形中失去了很多程序员的业余贡献,比如我的主业是 Linux 内核驱动的开发,如果 TextMate 开源,我倒是乐于贡献,但要让我去做一辈子编辑器,恐怕就不会原意了。

当然,开源也有很多弊端,软件项目管理本来就是一件很难两全的事情。

Cocoa Text System

[Cocoa Text System](http://www.hcs.harvard.edu/~jrus/site/cocoa-text.html),所有 Mac OS X 用户的必读,这篇文章对所有的 Cocoa 软件都有用,非常易读,简洁。

可以参考的还有:[Mac OS X Keybindings](http://www.lsmason.com/articles/macosxkeybindings.html), [Usable Selectors for Cocoa Key Bindings](http://www.hcs.harvard.edu/~jrus/site/selectors.html) 和 [Default Mac OS X System Key Bindings](http://www.hcs.harvard.edu/~jrus/site/system-bindings.html).

可惜还是不能解决它下层的键映射问题,比如右 enter 的作用,fn 键,等等。

xcp.py 的一个简单例子

有朋友问到 xcp.py 究竟怎么用,是我不对,说了半天连个例子都没举出来,光看两句介绍当然无法理解。我自己记性也不好,怕以后忘了,现在赶紧写下来:

\documentclass{article}

\usepackage{fontspec}

% 定义英文字体,更换为你希望使用的
\setromanfont{Minion Pro}

% 定义中文字体,可将 SimSun 更换为你希望使用的字体
\newfontinstance{\zhfont}{SimSun}
\newcommand{\zh}[1]{{\zhfont #1}}

% 设置中文断行,必备
\XeTeXlinebreaklocale “zh”
\XeTeXlinebreakskip = 0pt plus 1pt

\begin{document}

TeX 提供了一套功能强大并且十分灵活的排版语言,它多达 900
多条指令,并且 TeX 有宏功能,用户可以不断地定义自己适用的
新命令来扩展 TeX 系统的功能。许多人利用 TeX 提供的宏定义
功能对 TeX 进行了二次开发,其中比较著名的有美国数学学会推
荐的非常适合于数学家使用的 AMS-TeX 以及适合于一般文章、报
告、书籍的 LaTeX 系统。

\end{document}

将此文件存为 foo.tex,对它

python xcp.py foo.tex > foo.out.tex
xelatex foo.out.tex
mv foo.out.pdf foo.pdf

就可以得到你需要的 PDF 啦。如果你有兴趣,还可以看看 foo.out.tex 是什么样子的:

\documentclass{article}

\usepackage{fontspec}

% 定义英文字体,更换为你希望使用的
\setromanfont{Minion Pro}

% 定义中文字体,可将 SimSun 更换为你希望使用的字体
\newfontinstance{\zhfont}{SimSun}
\newcommand{\zh}[1]{{\zhfont #1}}

% 设置中文断行,必备
\XeTeXlinebreaklocale “zh”
\XeTeXlinebreakskip = 0pt plus 1pt

\begin{document}

TeX \zh{提供了一套功能强大并且十分灵活的排版语言,它多达} 900
\zh{多条指令,并且} TeX \zh{有宏功能,用户可以不断地定义自己适用的%
新命令来扩展} TeX \zh{系统的功能。许多人利用} TeX \zh{提供的宏定义%
功能对} TeX \zh{进行了二次开发,其中比较著名的有美国数学学会推%
荐的非常适合于数学家使用的} AMS-TeX \zh{以及适合于一般文章、报%
告、书籍的} LaTeX \zh{系统。}

\end{document}

可见导言区都没有修改,只是对正文区进行了预处理。

我们可以打开 PDF 看看,效果如图:

PDF produced

可见中文使用了宋体,英文使用了 Minion Pro,正是我们需要的效果。