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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.yardopts +3 -0
- data/README.md +98 -0
- data/lib/rb_sys/cargo/metadata.rb +69 -18
- data/lib/rb_sys/error.rb +13 -7
- data/lib/rb_sys/mkmf.rb +21 -0
- data/lib/rb_sys/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +5 -4
- metadata.gz.sig +0 -0
- data/sig/rb_sys.rbs +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: da8a462e7210f1746cca7dd9935d243b179176318aa766474fc33dd2de71227c
|
|
4
|
+
data.tar.gz: 7cd4a0126f7240b2b58ee3338dceec912d1cd9de211adc55a6f4da320fa982cc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: be81aba075a717c61a156cfcfafba1b9e7b36a33a045a2f04372b1c8244dd4280c0ebcc113fdc5c468bf72e49b6aaa8eff8d20784706ac779bab80e64d09ae04
|
|
7
|
+
data.tar.gz: 3fa8cb0393b6cbbd53cba685b8616e5b747556ea583b8e943ec54b93a938b6b0f6610768c545e28076eb9806afb92108e1bdf6e0e2f9d78b6cdaf05666fa6bd9
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/.yardopts
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# The `rb_sys` gem
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
[](https://www.rubydoc.info/gems/rb_sys/frames)
|
|
5
|
+
[](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
|
-
#
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
#
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
49
|
+
# Returns the path to the package's Cargo.toml.
|
|
37
50
|
#
|
|
38
51
|
# @return [String]
|
|
39
|
-
def
|
|
40
|
-
|
|
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,
|
|
60
|
-
|
|
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
|
|
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
|
|
22
|
+
def initialize(err, stderr)
|
|
23
23
|
msg = <<~MSG.chomp.tr("\n", " ")
|
|
24
|
-
Could not
|
|
25
|
-
is valid. The error was: #{err}
|
|
24
|
+
Could not infer Rust crate information using `cargo metadata`.
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
Original error was:
|
|
27
|
+
#{err.class}: #{err.message}
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
data/lib/rb_sys/version.rb
CHANGED
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.
|
|
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-
|
|
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
|
-
-
|
|
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