mirror of
https://github.com/aphrody-labs/cef-rs.git
synced 2026-10-13 21:06:46 +00:00
234 lines
8.1 KiB
Rust
234 lines
8.1 KiB
Rust
#[cfg(not(feature = "dox"))]
|
|
fn main() -> anyhow::Result<()> {
|
|
use download_cef::{CefIndex, OsAndArch};
|
|
use std::{
|
|
env, fs,
|
|
path::{Path, PathBuf},
|
|
};
|
|
|
|
println!("cargo::rerun-if-changed=build.rs");
|
|
|
|
let target = env::var("TARGET")?;
|
|
let os_arch = OsAndArch::try_from(target.as_str())?;
|
|
|
|
println!("cargo::rerun-if-env-changed=FLATPAK");
|
|
println!("cargo::rerun-if-env-changed=CEF_PATH");
|
|
let package_version = env::var("CARGO_PKG_VERSION")?;
|
|
let cef_version = download_cef::default_version(&package_version);
|
|
|
|
let check_archive = |path: &Path| -> anyhow::Result<()> {
|
|
download_cef::check_archive_json(&package_version, &path.to_string_lossy())?;
|
|
Ok(())
|
|
};
|
|
|
|
let resolve_cef_dir = |location: &Path| -> anyhow::Result<PathBuf> {
|
|
let cef_dir = location.join(os_arch.to_string());
|
|
|
|
if !fs::exists(&cef_dir)? {
|
|
let download_url = download_cef::default_download_url();
|
|
let index = CefIndex::download_from(&download_url)?;
|
|
let platform = index.platform(&target)?;
|
|
let version = platform.version(&cef_version)?;
|
|
|
|
let archive = version.download_archive_from(&download_url, location, false)?;
|
|
let extracted_dir =
|
|
download_cef::extract_target_archive(&target, &archive, location, false)?;
|
|
let extracted_dir_canonical = fs::canonicalize(&extracted_dir)?;
|
|
let cef_dir_canonical = fs::canonicalize(&cef_dir)?;
|
|
if extracted_dir_canonical != cef_dir_canonical {
|
|
return Err(anyhow::anyhow!(
|
|
"extracted dir {extracted_dir_canonical:?} does not match cef_dir {cef_dir_canonical:?}",
|
|
));
|
|
}
|
|
|
|
version.write_archive_json(extracted_dir)?;
|
|
}
|
|
|
|
Ok(cef_dir)
|
|
};
|
|
|
|
let resolve_from_versioned = |configured_path: &Path| -> anyhow::Result<PathBuf> {
|
|
let versioned_location = configured_path.join(&cef_version);
|
|
let resolved = resolve_cef_dir(&versioned_location)?;
|
|
println!(
|
|
"Using versioned CEF path from environment: {}",
|
|
resolved.display()
|
|
);
|
|
check_archive(&resolved)?;
|
|
Ok(resolved)
|
|
};
|
|
|
|
let download_to_versioned = |configured_path: &Path, reason: &str| -> anyhow::Result<PathBuf> {
|
|
let versioned_location = configured_path.join(&cef_version);
|
|
println!(
|
|
"{reason}, downloading archive to: {}",
|
|
versioned_location.display()
|
|
);
|
|
let resolved = resolve_cef_dir(&versioned_location)?;
|
|
println!("Using downloaded CEF path: {}", resolved.display());
|
|
Ok(resolved)
|
|
};
|
|
|
|
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
|
|
|
|
let cef_dir = if env::var("FLATPAK").is_ok() {
|
|
let cef_path = String::from("/usr/lib");
|
|
println!("Using CEF path from FLATPAK: {cef_path}");
|
|
let cef_path = PathBuf::from(cef_path);
|
|
check_archive(&cef_path)?;
|
|
cef_path
|
|
} else if let Ok(cef_path) = env::var("CEF_PATH") {
|
|
let configured_path = PathBuf::from(cef_path);
|
|
if fs::exists(&configured_path)? {
|
|
let versioned_location = configured_path.join(&cef_version);
|
|
if fs::exists(&versioned_location)? {
|
|
resolve_from_versioned(&configured_path)?
|
|
} else {
|
|
println!(
|
|
"Using CEF path from environment: {}",
|
|
configured_path.display()
|
|
);
|
|
match check_archive(&configured_path) {
|
|
Ok(()) => configured_path,
|
|
Err(error) => download_to_versioned(
|
|
&configured_path,
|
|
&format!("CEF_PATH is invalid ({error})"),
|
|
)?,
|
|
}
|
|
}
|
|
} else {
|
|
download_to_versioned(&configured_path, "CEF_PATH does not exist")?
|
|
}
|
|
} else {
|
|
resolve_cef_dir(&out_dir)?
|
|
};
|
|
|
|
// TODO: far from ideal, but there's no other way to get the target dir, see <https://github.com/rust-lang/cargo/issues/9661>
|
|
let target_dir = out_dir
|
|
.parent()
|
|
.unwrap()
|
|
.parent()
|
|
.unwrap()
|
|
.parent()
|
|
.unwrap();
|
|
|
|
let cef_dir_str = cef_dir.to_string_lossy().into_owned();
|
|
|
|
// Re-run when the resolved CEF directory changes/deletes.
|
|
println!("cargo::rerun-if-changed={cef_dir_str}");
|
|
|
|
println!("cargo::metadata=CEF_DIR={cef_dir_str}");
|
|
println!("cargo::rustc-link-search=native={cef_dir_str}");
|
|
|
|
let mut cef_dll_wrapper = cmake::Config::new(&cef_dir);
|
|
cef_dll_wrapper
|
|
.generator("Ninja")
|
|
.profile("RelWithDebInfo")
|
|
.build_target("libcef_dll_wrapper");
|
|
|
|
let project_arch = match os_arch.arch {
|
|
"aarch64" => "arm64",
|
|
arch => arch,
|
|
};
|
|
|
|
let sandbox = if cfg!(feature = "sandbox") {
|
|
"ON"
|
|
} else {
|
|
"OFF"
|
|
};
|
|
|
|
match os_arch.os {
|
|
"linux" => {
|
|
// On Windows and Linux the cef files usually have to be next to the main binary.
|
|
// On macOS it's more complicated so we'll leave it to tools like tauri-cli for now.
|
|
// TODO: Consider to put this behind a feature flag
|
|
copy_cef_runtime_files(&cef_dir, target_dir)?;
|
|
|
|
println!("cargo::rustc-link-lib=dylib=cef");
|
|
}
|
|
"windows" => {
|
|
// On Windows and Linux the cef files usually have to be next to the main binary.
|
|
// On macOS it's more complicated so we'll leave it to tools like tauri-cli for now.
|
|
// TODO: Consider to put this behind a feature flag
|
|
copy_cef_runtime_files(&cef_dir, target_dir)?;
|
|
|
|
let sdk_libs = [
|
|
"comctl32.lib",
|
|
"delayimp.lib",
|
|
"mincore.lib",
|
|
"powrprof.lib",
|
|
"propsys.lib",
|
|
"runtimeobject.lib",
|
|
"setupapi.lib",
|
|
"shcore.lib",
|
|
"shell32.lib",
|
|
"shlwapi.lib",
|
|
"user32.lib",
|
|
"version.lib",
|
|
"wbemuuid.lib",
|
|
"winmm.lib",
|
|
]
|
|
.join(" ");
|
|
|
|
let build_dir = cef_dll_wrapper
|
|
.define("CMAKE_MSVC_RUNTIME_LIBRARY", "MultiThreaded")
|
|
.define("CMAKE_OBJECT_PATH_MAX", "500")
|
|
.define("CMAKE_STATIC_LINKER_FLAGS", &sdk_libs)
|
|
.define("PROJECT_ARCH", project_arch)
|
|
.define("USE_SANDBOX", sandbox)
|
|
.build()
|
|
.to_string_lossy()
|
|
.into_owned();
|
|
|
|
println!("cargo::rustc-link-search=native={build_dir}/build/libcef_dll_wrapper");
|
|
println!("cargo::rustc-link-lib=static=libcef_dll_wrapper");
|
|
|
|
println!("cargo::rustc-link-lib=dylib=libcef");
|
|
}
|
|
"macos" => {
|
|
println!("cargo::rustc-link-lib=framework=AppKit");
|
|
|
|
let build_dir = cef_dll_wrapper
|
|
.no_default_flags(true)
|
|
.define("PROJECT_ARCH", project_arch)
|
|
.define("USE_SANDBOX", sandbox)
|
|
.build()
|
|
.to_string_lossy()
|
|
.into_owned();
|
|
println!("cargo::rustc-link-search=native={build_dir}/build/libcef_dll_wrapper");
|
|
println!("cargo::rustc-link-lib=static=cef_dll_wrapper");
|
|
}
|
|
os => unimplemented!("unknown target {os}"),
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(not(feature = "dox"))]
|
|
fn copy_directory(src: &std::path::Path, dest: &std::path::Path) -> Result<(), std::io::Error> {
|
|
std::fs::create_dir_all(dest)?;
|
|
for entry in std::fs::read_dir(src)? {
|
|
let entry = entry?;
|
|
if entry.path().is_file() {
|
|
std::fs::copy(entry.path(), dest.join(entry.file_name()))?;
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(not(feature = "dox"))]
|
|
fn copy_cef_runtime_files(
|
|
cef_dir: &std::path::Path,
|
|
target_dir: &std::path::Path,
|
|
) -> Result<(), std::io::Error> {
|
|
copy_directory(cef_dir, target_dir)?;
|
|
|
|
const LOCALES_DIR: &str = "locales";
|
|
copy_directory(&cef_dir.join(LOCALES_DIR), &target_dir.join(LOCALES_DIR))?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(feature = "dox")]
|
|
fn main() {}
|