diff --git a/build.rs b/build.rs index 53ab962..9c70b28 100644 --- a/build.rs +++ b/build.rs @@ -1,63 +1,109 @@ use std::env; -use std::io; -use std::path::PathBuf; +use std::fs::File; +use std::io::{BufRead, BufReader, Error, ErrorKind, Result}; +use std::ops::Bound; +use std::path::{Path, PathBuf}; use std::process::Command; trait CommandExt { - fn execute(&mut self) -> io::Result<()>; + fn execute(&mut self) -> Result<()>; } impl CommandExt for Command { /// Execute the command and return an error if it exited with a failure status. - fn execute(&mut self) -> io::Result<()> { - self.status().map(|_| ()).map_err(|_| { - io::Error::new( - io::ErrorKind::Other, - format!( - "The command\n\ - \t{:?}\n\ - did not run successfully.", - self - ), - ) - }) + fn execute(&mut self) -> Result<()> { + self.status() + .and_then(|status| { + if status.success() { + Ok(()) + } else { + Err(Error::new(ErrorKind::Other, "non-zero exit code")) + } + }) + .map_err(|_| { + Error::new( + ErrorKind::Other, + format!("The command {:?} did not run successfully.", self), + ) + }) } } -fn main() { - let lua = pkg_config::Config::new() - .atleast_version("5.1") - .probe("lua") - .unwrap(); +fn use_custom_lua>(include_dir: &S, lib_dir: &S, lua_lib: &S) -> Result { + let mut version_found = String::new(); + // 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::>(); + 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 + std::fmt::Debug>(include_paths: &[P]) { let build_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); // Ensure the presence of glue.rs - if !build_dir.join("glue.rs").exists() { - let mut config = cc::Build::new(); + // if build_dir.join("glue.rs").exists() { + // return; + // } - for path in lua.include_paths { - config.include(path); - } - for (k, v) in lua.defines { - config.define(&k, v.as_ref().map(|x| x.as_str())); - } + let mut config = cc::Build::new(); - // Compile and run glue.c - let glue = build_dir.join("glue"); - - config - .get_compiler() - .to_command() - .arg("src/ffi/glue/glue.c") - .arg("-o") - .arg(&glue) - .execute() - .unwrap(); - - Command::new(glue) - .arg(build_dir.join("glue.rs")) - .execute() - .unwrap(); + for path in include_paths { + config.include(path); } + + // Compile and run glue.c + let glue = build_dir.join("glue"); + + config + .get_compiler() + .to_command() + .arg("src/ffi/glue/glue.c") + .arg("-o") + .arg(&glue) + .execute() + .unwrap(); + + Command::new(glue) + .arg(build_dir.join("glue.rs")) + .execute() + .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); }