Class: RubyInstaller::Build::Msys2Installation
Do not use. This class is for internal use only.
Relationships & Source Files | |
Namespace Children | |
Exceptions:
| |
Inherits: | Object |
Defined in: | lib/ruby_installer/build/msys2_installation.rb |
Constant Summary
-
MSYS2_INSTALL_KEY =
# File 'lib/ruby_installer/build/msys2_installation.rb', line 7"SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall/"
-
MSYS2_INSTALL_KEY_WOW =
# File 'lib/ruby_installer/build/msys2_installation.rb', line 8"SOFTWARE/WOW6432Node/Microsoft/Windows/CurrentVersion/Uninstall/"
Class Method Summary
Instance Attribute Summary
- #mingw_package_prefix readonly
- #mingwarch readonly
- #mingwdir readonly
- #ruby_bin_dir readonly
Instance Method Summary
- #disable_dll_search_paths
- #disable_msys_apps(if_no_msys: :hint)
-
#disable_msys_apps_per_cmd
This method is used for the ridk command.
-
#disable_msys_apps_per_ps1
This method is used for the ridk command.
- #enable_dll_search_paths
- #enable_msys_apps(if_no_msys: :hint, for_gem_install: false)
-
#enable_msys_apps_per_cmd
This method is used for the ridk command.
-
#enable_msys_apps_per_ps1
This method is used for the ridk command.
- #install_mingw_packages(packages, verbose: false)
- #install_packages(packages, verbose: false)
- #iterate_msys_paths {|File.join(RbConfig::TOPDIR, "msys64")| ... }
- #mingw_bin_path
- #mingw_prefix
- #msys_bin_path
- #msys_path
- #reset_cache
- #with_msys_apps_disabled(**args)
- #with_msys_apps_enabled(**args)
- #backslachs(path) private
- #msys_apps_envvars private
- #with_msys_install_hint(if_no_msys = :hint) private
Instance Attribute Details
#mingw_package_prefix (readonly)
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 17
attr_reader :mingw_package_prefix
#mingwarch (readonly)
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 16
attr_reader :mingwarch
#mingwdir (readonly)
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 15
attr_reader :mingwdir
#ruby_bin_dir (readonly)
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 18
attr_reader :ruby_bin_dir
Instance Method Details
#backslachs(path) (private)
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 143
private def backslachs(path) path.gsub("/", "\\") end
#disable_dll_search_paths
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 138
def disable_dll_search_paths @mingwdir.remove if @mingwdir @mingwdir = nil end
#disable_msys_apps(if_no_msys: :hint)
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 240
def disable_msys_apps(if_no_msys: :hint) vars = with_msys_install_hint(if_no_msys) do msys_apps_envvars end changed = false if path=vars.delete("PATH") old_path = ENV['PATH'] ENV['PATH'] = old_path.gsub(path + ";", "") changed = ENV['PATH'] != old_path end vars.each do |key, val| changed = true if ENV[key] ENV.delete(key) end changed end
#disable_msys_apps_per_cmd
This method is used for the ridk command.
# File 'lib/ruby_installer/build/msys2_installation.rb', line 288
def disable_msys_apps_per_cmd vars = with_msys_install_hint{ msys_apps_envvars } str = "".dup if path=vars.delete("PATH") str << "PATH=#{ ENV['PATH'].gsub(path + ";", "") }\n" end str << vars.map do |key, val| "#{key}=" end.join("\n") end
#disable_msys_apps_per_ps1
This method is used for the ridk command.
# File 'lib/ruby_installer/build/msys2_installation.rb', line 311
def disable_msys_apps_per_ps1 vars = with_msys_install_hint{ msys_apps_envvars } str = "".dup if path=vars.delete("PATH") str << "$env:PATH=\"#{ ENV['PATH'].gsub(path + ";", "").gsub('"', '`"') }\";" end str << vars.map do |key, val| "$env:#{key}=''" end.join(";") end
#enable_dll_search_paths
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 128
def enable_dll_search_paths @mingwdir ||= begin DllDirectory.set_defaults path = mingw_bin_path DllDirectory.new(path) if File.directory?(path) rescue MsysNotFound # We silently ignore this error to allow Ruby installations without MSYS2. end end
#enable_msys_apps(if_no_msys: :hint, for_gem_install: false)
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 215
def enable_msys_apps(if_no_msys: :hint, for_gem_install: false) vars = with_msys_install_hint(if_no_msys) do msys_apps_envvars end changed = false if (path=vars.delete("PATH")) && !ENV['PATH'].include?(path) phrase = "Temporarily enhancing PATH for MSYS/MINGW..." if for_gem_install && defined?(Gem) Gem.ui.say(phrase) if Gem.configuration.verbose elsif $DEBUG $stderr.puts phrase end changed = true ENV['PATH'] = path + ";" + ENV['PATH'] end vars.each do |key, val| changed = true if ENV[key] != val ENV[key] = val end changed end
#enable_msys_apps_per_cmd
This method is used for the ridk command.
# File 'lib/ruby_installer/build/msys2_installation.rb', line 277
def enable_msys_apps_per_cmd vars = with_msys_install_hint{ msys_apps_envvars } if (path=vars.delete("PATH")) && !ENV['PATH'].include?(path) vars['PATH'] = path + ";" + ENV['PATH'] end vars.map do |key, val| "#{key}=#{val}" end.join("\n") end
#enable_msys_apps_per_ps1
This method is used for the ridk command.
# File 'lib/ruby_installer/build/msys2_installation.rb', line 300
def enable_msys_apps_per_ps1 vars = with_msys_install_hint{ msys_apps_envvars } if (path=vars.delete("PATH")) && !ENV['PATH'].include?(path) vars['PATH'] = path + ";" + ENV['PATH'] end vars.map do |key, val| "$env:#{key}=\"#{val.gsub('"', '`"')}\"" end.join(";") end
#install_mingw_packages(packages, verbose: false)
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 349
def install_mingw_packages(packages, verbose: false) packages = packages.map{|pack| "#{mingw_package_prefix}-#{pack}" } install_packages(packages, verbose: verbose) end
#install_packages(packages, verbose: false)
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 322
def install_packages(packages, verbose: false) return if packages.empty? with_msys_apps_enabled do # Find packages that are already installed skips, installs = packages.partition do |package| IO.popen(["pacman", "-Q", package], err: :out, &:read) $?.success? end Gem.ui.say("Using msys2 packages: #{skips.join(" ")}") if verbose && skips.any? # Install required packages if installs.any? Gem.ui.say("Installing required msys2 packages: #{installs.join(" ")}") if verbose args = ["pacman", "-S", "--needed", "--noconfirm", *installs] Gem.ui.say("> #{args.join(" ")}") if verbose==1 res = IO.popen(args, &:read) raise CommandError, "pacman failed with the following output:\n#{res}" if !$? || $?.exitstatus != 0 Gem.ui.say(res) if verbose==1 end end end
#iterate_msys_paths {|File.join(RbConfig::TOPDIR, "msys64")| ... }
# File 'lib/ruby_installer/build/msys2_installation.rb', line 48
def iterate_msys_paths # Prefer MSYS2_PATH if ENV set if ENV["MSYS2_PATH"] yield ENV["MSYS2_PATH"] end # Prefer MSYS2 when installed within the ruby directory. yield File.join(RbConfig::TOPDIR, "msys64") yield File.join(RbConfig::TOPDIR, "msys32") # Then try MSYS2 next to the ruby directory. yield File.join(File.dirname(RbConfig::TOPDIR), "msys64") yield File.join(File.dirname(RbConfig::TOPDIR), "msys32") # If msys2 is installed at the default location yield "c:/msys64" yield "c:/msys32" # If msys2 is installed per installer.exe require "win32/registry" [ [Win32::Registry::HKEY_CURRENT_USER, MSYS2_INSTALL_KEY], [Win32::Registry::HKEY_CURRENT_USER, MSYS2_INSTALL_KEY_WOW], [Win32::Registry::HKEY_LOCAL_MACHINE, MSYS2_INSTALL_KEY], [Win32::Registry::HKEY_LOCAL_MACHINE, MSYS2_INSTALL_KEY_WOW], ].each do |reg_root, base_key| begin reg_root.open(backslachs(base_key)) do |reg| reg.each_key do |subkey| subreg = reg.open(subkey) begin if subreg['DisplayName'] =~ /^MSYS2 / && File.directory?(il=subreg['InstallLocation']) yield il end rescue Encoding::InvalidByteSequenceError, Win32::Registry::Error # Ignore entries without valid installer data or broken character encoding end end rescue Encoding::InvalidByteSequenceError, Encoding::UndefinedConversionError # Avoid crash even if subkey includes inconvertible characters to internal encoding end rescue Win32::Registry::Error end end ENV['PATH'] && ENV['PATH'].split(";").each do |path| # If /path/to/msys64 is in the PATH (e.g. Chocolatey) yield path end # If msys2 is installed by scoop package manager begin yield IO.popen(["scoop", "prefix", "msys2"], &:read).strip rescue SystemCallError end raise MsysNotFound, "MSYS2 could not be found" end
#mingw_bin_path
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 120
def mingw_bin_path backslachs( File.join(msys_path, mingwarch, "bin") ) end
#mingw_prefix
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 124
def mingw_prefix "/#{mingwarch}" end
#msys_apps_envvars (private)
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 147
private def msys_apps_envvars vars = {} msys_bin = msys_bin_path mingw_bin = mingw_bin_path ruby_bin = backslachs( ruby_bin_dir ) ridkusepath = ENV["RIDK_USE_PATH"] vars['PATH'] = [ridkusepath, ruby_bin, mingw_bin, msys_bin].compact.join(";") vars['RI_DEVKIT'] = msys_path vars['MSYSTEM'] = mingwarch.upcase vars['PKG_CONFIG_PATH'] = "#{mingw_prefix}/lib/pkgconfig:#{mingw_prefix}/share/pkgconfig" vars['ACLOCAL_PATH'] = "#{mingw_prefix}/share/aclocal:/usr/share/aclocal" vars['MANPATH'] = "#{mingw_prefix}/share/man" vars['MINGW_PACKAGE_PREFIX'] = mingw_package_prefix if ENV['TMP'] !~ /\A[ -~]*\z/ # TMP has some Unicode characters -> use MSYS2's /tmp to work around incompat with gcc's temporary files vars['TMP'] = backslachs( msys_path + "/tmp" ) end case mingwarch when 'mingw32' vars['MSYSTEM_PREFIX'] = '/mingw32' vars['MSYSTEM_CARCH'] = 'i686' vars['MSYSTEM_CHOST'] = 'i686-w64-mingw32' vars['MINGW_CHOST'] = vars['MSYSTEM_CHOST'] vars['MINGW_PREFIX'] = vars['MSYSTEM_PREFIX'] when 'mingw64' vars['MSYSTEM_PREFIX'] = '/mingw64' vars['MSYSTEM_CARCH'] = 'x86_64' vars['MSYSTEM_CHOST'] = 'x86_64-w64-mingw32' vars['MINGW_CHOST'] = vars['MSYSTEM_CHOST'] vars['MINGW_PREFIX'] = vars['MSYSTEM_PREFIX'] when 'ucrt64' vars['MSYSTEM_PREFIX'] = '/ucrt64' vars['MSYSTEM_CARCH'] = 'x86_64' vars['MSYSTEM_CHOST'] = 'x86_64-w64-mingw32' vars['MINGW_CHOST'] = vars['MSYSTEM_CHOST'] vars['MINGW_PREFIX'] = vars['MSYSTEM_PREFIX'] else raise "unknown mingwarch #{@mingwarch.inspect}" end begin locale = IO.popen([File.join(msys_bin, "locale"), "-uU"], &:read) rescue SystemCallError else vars['LANG'] = locale=~/UTF-8/ ? locale.to_s.strip : 'C' end vars end
#msys_bin_path
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 116
def msys_bin_path backslachs( File.join(msys_path, "/usr/bin") ) end
#msys_path
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 106
def msys_path @msys_path ||= begin iterate_msys_paths do |path| if File.exist?(File.join(path, "usr/bin/msys-2.0.dll")) break backslachs(path) end end end end
#reset_cache
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 44
def reset_cache @msys_path = nil unless @msys_path_fixed end
#with_msys_apps_disabled(**args)
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 267
def with_msys_apps_disabled(**args) changed = disable_msys_apps(**args) begin yield ensure enable_msys_apps(**args) if changed end end
#with_msys_apps_enabled(**args)
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 258
def with_msys_apps_enabled(**args) changed = enable_msys_apps(**args) begin yield ensure disable_msys_apps(**args) if changed end end
#with_msys_install_hint(if_no_msys = :hint) (private)
[ GitHub ]# File 'lib/ruby_installer/build/msys2_installation.rb', line 198
private def with_msys_install_hint(if_no_msys = :hint) case if_no_msys when :hint begin yield rescue MsysNotFound $stderr.puts "MSYS2 could not be found. Please run 'ridk install'" $stderr.puts "or download and install MSYS2 manually from https://msys2.github.io/" exit 1 end when :raise yield else raise ArgumentError, "invalid value #{if_no_msys.inspect} for variable if_no_msys" end end