By default try to find global installed unicorn if not specified

This commit is contained in:
2022-04-23 22:41:34 +02:00
parent 185a6fec9e
commit f4ab42d930
2 changed files with 32 additions and 31 deletions

View File

@@ -34,11 +34,10 @@ bitflags = "1.3"
libc = "0.2" libc = "0.2"
[build-dependencies] [build-dependencies]
cc = { optional = true, version = "1.0" } cc = { version = "1.0" }
cmake = { optional = true, version = "0.1" } cmake = { version = "0.1" }
pkg-config = { optional = true, version = "0.3" } pkg-config = { version = "0.3" }
[features] [features]
default = ["build_unicorn_cmake"] default = []
build_unicorn_cmake = ["cc", "cmake"] build_unicorn_cmake = []
use_system_unicorn = ["pkg-config"]

View File

@@ -1,23 +1,16 @@
#[cfg(feature = "use_system_unicorn")]
use pkg_config; use pkg_config;
#[cfg(feature = "build_unicorn_cmake")]
use std::env; use std::env;
#[cfg(feature = "build_unicorn_cmake")]
use std::path::PathBuf; use std::path::PathBuf;
#[cfg(feature = "build_unicorn_cmake")]
use std::process::Command; use std::process::Command;
#[cfg(all(feature = "build_unicorn_cmake"))]
fn ninja_available() -> bool { fn ninja_available() -> bool {
Command::new("ninja").arg("--version").spawn().is_ok() Command::new("ninja").arg("--version").spawn().is_ok()
} }
#[cfg(all(feature = "build_unicorn_cmake"))]
fn msvc_cmake_tools_available() -> bool { fn msvc_cmake_tools_available() -> bool {
Command::new("cmake").arg("--version").spawn().is_ok() && ninja_available() Command::new("cmake").arg("--version").spawn().is_ok() && ninja_available()
} }
#[cfg(all(feature = "build_unicorn_cmake"))]
fn setup_env_msvc(compiler: &cc::Tool) { fn setup_env_msvc(compiler: &cc::Tool) {
// If PATH already contains what we need, skip this // If PATH already contains what we need, skip this
if msvc_cmake_tools_available() { if msvc_cmake_tools_available() {
@@ -27,20 +20,24 @@ fn setup_env_msvc(compiler: &cc::Tool) {
let target = env::var("TARGET").unwrap(); let target = env::var("TARGET").unwrap();
let devenv = cc::windows_registry::find_tool(target.as_str(), "devenv"); let devenv = cc::windows_registry::find_tool(target.as_str(), "devenv");
let tool_root: PathBuf = match devenv { let tool_root: PathBuf = match devenv {
Some(devenv_tool) => { Some(devenv_tool) => devenv_tool.path().parent().unwrap().to_path_buf(),
devenv_tool.path().parent().unwrap().to_path_buf()
},
None => { None => {
// if devenv (i.e. Visual Studio) was not found, assume compiler is // if devenv (i.e. Visual Studio) was not found, assume compiler is
// from standalone Build Tools and look there instead. // from standalone Build Tools and look there instead.
// this should be done properly in cc crate, but for now it's not. // this should be done properly in cc crate, but for now it's not.
let tools_name = std::ffi::OsStr::new("BuildTools"); let tools_name = std::ffi::OsStr::new("BuildTools");
let compiler_path = compiler.path().to_path_buf(); let compiler_path = compiler.path().to_path_buf();
compiler_path.iter().find(|x| *x == tools_name) compiler_path
.iter()
.find(|x| *x == tools_name)
.expect("Failed to find devenv or Build Tools"); .expect("Failed to find devenv or Build Tools");
compiler_path.iter().take_while(|x| *x != tools_name) compiler_path
.collect::<PathBuf>().join(tools_name).join(r"Common7\IDE") .iter()
}, .take_while(|x| *x != tools_name)
.collect::<PathBuf>()
.join(tools_name)
.join(r"Common7\IDE")
}
}; };
let cmake_pkg_dir = tool_root.join(r"CommonExtensions\Microsoft\CMake"); let cmake_pkg_dir = tool_root.join(r"CommonExtensions\Microsoft\CMake");
let cmake_path = cmake_pkg_dir.join(r"CMake\bin\cmake.exe"); let cmake_path = cmake_pkg_dir.join(r"CMake\bin\cmake.exe");
@@ -63,7 +60,6 @@ fn setup_env_msvc(compiler: &cc::Tool) {
} }
} }
#[cfg(feature = "build_unicorn_cmake")]
fn build_with_cmake() { fn build_with_cmake() {
let uc_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); let uc_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let compiler = cc::Build::new().get_compiler(); let compiler = cc::Build::new().get_compiler();
@@ -92,11 +88,16 @@ fn build_with_cmake() {
// unicorn's CMakeLists.txt doesn't properly support 'install', so we use // unicorn's CMakeLists.txt doesn't properly support 'install', so we use
// the build artifacts from the build directory, which cmake crate sets // the build artifacts from the build directory, which cmake crate sets
// to "<out_dir>/build/" // to "<out_dir>/build/"
let dst = config.define("BUILD_SHARED_LIBS", "OFF") let dst = config
.define("BUILD_SHARED_LIBS", "OFF")
.define("UNICORN_BUILD_TESTS", "OFF") .define("UNICORN_BUILD_TESTS", "OFF")
.define("UNICORN_INSTALL", "OFF") .define("UNICORN_INSTALL", "OFF")
.no_build_target(true).build(); .no_build_target(true)
println!("cargo:rustc-link-search=native={}", dst.join("build").display()); .build();
println!(
"cargo:rustc-link-search=native={}",
dst.join("build").display()
);
// Lazymio(@wtdcode): Why do I stick to static link? See: https://github.com/rust-lang/cargo/issues/5077 // Lazymio(@wtdcode): Why do I stick to static link? See: https://github.com/rust-lang/cargo/issues/5077
println!("cargo:rustc-link-lib=static=unicorn"); println!("cargo:rustc-link-lib=static=unicorn");
@@ -107,14 +108,15 @@ fn build_with_cmake() {
} }
fn main() { fn main() {
if cfg!(feature = "use_system_unicorn") { if cfg!(feature = "build_unicorn_cmake") {
#[cfg(feature = "use_system_unicorn")] build_with_cmake();
pkg_config::Config::new() } else {
if !pkg_config::Config::new()
.atleast_version("2") .atleast_version("2")
.probe("unicorn") .probe("unicorn")
.expect("Could not find system unicorn2"); .is_ok()
} else { {
#[cfg(feature = "build_unicorn_cmake")] build_with_cmake();
build_with_cmake(); }
} }
} }