【工作点滴】用VS 2010 编译 Ruby 1.9.1

关键字:ruby 1.9.1 Visual studio 2010 MSVC 1600 download compile

VC 2010增加了许多对C99的支持,编译许多GNU的项目会方便许多,考虑到以后编译ruby扩展的方便,所以重新用VC 2010 (1600) 把ruby编译了一遍。

编译Ruby需要一些第三方类库,首先是Zlib,Zlib最新版本是1.2.4,编译很简单,解开之后,nmake -f .\win32\makefile.msc,编译完成之后,得到2个头文件zlib.h和zconf.h和一个library zlib.lib,将他们放到VC的目录(默认是"C:\Program Files\Microsoft Visual Studio 10.0\VC"),这其实是个偷懒的做法--:)

有了Zlib之后,就可以开始ruby的编译工作,最新的ruby版本是ruby-1.9.1-p376,这个版本需要做适当的修改才能被编译,首先要解决的是win32.h里许多errono的重定义问题,VC 1600已经定义了自己的errono,为了兼容之前的VC,打开<ruby-src>\include\ruby下的win32.h,修改成条件编译。
#if _MSC_VER <1600
#define EWOULDBLOCK		WSAEWOULDBLOCK
.....
#define EREMOTE		WSAEREMOTE
#endif


之后运行ruby的命令 .\win32\configure.bat --prefix="C:/ruby",之后如果直接运行nmake,会遇到C1010070 "Failed to load and parse the manifest",这是生成的makefile的bug,增加以下两行

CFLAGS = -nologo -MD $(DEBUGFLAGS) $(OPTFLAGS) $(PROCESSOR_FLAG)
LDFLAGS = $(LDFLAGS) -manifest


继续编译的话,在testThread.c会有个编译错误,将附件中的testThread.c覆盖掉Ruby原来的那个,一切就ok.

编译过程中有一个warning C4273: 'vsnprintf' : inconsistent dll,这个是因为ruby的missing.h,又定义了一个
extern int vsnprintf(char *, size_t n, char const *, va_list);


直接rem掉之后就可以继续下去了。

编译完的ruby之后并不能运行rails,因为有两个重要的lib(iconv和open ssl)没有被编译,会导致rails运行失败。

首先编译iconv,由于后续一些版本的iconv去掉了对VC的支持,所以必须寻找合适的版本,我找到的最高版本是iconv 1.11.1,足够支持rails了,编译命令用
nmake -f makefile.msvc NO_NLS=1
nmake -f makefile.msvc install

NLS是native language support,将得到的头文件和library也放到VC的目录里去。。(又一次坏习惯)。

接下来是可怕的Open SSL,OpenSSL本身对VC支持得很好,问题出在ruby身上,几个作者搞了一整年,还是没办法兼容好Open SSL 0.9和1.0版本,编译的错误多得不计其数,有兴趣你可以参考这些补丁:


    http://redmine.ruby-lang.org/issues/show/2022
    http://redmine.ruby-lang.org/issues/show/814
    http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/39053
    ]http://projects.reductivelabs.com/issues/3363


就是打上这些补丁,也未必能正确运行rails,(比如SSL_SESSION_CMP被OpenSSL修改成private之类的问题) 建议回退到0.9.8,让作者去埋头苦干吧。。。

perl configure VC-WIN32
.\ms\do_ms.bat
nmake -f .\ms\ntdll.mak
nmake -f .\ms\ntdll.mak install


另外还需要把openssl extconf.rb的 if(mingw) 这一行去掉。。。

最后结果:

【工作点滴】用VS 2010 编译 Ruby 1.9.1_第1张图片

Ruby的插件的缺点是十分致命的,一旦更换了ruby的运行时,所有的C插件会全部失效,包括sqlite3-ruby之类。

下载sqlite3-ruby,利用下面的方法编译它
lib /def:sqlite3.def /machine:x86

这样可以得到sqlite3.lib,同时从源代码里拿到sqlite3.h,拷贝到某个目录,比如win32中,可以这样放置文件
c:\win32\include\sqlite3.h
c:\win32\lib\sqlite3.lib


这个sqlite3.lib只是sqlite3.dll的wrapper而已,所以要把sqlite3.dll放到路径里的某个目录下,比如C:\WINDOWS或者C:\WINDOWS\SYSTEM32

修改一下sqlite3-ruby的源代码里的extconf.rb,指向我们的目录
require 'mkmf'

SWIG_WRAP = "sqlite3_api_wrap.c"

dir_config( "sqlite3", "c:/win32/include","c:/win32/lib" )

have_library( "rt", "fdatasync" )

if have_header( "sqlite3.h" ) && have_library( "sqlite3", "sqlite3_open" )
  if !File.exists?( SWIG_WRAP ) || with_config( "swig", false )
    puts "creating #{SWIG_WRAP}"
    system "swig -ruby sqlite3_api.i" or raise "could not build wrapper via swig (perhaps swig is not installed?)"
  end

  create_makefile( "sqlite3_api" )
end


然后运行ruby setup.rb,看看最后是不是在rails中正常工作了?

【工作点滴】用VS 2010 编译 Ruby 1.9.1_第2张图片


附件里带有有编译后的基于msvcrt10的ruby 1.9.1-P376,不想要重新经历编译的痛苦的同学可以直接下载。

你可能感兴趣的:(工作,C#,Ruby,vc++,Rails)