From bdb34c5c8882c767b65b77a89731b731007624fb Mon Sep 17 00:00:00 2001 From: SFG545 Date: Tue, 17 Mar 2026 19:59:54 -0500 Subject: [PATCH] feat: update depot version to 0.27.1 and enhance pkg-config environment configuration --- Cargo.lock | 2 +- Cargo.toml | 2 +- meson.build | 2 +- src/builder/meson.rs | 161 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 164 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4b0e8d9..0be5c42 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -418,7 +418,7 @@ checksum = "807800ff3288b621186fe0a8f3392c4652068257302709c24efd918c3dffcdc2" [[package]] name = "depot" -version = "0.27.0" +version = "0.27.1" dependencies = [ "anyhow", "ar", diff --git a/Cargo.toml b/Cargo.toml index 37f953d..8d0983a 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "depot" -version = "0.27.0" +version = "0.27.1" edition = "2024" [lints.rust] diff --git a/meson.build b/meson.build index 93a785e..adf4e82 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project( 'depot', - version: '0.27.0', + version: '0.27.1', meson_version: '>=0.60.0', default_options: ['buildtype=release'], ) diff --git a/src/builder/meson.rs b/src/builder/meson.rs index 545ef9f..990b990 100755 --- a/src/builder/meson.rs +++ b/src/builder/meson.rs @@ -37,6 +37,7 @@ pub fn build( host_dir.to_string_lossy().into_owned(), ); } + configure_pkg_config_env(&mut env_vars, flags, cross); // Generate cross file if cross-compiling, or when the lib32 variant needs // Meson to treat the build as x86 instead of the native x86_64 host. @@ -211,6 +212,8 @@ pub(crate) fn ensure_host_build( let env_vars = crate::builder::standard_build_env(&host_spec, None, true, export_compiler_flags); + let mut env_vars = env_vars; + configure_pkg_config_env(&mut env_vars, flags, None); let mut state = StateTracker::new_with_namespace(&actual_src, Some("host"))?; if !state.is_done(BuildStep::Configured) { @@ -379,6 +382,10 @@ fn generate_lib32_meson_cross_file( let mut content = format!( "# Meson cross file for lib32 builds\n# Generated by depot for target: {target}\n\n[binaries]\nc = {c}\ncpp = {cpp}\nar = {ar}\n" ); + if let Some(pkg_config) = resolve_pkg_config_binary() { + let pkg_config = meson_binary_value(&[pkg_config], "pkg-config")?; + content.push_str(&format!("pkg-config = {pkg_config}\n")); + } if !flags.ld.trim().is_empty() { let ld = meson_binary_value(&command_words(&flags.ld), "linker")?; content.push_str(&format!("ld = {ld}\n")); @@ -420,6 +427,92 @@ fn compiler_command_with_lib32_target(command: &str, target: &str) -> Vec, +) { + if let Some(pkg_config) = resolve_pkg_config_binary() { + crate::builder::set_env_var(env_vars, "PKG_CONFIG", pkg_config); + } + + if !(flags.lib32_variant || cross.is_some()) { + return; + } + + crate::builder::set_env_var( + env_vars, + "PKG_CONFIG_LIBDIR", + target_pkg_config_libdir(flags), + ); + if !flags.rootfs.trim().is_empty() && flags.rootfs.trim() != "/" { + crate::builder::set_env_var(env_vars, "PKG_CONFIG_SYSROOT_DIR", flags.rootfs.clone()); + } +} + +fn target_pkg_config_libdir(flags: &crate::package::BuildFlags) -> String { + let install_dirs = crate::builder::install_dirs(flags); + [ + rootfs_path(&flags.rootfs, &format!("{}/pkgconfig", install_dirs.libdir)), + rootfs_path(&flags.rootfs, "/usr/share/pkgconfig"), + ] + .join(":") +} + +fn rootfs_path(rootfs: &str, path: &str) -> String { + let trimmed_root = rootfs.trim(); + if trimmed_root.is_empty() || trimmed_root == "/" { + return path.to_string(); + } + + format!("{}{}", trimmed_root.trim_end_matches('/'), path) +} + +fn resolve_pkg_config_binary() -> Option { + let env_candidate = std::env::var("PKG_CONFIG") + .ok() + .map(|value| value.trim().to_string()) + .filter(|value| !value.is_empty()); + if let Some(candidate) = env_candidate + && let Some(resolved) = resolve_command_path(&candidate) + { + return Some(resolved); + } + + for candidate in ["pkg-config", "pkgconf"] { + if let Some(resolved) = resolve_command_path(candidate) { + return Some(resolved); + } + } + + None +} + +fn resolve_command_path(command: &str) -> Option { + let trimmed = command.trim(); + if trimmed.is_empty() { + return None; + } + let path = Path::new(trimmed); + if path.is_absolute() && path.exists() { + return Some(trimmed.to_string()); + } + + if trimmed.contains('/') { + return path.exists().then(|| trimmed.to_string()); + } + + let search_path = std::env::var_os("PATH")?; + for dir in std::env::split_paths(&search_path) { + let candidate = dir.join(trimmed); + if candidate.is_file() { + return Some(candidate.to_string_lossy().into_owned()); + } + } + + None +} + fn command_words(command: &str) -> Vec { command .split_whitespace() @@ -533,6 +626,7 @@ fn resolve_actual_src(spec: &crate::package::PackageSpec, src_dir: &Path) -> Res mod tests { use super::*; use crate::package::{Build, BuildFlags, BuildType, Dependencies, PackageInfo, Source}; + use crate::test_support::TestEnv; use tempfile::tempdir; #[test] @@ -571,6 +665,73 @@ mod tests { assert!(args.iter().any(|a| a == "-Dtools_dir=/tmp/build-host/bin")); } + #[test] + fn test_configure_pkg_config_env_uses_lib32_dirs_and_pkgconf() -> Result<()> { + let tmp = tempdir()?; + let pkgconf = tmp.path().join("pkgconf"); + std::fs::write(&pkgconf, "#!/bin/sh\nexit 0\n")?; + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + let mut perms = std::fs::metadata(&pkgconf)?.permissions(); + perms.set_mode(0o755); + std::fs::set_permissions(&pkgconf, perms)?; + } + + let mut env = TestEnv::new(); + env.set_var("PATH", tmp.path()); + env.set_var("PKG_CONFIG", ""); + + let mut env_vars = Vec::new(); + let flags = BuildFlags { + lib32_variant: true, + rootfs: "/".into(), + ..BuildFlags::default() + }; + configure_pkg_config_env(&mut env_vars, &flags, None); + + assert!( + env_vars + .iter() + .any(|(k, v)| k == "PKG_CONFIG" && v.ends_with("/pkgconf")) + ); + assert!(env_vars.iter().any(|(k, v)| { + k == "PKG_CONFIG_LIBDIR" && v == "/usr/lib32/pkgconfig:/usr/share/pkgconfig" + })); + Ok(()) + } + + #[test] + fn test_generate_lib32_meson_cross_file_writes_pkg_config_binary_when_available() -> Result<()> + { + let tmp = tempdir()?; + let tools = tempdir()?; + let pkgconf = tools.path().join("pkgconf"); + std::fs::write(&pkgconf, "#!/bin/sh\nexit 0\n")?; + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + let mut perms = std::fs::metadata(&pkgconf)?.permissions(); + perms.set_mode(0o755); + std::fs::set_permissions(&pkgconf, perms)?; + } + + let mut env = TestEnv::new(); + env.set_var("PATH", tools.path()); + env.set_var("PKG_CONFIG", ""); + + let flags = BuildFlags { + chost: "x86_64-sfg-linux-gnu".into(), + ..BuildFlags::default() + }; + + let path = generate_lib32_meson_cross_file(&flags, tmp.path())?; + let content = std::fs::read_to_string(path)?; + assert!(content.contains("pkg-config = '/")); + assert!(content.contains("pkgconf")); + Ok(()) + } + #[test] fn test_meson_setup_args_include_install_dirs() { let args = meson_setup_args(&BuildFlags::default(), None, &[]);