1

There are some batch files in the Ruby installation that reference this Ruby exe ($~dp0ruby.exe). For example, gem.bat (note the last line)

@ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
ECHO.This version of Ruby has not been built with support for Windows 95/98/Me.
GOTO :EOF
:WinNT
@"%~dp0ruby.exe" "%~dpn0" %*

But, some gems get a batch file that references the system Ruby (ruby.exe), whichever one is on the PATH. For example, bundle.bat

@ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
@"ruby.exe" "C:/Ruby192/bin/bundle" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
@"ruby.exe" "%~dpn0" %*

I have an isolated Ruby environment for a .NET project (where it's unlikely that the developers or build agents have a system Ruby). But, many gems (bundler, rake, etc) are trying to execute in a non-existent system Ruby.

C:\
  Ruby192\            <-- System Ruby, would be here
    bin\                  and this bin would be in the
      bundle.bat          PATH
      gem.bat
      ruby.exe

  <some-other-path>\  <-- An isolated environment, in
    Ruby\                 my problem, this is deployed 
      bin\                to a build agent
        bundle.bat
        gem.bat
        ruby.exe

What gives? Is this a defect in the way that rubygems creates the batch file?

def windows_stub_script(bindir, bin_file_name)
  ruby = File.basename(Gem.ruby).chomp('"')
  return <<-TEXT
@ECHO OFF
IF NOT "%~f0" == "~f0" GOTO :WinNT
@"#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
@"#{ruby}" "%~dpn0" %*
TEXT
end

What's the thinking of not referencing the ruby.exe that you used to gem install this gem? Am I just doing it wrong? Should I require a system Ruby and then using Bundler or something to isolate it?

4

1 に答える 1

3

私は、あなたが示した最初のバッチ ファイルを作成した RubyInstaller プロジェクトのメンテナーの 1 人です。

Ruby がコンパイルされると、Ruby がビルドする生成されたバッチ ファイルを独自のバッチ ファイルに置き換えます。batch_stub

このスタブ%~dp0は、これらのバッチ ファイルが実行可能ファイルに沿っていることがわかっているため、このバッチ ファイルに関連する Ruby の実行可能ファイルの場所と見なされます。

Gem は、Ruby のツリー内だけでなく、どこにでもインストールできます (たとえば、Bundler またはgem install --install-dirまたはを使用して--bindir)。

このような場合、 RubyGems バッチ ファイルを使用%~dp0して Ruby を特定することはできませ ruby.exeん。

あなたが指摘したように、問題は、作業中の分離されたインストールではなく、グローバルな Ruby インストールを含むruby.exeから見つかることです。PATH

簡単な修正PATHとして、この分離された Ruby のディレクトリを先頭に追加します。

SET PATH=C:\<some-other-path>\Ruby\bin;%PATH%

setenv.batRubyの実行前に(または起動スクリプトとして)環境を調整するようなバッチファイルに入れることができます。

もう 1 つの方法は、gem-exefyのようなものを使用することです。これは、実行可能なスタブのバッチ ファイルを置き換え、それに関連して見つかった Ruby dll を使用するため、グローバル バージョンではなく分離バージョンを使用します。

宿題については、実行する実行可能ファイルを探すためにbundle exec使用するので、うまくいくかどうかわからないので、詳しくは言えません。PATH

これで、RubyGems によって生成されたバッチ ファイルが RubyInstaller によって生成されたものと異なる理由が説明されることを願っています。

于 2012-09-19T15:23:05.123 に答える