Skip to content

Commit

Permalink
hack our way around missing libcrypt in cross-compilation (#438)
Browse files Browse the repository at this point in the history
  • Loading branch information
froydnj authored and reese-stripe committed Sep 12, 2023
1 parent 2bcedef commit 52fe52c
Showing 1 changed file with 39 additions and 3 deletions.
42 changes: 39 additions & 3 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,47 @@
fn main() {
use std::env;
use std::error::Error;

type Output = Result<(), Box<dyn Error>>;

fn main() -> Output {
// this is wild
#[cfg(target_os = "macos")]
{
println!("cargo:rustc-link-lib=framework=foundation");
println!("cargo:rustc-link-lib=framework=security");
}

#[cfg(target_os = "linux")]
println!("cargo:rustc-link-lib=dylib=crypt");
let target = env::var("TARGET").ok();
let host = env::var("HOST").ok();

// This is an enormous hack. Normally on Linux, Ruby would use
// libcrypt functions libruby-static.a would contain references to
// such functions, and we would need to specify -lcrypt via the
// link line below.
//
// But on a vanilla cross-compilation setup on Ubuntu, libcrypt
// doesn't exist for cross-compilation. Ruby is OK with that (its
// configure script will detect the absence of a linkable
// libcrypt) and therefore in such a situation we would not need
// to specify -lcrypt. Ruby's rbconfig.rb file, generated by its
// configure script, will helpfully include information about the
// presence or absence of libcrypt on the system.
//
// But we can't access that Ruby configuration information here:
// we have no control over when the build script for this crate
// runs vs. the build script for librubyfmt, and it is the latter
// that configures Ruby and generates the very files that we would
// need to look at to make the determination of whether to specify
// -lcrypt.
//
// So instead we make an assumption: if our target and host are
// different, then we're running in a vanilla-ish Ubuntu
// environment where libcrypt wouldn't be available. In a more
// full-featured cross-compilation setup, this assumption is
// invalid, but it works well enough for our purposes.
if cfg!(target_os = "linux") && target.zip(host).map(|(t, h)| t == h).unwrap_or(false) {
println!("cargo:rustc-link-lib=dylib=crypt");
}

Ok(())
}

0 comments on commit 52fe52c

Please sign in to comment.