ruby 1.9.1 openssl编译问题

问题描述:

编译环境 mingw + gcc 4.3

1、下载openssl-0.9.8k.tar.gz,编译安装:perl Configure -DMK1MF_BUILD mingw; make; make install,一切正常
2、下载ruby-1.9.1-p129.tar.gz,编译安装:./configure --prefix=C:/Ruby; make; make install, 一切正常(正确编译出openssl.so文件)
3、irb下,require 'openssl.so',出错:

[img]/upload/attachment/114542/98259934-31ba-38c7-a7eb-ca11ad8aa7de.gif[/img]

请问是什么问题,谢谢
[b]问题补充:[/b]
require 'openssl'是正常的,night_stalker给出的代码也执行正常,但rails却无法正常使用,请问有什么办法可以解决

运行环境 Ruby 1.9.1 + Rails 2.3.2

[img]/upload/attachment/116189/f9745f25-d2fd-3b98-9fdd-d6fd955c51de.gif[/img]

[b]问题补充:[/b]
多谢night_stalker,问题算是解决了吧

解决办法:

http://rubyinstaller.org/downloads/中的ruby 1.9.1p129里面的openssl.so替换自己编译的openssl.so,rails启动正常

openssl 0.9.7、0.9.8版本编译时,需要使用参数[color=red]MK1MF_BUILD[/color],编译命令行为[color=red]perl Configure -DMK1MF_BUILD mingw[/color],1.0.0版本,编译时不需要使用参数

经测试,使用0.9.7、0.9.8、1.0.0版本编译后,运行rails都会产生内存分配访问无效的问题

-_- 无法再现……

内存分配访问无效的原因很多很复杂 ……
可能是加载错了某个 dll,也有可能是因为 vcrt 的版本不匹配,也有可能是因为在 64 位系统下跑 32 位程序 ……

最省事是下载 Luis Lavena 编好的二进制版本:[url]http://rubyinstaller.org/downloads/[/url]
另外还附送一个 mingw 的 devkit,不过这个 mingw 版本没 gcc 4.3.2 这么潮。

用 require 'openssl'

就没问题…… 大概是路径什么的原因

找到原因了,是循环依赖。
openssl.rb 依赖 openssl.so,但是 openssl.so 依赖 openssl.rb。
所以你 require 其中任何一个都会出问题,[color=red]但是 require 'openssl' 就没问题……[/color]

如果真想 require 'openssl.so' 不出错,可以修改源代码目录下的 ext/openssl/ossl_digest.c
在 233 行附近找到这个:
[code="c"]
void
Init_ossl_digest()
{
// rb_require("openssl");
rb_require("digest");
...
[/code]
如上所示注释掉 rb_require("openssl");

最后[color=blue]在这个目录下[/color] make && make install 就 ok。

[搬运] 可以用这个样板代码验证 openssl 是否能正常工作:
[code="ruby"]
require 'openssl'

key = OpenSSL::PKey::RSA.new(1024)
digest = OpenSSL::Digest::SHA1.new()

issu = sub = OpenSSL::X509::Name.new()
sub.add_entry('C', 'JP')
sub.add_entry('ST', 'Shimane')
sub.add_entry('CN', 'Ruby Taro')

cer = OpenSSL::X509::Certificate.new()
cer.not_before = Time.at(0)
cer.not_after = Time.at(0)
cer.public_key = key # <= 接受签署的公匙
cer.serial = 1
cer.issuer = issu
cer.subject = sub

cer.sign(key, digest) # <= 签署用的秘匙和哈希表函数
print cer.to_text
[/code]

对了,我用的 openssl 0.9.7 …… 貌似其它版本都编译得很痛苦 ……