Until the other day, I was researching How to build a native extension of Ruby with Rust, but finally I was able to publish it as ruby gems. I've given it a pretty bold name.
hello_rust_gem
RubyGems: https://rubygems.org/gems/hello_rust GitHub: https://github.com/irxground/hello_rust_gem (It would be very helpful if you could review the code !!)
This gem itself is meaningless, and I created it for the purpose of being a reference when I want to write a Ruby gem in Rust.
hello_rust_gem does not depend on any other library. (However, libraries used during development such as rspec
are excluded)
require "hello_rust"
p HelloRust::VERSION
src/lib.rs
This file is the body of Ruby's native extension.
It's not a big deal because it only contains the definitions of the HelloRust
module and the HelloRust :: VERSION
constants.
When writing a real native extension, you can extend it here.
Cargo.toml
Rust project definition. Only the crate-type = ["cdylib "]
part is important
build.rs
I'm generating settings for linking the Ruby API from Rust code. build.rs
is called automatically when you do cargo build
.
lib/hello_rust.rb
This will be the file that will be read when you require" hello_rust "
from the outside.
If you suddenly load the native library, you may be in trouble when you want to write Ruby code, so it is good to make the first entrance a Ruby file. Rather, bundle gem --ext
is so, so I followed it.
There is require" hello_rust/hello_rust "
in it, but the native library is loaded in this part.
hello_rust.gemspec
A file to write RubyGems settings. This time, as an example, I tried to reuse the data written in Cargo.toml
, but it is not necessary to do so. (However, updating the version number is easy to make a mistake, so it may be better to put it in one place as in this example)
The important part is spec.extensions = ["ext/Rakefile "]
gem install
will deploy the source code and then run ext/Rakefile
to build the native extension.
Rakefile
Rakefile for the rake
command used by developers
Erase the artifacts with rake
, build and run the test.
Rust and Ruby formatters run on rake fmt
.
See rake -T
for more.
ext/Rakefile
As written in gemspec, it is called during gem install
.
An environment variable called RUBYLIBDIR
is passed, so place the native library there.
This time, the file path will be $ RUBYLIBDIR/hello_rust/hello_rust.so
(for Linux) so that it can be read byrequire "hello_rust/hello_rust"
.
ext/build_task.rb
When developing locally and when installing the gem, you will have to compile and place the library in the appropriate path, so I've summarized the common parts here.
When building on Windows, the RUSTUP_TOOLCHAIN
environment variable is set.
Ruby entered by RubyInstaller is mingw, but Rust on Windows can be selected from two types, mingw and msvc, so to force mingw.
The rest is tests, license files, etc.
spec/hello_rust_spec.rb
tests HelloRust :: VERSION
, which is minimal but notices that the native library will fail to compile.
I have confirmed that it works on most platforms, so I would like to enhance CI.
Recommended Posts