Parece um resultado inesperado do lançamento do cygwin 2.5.2
Como solução alternativa, faça o downgrade do pacote cygwin para 2.5.1
Em um Windows 7 Professional 64 Bit instalado recentemente, eu instalei o Cygwin (64) e alguns de seus pacotes, incluindo o Ruby. Eu também instalei o Ruby usando o instalador Ruby, porque provavelmente precisarei dele tanto para o Windows como para o Cygwin.
Agora, quando tento executar um comando gem
como gem list
ou gem install foo
, recebo um erro estranho que não consegui resolver nas últimas horas de pesquisa na Internet.
$ which ruby
/usr/bin/ruby
$ which gem
/usr/bin/gem
$ ruby -v
ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-cygwin]
$ gem -v
2.4.8
$ gem list
ERROR: Loading command: list (Fiddle::DLError)
can't load kernel32
ERROR: While executing gem ... (NoMethodError)
undefined method 'invoke_with_build_args' for nil:NilClass
$ gem install sass
ERROR: Loading command: install (Fiddle::DLError)
can't load kernel32
ERROR: While executing gem ... (NoMethodError)
undefined method 'invoke_with_build_args' for nil:NilClass
No entanto, com a versão nativa do Windows, a partir do Windows CMD, funciona sem problemas. Eu não posso, no entanto, usar o material nativo do Ruby do Windows, porque isso me dá erros, mas essa não é a questão aqui de qualquer maneira.
Com o Process Monitor, descobri que Ruby tenta abrir C:\cygwin64\bin\kernel32.dll
e falha, porque esse arquivo não está lá. Eu tentei copiar o kernel32.dll
de C:\Windows\System32
e aquele de C:\Windows\SysWOW64
na pasta Cygwin bin
e ainda recebi o mesmo erro (além disso, ele disse não é possível carregar o kernel32.dll ), embora o Process Monitor não mostre mais um erro NAME NOT FOUND
.
Que mágica está acontecendo aqui? Eu realmente gostaria de entender o que está errado aqui. Agradeço qualquer ajuda.
Parece um resultado inesperado do lançamento do cygwin 2.5.2
Como solução alternativa, faça o downgrade do pacote cygwin para 2.5.1
Uma maneira de corrigir isso sem alterar o processo de criação do rvm é:
ln -s /cygdrive/c/Windows/System32/kernel32.dll /usr/lib/kernel32
Isso acontece porque o ruby está procurando por uma biblioteca compartilhada chamada simplesmente kernel32
. O Cygwin 2.5.1 e anteriores adicionaram automaticamente a extensão ".dll" às cargas da biblioteca compartilhada. Mas o cygwin 2.5.2 introduziu um patch exigindo nomes completos de arquivos de bibliotecas compartilhadas. A adição de um link simbólico no caminho de pesquisa da biblioteca ( /usr/lib
) permite que a biblioteca seja encontrada mesmo quando carregada com o nome antigo.
Eu instalei o ruby usando rvm para que os binários ruby atualizados do Cygwin não ajudassem muito e eu realmente não queria fazer o downgrade da instalação do Cygwin - como eu saberia quando era seguro atualizar novamente?
Seguindo as informações na resposta de Michael D, o problema parece estar no arquivo resolv.rb
localizado em ~\.rvm\rubies\ruby-<version>\lib\ruby\<version>\win32
(no meu caso ~\.rvm\rubies\ruby-2.1.7\lib\ruby.1.0\win32
).
Em algum lugar perto do topo deste arquivo, existe o código
module Kernel32
extend Importer
dlload "kernel32"
end
A simples alteração da linha dlload "kernel32"
para dlload "kernel32.dll"
pareceu corrigir isso para mim. Como alternativa, usando o caminho completo
dlload "c:/Windows/System32/kernel32.dll"
também funcionou, mas parece ser a extensão que é o bit crucial (o caminho completo sem a extensão também não funciona).
Isso pode ter sido corrigido em uma versão mais recente do rvm, mas eu não queria passar pelo incômodo de atualizar e reinstalar, então isso funciona para mim. É claro que isso provavelmente precisaria ser alterado para todos os rubis instalados.
O pacote Ruby tem problemas ao carregar bibliotecas nativas (pelo menos kernel32.dll). O problema vem de uma chamada para dns.getresource("_rubygems._tcp.#{host}", Resolv::DNS::Resource::IN::SRV)
, que provavelmente faz uma chamada nativa para kernel32.dll
, carregando a biblioteca kernel32.dll
.
Se você especificar o caminho completo para a biblioteca, ele funcionará corretamente.
kernel = Fiddle::Handle.new("c:/Windows/System32/kernel32.dll")
Para resolver o problema, tente o seguinte:
devkit
ao executar extconf.rb
da seguinte forma: ruby -rdevkit extconf.rb
ou apenas adicionando require "devkit"
a extconf.rb
e, em seguida, executando o script normalmente. devkitvars.bat
do devkit para configurar o PATH
com o conjunto de ferramentas antes de compilar.