rb_sys 0.9.62 → 0.9.64

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb45d1f47ed05580f9d5e9d1799b17c9f29dc503846a70b579db5817c65efb25
4
- data.tar.gz: 758e642b26c85bd37cb1787131a223958cd93d7358c44ccc99a9dc889f089b29
3
+ metadata.gz: da8a462e7210f1746cca7dd9935d243b179176318aa766474fc33dd2de71227c
4
+ data.tar.gz: 7cd4a0126f7240b2b58ee3338dceec912d1cd9de211adc55a6f4da320fa982cc
5
5
  SHA512:
6
- metadata.gz: 728591453d68f544915dfaaf0fbf2d66a55f72879542853f8c7dab8a1313a23bd85c78cd7befa1ffc3dbecccbef5f565ae0a5998a0801cf0798d9a0315360fc5
7
- data.tar.gz: d9c3344159a08fe66f227adb5bf65b1c2fe7307ded78536da7760ea0cdf6c4806e9e955a1edd70b2b6efb99202d40903390657cc2ebeadde8918533a189c0b90
6
+ metadata.gz: be81aba075a717c61a156cfcfafba1b9e7b36a33a045a2f04372b1c8244dd4280c0ebcc113fdc5c468bf72e49b6aaa8eff8d20784706ac779bab80e64d09ae04
7
+ data.tar.gz: 3fa8cb0393b6cbbd53cba685b8616e5b747556ea583b8e943ec54b93a938b6b0f6610768c545e28076eb9806afb92108e1bdf6e0e2f9d78b6cdaf05666fa6bd9
checksums.yaml.gz.sig CHANGED
Binary file
data/.yardopts ADDED
@@ -0,0 +1,3 @@
1
+ --no-private
2
+ --list-undoc
3
+ 'lib/**/*.rb'
data/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # The `rb_sys` gem
2
+
3
+ ![Gem](https://img.shields.io/gem/v/rb_sys)
4
+ [![Documentation](https://img.shields.io/badge/docs-rdoc.info-blue.svg)](https://www.rubydoc.info/gems/rb_sys/frames)
5
+ [![Join the discussion](https://img.shields.io/badge/slack-chat-blue.svg)](https://join.slack.com/t/oxidize-rb/shared_invite/zt-16zv5tqte-Vi7WfzxCesdo2TqF_RYBCw)
6
+
7
+ The `rb_sys` gem is a Ruby gem makes it easy to build native Ruby extensions in Rust. It interops with the existing Ruby
8
+ native extension toolchains (i.e. `rake-compiler`) to make testing, building, and cross compilation of gems easy.
9
+
10
+ ## `RbSys::ExtensionTask`
11
+
12
+ This gem provides a `RbSys::ExtensionTask` class that can be used to build a Ruby extension in Rust. It's a thin wrapper
13
+ around `Rake::ExtensionTask` that provides sane defaults for building Rust extensions.
14
+
15
+ ```ruby
16
+ # Rakefile
17
+
18
+ require "rb_sys/extensiontask"
19
+
20
+ GEMSPEC = Gem::Specification.load("my_gem.gemspec")
21
+
22
+ RbSys::ExtensionTask.new("my-crate-name", GEMSPEC) do |ext|
23
+ ext.lib_dir = "lib/my_gem"
24
+ end
25
+ ```
26
+
27
+ ## `create_rust_makefile`
28
+
29
+ This gem provides a simple helper to build a Ruby compatible Makefile for you Rust extension. For a full example, see
30
+ the [examples](./../examples) directory.
31
+
32
+ ```ruby
33
+ # ext/rust_reverse/extconf.rb
34
+
35
+ # We need to require mkmf *first* this since `rake-compiler` injects code here for cross compilation
36
+ require "mkmf"
37
+ require "rb_sys/mkmf"
38
+
39
+ create_rust_makefile("rust_reverse") do |r|
40
+ # Create debug builds in dev. Make sure that release gems are compiled with
41
+ # `RB_SYS_CARGO_PROFILE=release` (optional)
42
+ r.profile = ENV.fetch("RB_SYS_CARGO_PROFILE", :dev).to_sym
43
+
44
+ # Can be overridden with `RB_SYS_CARGO_FEATURES` env var (optional)
45
+ r.features = ["test-feature"]
46
+
47
+ # You can add whatever env vars you want to the env hash (optional)
48
+ r.env = {"FOO" => "BAR"}
49
+
50
+ # If your Cargo.toml is in a different directory, you can specify it here (optional)
51
+ r.ext_dir = "."
52
+
53
+ # Extra flags to pass to the $RUSTFLAGS environment variable (optional)
54
+ r.extra_rustflags = ["--cfg=some_nested_config_var_for_crate"]
55
+
56
+ # Force a rust toolchain to be installed via rustup (optional)
57
+ # You can also set the env var `RB_SYS_FORCE_INSTALL_RUST_TOOLCHAIN=true`
58
+ r.force_install_rust_toolchain = "stable"
59
+
60
+ # Clean up the target/ dir after `gem install` to reduce bloat (optional)
61
+ r.clean_after_install = false # default: true if invoked by rubygems
62
+
63
+ # Auto-install Rust toolchain if not present on "gem install" (optional)
64
+ r.auto_install_rust_toolchain = false # default: true if invoked by rubygems
65
+ end
66
+ ```
67
+
68
+ ## Tips and Tricks
69
+
70
+ - When using `rake-compiler` to build your gem, you can use the `RB_SYS_CARGO_PROFILE` environment variable to set the
71
+ Cargo profile (i.e. `release` or `dev`).
72
+
73
+ - You can pass Cargo arguments to `rake-compiler` like so: `rake compile -- --verbose`
74
+
75
+ - It's possible to force an installation of a Rust toolchain by setting the `RB_SYS_FORCE_INSTALL_RUST_TOOLCHAIN`
76
+ environment variable. This will install [rustup](https://rustup.rs/) and [cargo](https://crates.io/) in the build
77
+ directory, so the end user does not have to have Rust pre-installed. Ideally, this should be a last resort, as it's
78
+ better to already have the toolchain installed on your system.
79
+
80
+ ## Troubleshooting
81
+
82
+ ### Libclang issues
83
+
84
+ If you see an error like this:
85
+
86
+ ```
87
+ thread 'main' panicked at 'Unable to find libclang: "couldn't find any valid shared libraries matching: \['libclang.so', 'libclang-*.so', 'libclang.so.*', 'libclang-*.so.*'\], set the `LIBCLANG_PATH` environment variable to a path where one of these files can be found (invalid: \[\])"'
88
+ ```
89
+
90
+ This means that bindgen is having issues finding a usable version of libclang. An easy way to fix this is to install the
91
+ [`libclang` gem](https://github.com/oxidize-rb/libclang-rb), which will install a pre-built version of libclang for you.
92
+ `rb_sys` will automatically detect this gem and use it.
93
+
94
+ ```ruby
95
+ # Gemfile
96
+
97
+ gem "libclang", "~> 14.0.6"
98
+ ```
data/exe/rb-sys-dock CHANGED
@@ -300,8 +300,10 @@ def download_image(options)
300
300
  end
301
301
  end
302
302
 
303
- def log_some_useful_info(_options)
304
- if ARGV.empty? && !options[:build]
303
+ def log_some_useful_info(options)
304
+ return if options[:build]
305
+
306
+ if ARGV.empty?
305
307
  log(:notice, "Entering shell in Docker container #{ENV["RCD_IMAGE"].inspect}")
306
308
  else
307
309
  log(:notice, "Running command #{ARGV.inspect} in Docker container #{ENV["RCD_IMAGE"].inspect}")
@@ -9,35 +9,83 @@ module RbSys
9
9
  class Metadata
10
10
  attr_reader :name
11
11
 
12
+ # Initializes a new Cargo::Metadata instance.
13
+ #
14
+ # @param name [String] the name of the Cargo project
12
15
  def initialize(name)
13
16
  raise ArgumentError, "name must be a String" unless name.is_a?(String)
14
17
 
15
18
  @name = name
16
19
  end
17
20
 
18
- # @api private
19
- def self.delegates_to_cargo_metadata(*methods)
20
- methods.each do |method|
21
- define_method(method) { cargo_metadata.fetch(method.to_s) }
22
- end
21
+ # Returns the path where the Cargo project's Cargo.toml is located.
22
+ #
23
+ # @return [String]
24
+ def manifest_directory
25
+ @manifest_directory ||= File.dirname(manifest_path)
23
26
  end
24
27
 
25
- # @api private
26
- def self.delegates_to_package_metadata(*methods)
27
- methods.each do |method|
28
- define_method(method) { package_metadata.fetch(method.to_s) }
29
- end
28
+ # Returns the target directory for the Cargo project.
29
+ #
30
+ # @return [String]
31
+ def target_directory
32
+ cargo_metadata.fetch("target_directory")
30
33
  end
31
34
 
32
- delegates_to_cargo_metadata :target_directory, :workspace_root, :packages
35
+ # Returns the workspace root for the Cargo project.
36
+ #
37
+ # @return [String]
38
+ def workspace_root
39
+ cargo_metadata.fetch("workspace_root")
40
+ end
33
41
 
34
- delegates_to_package_metadata :manifest_path, :version, :id, :edition, :targets, :features, :metadata
42
+ # Returns the workspace members for the Cargo project.
43
+ #
44
+ # @return [Array<Hash>]
45
+ def packages
46
+ cargo_metadata.fetch("packages")
47
+ end
35
48
 
36
- # Returns the path where the Cargo project's Cargo.toml is located.
49
+ # Returns the path to the package's Cargo.toml.
37
50
  #
38
51
  # @return [String]
39
- def manifest_directory
40
- @manifest_directory ||= File.dirname(manifest_path)
52
+ def manifest_path
53
+ package_metadata.fetch("manifest_path")
54
+ end
55
+
56
+ # Returns the package's version.
57
+ #
58
+ # @return [String]
59
+ def version
60
+ package_metadata.fetch("version")
61
+ end
62
+
63
+ # Returns the package's id.
64
+ #
65
+ # @return [String]
66
+ def id
67
+ package_metadata.fetch("id")
68
+ end
69
+
70
+ # Returns the package's Rust edition.
71
+ #
72
+ # @return [String]
73
+ def edition
74
+ package_metadata.fetch("edition")
75
+ end
76
+
77
+ # Returns the package's features.
78
+ #
79
+ # @return [Array<String>]
80
+ def features
81
+ package_metadata.fetch("features")
82
+ end
83
+
84
+ # Returns the package's custom metadata.
85
+ #
86
+ # @return [Hash]
87
+ def metadata
88
+ package_metadata.fetch("metadata")
41
89
  end
42
90
 
43
91
  private
@@ -56,10 +104,13 @@ module RbSys
56
104
  ::Gem.load_yaml
57
105
  cargo = ENV["CARGO"] || "cargo"
58
106
  args = ["metadata", "--no-deps", "--format-version", "1"]
59
- out, stderr, _status = Open3.capture3(cargo, *args)
60
- @cargo_metadata = Gem::SafeYAML.safe_load(out)
107
+ out, stderr, status = Open3.capture3(cargo, *args)
108
+ raise "exited with non-zero status (#{status})" unless status.success?
109
+ data = Gem::SafeYAML.safe_load(out)
110
+ raise "metadata must be a Hash" unless data.is_a?(Hash)
111
+ @cargo_metadata = data
61
112
  rescue => err
62
- raise CargoMetadataError.new(err, stderr, manifest_path)
113
+ raise CargoMetadataError.new(err, stderr)
63
114
  end
64
115
  end
65
116
  end
data/lib/rb_sys/error.rb CHANGED
@@ -19,18 +19,24 @@ module RbSys
19
19
 
20
20
  # Raised when Cargo metadata cannot be parsed.
21
21
  class CargoMetadataError < Error
22
- def initialize(err, stderr, manifest_path)
22
+ def initialize(err, stderr)
23
23
  msg = <<~MSG.chomp.tr("\n", " ")
24
- Could not parse Cargo metadata. Please check that your Cargo.toml
25
- is valid. The error was: #{err}
24
+ Could not infer Rust crate information using `cargo metadata`.
26
25
 
27
- Looking for this Cargo.toml: #{manifest_path.inspect}
26
+ Original error was:
27
+ #{err.class}: #{err.message}
28
28
 
29
- Stderr
30
- ------
31
- #{stderr}
29
+ Things to check:
30
+ - Check that your ext/*/Cargo.toml at is valid
31
+ - If you are using a workspace, make sure you are the root Cargo.toml exists
32
+ - Make sure `cargo` is installed and in your PATH
32
33
  MSG
33
34
 
35
+ if !stderr.empty?
36
+ indented_stderr = stderr.lines.map { |line| " #{line}" }.join
37
+ msg << "Stderr from `cargo metadata` was:\n#{indented_stderr}"
38
+ end
39
+
34
40
  super(msg)
35
41
  end
36
42
  end
data/lib/rb_sys/mkmf.rb CHANGED
@@ -59,6 +59,7 @@ module RbSys
59
59
  #{conditional_assign("CARGO", "cargo")}
60
60
  #{conditional_assign("CARGO_BUILD_TARGET", builder.target)}
61
61
  #{conditional_assign("SOEXT", builder.so_ext)}
62
+ #{try_load_bundled_libclang(builder)}
62
63
 
63
64
  # Determine the prefix Cargo uses for the lib.
64
65
  #{if_neq_stmt("$(SOEXT)", "dll")}
@@ -317,6 +318,26 @@ module RbSys
317
318
  end
318
319
  end
319
320
 
321
+ def try_load_bundled_libclang(_builder)
322
+ require "libclang"
323
+ assert_libclang_version_valid!
324
+ export_env("LIBCLANG_PATH", Libclang.libdir)
325
+ rescue LoadError
326
+ # If we can't load the bundled libclang, just continue
327
+ end
328
+
329
+ def assert_libclang_version_valid!
330
+ libclang_version = Libclang.version
331
+
332
+ if libclang_version < Gem::Version.new("5.0.0")
333
+ raise "libclang version 5.0.0 or greater is required (current #{libclang_version})"
334
+ end
335
+
336
+ if libclang_version >= Gem::Version.new("15.0.0")
337
+ raise "libclang version > 14.0.0 or greater is required (current #{libclang_version})"
338
+ end
339
+ end
340
+
320
341
  def set_cargo_profile(builder)
321
342
  return assign_stmt("RB_SYS_CARGO_PROFILE", "release") if builder.rubygems_invoked?
322
343
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RbSys
4
- VERSION = "0.9.62"
4
+ VERSION = "0.9.64"
5
5
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rb_sys
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.62
4
+ version: 0.9.64
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian Ker-Seymer
@@ -30,7 +30,7 @@ cert_chain:
30
30
  Rl+ASkq2/1i07TkBpCf+2hq66+h/hx+/Y/KrUzXfe0jtvil0WESkJT2kqRqHWNhD
31
31
  9GKBxaQlXokNDtWCm1/gl6cD8WRZ0N5S4ZGJT1FLLsA=
32
32
  -----END CERTIFICATE-----
33
- date: 2023-02-06 00:00:00.000000000 Z
33
+ date: 2023-02-07 00:00:00.000000000 Z
34
34
  dependencies: []
35
35
  description:
36
36
  email:
@@ -40,8 +40,10 @@ executables:
40
40
  extensions: []
41
41
  extra_rdoc_files: []
42
42
  files:
43
+ - ".yardopts"
43
44
  - LICENSE-APACHE
44
45
  - LICENSE-MIT
46
+ - README.md
45
47
  - certs/ianks.pem
46
48
  - exe/rb-sys-dock
47
49
  - lib/rb_sys.rb
@@ -56,8 +58,7 @@ files:
56
58
  - lib/rb_sys/toolchain_info.rb
57
59
  - lib/rb_sys/toolchain_info/data.rb
58
60
  - lib/rb_sys/version.rb
59
- - sig/rb_sys.rbs
60
- homepage: https://github.com/oxidize-rb/rb-sys
61
+ homepage: https://oxidize-rb.github.io/rb-sys/
61
62
  licenses:
62
63
  - MIT
63
64
  - Apache-2.0
metadata.gz.sig CHANGED
Binary file
data/sig/rb_sys.rbs DELETED
@@ -1,4 +0,0 @@
1
- module RbSys
2
- VERSION: String
3
- # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
- end