題 寶石不在Cygwin工作


在新安裝的Windows 7 Professional 64 Bit上,我安裝了Cygwin(64)及其一些軟件包,包括Ruby。我也使用Ruby安裝程序安裝了Ruby,因為我可能需要它來支持默認的Windows shell和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 CMD的本機Windows版本,它可以正常工作。然而,我不能使用來自Cygwin的原生Windows Ruby東西,因為這給了我錯誤,但這不是問題。

使用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
2018-06-27 12:22


起源




答案:


這似乎是cygwin 2.5.2發布的意外結果

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

解決方法是將cygwin軟件包降級到2.5.1


3
2018-06-27 14:09



問題解決了 cygwin.com/ml/cygwin-announce/2016-06/msg00054.html - matzeri
“問題解決了”只能通過Cygwin安裝程序安裝Ruby時解決問題,對吧?我在嘗試通過RVM安裝時遇到此錯誤,所以我想我唯一的選擇是降級Cygwin。 - Ajedi32
如果ruby沒有安裝“Cygwin安裝程序”而不是一個cygwin程序,我不明白它為什麼要關心cygwin dll loader。 - matzeri
RVM的工作原理是從源代碼下載和編譯Ruby。因此,如果您在Cygwin環境中運行它,那么生成的二進製文件將是“Cygwin程序”。無論如何,將Cygwin降級到2.5.1確實解決了我的問題。 - Ajedi32
@ Ajedi32,如果這仍然是你的問題,我在下面發布了RVM安裝紅寶石的答案。我真的不想降級我的Cygwin版本! - zelanix


在不更改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)即使加載了舊式名稱,也可以找到庫。


6
2017-10-07 20:46



+1恕我直言這個解決方案是最好的,因為沒有必要編輯 resolv.rb。使用Cygwin 2.6.0和rbenv - edwardsmatt


我使用rvm安裝了ruby,所以更新的Cygwin ruby​​二進製文件沒什麼幫助,我真的不想降級我的Cygwin安裝 - 我怎麼知道什麼時候再安全升級?

根據Michael D的回答,問題似乎在於 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中修復,但我不想經歷更新和重新安裝的麻煩,所以這對我有用。或者,對於所有已安裝的紅寶石,可能需要更改。


4
2017-08-04 21:06



這個問題自6月28日起就解決了。我不建議使用Cygwin的rvm安裝。我只是遇到了問題,最遲需要編譯寶石。而且我沒有看到Cygwin版本的任何問題(除了這個,已經修復並且可以輕鬆完成)。 - Neon
@Neon,我更喜歡使用rvm以便我可以輕鬆測試不同的ruby版本並使用gemsets,所以對我來說問題沒有解決,但每個都是他們自己的。 - zelanix
此外,cygwin不提供最新的ruby版本。例如,回購中沒有2.3.1。此外,還有一些項目 使用 特別是rvm,以正確管理使用的ruby版本。 - Timotei


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")

要解決此問題,請嘗試以下操作:

  1. 要求 devkit 跑步的時候 extconf.rb 如下: ruby -rdevkit extconf.rb ,或只是添加 require "devkit" 至 extconf.rb 然後正常運行腳本。
  2. 跑過 devkitvars.bat 來自devkit的腳本來配置 PATH 在編譯之前使用工具鏈。

2
2018-06-27 12:41



我不太明白你想讓我做什麼。我正在使用 gem,沒有來自我身邊的腳本。所以我無法指定完整路徑,我不知道是什麼 extconf.rb 是不是如何或何時使用它。我也沒有編譯任何東西。請提供一些進一步的說明,以便我可以測試您的建議。 - Neon
要了解更多信息 extconf.rb 請參考 這裡。要檢查加載 kernel32.dll 試著用 這個 腳本。 - Michael D
對不起,我好像已經連了兩次相同的鏈接, 這裡的 我在之前的評論中談過的腳本。 - Michael D