Created
January 3, 2021 09:38
-
-
Save leostera/3e42a685ee1a6c33d8f796e1038b0146 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use super::archive::Archive; | |
use super::IntoToolchainBuilder; | |
use super::ToolchainBuilder; | |
use anyhow::{anyhow, Context}; | |
use log::debug; | |
use std::collections::HashMap; | |
use std::collections::HashSet; | |
use std::io::{BufRead, BufReader, Write}; | |
use std::path::PathBuf; | |
use std::process::{Command, Stdio}; | |
#[derive(Debug, Clone)] | |
pub struct Toolchain { | |
archive: Archive, | |
root: PathBuf, | |
erl: PathBuf, | |
erlc: PathBuf, | |
} | |
impl Default for Toolchain { | |
fn default() -> Toolchain { | |
let archive = Archive::default() | |
.with_url("https://github.com/erlang/otp/archive/OTP-23.1.tar.gz".to_string()) | |
.with_sha1("2d6eaefe960f52cc79d7614c11256b73174e4161".to_string()) | |
.with_prefix("otp-OTP-23.1".to_string()); | |
let erl = PathBuf::from("erl"); | |
let erlc = PathBuf::from("erlc"); | |
let root = PathBuf::from("."); | |
Toolchain { | |
archive, | |
erl, | |
erlc, | |
root, | |
} | |
} | |
} | |
impl Toolchain { | |
pub fn root(&self) -> &PathBuf { | |
&self.root | |
} | |
pub fn archive(&self) -> &Archive { | |
&self.archive | |
} | |
pub fn with_archive(self, archive: Archive) -> Toolchain { | |
Toolchain { archive, ..self } | |
} | |
pub fn with_root(self, root: PathBuf) -> Toolchain { | |
let root = root | |
.join(self.name()) | |
.join(self.archive().hash()) | |
.join(self.archive().prefix()); | |
let erl = root.join("bin").join("erl"); | |
let erlc = root.join("bin").join("erlc"); | |
Toolchain { | |
root, | |
erl, | |
erlc, | |
..self | |
} | |
} | |
pub fn name(&self) -> String { | |
"erlang".to_string() | |
} | |
} | |
impl IntoToolchainBuilder for Toolchain { | |
fn toolchain_builder(&self) -> ToolchainBuilder { | |
let root = self.root.clone(); | |
let erlc = self.erlc.clone(); | |
let is_cached = Box::new(move || Ok(std::fs::metadata(erlc.clone()).is_ok())); | |
let build_toolchain = Box::new(move || { | |
let root = root.clone(); | |
debug!("Starting to build Erlang toolchain at: {:?}", root); | |
let otp_build = std::fs::canonicalize(root.join("otp_build")) | |
.context("Could not find otp_build!")?; | |
let otp_build = Command::new(otp_build) | |
.args(&["autoconf"]) | |
.current_dir(&root) | |
.output() | |
.context("Could not spawn otp_build")?; | |
if otp_build.status.success() { | |
Ok(()) | |
} else { | |
std::io::stdout().write_all(&otp_build.stdout).unwrap(); | |
std::io::stderr().write_all(&otp_build.stderr).unwrap(); | |
Err(anyhow!("Error running otp_build")) | |
}?; | |
let configure = std::fs::canonicalize(root.join("configure")) | |
.context("Could not find configure!")?; | |
let configure = Command::new(configure) | |
.current_dir(&root) | |
.output() | |
.context("Could not spawn configure")?; | |
if configure.status.success() { | |
Ok(()) | |
} else { | |
std::io::stdout().write_all(&configure.stdout).unwrap(); | |
std::io::stderr().write_all(&configure.stderr).unwrap(); | |
Err(anyhow!("Error running configure")) | |
}?; | |
debug!("Erlang: running make -j32 in {:?}", &root); | |
let make = Command::new("make") | |
.stdout(Stdio::piped()) | |
.args(&["-j32"]) | |
.current_dir(&root) | |
.output() | |
.context("Could not spawn make")?; | |
debug!("Erlang: {:?}", &make.status.success()); | |
if make.status.success() { | |
Ok(()) | |
} else { | |
std::io::stdout().write_all(&make.stdout).unwrap(); | |
std::io::stderr().write_all(&make.stderr).unwrap(); | |
Err(anyhow!("Error running make")) | |
} | |
}); | |
ToolchainBuilder { | |
name: self.name(), | |
archive: self.archive().clone(), | |
is_cached, | |
build_toolchain, | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment