rb_sys 0.9.63 → 0.9.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52407f94f77dfbef05d18940ac493f58192b704c64bfa30a023498e2a78c42d6
4
- data.tar.gz: 25d5c1894e187b3208933d3c7874923c44f77fb0fbdbc68e63800430dfba3378
3
+ metadata.gz: da8a462e7210f1746cca7dd9935d243b179176318aa766474fc33dd2de71227c
4
+ data.tar.gz: 7cd4a0126f7240b2b58ee3338dceec912d1cd9de211adc55a6f4da320fa982cc
5
5
  SHA512:
6
- metadata.gz: 4df8ead8517d700e6690fd52e74ccf67c7b8fcd74fbbacf4a7fb9dca6bffc2da8ef8f6803c55159011030f0cf3b703d8015d29ab71ea078ef3d9649f2653247e
7
- data.tar.gz: c87238853cb91b0e9bbd5deb0b1eba7ce0463812da6a9aac7c3d6695ba9102c411b0c41724c5a6fcbad2c19885447d184b7836c93240ae4d43712caf16b8c2e6
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
+ ```
@@ -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.63"
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.63
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