Skip to content

Commit

Permalink
Merge pull request #48 from d-xo/nixos-support
Browse files Browse the repository at this point in the history
  • Loading branch information
roynalnaruto authored Jun 23, 2022
2 parents 7f03150 + 84687f2 commit 40227b8
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub enum SolcVmError {
ChecksumMismatch(String),
#[error("Install step for solc version {0} timed out after {1} seconds")]
Timeout(String, u64),
#[error("Unable to patch solc binary for nixos. stdout: {0}. stderr: {1}")]
CouldNotPatchForNixOs(String, String),
#[error(transparent)]
IoError(#[from] std::io::Error),
#[error(transparent)]
Expand Down
34 changes: 32 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use once_cell::sync::Lazy;
use semver::Version;
use semver::{Version, VersionReq};
use sha2::Digest;

use std::{
ffi::OsString,
fs,
io::{Cursor, Write},
path::PathBuf,
process::Command,
};

use std::time::Duration;
Expand Down Expand Up @@ -43,6 +44,9 @@ pub static SVM_HOME: Lazy<PathBuf> = Lazy::new(|| {
/// The timeout to use for requests to the source
const REQUEST_TIMEOUT: Duration = Duration::from_secs(120);

/// Version beyond which solc binaries are not fully static, hence need to be patched for NixOS.
static NIXOS_PATCH_REQ: Lazy<VersionReq> = Lazy::new(|| VersionReq::parse(">=0.8.0").unwrap());

// Installer type that copies binary data to the appropriate solc binary file:
// 1. create target file to copy binary data
// 2. copy data
Expand All @@ -68,7 +72,33 @@ impl Installer {
let mut content = Cursor::new(&self.binbytes);
std::io::copy(&mut content, &mut f)?;

Ok(solc_path)
if platform::is_nixos() && NIXOS_PATCH_REQ.matches(&self.version) {
patch_for_nixos(solc_path)
} else {
Ok(solc_path)
}
}
}

/// Patch the given binary to use the dynamic linker provided by nixos
pub fn patch_for_nixos(bin: PathBuf) -> Result<PathBuf, SolcVmError> {
let output = Command::new("nix-shell")
.arg("-p")
.arg("patchelf")
.arg("--run")
.arg(format!(
"patchelf --set-interpreter \"$(cat $NIX_CC/nix-support/dynamic-linker)\" {}",
bin.display()
))
.output()
.expect("Failed to execute command");

match output.status.success() {
true => Ok(bin),
false => Err(SolcVmError::CouldNotPatchForNixOs(
String::from_utf8(output.stdout).expect("Found invalid UTF-8 when parsing stdout"),
String::from_utf8(output.stderr).expect("Found invalid UTF-8 when parsing stderr"),
)),
}

/// Extracts the solc archive at the version specified destination and returns the path to the
Expand Down
4 changes: 4 additions & 0 deletions src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ impl FromStr for Platform {
}
}

pub fn is_nixos() -> bool {
std::path::Path::new("/etc/NIXOS").exists()
}

/// Read the current machine's platform.
pub fn platform() -> Platform {
match (env::consts::OS, env::consts::ARCH) {
Expand Down

0 comments on commit 40227b8

Please sign in to comment.