gem ne fonctionne pas dans Cygwin

4

Sur un Windows 7 Professionnel 64 bits fraîchement installé, j'ai installé Cygwin (64) et certains de ses packages, y compris Ruby. J'ai également installé Ruby à l'aide du programme d'installation de Ruby, car j'en aurai probablement besoin à la fois pour les shells Windows par défaut et pour Cygwin.

Maintenant, quand j'essaye d'exécuter un gem commande comme gem list ou gem install foo, Je reçois une erreur étrange que je n’ai pas résolue au cours des dernières heures de recherche sur 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

Cependant, avec la version Windows native, à partir du CMD Windows, cela fonctionne sans problème. Je ne peux cependant pas utiliser les éléments Windows Ruby natifs de Cygwin, car cela me donne des erreurs, mais ce n’est pas la question qui se pose ici.

Avec Process Monitor, j'ai compris que Ruby essayait d'ouvrir C:\cygwin64\bin\kernel32.dll et échoue, car ce fichier n’est pas là. J'ai essayé de copier le kernel32.dll de C:\Windows\System32 et celui de C:\Windows\SysWOW64 dans ce Cygwin bin dossier et toujours la même erreur (à part cela, il a ensuite dit ne peut pas charger kernel32.dll ), bien que le moniteur de processus n’ait pas montré de NAME NOT FOUND erreur plus.

Quelle magie se passe ici? J'aimerais vraiment comprendre ce qui ne va pas ici. J'apprécie toute aide.

Neon
la source

Réponses:

3

C’est un résultat inattendu de la version 2.5.2 de cygwin

https://www.cygwin.com/ml/cygwin/2016-06/msg00378.html

En guise de solution de contournement, rétrogradez le paquet cygwin en 2.5.1

matzeri
la source
"Problème résolu" Cela ne résout que le problème lorsque vous installez Ruby via le programme d'installation de Cygwin, n'est-ce pas? J'obtiens cette erreur en essayant d'installer via RVM, donc je suppose que ma seule option est de rétrograder Cygwin.
Ajedi32
Si ruby ​​n’est pas installé avec "l’installateur Cygwin", il ne s’agit pas d’un programme cygwin et je ne vois pas pourquoi il devrait se préoccuper du chargeur cygwin dll.
matzeri
RVM fonctionne en téléchargeant et en compilant Ruby à partir des sources. Donc, si vous l'exécutez dans un environnement Cygwin, les fichiers binaires résultants seront un "programme Cygwin". Quoi qu'il en soit, le déclassement de Cygwin à la version 2.5.1 a résolu mon problème.
Ajedi32
@ Ajedi32, au cas où cela poserait toujours un problème, j'ai posté une réponse pour les rubis RVM installés ci-dessous. Je ne voulais pas vraiment déclasser ma version de Cygwin!
zelanix
6

Une façon de résoudre ce problème sans changer le processus de construction de rvm est la suivante:

ln -s /cygdrive/c/Windows/System32/kernel32.dll /usr/lib/kernel32

Cela se produit parce que ruby ​​recherche une bibliothèque partagée nommée simplement kernel32. Cygwin 2.5.1 et versions antérieures ont automatiquement ajouté l’extension ".dll" aux chargements de bibliothèques partagées. Mais cygwin 2.5.2 a introduit un correctif nécessitant des noms de fichiers de bibliothèque partagés complets. Ajout d’un lien symbolique dans le chemin de recherche de la bibliothèque ( /usr/lib ) permet de retrouver la bibliothèque même chargée avec l'ancien nom.

tombrown52
la source
1
+1 IMHO cette solution est la plus soignée car il n'y a pas besoin de modifier le resolv.rb. Travaillé avec Cygwin 2.6.0 et rbenv
edwardsmatt
4

J'ai installé ruby ​​en utilisant rvm, de sorte que les fichiers binaires ruby ​​Cygwin mis à jour ne m'ont pas beaucoup aidé et que je ne voulais pas vraiment rétrograder mon installation Cygwin. Comment saurais-je que la mise à niveau est sûre?

À la suite des informations contenues dans la réponse de Michael D, le problème semble être lié à la resolv.rb fichier situé dans ~\.rvm\rubies\ruby-<version>\lib\ruby\<version>\win32 (dans mon cas ~\.rvm\rubies\ruby-2.1.7\lib\ruby\2.1.0\win32 ).

Quelque part vers le haut de ce fichier, il y a le code

module Kernel32
  extend Importer
  dlload "kernel32"
end

Changer simplement le dlload "kernel32" ligne à dlload "kernel32.dll" semblait le réparer pour moi. Alternativement en utilisant le chemin complet

dlload "c:/Windows/System32/kernel32.dll"

Cela a également fonctionné, mais il semble que l'extension soit l'élément le plus important (le chemin complet sans l'extension ne fonctionne pas non plus).

Cela a peut-être été corrigé dans une version plus récente de rvm, mais je ne voulais pas passer par les tracas de la mise à jour et de la réinstallation, cela fonctionne donc pour moi. Bien sûr, cela devrait probablement être changé pour tous les rubis installés.

zelanix
la source
Le problème est résolu depuis le 28 juin . Je ne recommande pas d'utiliser une installation rvm de Cygwin. Je n’avais que des problèmes avec cela, au plus tard lorsque des pierres précieuses doivent être compilées. Et je ne vois aucun problème avec la version de Cygwin (à part celle-ci, qui a été corrigée et pourrait être facilement contournée).
Neon
1
@Neon, je préfère utiliser rvm pour pouvoir facilement tester différentes versions de ruby ​​et utiliser des gemsets. Le problème n'a donc pas été résolu, mais chacun pour soi.
zelanix
De plus, cygwin ne fournit pas les dernières versions de ruby. Par exemple, 2.3.1 n'est pas disponible dans le dépôt. En outre, il y a des projets qui utilisation rvm en particulier, pour gérer correctement la version de ruby ​​utilisée.
Timotei
2

Le package Ruby rencontre des difficultés pour charger les bibliothèques natives (au moins kernel32.dll). Le problème vient d'un appel à dns.getresource("_rubygems._tcp.#{host}", Resolv::DNS::Resource::IN::SRV) qui fait probablement un appel natif à kernel32.dll d'où le chargement du kernel32.dll bibliothèque.

Si vous spécifiez le chemin complet de la bibliothèque, cela fonctionnera correctement.

kernel = Fiddle::Handle.new("c:/Windows/System32/kernel32.dll")

Pour résoudre le problème, essayez ce qui suit:

  1. Exiger devkit en cours d'exécution extconf.rb comme suit: ruby -rdevkit extconf.rb ou simplement en ajoutant require "devkit" à extconf.rb puis en exécutant le script normalement.
  2. Exécuter le devkitvars.bat script du devkit pour configurer le PATH avec la chaîne d’outils avant de compiler.
Michael D
la source
1
Je ne comprends pas très bien ce que vous voulez que je fasse. J'utilise juste gem, pas de scripts de mon côté. Donc, je ne suis pas en mesure de spécifier un chemin complet et je ne sais pas quel est le extconf.rb n’est ni comment ni quand l’utiliser. Je ne compile rien non plus. S'il vous plaît donner quelques instructions supplémentaires afin que je puisse tester ce que vous avez conseillé.
Neon
En savoir plus sur extconf.rb se il vous plaît se référer ici . Pour vérifier le chargement de kernel32.dll Essayez d'utiliser ce scénario.
Michael D
Je suis désolé, il me semble avoir attaché le même lien deux fois, voici le script dont j'ai parlé dans le commentaire précédent.
Michael D