Камень не работает в Cygwin
На недавно установленной Windows 7 Professional 64 Bit я установил Cygwin (64) и некоторые его пакеты, включая Ruby. Я также установил Ruby с помощью установщика Ruby, потому что он, вероятно, понадобится как для стандартных оболочек Windows, так и для Cygwin.
Теперь, когда я пытаюсь выполнить gem
команда как gem list
или же gem install foo
Я получаю странную ошибку, которую не удалось устранить в течение последних нескольких часов поиска в Интернете.
$ 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
Однако с родной версией Windows, из Windows CMD, она работает без проблем. Однако я не могу использовать нативную Windows Ruby от Cygwin, потому что это дает мне ошибки, но в любом случае это не вопрос.
С Process Monitor я понял, что Ruby пытается открыть C:\cygwin64\bin\kernel32.dll
и терпит неудачу, потому что этот файл не существует. Я пытался скопировать kernel32.dll
от C:\Windows\System32
и один из C:\Windows\SysWOW64
в этот Cygwin bin
папку и все еще получил ту же ошибку (кроме того, что он сказал, что не может загрузить kernel32.dll), хотя Process Monitor не отображал NAME NOT FOUND
ошибка больше.
Какая магия здесь происходит? Мне бы очень хотелось понять, что здесь не так. Я ценю любую помощь.
4 ответа
Кажется, неожиданный результат выпуска Cygwin 2.5.2
https://www.cygwin.com/ml/cygwin/2016-06/msg00378.html
Как обходной путь, понизьте пакет cygwin до 2.5.1
Способ исправить это без изменения процесса сборки rvm:
ln -s /cygdrive/c/Windows/System32/kernel32.dll /usr/lib/kernel32
Это происходит потому, что ruby ищет общую библиотеку с именем просто kernel32
, Cygwin 2.5.1 и более ранние версии автоматически добавляли расширение ".dll" к загрузке совместно используемой библиотеки. Но Cygwin 2.5.2 представил патч, требующий полных имен общих библиотек. Добавление символической ссылки в пути поиска библиотеки (/usr/lib
) позволяет найти библиотеку даже при загрузке с именем в старом стиле.
Я установил ruby с помощью rvm, поэтому обновленные бинарные файлы Cygwin для ruby не сильно помогли, и я не хотел отказываться от установки моей системы Cygwin - как узнать, когда будет безопасно обновлять снова?
После информации в ответе Майкла Д. проблема, как представляется, заключается в resolv.rb
файл находится в ~\.rvm\rubies\ruby-<version>\lib\ruby\<version>\win32
(в моем случае ~\.rvm\rubies\ruby-2.1.7\lib\ruby\2.1.0\win32
).
Где-то в верхней части этого файла есть код
module Kernel32
extend Importer
dlload "kernel32"
end
Просто меняя dlload "kernel32"
линия к dlload "kernel32.dll"
казалось, это исправить для меня. Альтернативно, используя полный путь
dlload "c:/Windows/System32/kernel32.dll"
также сработало, но, кажется, это решающее значение - расширение (полный путь без расширения также не работает).
Возможно, это было исправлено в более поздней версии rvm, но я не хотел проходить через обновление и переустановку, так что это работает для меня. Или, конечно, это, вероятно, необходимо изменить для всех установленных рубинов.
В пакете Ruby есть проблемы с загрузкой собственных библиотек (по крайней мере, kernel32.dll). Проблема исходит от звонка dns.getresource("_rubygems._tcp.#{host}", Resolv::DNS::Resource::IN::SRV)
которые, вероятно, делают родной вызов kernel32.dll
следовательно, загрузка kernel32.dll
библиотека.
Если вы укажете полный путь к библиотеке, она будет работать правильно.
kernel = Fiddle::Handle.new("c:/Windows/System32/kernel32.dll")
Чтобы решить эту проблему, попробуйте следующее:
- требовать
devkit
при бегеextconf.rb
следующее:ruby -rdevkit extconf.rb
или просто добавивrequire "devkit"
вextconf.rb
затем запустить скрипт нормально. - Запустить
devkitvars.bat
скрипт из devkit для настройкиPATH
с цепочкой инструментов перед компиляцией.