Module: Rubycc::GemPlugin

Defined in:
lib/rubygems_plugin.rb

Constant Summary collapse

LIB_DIR =

This file lives at lib/rubygems_plugin.rb, so dir is the gem's lib/ and the executables sit at ../exe relative to it.

__dir__
RMAKE_EXE =
File.expand_path("../exe/rmake", __dir__)
PKGCONF_EXE =
File.expand_path("../exe/rubycc-pkgconf", __dir__)
MKMF_SHIM_FEATURE =

The require the extconf child needs so mkmf's conftests route to rubycc.

"rubycc/mkmf_shim"
AUTO_ENABLE_ABSENT_TOOLS =

The external programs whose absence (all three) turns rubycc on by default: a host with no C compiler and no make is one that cannot build extensions the conventional way, which is exactly where rubycc takes over.

%w[cc gcc make].freeze

Class Method Summary collapse

Class Method Details

.auto_enable?Boolean

The unset-RUBYCC default: on only when none of the conventional tools is available, so a host that already has gcc/make is left completely alone.

Returns:

  • (Boolean)


57
58
59
# File 'lib/rubygems_plugin.rb', line 57

def auto_enable?
  AUTO_ENABLE_ABSENT_TOOLS.none? { |tool| on_path?(tool) }
end

.enabled?Boolean

Whether the rubycc build path should be active for this process.

Returns:

  • (Boolean)


47
48
49
50
51
52
53
# File 'lib/rubygems_plugin.rb', line 47

def enabled?
  case ENV["RUBYCC"]
  when "1" then true
  when "0" then false
  else auto_enable?
  end
end

.install!Object

Inject the environment that makes the RubyGems extension build use rubycc.



62
63
64
65
66
67
# File 'lib/rubygems_plugin.rb', line 62

def install!
  ENV["MAKE"] = RMAKE_EXE
  ENV["PKG_CONFIG"] = PKGCONF_EXE
  prepend_path_entry("RUBYLIB", LIB_DIR)
  prepend_ruby_require(MKMF_SHIM_FEATURE)
end

.on_path?(name) ⇒ Boolean

A PATH lookup that spawns nothing: scan the PATH directories for an executable file of that name (the same resolution command -v performs).

Returns:

  • (Boolean)


71
72
73
74
75
76
77
78
# File 'lib/rubygems_plugin.rb', line 71

def on_path?(name)
  ENV["PATH"].to_s.split(File::PATH_SEPARATOR).any? do |dir|
    next false if dir.empty?

    candidate = File.join(dir, name)
    File.file?(candidate) && File.executable?(candidate)
  end
end

.prepend_path_entry(var, dir) ⇒ Object

Prepend dir to a PATH-style environment variable (RUBYLIB) unless it is already the leading entry — so the extconf child can require rubycc from this gem's lib/.



83
84
85
86
87
88
# File 'lib/rubygems_plugin.rb', line 83

def prepend_path_entry(var, dir)
  entries = ENV[var].to_s.split(File::PATH_SEPARATOR)
  return if entries.first == dir

  ENV[var] = [dir, *entries].join(File::PATH_SEPARATOR)
end

.prepend_ruby_require(feature) ⇒ Object

Add -r<feature> to RUBYOPT (at the front, so the shim loads before the extconf script's own requires) unless it is already present.



92
93
94
95
96
97
98
# File 'lib/rubygems_plugin.rb', line 92

def prepend_ruby_require(feature)
  flag = "-r#{feature}"
  current = ENV["RUBYOPT"].to_s
  return if current.split(/\s+/).include?(flag)

  ENV["RUBYOPT"] = current.empty? ? flag : "#{flag} #{current}"
end