Skip to content

Commit

Permalink
Make dependency resolution explicit
Browse files Browse the repository at this point in the history
  • Loading branch information
kornelski committed Jun 14, 2024
1 parent fc93d8d commit 7779766
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 40 deletions.
79 changes: 41 additions & 38 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,10 @@ pub struct Package {
/// The maintainer of the Debian package.
/// In Debian `control` file `Maintainer` field format.
pub maintainer: String,
/// Deps including `$auto`
pub wildcard_depends: String,
/// The Debian dependencies required to run the project.
pub depends: String,
pub resolved_depends: Option<String>,
/// The Debian pre-dependencies.
pub pre_depends: Option<String>,
/// The Debian recommended dependencies.
Expand Down Expand Up @@ -315,7 +317,8 @@ impl Config {
Ok(package.authors().first()
.ok_or("The package must have a maintainer or authors property")?.to_owned())
})?,
depends: deb.depends.take().map(DependencyList::into_depends_string).unwrap_or_else(|| "$auto".to_owned()),
wildcard_depends: deb.depends.take().map(DependencyList::into_depends_string).unwrap_or_else(|| "$auto".to_owned()),
resolved_depends: None,
pre_depends: deb.pre_depends.take().map(DependencyList::into_depends_string),
recommends: deb.recommends.take().map(DependencyList::into_depends_string),
suggests: deb.suggests.take().map(DependencyList::into_depends_string),
Expand Down Expand Up @@ -352,40 +355,6 @@ impl Config {
Ok(config)
}

pub(crate) fn get_dependencies(&self, listener: &dyn Listener) -> CDResult<String> {
let mut deps = HashSet::new();
for word in self.deb.depends.split(',') {
let word = word.trim();
if word == "$auto" {
let bin = self.deb.all_binaries();
let resolved = bin.par_iter()
.filter(|bin| !bin.archive_as_symlink_only())
.filter_map(|p| p.path())
.filter_map(|bname| match resolve(bname, &self.target) {
Ok(bindeps) => Some(bindeps),
Err(err) => {
listener.warning(format!("{} (no auto deps for {})", err, bname.display()));
None
},
})
.collect::<Vec<_>>();
for dep in resolved.into_iter().flat_map(|s| s.into_iter()) {
deps.insert(dep);
}
} else {
let (dep, arch_spec) = get_architecture_specification(word)?;
if let Some(spec) = arch_spec {
if match_architecture(spec, &self.deb.architecture)? {
deps.insert(dep);
}
} else {
deps.insert(dep);
}
}
}
Ok(deps.into_iter().collect::<Vec<_>>().join(", "))
}

pub fn extend_cargo_build_flags(&self, flags: &mut Vec<String>) {
if flags.iter().any(|f| f == "--workspace" || f == "--all") {
return;
Expand Down Expand Up @@ -629,6 +598,40 @@ impl Package {
}
self.conf_files.append(&mut new_conf);
}

/// run dpkg/ldd to check deps of libs
pub fn resolve_binary_dependencies(&mut self, target: Option<&str>, listener: &dyn Listener) -> CDResult<()> {
let mut deps = HashSet::new();
for word in self.wildcard_depends.split(',') {
let word = word.trim();
if word == "$auto" {
let bin = self.all_binaries();
let resolved = bin.par_iter()
.filter(|bin| !bin.archive_as_symlink_only())
.filter_map(|p| p.path())
.filter_map(|bname| match resolve(bname, target) {
Ok(bindeps) => Some(bindeps),
Err(err) => {
listener.warning(format!("{} (no auto deps for {})", err, bname.display()));
None
},
})
.collect::<Vec<_>>();
for dep in resolved.into_iter().flat_map(|s| s.into_iter()) {
deps.insert(dep);
}
} else {
let (dep, arch_spec) = get_architecture_specification(word)?;
if let Some(spec) = arch_spec {
if match_architecture(spec, &self.architecture)? {
deps.insert(dep);
}
} else {
deps.insert(dep);
}
}
}
self.resolved_depends = Some(deps.into_iter().collect::<Vec<_>>().join(", "));
Ok(())
}

Expand Down Expand Up @@ -688,7 +691,7 @@ impl Package {
}

/// Generates the control file that obtains all the important information about the package.
pub fn generate_control(&self, deps: &str) -> CDResult<Vec<u8>> {
pub fn generate_control(&self) -> CDResult<Vec<u8>> {
// Create and return the handle to the control file with write access.
let mut control: Vec<u8> = Vec::with_capacity(1024);

Expand Down Expand Up @@ -720,7 +723,7 @@ impl Package {

writeln!(&mut control, "Installed-Size: {installed_size}")?;

if !deps.is_empty() {
if let Some(deps) = &self.resolved_depends {
writeln!(&mut control, "Depends: {deps}")?;
}

Expand Down
4 changes: 2 additions & 2 deletions src/dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::Path;
use std::process::Command;

/// Resolves the dependencies based on the output of dpkg-shlibdeps on the binary.
pub fn resolve(path: &Path, target: &Option<String>) -> CDResult<Vec<String>> {
pub(crate) fn resolve(path: &Path, target: Option<&str>) -> CDResult<Vec<String>> {
let temp_folder = tempfile::tempdir()?;
let debian_folder = temp_folder.path().join("debian");
let control_file_path = debian_folder.join("control");
Expand Down Expand Up @@ -56,7 +56,7 @@ pub fn resolve(path: &Path, target: &Option<String>) -> CDResult<Vec<String>> {
#[cfg(target_os = "linux")]
fn resolve_test() {
let exe = std::env::current_exe().unwrap();
let deps = resolve(&exe, &None).unwrap();
let deps = resolve(&exe, None).unwrap();
assert!(deps.iter().any(|d| d.starts_with("libc")));
assert!(!deps.iter().any(|d| d.starts_with("libgcc")), "{deps:?}");
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ fn process(
}

config.deb.resolve_assets()?;
config.deb.resolve_binary_dependencies(config.target.as_deref(), listener)?;

compress_assets(&mut config, listener)?;

Expand Down

0 comments on commit 7779766

Please sign in to comment.