解名缰 鸟倦飞

R会议、animation、安全及其他

2009 年 12 月 14 日 | 分类于 R学习中

第二届中国R语言会议上海会场已经在昨天顺利闭幕,虽然我无法亲临现场,而且现在也还没有看到相关的照片和报道,但我相信一定是extRemely wondeRful的。

“两会”的召开确实让我们扩展了自己的视野,直接的和间接的受益都非常多。下面说说我的一些意外收获吧。 在北京会场闭幕、上海会场开幕之前的这段时间里,除了整理会后的材料,我还花了些时间研究了一下把应用程序嵌到R中的方法。这源于宫雨老师的演讲以及谢老大为上海会场演讲写的一个幻灯片,里面提到animation包中输出动画的功能依赖于ImageMagick和SWF Tools这两个软件。但因为实际用到的功能只是这两个软件的很小一部分,而且这两个软件的体积都不小,所以希望能从中提取出animation包需要用到的少数几个函数。换句话说,就是把软件打个包,放到animation中去。

理论上要打包的话,可以直接把那两个软件中要用到的几个exe拷贝到包的目录中,然后在包中写函数调用。但如果这样做,一来是跨平台的特性会大打折扣,二来牵涉到GPL协议中公开源代码的问题,三来是R CMD check中那句checking for executable files着实让人发怵……所以能做的基本上就是把那两个软件的源代码找来,然后分离出有用的源代码来编译。

有了这个想法后,我就开始拿SWF Tools来做实验。我一开始觉得应该很容易完成,因为无非就是拿源代码来编译嘛,此外为了以防万一,我先不管R,而是直接编译成exe文件试试。可是刚在Code::Blocks(一个开源的C/C++开发集成环境)中按下编译按钮就傻眼了,老是说缺少config.h这个头文件,于是找呀找,却只找到个config.h.in文件。后来才知道,原来这些开源软件大部分都需要先运行configure程序,以解决环境的依赖问题。config.h.in里面有很多“开关”,configure程序就是依照当前环境的各种指标,把这些“开关”打开或关上,然后生成当前环境下的config.h文件。为了明白这一点着实不容易,我先后绝望了好几次,把程序装了又删,删了又装,好在没有完全放弃,否则可能永远也搞不明白了。

把这个搞明白了只是第一步,后面依然老是出错。兜了几个弯子,才知道编译SWF Tools需要另外两个库,就是JPEG的库和Zlib库。于是又上网搜源代码,调试,杀虫,总之折腾了两三天,好歹能编译成功了,但是接下来又有问题了。SWF Tools的源代码解压开有10M多,加上JPEG库3M,Zlib库2M,如果都放到R包中去也未免太臃肿,所以必须要提取出有用的成份。但是这个过程就太痛苦了,因为你直接看的话很难搞清楚其中的依赖关系,有的时候删一个文件就有几百个编译错误,关系太复杂。好在Code::Blocks提供了一些查询和搜索的工具,又折腾了两天,删掉了N个文件,注释掉了M个函数,最终精简成了现在的2M左右的大小。

好不容易自信满满准备把程序嵌到R中,才发现灾难又来临了。R是一个跨平台的软件,编写的程序包也应该尽量满足这个特性。但是我经常发现Windows下配置好的源代码放到Linux下无法编译,Linux下配置好了Windows又不行了,所以没办法,还得把configure脚本学一学,于是上网搜了半天,知道要先用autoscan生成configure.ac,然后用auroheader生成config.h.in,最后用autoconf生成configure什么的。而直到现在,依然有很多问题没有解决,比如R需要另外生成一个configure.win文件,用来在Windows下进行配置,但是我在网上没有找到什么文献,所以只能作罢。

记得老大之前说过一句话,就是程序员和网页设计者最抓狂的事就是要面向不同的平台编写不同的代码,这几天也实在是被跨平台的问题折磨得不轻。不过好在这几天趁机把C语言又学习了一番,而且还了解到更多的与GNU有关的内容,算是意外的收获吧。目前的成果是把SWF Tools中的jpeg2swfpng2swf两个程序放到了animation包中,在R中是sth2swf()这个函数,当然还没写说明文档什么的(老大要笑了:)),可以到http://yixuan.cos.name/cn/2009/12/enhanced-animation-package/去下载,里面给了示例的代码。当然这个东西还非常初级,需要很多进一步的工作,等yanlinlin忙完了一定要好好跟他取取经。如果真的能把这块东西搞定了,那老大的animation包的实用性肯定会有很大提升的。

而做到这一步我又不禁想起肖楠对于R环境安全的演讲。试想,既然这些工具可以嵌入到R中,那么恶意程序岂不是也可以进行类似的操作?而且把恶意代码写成C并编译的话,就更加难以被人发现了,毕竟读一段C代码一般要比读一段R代码更难。前两天COS被一些不速之客光临过了,这也让我们不得不审视一下当前网络的安全问题,攻防之战依然在继续啊。

附:sth2swf()的说明。
sth2swf(from, cmdargs)有两个参数,from可以取“jpeg”和“png”,说明你是要将什么格式的文件转成swf;cmdargs是命令行参数,参见SWF Tools的官方说明