Камень не работает в 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с цепочкой инструментов перед компиляцией.