ale-sys 0.1.2

Rust bindings to the Arcade Learning Environment
Documentation

use std::io;
use std::path::{Path, PathBuf};
use std::fs::{self, DirEntry};
use std::ffi::OsStr;

#[cfg(windows)]
fn is_win() -> bool {
	true
}

#[cfg(not(windows))]
fn is_win() -> bool {
	false
}

fn visit_dirs<F: FnMut(&DirEntry), G: Fn(&DirEntry) -> bool>(dir: &Path, cb: &mut F, filter: &G) -> io::Result<()> {
	if dir.is_dir() {
		for entry in fs::read_dir(dir)? {
			let entry = entry?;
			let path = entry.path();
			if !filter(&entry) {
				continue;
			}
			if path.is_dir() {
				visit_dirs(&path, cb, filter)?;
			} else {
				cb(&entry);
			}
		}
	}
	Ok(())
}

fn main() {
	let debug = std::env::var("DEBUG").expect("DEBUG env var required")
		.parse::<bool>().expect("DEBUG not set to valid bool");
	let profile = match std::env::var("OPT_LEVEL").unwrap().as_str() {
		"0" => "Debug",
		"1" | "2" | "3" => if debug { "RelWithDebInfo" } else { "Release" },
		"s" | "z" => "MinSizeRel",
		lvl => panic!("Unknown OPT_LEVEL: {}", lvl),
	};

	let temp_dir = tempdir::TempDir::new("ale-sys-build").expect("failed to create temp dir");
	println!("temp_dir={}", temp_dir.path().display());
	let lib_dir = out_dir().join("build").join("lib");

	let cwd = std::env::current_dir().expect("failed to get current dir");
	std::env::set_current_dir(&temp_dir).expect("failed to set current dir");

	let ale_dir = project_root().join("ale");
	let mut config = cmake::Config::new(&ale_dir);
	config
		.define("USE_SDL", "OFF")
		.define("USE_RLGLUE", "OFF")
		.define("BUILD_EXAMPLES", "OFF")
		.define("BUILD_CPP_LIB", "OFF")
		.define("BUILD_CLI", "OFF")
		.define("BUILD_C_LIB", "ON")
		.define(format!("CMAKE_ARCHIVE_OUTPUT_DIRECTORY_{}", &profile.to_uppercase()), &lib_dir)
		.profile(profile)
		.build_target("ale-c-lib-static");

	if is_win() {
		config.cflag("-DWIN32=1").cxxflag("-DWIN32=1");
	}

	let dst = config.build();
	std::env::set_current_dir(&cwd).expect("failed to set current dir");
	println!("dst={}", dst.display());

	let ignore_files: &[&OsStr] = &["build".as_ref(), ".git".as_ref()];
	let mut ale_files = vec![];
	visit_dirs(&ale_dir, &mut |de| ale_files.push(de.path()), &|de| de.path().file_name().map(|n| !ignore_files.contains(&n)).unwrap_or(true)).expect(&format!("visit_dirs failed in {}", ale_dir.display()));

	for path in ale_files {
		println!("cargo:rerun-if-changed={}", path.display());
	}
	println!("cargo:rerun-if-changed=build.rs");
	println!("cargo:rustc-link-search=native={}", lib_dir.display());
	println!("cargo:rustc-link-lib=static=ale_c_static");
}

fn project_root() -> PathBuf {
	Path::new(&env!("CARGO_MANIFEST_DIR")).to_path_buf()
}

fn out_dir() -> PathBuf {
	Path::new(&std::env::var_os("OUT_DIR").expect("OUT_DIR not defined")).to_path_buf()
}