1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use anyhow::{anyhow, Result};
use std::path::Path;
fn run_command(current_dir: &Path, cmd: &[&str]) -> Result<String> {
println!("Start: {:?}", cmd);
let output = std::process::Command::new(cmd[0])
.args(&cmd[1..])
.current_dir(current_dir)
.output()?;
if output.status.success() {
Ok(String::from_utf8_lossy(&output.stdout).to_string())
} else {
Err(anyhow!(format!("Executing {:?} failed", cmd)))
}
}
pub struct MRubyBuilder<'a> {
pub base_dir: &'a Path,
pub mruby_version: String,
}
impl<'a> MRubyBuilder<'a> {
pub fn link_mruby(&self) -> Result<()> {
self.internal_link_mruby(None)
}
pub fn link_mruby_with_build_config(&self, build_config_path: &Path) -> Result<()> {
self.internal_link_mruby(Some(build_config_path))
}
fn internal_link_mruby(&self, build_config_path: Option<&Path>) -> Result<()> {
let mruby_config = self.base_dir.join("mruby").join("bin").join("mruby-config");
if let Some(path) = build_config_path {
let c = &[
"rake",
"all",
&format!("MRUBY_CONFIG={}", path.to_string_lossy()),
];
run_command(&self.base_dir.join("mruby"), c)?;
} else {
let c = &["rake", "all"];
run_command(&self.base_dir.join("mruby"), c)?;
};
let ldflags_before_libs = run_command(
self.base_dir,
&[mruby_config.to_str().unwrap(), "--ldflags-before-libs"],
)?;
let ldflags = run_command(
self.base_dir,
&[mruby_config.to_str().unwrap(), "--ldflags"],
)?;
let libs = run_command(self.base_dir, &[mruby_config.to_str().unwrap(), "--libs"])?;
println!(
"cargo:rustc-flags={} {} {}",
ldflags_before_libs.trim(),
ldflags.trim(),
libs.trim()
);
Ok(())
}
pub fn download_mruby(&self) -> Result<()> {
if self.base_dir.join("mruby").exists() {
return Ok(());
}
let url = if self.mruby_version == "master" {
String::from("https://github.com/mruby/mruby/archive/refs/heads/master.tar.gz")
} else {
format!(
"https://github.com/mruby/mruby/archive/refs/tags/{}.tar.gz",
self.mruby_version
)
};
let resp = reqwest::blocking::get(url)?;
let tar_gz = resp.bytes()?;
let tar = {
use bytes::Buf;
flate2::read::GzDecoder::new(tar_gz.reader())
};
let mut archive = tar::Archive::new(tar);
archive.unpack(&self.base_dir)?;
std::fs::rename(
self.base_dir.join(format!("mruby-{}", self.mruby_version)),
self.base_dir.join("mruby"),
)?;
Ok(())
}
}