167467d169
- Introduced `real_name` field in `InstalledPackageRecord` and `PackageInfo` to handle renamed packages. - Added `abi_breaking` field to manage versioned shared libraries during renamed updates. - Updated database schema to include `real_name` and `abi_breaking` columns. - Enhanced package registration logic to support replacement of renamed packages while retaining specified files and directories. - Modified various functions and tests to accommodate the new fields and ensure backward compatibility. - Updated TOML serialization to include `real_name` and `abi_breaking` in package metadata.
129 lines
4.1 KiB
Rust
129 lines
4.1 KiB
Rust
//! Binary package "build" system — used when package supplies a prebuilt binary installer
|
|
|
|
use crate::cross::CrossConfig;
|
|
use crate::package::PackageSpec;
|
|
use anyhow::{Context, Result};
|
|
use std::fs;
|
|
use std::os::unix::fs as unix_fs;
|
|
use std::path::Path;
|
|
use walkdir::WalkDir;
|
|
|
|
/// For binary packages we simply copy the extracted files into DESTDIR (preserving
|
|
/// directory structure). This is useful for .deb packages where extract step
|
|
/// already unpacked the data payload into the source directory.
|
|
pub fn build(
|
|
_spec: &PackageSpec,
|
|
src_dir: &Path,
|
|
destdir: &Path,
|
|
_cross: Option<&CrossConfig>,
|
|
_export_compiler_flags: bool,
|
|
) -> Result<()> {
|
|
crate::log_info!(
|
|
"Binary install: copying files from {} to {} (pkg type={})",
|
|
src_dir.display(),
|
|
destdir.display(),
|
|
_spec.build.flags.binary_type
|
|
);
|
|
fs::create_dir_all(destdir)
|
|
.with_context(|| format!("Failed to create destdir: {}", destdir.display()))?;
|
|
|
|
for entry in WalkDir::new(src_dir) {
|
|
let entry = entry?;
|
|
let rel = entry.path().strip_prefix(src_dir).unwrap();
|
|
let target = destdir.join(rel);
|
|
if entry.file_type().is_dir() {
|
|
fs::create_dir_all(&target)?;
|
|
} else if entry.file_type().is_symlink() {
|
|
let link_target = fs::read_link(entry.path())?;
|
|
if let Some(parent) = target.parent() {
|
|
fs::create_dir_all(parent)?;
|
|
}
|
|
// overwrite existing links/files
|
|
if target.exists() {
|
|
let _ = fs::remove_file(&target);
|
|
}
|
|
unix_fs::symlink(link_target, &target)?;
|
|
} else {
|
|
if let Some(parent) = target.parent() {
|
|
fs::create_dir_all(parent)?;
|
|
}
|
|
fs::copy(entry.path(), &target)?;
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::package::{Build, BuildFlags, BuildType, Dependencies, PackageInfo};
|
|
use std::fs;
|
|
use std::os::unix::fs as unix_fs;
|
|
use tempfile::tempdir;
|
|
|
|
fn mk_spec(name: &str, version: &str) -> PackageSpec {
|
|
PackageSpec {
|
|
package: PackageInfo {
|
|
name: name.into(),
|
|
real_name: None,
|
|
version: version.into(),
|
|
revision: 1,
|
|
description: "d".into(),
|
|
homepage: "h".into(),
|
|
abi_breaking: false,
|
|
license: vec!["MIT".into()],
|
|
},
|
|
packages: Vec::new(),
|
|
alternatives: Default::default(),
|
|
manual_sources: Vec::new(),
|
|
source: vec![crate::package::Source {
|
|
url: "h".into(),
|
|
sha256: "s".into(),
|
|
extract_dir: "e".into(),
|
|
patches: Vec::new(),
|
|
post_extract: Vec::new(),
|
|
cherry_pick: Vec::new(),
|
|
}],
|
|
build: Build {
|
|
build_type: BuildType::Bin,
|
|
flags: BuildFlags::default(),
|
|
},
|
|
dependencies: Dependencies::default(),
|
|
package_alternatives: Default::default(),
|
|
package_dependencies: Default::default(),
|
|
spec_dir: std::path::PathBuf::from("."),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_bin_build_copies_files_and_symlinks() -> Result<()> {
|
|
let tmp_src = tempdir()?;
|
|
let tmp_dest = tempdir()?;
|
|
let src = tmp_src.path();
|
|
let dest = tmp_dest.path();
|
|
|
|
// Create a directory and files
|
|
fs::create_dir_all(src.join("usr/bin"))?;
|
|
fs::write(src.join("usr/bin/hello"), b"hi")?;
|
|
|
|
// Create a symlink
|
|
let target = src.join("usr/lib/libdummy.so");
|
|
fs::create_dir_all(target.parent().unwrap())?;
|
|
fs::write(&target, b"lib")?;
|
|
unix_fs::symlink(&target, src.join("usr/lib/libdummy.so.link"))?;
|
|
|
|
let spec = mk_spec("bin-test", "1.0");
|
|
build(&spec, src, dest, None, true)?;
|
|
|
|
// Check copied file
|
|
assert!(dest.join("usr/bin/hello").exists());
|
|
|
|
// Check symlink target exists at dest
|
|
let link_path = dest.join("usr/lib/libdummy.so.link");
|
|
assert!(link_path.exists());
|
|
|
|
Ok(())
|
|
}
|
|
}
|