class Gem::Ext::CargoBuilder
This class is used by rubygems to build Rust extensions. It is a thin-wrapper over the ‘cargo rustc` command which takes care of building Rust code in a way that Ruby can use.
Attributes
profile
[RW]
runner
[RW]
spec
[RW]
Public Class Methods
new
()
# File lib/rubygems/ext/cargo_builder.rb, line 11 def initialize require_relative "../command" require_relative "cargo_builder/link_flag_converter" @runner = self.class.method(:run) @profile = :release end
Public Instance Methods
build
(extension, dest_path, results, args = [], lib_dir = nil, cargo_dir = Dir.pwd, target_rbconfig=Gem.target_rbconfig)
# File lib/rubygems/ext/cargo_builder.rb, line 19 def build(extension, dest_path, results, args = [], lib_dir = nil, cargo_dir = Dir.pwd, target_rbconfig=Gem.target_rbconfig) require "tempfile" require "fileutils" if target_rbconfig.path warn "--target-rbconfig is not yet supported for Rust extensions. Ignoring" end # Where's the Cargo.toml of the crate we're building cargo_toml = File.join(cargo_dir, "Cargo.toml") # What's the crate's name crate_name = cargo_crate_name(cargo_dir, cargo_toml, results) begin # Create a tmp dir to do the build in tmp_dest = Dir.mktmpdir(".gem.", cargo_dir) # Run the build cmd = cargo_command(cargo_toml, tmp_dest, args, crate_name) runner.call(cmd, results, "cargo", cargo_dir, build_env) # Where do we expect Cargo to write the compiled library dylib_path = cargo_dylib_path(tmp_dest, crate_name) # Helpful error if we didn't find the compiled library raise DylibNotFoundError, tmp_dest unless File.exist?(dylib_path) # Cargo and Ruby differ on how the library should be named, rename from # what Cargo outputs to what Ruby expects dlext_name = "#{crate_name}.#{makefile_config("DLEXT")}" dlext_path = File.join(File.dirname(dylib_path), dlext_name) FileUtils.cp(dylib_path, dlext_path) nesting = extension_nesting(extension) if Gem.install_extension_in_lib && lib_dir nested_lib_dir = File.join(lib_dir, nesting) FileUtils.mkdir_p nested_lib_dir FileUtils.cp_r dlext_path, nested_lib_dir, remove_destination: true end # move to final destination nested_dest_path = File.join(dest_path, nesting) FileUtils.mkdir_p nested_dest_path FileUtils.cp_r dlext_path, nested_dest_path, remove_destination: true ensure # clean up intermediary build artifacts FileUtils.rm_rf tmp_dest if tmp_dest end results end
build_env
()
# File lib/rubygems/ext/cargo_builder.rb, line 73 def build_env build_env = rb_config_env build_env["RUBY_STATIC"] = "true" if ruby_static? && ENV.key?("RUBY_STATIC") cfg = "--cfg=rb_sys_gem --cfg=rubygems --cfg=rubygems_#{Gem::VERSION.tr(".", "_")}" build_env["RUSTFLAGS"] = [ENV["RUSTFLAGS"], cfg].compact.join(" ") build_env end
cargo_command
(cargo_toml, dest_path, args = [], crate_name = nil)
# File lib/rubygems/ext/cargo_builder.rb, line 81 def cargo_command(cargo_toml, dest_path, args = [], crate_name = nil) cmd = [] cmd += [cargo, "rustc"] cmd += ["--crate-type", "cdylib"] cmd += ["--target", ENV["CARGO_BUILD_TARGET"]] if ENV["CARGO_BUILD_TARGET"] cmd += ["--target-dir", dest_path] cmd += ["--manifest-path", cargo_toml] cmd += ["--lib"] cmd += ["--profile", profile.to_s] cmd += ["--locked"] cmd += Gem::Command.build_args cmd += args cmd += ["--"] cmd += [*cargo_rustc_args(dest_path, crate_name)] cmd end