mirror of
https://github.com/Noratrieb/cargo-minimize.git
synced 2026-01-14 16:35:01 +01:00
Make dylib_flag cross-platform
This commit is contained in:
parent
8c8172c55d
commit
cf6706ebd6
5 changed files with 42 additions and 44 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
|
@ -101,7 +101,7 @@ dependencies = [
|
|||
"clap",
|
||||
"ctrlc",
|
||||
"genemichaels",
|
||||
"libc",
|
||||
"libloading",
|
||||
"owo-colors",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -354,6 +354,16 @@ version = "0.2.148"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.7"
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ anyhow = "1.0.65"
|
|||
clap = { version = "4.0.29", features = ["derive"] }
|
||||
ctrlc = "3.2.5"
|
||||
genemichaels = "0.1.21"
|
||||
libloading = "0.8.0"
|
||||
owo-colors = "3.5.0"
|
||||
proc-macro2 = { version = "1.0.48", features = ["span-locations"] }
|
||||
quote = "1.0.23"
|
||||
|
|
@ -33,6 +34,3 @@ tracing = "0.1.37"
|
|||
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
|
||||
tracing-tree = "0.2.2"
|
||||
walkdir = "2.3.2"
|
||||
|
||||
[target."cfg(unix)".dependencies]
|
||||
libc = "0.2.138"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
//! Handles the --verify-fn flag.
|
||||
//! It takes in a Rust closure like `|str| true` that takes in a `&str` and returns a bool.
|
||||
|
||||
use std::{fmt::Debug, str::FromStr};
|
||||
use std::{fmt::Debug, mem::ManuallyDrop, str::FromStr};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use libloading::Symbol;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct RawOutput {
|
||||
|
|
@ -24,7 +25,7 @@ impl FromStr for RustFunction {
|
|||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Self::compile(s)
|
||||
Self::compile(s).context("compiling and loading rust function")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -83,17 +84,9 @@ fn wrap_func_body(func: &str) -> Result<String> {
|
|||
}
|
||||
|
||||
impl RustFunction {
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
pub fn compile(body: &str) -> Result<Self> {
|
||||
Err(anyhow::anyhow!("--verify-fn only works on unix"))
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn compile(body: &str) -> Result<Self> {
|
||||
use anyhow::bail;
|
||||
use std::io;
|
||||
use std::process::Command;
|
||||
use std::{ffi::CString, os::unix::prelude::OsStringExt};
|
||||
|
||||
let file = tempfile::tempdir()?;
|
||||
|
||||
|
|
@ -103,9 +96,17 @@ impl RustFunction {
|
|||
|
||||
std::fs::write(&source_path, full_file).context("writing source")?;
|
||||
|
||||
let library_path = file.path().join("libhelper");
|
||||
|
||||
let mut rustc = Command::new("rustc");
|
||||
rustc.arg(source_path);
|
||||
rustc.args(["--crate-type=cdylib", "--crate-name=helper", "--emit=link"]);
|
||||
rustc.args([
|
||||
"--crate-type=cdylib",
|
||||
"--crate-name=helper",
|
||||
"--emit=link",
|
||||
"-o",
|
||||
]);
|
||||
rustc.arg(&library_path);
|
||||
rustc.current_dir(file.path());
|
||||
|
||||
let output = rustc.output().context("running rustc")?;
|
||||
|
|
@ -114,29 +115,19 @@ impl RustFunction {
|
|||
bail!("Failed to compile code: {stderr}");
|
||||
}
|
||||
|
||||
let dylib_path = file.path().join("libhelper.so");
|
||||
// SAFETY: We are loading a simple rust cdylib, which does not do weird things. But we cannot unload Rust dylibs, so we use MD below.
|
||||
let dylib = unsafe {
|
||||
libloading::Library::new(&library_path).context("loading helper shared library")?
|
||||
};
|
||||
let dylib = ManuallyDrop::new(dylib);
|
||||
|
||||
let os_str = dylib_path.into_os_string();
|
||||
let vec = os_str.into_vec();
|
||||
let cstr = CString::new(vec)?;
|
||||
let func: Symbol<CheckerCFn> = unsafe {
|
||||
dylib
|
||||
.get(b"cargo_minimize_ffi_function\0")
|
||||
.context("failed to find entrypoint symbol")?
|
||||
};
|
||||
|
||||
let dylib = unsafe { libc::dlopen(cstr.as_ptr(), libc::RTLD_LAZY) };
|
||||
|
||||
if dylib.is_null() {
|
||||
bail!("failed to open dylib: {}", io::Error::last_os_error());
|
||||
}
|
||||
|
||||
let symbol = b"cargo_minimize_ffi_function\0";
|
||||
|
||||
let func = unsafe { libc::dlsym(dylib, symbol.as_ptr().cast()) };
|
||||
|
||||
if func.is_null() {
|
||||
bail!("didn't find entrypoint symbol");
|
||||
}
|
||||
|
||||
let func = unsafe { std::mem::transmute::<*mut _, CheckerCFn>(func) };
|
||||
|
||||
Ok(Self { func })
|
||||
Ok(Self { func: *func })
|
||||
}
|
||||
|
||||
pub fn call(&self, output: &str, code: Option<i32>) -> bool {
|
||||
|
|
@ -169,7 +160,6 @@ mod tests {
|
|||
use super::RustFunction;
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(not(target_os = "linux"), ignore)]
|
||||
fn basic_contains_work() {
|
||||
let code = r#"|output| output.out.contains("test")"#;
|
||||
|
||||
|
|
|
|||
|
|
@ -198,7 +198,8 @@ impl PassController {
|
|||
fn next_in_worklist(&mut self) {
|
||||
let PassControllerState::Bisecting {
|
||||
current, worklist, ..
|
||||
} = &mut self.state else {
|
||||
} = &mut self.state
|
||||
else {
|
||||
unreachable!("next_in_worklist called on non-bisecting state");
|
||||
};
|
||||
match worklist.pop() {
|
||||
|
|
|
|||
|
|
@ -62,10 +62,9 @@ impl Minimizer {
|
|||
suggestions: &HashMap<&Path, Vec<&Suggestion>>,
|
||||
) -> Result<()> {
|
||||
for (sugg_file, suggestions) in suggestions {
|
||||
let Some(file) = self
|
||||
.files
|
||||
.iter()
|
||||
.find(|source| source.path.ends_with(sugg_file) || sugg_file.ends_with(&source.path)) else {
|
||||
let Some(file) = self.files.iter().find(|source| {
|
||||
source.path.ends_with(sugg_file) || sugg_file.ends_with(&source.path)
|
||||
}) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue