### Install .deb files Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/api-reference.md Executes dpkg -i to install one or more .deb archives, prompting for root privileges if necessary. ```rust pub fn install_debs(paths: &[&Path]) -> CDResult<()> ``` -------------------------------- ### Configuration precedence example Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/configuration.md Demonstrates how command-line flags and variant sections override base configuration. ```bash # Command-line wins cargo deb --maintainer "CLI User" --variant full ``` ```toml # Variant inherits from main section but can override [package.metadata.deb] maintainer = "Base Maintainer" [package.metadata.deb.variants.full] maintainer = "Variant Maintainer" # This is used with --variant full ``` -------------------------------- ### Main application entry point Source: https://github.com/kornelski/cargo-deb/blob/main/systemd.md A simple Rust main function for the example package. ```rust fn main() { println!("Hello World!"); } ``` -------------------------------- ### Handle InstallFailed Error Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/errors.md Matches errors occurring during the dpkg installation process. ```rust match result { Err(CargoDebError::InstallFailed(status)) => { eprintln!("dpkg -i failed with status: {}", status); } _ => {} } ``` -------------------------------- ### Automate Package Installation Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/GUIDE.md Triggers an automatic installation of the generated .deb package using dpkg. Requires root privileges or sudo access. ```rust use cargo_deb::CargoDeb; use cargo_deb::listener::StdErrListener; use anstream::ColorChoice; fn main() -> Result<(), Box> { let listener = StdErrListener { verbose: true, quiet: false, color: ColorChoice::Auto, }; let deb = CargoDeb { // Install the generated .deb after building install: (true, false), verbose: true, ..Default::default() }; deb.process(&listener)?; println!("Package installed!"); Ok(()) } ``` -------------------------------- ### Configure Per-Unit Options in Cargo.toml Source: https://github.com/kornelski/cargo-deb/blob/main/systemd.md Demonstrates how to apply different start behaviors to specific systemd units by matching their unit-name. ```toml [package.metadata.deb] maintainer-scripts = "debian/" systemd-units = [ { unit-name = "my-daemon" }, { unit-name = "my-api", start = false }, ] ``` -------------------------------- ### Minimal build execution Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/README.md A basic example showing how to initialize CargoDeb with default settings and process it using a standard error listener. ```rust let deb = cargo_deb::CargoDeb::default(); let listener = cargo_deb::listener::StdErrListener { verbose: true, quiet: false, color: ColorChoice::Auto }; deb.process(&listener)?; ``` -------------------------------- ### Execute Debian Packaging Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/api-reference.md Example usage of the CargoDeb struct to initiate the build process with a listener. ```rust use cargo_deb::{CargoDeb, listener::StdErrListener}; use anstream::ColorChoice; let listener = StdErrListener { verbose: true, quiet: false, color: ColorChoice::Auto, }; let deb = CargoDeb::default(); deb.process(&listener)?; ``` -------------------------------- ### Install cargo-deb Source: https://github.com/kornelski/cargo-deb/blob/main/README.md Installs the cargo-deb command-line tool. Ensure your Rust toolchain is up-to-date. ```sh rustup update # Bookworm's Rust is too outdated, use Trixie or rustup.rs cargo install cargo-deb ``` -------------------------------- ### Install cargo-deb with static LZMA Source: https://github.com/kornelski/cargo-deb/blob/main/README.md Install cargo-deb with the static-lzma feature to resolve 'Undefined reference to `lzma_stream_encoder_mt`' errors. ```sh cargo install cargo-deb --features=static-lzma ``` -------------------------------- ### BuildProfile Methods Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/api-reference.md Methods for retrieving profile names for standard builds or cargo build --example. ```rust pub fn profile_name(&self) -> &str ``` ```rust pub fn example_profile_name(&self) -> &str ``` -------------------------------- ### install_debs Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/MANIFEST.md Function to install generated Debian packages using dpkg. ```APIDOC ## install_debs ### Description Invokes the system's dpkg utility to install the generated Debian package files. ### Signature `pub fn install_debs(paths: Vec) -> CDResult<()>` ### Parameters - **paths** (Vec) - Required - A list of file paths pointing to the .deb files to be installed. ``` -------------------------------- ### Example of Merging Assets in Cargo.toml Variants Source: https://github.com/kornelski/cargo-deb/blob/main/README.md Demonstrates how to merge asset lists within different build variants in Cargo.toml using 'append', 'by.dest', and 'by.src' strategies. Explicit paths take precedence over '$auto'. ```toml # Example parent asset list [package.metadata.deb] assets = [ # binary ["target/release/example", "usr/bin/", "755"], # assets ["assets/*", "var/lib/example", "644"], ["target/release/assets/*", "var/lib/example", "644"], ["3.txt", "var/lib/example/3.txt", "644"], ["3.txt", "var/lib/example/merged.txt", "644"], ] # Example merging by appending asset list [package.metadata.deb.variants.mergeappend] merge-assets.append = [ ["4.txt", "var/lib/example/appended/4.txt", "644"] ] # Example merging by `dest` path [package.metadata.deb.variants.mergedest] merge-assets.by.dest = [ ["4.txt", "var/lib/example/merged.txt", "644"] ] # Example merging by `src` path [package.metadata.deb.variants.mergesrc] merge-assets.by.src = [ ["3.txt", "var/lib/example/merged-2.txt", "644"] ] # Example merging by appending and by `src` path [package.metadata.deb.variants.mergeappendandsrc] merge-assets.append = [ ["4.txt", "var/lib/example/appended/4.txt", "644"] ] merge-assets.by.src = [ ["3.txt", "var/lib/example/merged-2.txt", "644"] ] ``` -------------------------------- ### Add filesystem data Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/deb-module.md Adds the compressed data tarball containing files to be installed. ```rust pub fn add_data(&mut self, data_tarball: Compressed) -> CDResult<()> ``` -------------------------------- ### Public Functions Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/MANIFEST.md The primary functions exposed by the library for building, installing, and processing Debian packages. ```APIDOC ## Public Functions ### write_deb() - **Description**: Writes a Debian package based on the provided configuration. ### install_debs() - **Description**: Installs the generated Debian packages. ### strip_binaries() - **Description**: Strips debug symbols from binaries as configured. ``` -------------------------------- ### Build with custom configuration Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/README.md Demonstrates configuring build options and verbose output before processing. ```rust let options = cargo_deb::config::BuildOptions { rust_target_triples: vec!["x86_64-unknown-linux-gnu"], ..Default::default() }; let deb = cargo_deb::CargoDeb { options, verbose: true, ..Default::default() }; deb.process(&listener)?; ``` -------------------------------- ### Execute Debian Archive Build Sequence Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/deb-module.md Demonstrates the step-by-step process of creating a .deb file, including control and data archive generation and final AR packaging. ```rust // 1. Create outer AR archive let mut deb_archive = DebArchive::new( PathBuf::from("package_1.0_amd64.deb"), 1234567890 )?; // 2. Build control archive let mut control = ControlArchiveBuilder::new(compressor, timestamp, listener); control.generate_archive(&config, &package)?; let control_compressed = control.finish()?.finish()?; // 3. Add control to AR deb_archive.add_control(control_compressed)?; // 4. Build data archive let tarball = Tarball::new(compressor, timestamp); let data_compressed = tarball.archive_files(&package, false, listener)? .finish()?; // 5. Add data to AR deb_archive.add_data(Compressed::new(data_compressed, Format::Xz))?; // 6. Finish let path = deb_archive.finish()?; println!("Created: {}", path.display()); ``` -------------------------------- ### Examine generated postinst script Source: https://github.com/kornelski/cargo-deb/blob/main/systemd.md View the content of the post-installation script to see the injected systemd management logic. ```sh $ cat deb_out/postinst #!/bin/sh set -e # Automatically added by cargo-deb if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then if deb-systemd-helper debian-installed example.service; then # This will only remove masks created by d-s-h on package removal. deb-systemd-helper unmask example.service >/dev/null || true if deb-systemd-helper --quiet was-enabled example.service; then # Create new symlinks, if any. deb-systemd-helper enable example.service >/dev/null || true fi fi # Update the statefile to add new symlinks (if any), which need to be cleaned # up on purge. Also remove old symlinks. deb-systemd-helper update-state example.service >/dev/null || true fi # End automatically added section # Automatically added by cargo-deb if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then if [ -d /run/systemd/system ]; then systemctl --system daemon-reload >/dev/null || true if [ -n "$2" ]; then _dh_action=restart else _dh_action=start fi deb-systemd-invoke $_dh_action example.service >/dev/null || true fi fi # End automatically added section ``` -------------------------------- ### Define Configuration Files Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/deb-module.md List files that should be treated as configuration files to prevent them from being overwritten during package upgrades. ```text /etc/my-app/config.conf /etc/my-app/defaults.conf /var/lib/my-app/config ``` -------------------------------- ### Minimal binary package configuration Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/configuration.md A basic configuration for a binary package using default asset locations. ```toml [package] name = "my-tool" version = "1.0.0" description = "A useful tool" [package.metadata.deb] maintainer = "Me " copyright = "2024 Me" section = "utility" priority = "optional" # Assets default to $auto: binary goes to usr/bin/ ``` -------------------------------- ### Build a Debian package Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/index.md Initializes the CargoDeb process with a standard listener to build a package. ```rust use cargo_deb::{CargoDeb, listener::StdErrListener}; use anstream::ColorChoice; let listener = StdErrListener { verbose: true, quiet: false, color: ColorChoice::Auto }; let deb = CargoDeb::default(); deb.process(&listener)?; ``` -------------------------------- ### Initialize ControlArchiveBuilder Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/deb-module.md Creates a new instance of the builder requiring a compressor, timestamp, and listener. ```rust pub fn new( compressor: Box, default_timestamp: u64, listener: &dyn Listener, ) -> Self ``` -------------------------------- ### Build a .deb with default settings Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/GUIDE.md Use the default CargoDeb configuration to process the current project's Cargo.toml. ```rust use cargo_deb::CargoDeb; use cargo_deb::listener::StdErrListener; use anstream::ColorChoice; fn main() -> Result<(), Box> { let listener = StdErrListener { verbose: true, quiet: false, color: ColorChoice::Auto, }; let deb = CargoDeb::default(); deb.process(&listener)?; Ok(()) } ``` -------------------------------- ### Configure build options for current platform Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/GUIDE.md Initialize default build options for the current platform by leaving the target list empty. ```rust let options = BuildOptions::default(); // Empty target list ``` -------------------------------- ### BuildEnvironment::from_manifest Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/README.md Loads the build configuration and package settings from the project's Cargo.toml manifest. ```APIDOC ## fn from_manifest(BuildOptions, &dyn Listener) -> CDResult<(Self, Vec)> ### Description Parses the project manifest to initialize the build environment and retrieve package configurations. ### Parameters - **BuildOptions** (BuildOptions) - Required - Configuration options for the build process. - **listener** (&dyn Listener) - Required - A trait object for reporting progress and errors during manifest parsing. ### Returns - **CDResult<(Self, Vec)>** - Returns a tuple containing the initialized BuildEnvironment and a list of PackageConfig objects. ``` -------------------------------- ### CargoDeb::process Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/README.md The process method is the main entry point for building .deb files. It consumes the CargoDeb instance and executes the build process using the provided listener for progress and error reporting. ```APIDOC ## fn process(mut self, listener: &dyn Listener) -> CDResult<()> ### Description Executes the Debian package build process based on the configuration defined in the CargoDeb instance. ### Parameters - **listener** (&dyn Listener) - Required - A trait object that receives progress updates and error notifications during the build process. ### Returns - **CDResult<()>** - Returns an empty result on success, or a CargoDebError variant on failure. ``` -------------------------------- ### Load build configuration Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/README.md Initializes the build environment and package configurations from the Cargo manifest. ```rust impl BuildEnvironment { pub fn from_manifest( BuildOptions { .. }: BuildOptions<'_>, listener: &dyn Listener, ) -> CDResult<(Self, Vec)> } ``` -------------------------------- ### Customizing Build Command Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/GUIDE.md Use BuildOptions to specify an alternative build command like zigbuild and pass custom flags. ```rust use cargo_deb::{CargoDeb, config::BuildOptions}; use cargo_deb::listener::StdErrListener; use anstream::ColorChoice; fn main() -> Result<(), Box> { let listener = StdErrListener { verbose: true, quiet: false, color: ColorChoice::Auto, }; let options = BuildOptions { // Use zigbuild instead of cargo build cargo_build_cmd: Some("zigbuild".to_string()), // Additional flags to pass to the build command cargo_build_flags: vec!["--verbose".to_string()], ..Default::default() }; let deb = CargoDeb { options, no_build: false, verbose: true, ..Default::default() }; deb.process(&listener)?; Ok(()) } ``` -------------------------------- ### Initialize DebArchive Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/deb-module.md Constructor for creating a new .deb archive at a specific path with a fixed timestamp for reproducible builds. ```rust pub fn new(out_abspath: PathBuf, mtime_timestamp: u64) -> CDResult ``` ```rust use cargo_deb::DebArchive; use std::path::PathBuf; let archive = DebArchive::new( PathBuf::from("/tmp/package_1.0_amd64.deb"), 1234567890 )?; ``` -------------------------------- ### Configure License File Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/configuration.md Defines the path to the license file and the number of header lines to skip. ```toml license-file = ["LICENSE", "4"] # [path, skip_lines] ``` -------------------------------- ### Define assets using simple array syntax Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/configuration.md Use this format for basic file inclusion and renaming. The third element specifies octal file permissions. ```toml assets = [ ["source/path", "dest/", "755"], # File to directory (inferred as target dir) ["README.md", "usr/share/doc/package/README", "644"], # File rename ] ``` -------------------------------- ### Define assets using advanced table syntax Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/configuration.md Use this format for more complex configurations, including symlink creation and preserving symlinks during copy. ```toml assets = [ { source = "target/release/binary", dest = "usr/bin/", mode = "755" }, { source = "config.toml", dest = "etc/app/", mode = "644", preserve-symlinks = true }, { dest = "usr/lib/app/", link_name = "usr/local/lib/app", target_path = "../lib/app" }, # Symlink ] ``` -------------------------------- ### Basic Library Usage Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/index.md Initializes a default CargoDeb instance and processes the build using the standard error listener. ```rust use cargo_deb::{CargoDeb, listener::StdErrListener}; use anstream::ColorChoice; fn main() -> Result<(), Box> { let listener = StdErrListener { verbose: true, quiet: false, color: ColorChoice::Auto, }; let deb = CargoDeb { no_build: false, verbose: true, ..Default::default() }; deb.process(&listener)?; Ok(()) } ``` -------------------------------- ### Build package with verbose output Source: https://github.com/kornelski/cargo-deb/blob/main/systemd.md Invoke cargo-deb with the -v flag to see detailed information about the packaging process and systemd unit augmentation. ```sh $ cargo-deb -v Compiling example v1.2.3 (/tmp/t) Running `rustc --crate-name example src/main.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type bin --emit=dep-info,link -C opt-level=3 -Cembed-bitcode=no -C metadata=25d9e83f3daf475a -C extra-filename=-25d9e83f3daf475a --out-dir /tmp/t/target/release/deps -L dependency=/tmp/t/target/release/deps` Finished release [optimized] target(s) in 0.12s info: Stripped '/tmp/t/target/release/example' info: /tmp/t/target/release/example -> usr/bin/example info: - -> usr/share/doc/example/copyright info: /tmp/t/debian/service -> lib/systemd/system/example.service info: Determining augmentations needed for systemd unit example.service info: Maintainer script postinst will be augmented with autoscript postinst-systemd-dont-enable info: Maintainer script postrm will be augmented with autoscript postrm-systemd info: Maintainer script postinst will be augmented with autoscript postinst-systemd-restart info: Maintainer script prerm will be augmented with autoscript prerm-systemd-restart info: Maintainer script postrm will be augmented with autoscript postrm-systemd-reload-only info: Generating maintainer script postinst info: Generating maintainer script prerm info: Generating maintainer script postrm info: compressed/original ratio 91596/243712 (37%) /tmp/t/target/debian/example_1.2.3_amd64.deb ``` -------------------------------- ### Enable multiarch support Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/GUIDE.md Configure multiarch-compatible packages by setting the multiarch field to Multiarch::Same in BuildOptions. ```rust use cargo_deb::{CargoDeb, config::{BuildOptions, Multiarch}}; use cargo_deb::listener::StdErrListener; use anstream::ColorChoice; fn main() -> Result<(), Box> { let listener = StdErrListener { verbose: true, quiet: false, color: ColorChoice::Auto, }; let options = BuildOptions { // Libraries go in /usr/lib/x86_64-linux-gnu/ instead of /usr/lib/ multiarch: Multiarch::Same, ..Default::default() }; let deb = CargoDeb { options, verbose: true, ..Default::default() }; deb.process(&listener)?; Ok(()) } ``` -------------------------------- ### Define a systemd service file Source: https://github.com/kornelski/cargo-deb/blob/main/systemd.md Create a standard systemd unit file in the debian directory to manage the application service. ```ini [Unit] Description=Example [Service] ExecStart=/usr/bin/example [Install] WantedBy=multi-user.target ``` -------------------------------- ### Write a .deb package Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/api-reference.md Generates a .deb file based on the provided build environment and package configuration. ```rust pub fn write_deb( config: &BuildEnvironment, deb_output_path: PathBuf, package_deb: &PackageConfig, compress_config: &CompressConfig, listener: &dyn Listener, ) -> Result ``` -------------------------------- ### Troubleshooting and Build Commands Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/configuration.md Various CLI commands to inspect, test, and override cargo-deb packaging behavior. ```bash cargo deb --no-build -vv ``` ```bash cargo deb --manifest-path subproject/Cargo.toml ``` ```bash cargo deb --variant minimal -vv ``` ```bash cargo deb --deb-version 2.0.0-custom ``` ```bash RUST_LOG=debug cargo deb -vv --separate-debug-symbols ``` -------------------------------- ### Create reproducible .deb files Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/GUIDE.md Sets the SOURCE_DATE_EPOCH environment variable to ensure deterministic package output. ```rust use cargo_deb::CargoDeb; use cargo_deb::listener::StdErrListener; use anstream::ColorChoice; fn main() -> Result<(), Box> { // Set reproducible build environment std::env::set_var("SOURCE_DATE_EPOCH", "1234567890"); let listener = StdErrListener { verbose: true, quiet: false, color: ColorChoice::Auto, }; let deb = CargoDeb { verbose: true, ..Default::default() }; deb.process(&listener)?; println!("āœ“ Reproducible package built!"); Ok(()) } ``` -------------------------------- ### Multi-architecture package with systemd units Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/configuration.md Advanced configuration for multi-arch support, systemd unit management, and build variants. ```toml [package.metadata.deb] maintainer = "Team " multiarch = "same" assets = [ ["target/release/my-lib.so*", "usr/lib/", "755"], ["target/release/my-bin", "usr/bin/", "755"], ["docs/", "usr/share/doc/my-package/", "644"], ] [package.metadata.deb.systemd-units] enable = true start = true restart-after-upgrade = true [package.metadata.deb.variants.minimal] assets = [ ["target/release/my-bin", "usr/bin/", "755"], ] merge-assets.by.src = [] ``` -------------------------------- ### DebArchive::new Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/deb-module.md Creates a new .deb archive file at the specified path with a fixed timestamp for reproducible builds. ```APIDOC ## DebArchive::new ### Description Creates a new .deb archive file. This initializes the AR archive with magic bytes, adds the 'debian-binary' header, and sets up the output file. ### Signature `pub fn new(out_abspath: PathBuf, mtime_timestamp: u64) -> CDResult` ### Parameters - **out_abspath** (PathBuf) - Required - Absolute path to write the .deb file - **mtime_timestamp** (u64) - Required - Unix timestamp for all file times (reproducible builds) ### Returns - **CDResult** - New DebArchive instance or error ``` -------------------------------- ### Build with custom configuration Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/index.md Overrides default package metadata and manifest paths during the build process. ```rust let options = BuildOptions { manifest_path: Some(Path::new("./Cargo.toml")), selected_package_name: Some("my-package"), config_variant: Some("minimal"), overrides: DebConfigOverrides { deb_version: Some("2.0.0".into()), maintainer: Some("Me ".into()), ..Default::default() }, ..Default::default() }; let deb = CargoDeb { options, ..Default::default() }; deb.process(&listener)?; ``` -------------------------------- ### Compression configuration Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/api-reference.md Structures for defining compression settings and formats for archive generation. ```rust pub struct CompressConfig { pub fast: bool, pub compress_type: Format, pub compress_system: bool, pub rsyncable: bool, } pub enum Format { Xz, Gzip, } ``` -------------------------------- ### Process .deb build Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/README.md The primary method to execute the build process using a listener for callbacks. ```rust impl CargoDeb<'_> { pub fn process(mut self, listener: &dyn Listener) -> CDResult<()> } ``` -------------------------------- ### Catch BinariesNotFound Error Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/errors.md Handles scenarios where no binaries or cdylibs are found for packaging. ```rust match result { Err(CargoDebError::BinariesNotFound(ref name)) => { eprintln!("Package '{}' has no binaries to package", name); eprintln!("Specify assets in [package.metadata.deb] assets"); } _ => {} } ``` -------------------------------- ### Define Process Method Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/api-reference.md The primary method for executing the build and packaging process. ```rust pub fn process(mut self, listener: &dyn Listener) -> CDResult<()> ``` -------------------------------- ### Build Multiple Packages Programmatically Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/GUIDE.md Iterate through a list of package names to build multiple debian packages sequentially using the CargoDeb struct. ```rust use cargo_deb::CargoDeb; use cargo_deb::listener::StdErrListener; use anstream::ColorChoice; fn main() -> Result<(), Box> { let listener = StdErrListener { verbose: true, quiet: false, color: ColorChoice::Auto, }; let packages = vec!["package1", "package2", "package3"]; for package in packages { println!("\nšŸ“¦ Building {}", package); let options = cargo_deb::config::BuildOptions { selected_package_name: Some(package), ..Default::default() }; let deb = CargoDeb { options, verbose: true, ..Default::default() }; deb.process(&listener)?; } println!("\nāœ“ All packages built!"); Ok(()) } ``` -------------------------------- ### Define OutputPath Structure Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/api-reference.md Configuration for specifying the destination directory or file for the generated .deb package. ```rust pub struct OutputPath<'tmp> { pub path: &'tmp Path, pub is_dir: bool, } ``` -------------------------------- ### DebArchive methods Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/api-reference.md Methods for creating, populating, and finalizing a .deb archive. ```rust pub fn new(out_abspath: PathBuf, mtime_timestamp: u64) -> CDResult pub fn add_control(&mut self, control_tarball: Compressed) -> CDResult<()> pub fn add_data(&mut self, data_tarball: Compressed) -> CDResult<()> pub fn finish(self) -> CDResult ``` -------------------------------- ### AssetSource Methods Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/api-reference.md Utility methods for interacting with asset sources, including path resolution and data reading. ```rust pub fn from_path(path: impl Into, preserve_symlinks: bool) -> Self ``` ```rust pub fn source_path(&self) -> Option<&Path> ``` ```rust pub fn file_size(&self) -> Option ``` ```rust pub fn data(&self) -> CDResult> ``` -------------------------------- ### Configure Custom Compression Settings Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/GUIDE.md Adjust compression parameters such as speed, format, and rsync compatibility using the CompressConfig struct. ```rust use cargo_deb::{CargoDeb, compress::{CompressConfig, Format}}; use cargo_deb::listener::StdErrListener; use anstream::ColorChoice; fn main() -> Result<(), Box> { let listener = StdErrListener { verbose: true, quiet: false, color: ColorChoice::Auto, }; let compress = CompressConfig { // Use faster compression fast: true, // Or use gzip instead of xz compress_type: Format::Gzip, // Use system gzip command instead of library compress_system: false, // Optimize for rsync rsyncable: true, }; let deb = CargoDeb { compress_config: compress, verbose: true, ..Default::default() }; deb.process(&listener)?; Ok(()) } ``` -------------------------------- ### Library package with debug symbols Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/configuration.md Configure a library package including custom asset paths and debug symbol generation. ```toml [package.metadata.deb] maintainer = "Maintainer " depends = "$auto" assets = [ ["target/release/libmylib.so*", "usr/lib/", "755"], ["include/mylib.h", "usr/include/", "644"], ] separate-debug-symbols = true ``` -------------------------------- ### BuildOptions Struct Definition Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/api-reference.md Represents command-line and configuration overrides for the build process. ```rust pub struct BuildOptions<'a> { pub manifest_path: Option<&'a Path>, pub selected_package_name: Option<&'a str>, pub rust_target_triples: Vec<&'a str>, pub config_variant: Option<&'a str>, pub overrides: DebConfigOverrides, pub build_profile: BuildProfile, pub debug: DebugSymbolOptions, pub cargo_locking_flags: CargoLockingFlags, pub multiarch: Multiarch, pub cargo_build_cmd: Option, pub cargo_build_flags: Vec, } ``` -------------------------------- ### Generate control archive files Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/deb-module.md Processes configuration and environment data to generate the required control files. ```rust pub fn generate_archive( &mut self, config: &BuildEnvironment, package_deb: &PackageConfig, ) -> CDResult<()> ``` -------------------------------- ### Configure Cargo.toml for Debian Packaging Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/GUIDE.md Define package metadata and asset mapping within the [package.metadata.deb] section of the Cargo.toml file. ```toml [package] name = "my-app" version = "1.0.0" description = "My application" [package.metadata.deb] maintainer = "John Doe " copyright = "2024 John Doe" license-file = ["LICENSE", "5"] section = "utility" priority = "optional" assets = [ ["target/release/my-app", "usr/bin/", "755"], ["README.md", "usr/share/doc/my-app/", "644"], ] depends = "$auto" # Auto-detect via dpkg-shlibdeps ``` -------------------------------- ### Module Structure Overview Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/README.md Visual representation of the cargo-deb crate module hierarchy. ```text cargo_deb ā”œā”€ā”€ CargoDeb Main entry point ā”œā”€ā”€ config:: │ ā”œā”€ā”€ BuildEnvironment Build configuration │ ā”œā”€ā”€ PackageConfig Per-package configuration │ ā”œā”€ā”€ BuildOptions Input options │ └── (other types) ā”œā”€ā”€ deb:: │ ā”œā”€ā”€ ar::DebArchive AR archive builder │ ā”œā”€ā”€ control:: Control metadata generation │ └── tar::Tarball Data filesystem generation ā”œā”€ā”€ listener:: │ ā”œā”€ā”€ Listener trait Progress callbacks │ └── StdErrListener Default implementation ā”œā”€ā”€ assets:: File asset handling ā”œā”€ā”€ error::CargoDebError 23 error variants └── compress:: Archive compression ``` -------------------------------- ### Configure Multiple Systemd Units Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/configuration.md Allows defining multiple systemd unit configurations using an array of tables. ```toml [package.metadata.deb.systemd-units] [[package.metadata.deb.systemd-units]] unit-scripts = "systemd/services" unit-name = "my-app" enable = true start = true [[package.metadata.deb.systemd-units]] unit-scripts = "systemd/timers" unit-name = "my-app-timer" enable = true start = true ``` -------------------------------- ### Configure package metadata in Cargo.toml Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/configuration.md Defines the primary Debian package settings, including metadata, dependencies, assets, and systemd integration. ```toml [package.metadata.deb] # Package metadata name = "custom-package-name" maintainer = "John Doe " copyright = "2024 John Doe " license-file = ["LICENSE", "4"] # [file, lines_to_skip] section = "utility" priority = "optional" # Descriptions description = "Short one-line description" extended-description = """\ This is a longer description that can span multiple lines and provide more details.""" extended-description-file = "DESCRIPTION.txt" # URLs homepage = "https://example.com" repository = "https://github.com/example/project" documentation = "https://docs.example.com" # Dependencies depends = "$auto" # or explicit: "libc6 (>= 2.31), libssl3" pre-depends = "" # Pre-dependencies (rarely needed) recommends = "optional-package" suggests = "extra-package" enhances = "other-package" conflicts = "conflicting-package" breaks = "broken-package" replaces = "old-package-name" provides = "virtual-package" # Debian package options revision = "ubuntu1" # Appended after version profile = "release" # Cargo build profile # Build configuration features = ["feature1", "feature2"] default-features = true all-features = false # Assets (files to include) assets = [ ["target/release/my-binary", "usr/bin/", "755"], ["README.md", "usr/share/doc/my-package/", "644"], { source = "config.toml", dest = "etc/my-app/config.toml", mode = "644" }, ] merge-assets.append = [ ["extra.txt", "var/lib/my-app/extra.txt", "644"] ] # Systemd integration [package.metadata.deb.systemd-units] unit-scripts = "systemd" # or uses maintainer_scripts dir enable = true start = true restart-after-upgrade = true stop-on-upgrade = true # Maintainer scripts maintainer-scripts = "debian" # Directory with preinst, postinst, etc. triggers-file = "debian/triggers" # dpkg triggers file changelog = "debian/changelog" # Debian-formatted changelog # Package variants conf-files = ["/etc/my-app/config.conf", "/var/lib/my-app/defaults"] preserve-symlinks = false multiarch = "none" # or "same" or "foreign" separate-debug-symbols = false ``` -------------------------------- ### Configure Basic Systemd Units Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/configuration.md Defines systemd unit management settings within the package metadata. ```toml [package.metadata.deb.systemd-units] # (Optional) directory containing unit files unit-scripts = "systemd" # (Optional) process only units matching this name unit-name = "my-app" # Whether to systemctl enable the unit enable = true # Whether to systemctl start the unit after install start = true # Whether to systemctl restart on upgrade restart-after-upgrade = true # Whether to systemctl stop on upgrade stop-on-upgrade = true ``` -------------------------------- ### Default CargoDeb Implementation Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/api-reference.md Initializes a CargoDeb struct with default build options and compression settings. ```rust CargoDeb { options: BuildOptions::default(), no_build: false, deb_output: None, verbose: false, verbose_cargo_build: false, install: (false, false), compress_config: CompressConfig { fast: false, compress_type: Format::Xz, compress_system: false, rsyncable: false, }, } ``` -------------------------------- ### Add and Catch Context Errors Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/errors.md Shows how to wrap errors with additional context and how to catch them. ```rust some_operation().map_err(|e| e.context("while processing assets"))? ``` ```rust match result { Err(CargoDebError::Context(ref msg, ref inner)) => { eprintln!("Error: {}\nCause: {}", msg, inner); } _ => {} } ``` -------------------------------- ### Configure Output Directory for .deb Files Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/GUIDE.md Use the OutputPath struct to specify a custom directory for generated .deb files. Ensure the path exists or is handled appropriately by the filesystem. ```rust use cargo_deb::{CargoDeb, OutputPath}; use cargo_deb::listener::StdErrListener; use anstream::ColorChoice; use std::path::Path; fn main() -> Result<(), Box> { let listener = StdErrListener { verbose: true, quiet: false, color: ColorChoice::Auto, }; let output = OutputPath { path: Path::new("/tmp/debs/"), is_dir: true, // Generate files in this directory }; let deb = CargoDeb { deb_output: Some(output), verbose: true, ..Default::default() }; deb.process(&listener)?; println!("Packages written to /tmp/debs/"); Ok(()) } ``` -------------------------------- ### Enable maximum logging Source: https://github.com/kornelski/cargo-deb/blob/main/README.md Increase logging verbosity for troubleshooting using -vv or RUST_LOG=debug. ```sh cargo deb -vv ``` ```sh RUST_LOG=debug cargo deb -vv ``` -------------------------------- ### CargoDeb::process Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/index.md The primary method for executing the Debian package build process using the configured options and a provided listener. ```APIDOC ## fn process(&mut self, listener: &dyn Listener) -> CDResult<()> ### Description Executes the build process for the Debian package based on the configuration defined in the `CargoDeb` struct. ### Parameters - **listener** (&dyn Listener) - Required - A trait object that receives progress updates, warnings, and error messages during the build process. ``` -------------------------------- ### Add cargo-deb to Cargo.toml Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/GUIDE.md Include the library and anstream for color output in your project dependencies. ```toml [dependencies] cargo-deb = "3.7" anstream = "1.0" # For color output ``` -------------------------------- ### Include files using glob patterns Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/configuration.md Use glob patterns to include multiple files matching a specific path structure. ```toml assets = [ ["src/config/*.toml", "etc/myapp/", "644"], ["docs/**/*.html", "usr/share/doc/myapp/", "644"], ] ``` -------------------------------- ### Define BuildEnvironment struct Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/types.md Represents the build configuration derived from Cargo.toml and manifest metadata. ```rust pub struct BuildEnvironment { pub package_manifest_dir: PathBuf, pub cargo_run_current_dir: PathBuf, pub target_dir_base: PathBuf, pub build_dir_base: Option, pub features: Vec, pub default_features: bool, pub all_features: bool, pub debug_symbols: DebugSymbols, pub reproducible: bool, } ``` -------------------------------- ### Cross-compile build Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/README.md Configures multiple target triples to build .deb packages for different architectures. ```rust let options = cargo_deb::config::BuildOptions { rust_target_triples: vec![ "x86_64-unknown-linux-gnu", "aarch64-unknown-linux-gnu", ], ..Default::default() }; let deb = cargo_deb::CargoDeb { options, ..Default::default() }; deb.process(&listener)?; ``` -------------------------------- ### Define Architecture-Specific Dependencies Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/configuration.md Specifies dependencies based on target architectures using bracket syntax. ```toml depends = "libc6 [amd64 arm64]" # Only on these architectures depends = "libfoo [!armhf]" # Everything except armhf depends = "base, optional [amd64]" # Mixed ``` -------------------------------- ### Specify package metadata crate in workspaces Source: https://github.com/kornelski/cargo-deb/blob/main/README.md When using workspaces, select the crate for package metadata using -p crate_name or --manifest-path. ```sh cargo deb -p crate_name ``` ```sh cargo deb --manifest-path= ``` -------------------------------- ### Enable verbose logging for cargo-deb Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/errors.md Use this command to display the full error chain and additional context during execution. ```bash RUST_LOG=debug cargo deb -vv ``` -------------------------------- ### Define CompressConfig struct Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/types.md Configuration settings for archive compression. ```rust pub struct CompressConfig { pub fast: bool, pub compress_type: Format, pub compress_system: bool, pub rsyncable: bool, } ``` -------------------------------- ### Configure Cargo.toml for systemd Source: https://github.com/kornelski/cargo-deb/blob/main/systemd.md Define package metadata to enable or disable systemd-units support within the debian packaging process. ```toml [package] name = "example" version = "1.2.3" description = "An example package to demonstrate cargo-deb systemd-units support." license = "MIT" authors = ["cargo-deb team"] [package.metadata.deb] maintainer-scripts = "debian/" systemd-units = { enable = false } ``` -------------------------------- ### Finish archive generation Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/deb-module.md Finalizes the process and returns the compressed control archive. ```rust pub fn finish(self) -> CDResult> ``` -------------------------------- ### Custom Build Configuration Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/index.md Configures specific build options such as manifest path and target triples before processing the Debian package build. ```rust use cargo_deb::{CargoDeb, config::BuildOptions, BuildProfile}; use std::path::Path; let options = BuildOptions { manifest_path: Some(Path::new("./Cargo.toml")), rust_target_triples: vec!["x86_64-unknown-linux-gnu"], build_profile: BuildProfile { profile_name: Some("release".into()), ..Default::default() }, ..Default::default() }; let deb = CargoDeb { options, verbose: true, ..Default::default() }; deb.process(&listener)?; ``` -------------------------------- ### Tarball::new Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/deb-module.md Creates a new instance of the Tarball builder with a specified compressor and timestamp. ```APIDOC ## Tarball::new ### Description Create a new tarball builder instance. ### Signature `pub fn new(compressor: Box, default_timestamp: u64) -> Self` ### Parameters - **compressor** (Box) - Required - Compression handler - **default_timestamp** (u64) - Required - Timestamp for reproducible builds ### Returns - **Tarball** - A new instance of the Tarball builder. ``` -------------------------------- ### Compressed Method Definitions Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/deb-module.md Methods for retrieving metadata and data from a Compressed instance. ```rust pub fn extension(&self) -> &str ``` ```rust pub fn len(&self) -> usize ``` ```rust pub fn finish(self) -> CDResult> ``` -------------------------------- ### Parse Manifest Configuration Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/api-reference.md Function to parse Cargo.toml and generate the build environment and package configurations. ```rust pub fn from_manifest( BuildOptions { .. }: BuildOptions<'_>, listener: &dyn Listener, ) -> CDResult<(Self, Vec)> ``` -------------------------------- ### write_deb Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/api-reference.md Writes a .deb file for a single package configuration. ```APIDOC ## write_deb ### Description Generates a .deb file by creating control and data tarballs and packaging them into an AR archive. ### Signature `pub fn write_deb(config: &BuildEnvironment, deb_output_path: PathBuf, package_deb: &PackageConfig, compress_config: &CompressConfig, listener: &dyn Listener) -> Result` ### Parameters - **config** (&BuildEnvironment) - Build environment with paths - **deb_output_path** (PathBuf) - Target file path for the .deb - **package_deb** (&PackageConfig) - Package configuration - **compress_config** (&CompressConfig) - Compression settings - **listener** (&dyn Listener) - Callback for progress ### Returns - **Result** - Path to the created .deb file ``` -------------------------------- ### Define package variants in Cargo.toml Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/configuration.md Creates alternative package configurations that inherit from the main metadata section. ```toml [package.metadata.deb.variants.minimal] name = "my-package-minimal" # Optional; appends variant name if not set assets = ["target/release/my-binary", "usr/bin/", "755"] merge-assets.by.dest = [ # Replace assets from parent by destination ] merge-assets.by.src = [ # Replace assets from parent by source ] [package.metadata.deb.variants.full] assets.append = [ ["docs/*", "usr/share/doc/my-package/", "644"] ] ``` -------------------------------- ### Handle GlobPatternError Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/errors.md Demonstrates an invalid glob pattern configuration and how to catch the resulting error. ```toml assets = ["src/[unclosed/", "usr/bin/"] # Invalid glob ``` ```rust match result { Err(CargoDebError::GlobPatternError(_)) => { eprintln!("Invalid glob pattern in assets"); } _ => {} } ``` -------------------------------- ### Custom Cargo.toml Metadata for Debian Packages Source: https://github.com/kornelski/cargo-deb/blob/main/README.md Configure Debian package metadata like maintainer, copyright, license file, extended description, dependencies, section, priority, and assets directly in Cargo.toml. ```toml [package.metadata.deb] maintainer = "Michael Aaron Murphy " copyright = "2017, Michael Aaron Murphy " license-file = ["LICENSE", "4"] extended-description = """ A simple subcommand for the Cargo package manager for \ building Debian packages from Rust projects.""" depends = "$auto" section = "utility" priority = "optional" assets = [ # target/release path is special, and gets replaced by cargo-deb with the actual target dir path. ["target/release/cargo-deb", "usr/bin/", "755"], # both array and object syntaxes are equivalent: { source = "README.md", dest = "usr/share/doc/cargo-deb/README", mode = "644"}, ] # assets = ["$auto"] # the default if assets are not specified ``` -------------------------------- ### Create New Tarball Builder Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/deb-module.md Initializes a new Tarball instance with a specific compressor and timestamp for reproducible builds. ```rust pub fn new( compressor: Box, default_timestamp: u64, ) -> Self ``` -------------------------------- ### Configure Debug Symbols and Ddeb Packages Source: https://github.com/kornelski/cargo-deb/blob/main/_autodocs/GUIDE.md Configures the build process to extract debug symbols into separate files and generate a corresponding -dbgsym.ddeb package using Zstd compression. ```rust use cargo_deb::{ CargoDeb, config::BuildOptions, BuildProfile, DebugSymbolOptions, CompressDebugSymbols }; use cargo_deb::listener::StdErrListener; use anstream::ColorChoice; fn main() -> Result<(), Box> { let listener = StdErrListener { verbose: true, quiet: false, color: ColorChoice::Auto, }; let options = BuildOptions { debug: DebugSymbolOptions { // Extract symbols to separate files separate_debug_symbols: Some(true), // Generate a separate -dbgsym.ddeb package generate_dbgsym_package: Some(true), // Compress debug symbols with Zstd compress_debug_symbols: Some(CompressDebugSymbols::Zstd), }, ..Default::default() }; let deb = CargoDeb { options, verbose: true, ..Default::default() }; deb.process(&listener)?; println!("Created both .deb and -dbgsym.ddeb packages!"); Ok(()) } ```