камень не работает в Cygwin

2374
Neon

На недавно установленной 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.dllfrom C:\Windows\System32и one from C:\Windows\SysWOW64в эту binпапку Cygwin и все еще получил ту же ошибку (кроме того, что он сказал, что не может загрузить kernel32.dll ), хотя Process Monitor больше не отображал NAME NOT FOUNDошибку.

Какая магия здесь происходит? Мне бы очень хотелось понять, что здесь не так. Я ценю любую помощь.

4

4 ответа на вопрос

6
tombrown52

Способ исправить это без изменения процесса сборки 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) позволяет найти библиотеку даже при загрузке с именем в старом стиле.

+1 ИМХО это решение самое лучшее, так как нет необходимости редактировать `resolv.rb`. Работал с Cygwin 2.6.0 и rbenv edwardsmatt 7 лет назад 1
4
zelanix

Я установил 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, но я не хотел проходить через обновление и переустановку, так что это работает для меня. Или, конечно, это, вероятно, нужно будет изменить для всех установленных рубинов.

[Проблема решена с 28 июня] (https://www.cygwin.com/ml/cygwin-announce/2016-06/msg00054.html). Я не рекомендую использовать установку rvm от Cygwin. У меня были только проблемы с этим, самое позднее, когда нужно было скомпилировать гемы. И я не вижу никаких проблем с версией Cygwin (кроме этой, которая была исправлена ​​и могла быть легко обойдена). Neon 8 лет назад 0
@ Неон, я предпочитаю использовать rvm, чтобы я мог легко тестировать разные версии ruby ​​и использовать наборы гемов, так что для меня проблема не была решена, но каждая из них была своей. zelanix 8 лет назад 1
Кроме того, Cygwin не предоставляет последние версии ruby. Например, 2.3.1 недоступен в репозиториях. Кроме того, есть проекты, которые * специально используют * rvm для правильного управления используемой версией ruby. Timotei 8 лет назад 0
3
matzeri

Кажется, неожиданный результат выпуска Cygwin 2.5.2

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

В качестве обходного пути, понизьте пакет Cygwin до версии 2.5.1.

Проблема решена https://www.cygwin.com/ml/cygwin-announce/2016-06/msg00054.html matzeri 8 лет назад 0
«Проблема решена» Это устраняет проблему только при установке Ruby через установщик Cygwin, верно? Я получаю эту ошибку при попытке установить через RVM, поэтому я думаю, что мой единственный вариант - понизить версию Cygwin. Ajedi32 8 лет назад 0
Если ruby ​​не установлен с «установщиком Cygwin», то это не программы cygwin, и я не понимаю, почему он должен заботиться о загрузчике cygwin dll. matzeri 8 лет назад 0
RVM работает, загружая и компилируя Ruby из исходного кода. Так что если вы запускаете его в среде Cygwin, то получающиеся двоичные файлы будут «программой Cygwin». В любом случае, понижение Cygwin до версии 2.5.1 решило мою проблему. Ajedi32 8 лет назад 0
@ Ajedi32, в случае, если это все еще проблема для вас, я разместил ответ для рубинов, установленных RVM ниже. Я действительно не хотел понижать свою версию Cygwin! zelanix 8 лет назад 0
2
Michael D

В пакете Ruby есть проблемы с загрузкой собственных библиотек (по крайней мере, kernel32.dll). Проблема возникает из-за вызова, dns.getresource("_rubygems._tcp.#", Resolv::DNS::Resource::IN::SRV)который, вероятно, делает собственный вызов, kernel32.dllследовательно, загружает kernel32.dllбиблиотеку.

Если вы укажете полный путь к библиотеке, она будет работать правильно.

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

Чтобы решить эту проблему, попробуйте следующее:

  1. Требуется, devkitесли выполняется extconf.rbследующим образом: ruby -rdevkit extconf.rbили просто добавляется, require "devkit"чтобы extconf.rbзапустить скрипт в обычном режиме.
  2. Запустите devkitvars.batсценарий из devkit для настройки PATHцепочки инструментов перед компиляцией.
Я не совсем понимаю, что вы от меня хотите. Я просто использую `gem`, никаких скриптов с моей стороны. Поэтому я не могу указать полный путь и не знаю, что такое extconf.rb, как и когда его использовать. Я тоже ничего не собираю. Пожалуйста, дайте некоторые дальнейшие инструкции, чтобы я мог проверить то, что вы посоветовали. Neon 8 лет назад 1
Чтобы узнать больше о `extconf.rb`, пожалуйста, обратитесь [здесь] (http://www.linuxtopia.org/online_books/programming_books/ruby_tutorial/Extending_Ruby_Creating_a_Makefile_with_extconf.rb.html). Чтобы проверить загрузку «kernel32.dll», попробуйте использовать скрипт [this] (http://www.linuxtopia.org/online_books/programming_books/ruby_tutorial/Extending_Ruby_Creating_a_Makefile_with_extconf.rb.html). Michael D 8 лет назад 0
Прошу прощения, я, кажется, прикрепил одну и ту же ссылку дважды, [здесь] (https://sourceforge.net/p/msys2/tickets/10/attachment/unable_to_load_kernel32_testcase.rb) скрипт, о котором я говорил в предыдущем комментарии. Michael D 8 лет назад 0