Support defining custom lua include and lib pathes

This commit is contained in:
Alex Orlenko 2019-09-30 22:41:09 +01:00
parent 2e5762f6e5
commit 9e06b10e50
1 changed files with 90 additions and 44 deletions

View File

@ -1,47 +1,69 @@
use std::env; use std::env;
use std::io; use std::fs::File;
use std::path::PathBuf; use std::io::{BufRead, BufReader, Error, ErrorKind, Result};
use std::ops::Bound;
use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
trait CommandExt { trait CommandExt {
fn execute(&mut self) -> io::Result<()>; fn execute(&mut self) -> Result<()>;
} }
impl CommandExt for Command { impl CommandExt for Command {
/// Execute the command and return an error if it exited with a failure status. /// Execute the command and return an error if it exited with a failure status.
fn execute(&mut self) -> io::Result<()> { fn execute(&mut self) -> Result<()> {
self.status().map(|_| ()).map_err(|_| { self.status()
io::Error::new( .and_then(|status| {
io::ErrorKind::Other, if status.success() {
format!( Ok(())
"The command\n\ } else {
\t{:?}\n\ Err(Error::new(ErrorKind::Other, "non-zero exit code"))
did not run successfully.", }
self })
), .map_err(|_| {
Error::new(
ErrorKind::Other,
format!("The command {:?} did not run successfully.", self),
) )
}) })
} }
} }
fn main() { fn use_custom_lua<S: AsRef<str>>(include_dir: &S, lib_dir: &S, lua_lib: &S) -> Result<String> {
let lua = pkg_config::Config::new() let mut version_found = String::new();
.atleast_version("5.1")
.probe("lua")
.unwrap();
// Find LUA_VERSION_NUM
let mut lua_h_path = PathBuf::from(include_dir.as_ref());
lua_h_path.push("lua.h");
let f = File::open(lua_h_path)?;
let reader = BufReader::new(f);
for line in reader.lines() {
let line = line?;
let parts = line.split_whitespace().collect::<Vec<_>>();
if parts.len() == 3 && parts[1] == "LUA_VERSION_NUM" {
version_found = parts[2].to_string();
}
}
println!("cargo:rustc-link-search=native={}", lib_dir.as_ref());
println!("cargo:rustc-link-lib={}", lua_lib.as_ref());
Ok(version_found)
}
fn build_glue<P: AsRef<Path> + std::fmt::Debug>(include_paths: &[P]) {
let build_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); let build_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
// Ensure the presence of glue.rs // Ensure the presence of glue.rs
if !build_dir.join("glue.rs").exists() { // if build_dir.join("glue.rs").exists() {
// return;
// }
let mut config = cc::Build::new(); let mut config = cc::Build::new();
for path in lua.include_paths { for path in include_paths {
config.include(path); config.include(path);
} }
for (k, v) in lua.defines {
config.define(&k, v.as_ref().map(|x| x.as_str()));
}
// Compile and run glue.c // Compile and run glue.c
let glue = build_dir.join("glue"); let glue = build_dir.join("glue");
@ -59,5 +81,29 @@ fn main() {
.arg(build_dir.join("glue.rs")) .arg(build_dir.join("glue.rs"))
.execute() .execute()
.unwrap(); .unwrap();
} }
fn main() {
let include_dir = env::var("LUA_INCLUDE_DIR").unwrap_or(String::new());
let lib_dir = env::var("LUA_LIB_DIR").unwrap_or(String::new());
let lua_lib = env::var("LUA_LIB_NAME").unwrap_or(String::new());
println!("cargo:rerun-if-env-changed=LUA_INCLUDE_DIR");
println!("cargo:rerun-if-env-changed=LUA_LIB_DIR");
println!("cargo:rerun-if-env-changed=LUA_LIB_NAME");
if include_dir != "" && lib_dir != "" && lua_lib != "" {
let _version = use_custom_lua(&include_dir, &lib_dir, &lua_lib).unwrap();
build_glue(&[include_dir]);
return;
}
// Find lua via pkg-config
let lua = pkg_config::Config::new()
.range_version((Bound::Included("5.3"), Bound::Excluded("5.4")))
.probe("lua")
.unwrap();
build_glue(&lua.include_paths);
} }