gem não funciona no Cygwin

4

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.

    
por Neon 27.06.2016 / 14:22

4 respostas

3

Parece um resultado inesperado do lançamento do cygwin 2.5.2

link

Como solução alternativa, faça o downgrade do pacote cygwin para 2.5.1

    
por 27.06.2016 / 16:09
6

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.

    
por 07.10.2016 / 22:46
4

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.

    
por 04.08.2016 / 23:06
2

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:

  1. Exigir 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.
  2. Execute o script devkitvars.bat do devkit para configurar o PATH com o conjunto de ferramentas antes de compilar.
por 27.06.2016 / 14:41