以前听说过ruby是因为Ruby On Rails,但是我对web却没有什么研究,所以也就不会去尝试ruby。最近想做一个跨平台的C++程序,所以我开始使用MinGW,但是用习惯了MS套餐的我对make始终不是很精通,找时间看了make指南,虽然我能完成项目组织功能,但是却不是很满意,因为不够智能和灵活。类UNIX系统是鼓励使用小程序组合完成复杂任务的,但是我对UNIX却不熟悉,要我在make中使用复杂的UNIX文本工具,的确头痛。所以我想尝试一些其他的项目组织工具,找到了Cpptasks for Ant,但是一看那些配置就觉得麻烦,因为它和make的本质是一样的,一种描述式的makefile,能表达的东西就不够灵活。这个时候我发现了Rake,一种使用ruby编写的并且以ruby作为脚本的make工具,去官方网站上看了一下,有个教程,看下来果真觉得被吸引了。结果看了几天ruby,真是令我着迷的东西。
Rake 使用ruby本身作为make的组织语言:
在传统make中的
main.o: main.cpp; cxx...
被
file "main.o" => ["main.cpp"] { sh "cxx.."}
取代了,表面看仅此而已,但是我看到了教程中的动态创建,才知道Rake和其他工具的最大不同,这也正式Rake独特的地方。
用于Rake使用的make语言是ruby,它和普通的gnu make和ant最大不同是,它是一个可以被执行的脚本语言,而不是一种侧重于描述的语言,尽管gun make可以使用eval函数来动态生成目标和依赖,但是那得面对天书一样的代码,而且还不一定足够灵活,gnu make是侧重描述的,它们通过make工具内嵌的函数或者shell工具来完成复杂的动态功能,ruby本身就是一种脚本,它使用的库都可以在rake的makefile中使用,使得功能灵活了很多。Rake的核心模式是通过执行一个rake的makefile,生成目标和依赖,然后再将这些结果送进rake执行,所以rake的makefile可以非常动态的生成目标和依赖关系。我使用了下面的代码来生成build过程(尽管Rake支持rule,但是我并不喜欢使用,同样,我也讨厌gnu make的默认规则一类的东西,它让build感觉不明确):
pairs =
{
"src/main.cpp" => "tmp/main.o",
"src/tool.cpp" => "tmp/tool.o"
}
pairs.each do |src, obj|
file obj => [src] do
sh "g++ -c #{src} -o #{obj}"
end
end
来动态生成明确的规则,这种感觉很棒,对于gnu make来说,实现起来很麻烦。
同样g++支持用-MM开关来检测依赖关系,这样我就可以轻易的使用ruby来动态执行g++,把生成的依赖关系自动的添加到依赖中,非常的舒服。gnu make则需要使用include来解决,麻烦了很多。
Rake具有这样的潜力:它可以解释另一个我们自定义的包含有make参数的描述性质的文件来完全动态的生成build过程,这就是我喜欢的make方式。
============================================
因为Rake,我开始学习Ruby,实际上只有几天而已,对ruby的了解也只是皮毛,这是一种给人很棒感觉的语言,如果你也感兴趣,那么也开始学习它吧。