Reputation: 3113
I'm building a gem with Rust and I need to know how to run the Rust compiler when installing the gem. With a C-extension, I can use mkmf
to generate a Makefile. But how can I run cargo build --release
?
The directory structure looks like this:
.
├── bin
│ ├── console
│ └── setup
├── CODE_OF_CONDUCT.md
├── Gemfile
├── Gemfile.lock
├── lib
│ ├── rmpd_adschedule
│ │ └── version.rb
│ └── rustgem.rb
├── LICENSE.txt
├── Rakefile
├── README.md
├── rustgem.gemspec
├── rust
│ ├── Cargo.lock
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
└── spec
├── rustgem.rb
└── spec_helper.rb
I've created a Rake task to build the Rust library:
task :compile do
sh "cd #{File.dirname(__FILE__)}/rust && cargo build --release"
end
But how to run this Rake task when installing the gem? Or how to generate a suitable Makefile with mkmf
? The Makefile should look like this:
all:
cd rust/ && cargo build --release
But it doesn't work if I put it into the root directory, and I don't know how to tell mkmf
to generate this exact Makefile.
I found one stupid way to do this when the gem is loading:
module Rustgem
system("cd #{File.dirname(__FILE__)}/../rust && cargo build --release")
end
But this is not a good solution.
Upvotes: 0
Views: 406
Reputation: 3113
Turns out I can do this:
# rust/extconf.rb
require 'mkmf'
create_makefile 'rust/rustgem'
system("cd #{File.dirname(__FILE__)} && cargo build --release")
In this case, create_makefile
will create an empty Makefile. Then make will return 0 make: Nothing to be done for 'all'.
which is what we need, and then system
call will do the work.
Or somewhat better:
require 'mkmf'
create_makefile 'rutgem'
File.write('Makefile', "all:\n\tcargo build --release\nclean:\n\trm -rf target\ninstall: ;")
I'm not sure if this is good solution. If you know a better one please tell it.
UPDATE
Actually, you can put Makefile
along with empty extconf.rb
in the same directory and it will work. Blog post about Ruby-Rust integration: http://undefined-reference.org/2016/05/14/writing-rubygem-in-rust.html
Upvotes: 2