Class: Kar::CargoTask::CargoBuilder

Inherits:
Gem::Ext::CargoBuilder
  • Object
show all
Defined in:
lib/kar/cargotask/cargo_builder.rb

Instance Method Summary collapse

Instance Method Details

#build(extension, dest_path, results, args = [], lib_dir = nil, cargo_dir = Dir.pwd, target_rbconfig = Gem.target_rbconfig, n_jobs: nil) ⇒ Object

Original Gem::Ext::CargoBuilder removes compiled files after installation. It is ideal for installation, but not for development. We override the behavior to keep the compiled files.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/kar/cargotask/cargo_builder.rb', line 5

def build(extension, dest_path, results, args = [], lib_dir = nil, cargo_dir = Dir.pwd,
  target_rbconfig = Gem.target_rbconfig, n_jobs: nil)
  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
    # Mimic tmp_dest to make diff with superclass's #build clean
    tmp_dest = 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
    #noop
  end

  results
end

#dl_path(extension, dest_path, cargo_dir) ⇒ Object

This intentionally duplicates part of #build to keep that method close to the upstream CargoBuilder implementation and make updates easy to review with diff.



60
61
62
63
64
65
66
# File 'lib/kar/cargotask/cargo_builder.rb', line 60

def dl_path(extension, dest_path, cargo_dir)
  cargo_toml = File.join(cargo_dir, "Cargo.toml")
  crate_name = cargo_crate_name(cargo_dir, cargo_toml, [])
  dlext_name = "#{crate_name}.#{makefile_config("DLEXT")}"
  nesting = extension_nesting(extension)
  File.join(dest_path, nesting, dlext_name)
end