-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
hack our way around missing
libcrypt
in cross-compilation (#438)
- Loading branch information
1 parent
2bcedef
commit 52fe52c
Showing
1 changed file
with
39 additions
and
3 deletions.
There are no files selected for viewing
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
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(()) | ||
} |