pocketpy-sys 0.1.1

Rust FFI bindings to pocketpy, a portable python 3.x interpreter
use std::{env, path::PathBuf};

fn main() {
	println!("cargo:rerun-if-changed=wrapper.h");

	let target = env::var("TARGET").unwrap();
	let is_debug = env::var("DEBUG").unwrap() == "true";

	// Generated the bindings
	let bindings = bindgen::Builder::default()
		.header("wrapper.h")
		.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
		.allowlist_item("py_.*|_py_.*|free")
		.clang_arg("-Ivendor/pocketpy/include")
		.generate()
		.expect("failed to generate bindings with Bindgen");

	// Write the bindings
	let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
	bindings
		.write_to_file(out_path.join("bindings.rs"))
		.expect("failed to write generated bindings");

	// We have to force disable IPO/LTO otherwise linker will crash
	const CMAKE_LISTS_PATH: &str = "./vendor/pocketpy/CMakeLists.txt";

	let original_cmake_lists_contents = std::fs::read_to_string(CMAKE_LISTS_PATH).unwrap();

	std::fs::write(
		CMAKE_LISTS_PATH,
		original_cmake_lists_contents.replace(
			"set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)",
			"set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE)",
		),
	)
	.unwrap();

	// Build pocketpy as static lib
	let built = cmake::Config::new("vendor/pocketpy")
		.define("PK_BUILD_SHARED_LIB", "OFF")
		.define("PK_BUILD_STATIC_LIB", "ON")
		.build_target("pocketpy")
		.build();

	// Add the compiled lib to the library search path of rustc
	if target.contains("windows") {
		if is_debug {
			println!(
				"cargo:rustc-link-search=native={}/build/Debug",
 				built.display()
			);
			println!(
				"cargo:rustc-link-search=native={}/build/RelWithDebInfo",
 				built.display()
			);
		} else {
			println!(
				"cargo:rustc-link-search=native={}/build/Release",
				built.display()
			);
		}
	} else {
		println!("cargo:rustc-link-search=native={}/build", built.display());
	}

	println!("cargo:rustc-link-lib=static=pocketpy");

	// Restore the original CMakeLists.txt
	std::fs::write(CMAKE_LISTS_PATH, original_cmake_lists_contents).unwrap();
}