#!/usr/bin/env bash # # Build a Debian package for QuickSearch. # # ./packaging/build-deb.sh build and package # ./packaging/build-deb.sh --no-build package an existing release binary # ./packaging/build-deb.sh --no-strip keep debug symbols (25 MB vs 20 MB) # ./packaging/build-deb.sh -o /tmp/out write the .deb somewhere else # # Environment: DEB_MAINTAINER, SOURCE_DATE_EPOCH. # # Deliberately does not use cargo-deb, debhelper, fakeroot or an SVG rasteriser: # dpkg-deb and desktop-file-utils are the only tools required, and both are part # of a standard Debian or Ubuntu install. set -euo pipefail readonly PKG=quicksearch # The GUI binary and the console-subsystem terminal binary. Both ship: on Unix # `quicksearch` does both jobs, but the README and the shared man page name # `quicksearch-cli` too, so it has to exist wherever the docs are installed. readonly BINARIES=(quicksearch quicksearch-cli) . "$(dirname -- "${BASH_SOURCE[0]}")/common.sh" parse_args "$@" require_tools dpkg-deb dpkg desktop-file-validate objdump gzip # No Debian revision: QuickSearch is only ever packaged from its own source, so # the version is native (no hyphen) and the .deb is named for the crate version # alone, matching the Windows installer. maintainer="${DEB_MAINTAINER:-Jeremy }" arch="$(dpkg --print-architecture)" stage="$out_dir/${PKG}_${version}_${arch}" deb="$out_dir/${PKG}_${version}_${arch}.deb" # ---------------------------------------------------------------- build ---- if [ "$do_build" -eq 1 ]; then build_host_release fi for bin in "${BINARIES[@]}"; do [ -x "$REPO_ROOT/target/release/$bin" ] \ || die "no release binary at target/release/$bin (drop --no-build?)" done # Both binaries link the same crates, so either gives the same glibc floor. readonly primary_binary="$REPO_ROOT/target/release/$PKG" [ -f "$ICON_SVG" ] || die "no icon at $ICON_SVG" [ -f "$REPO_ROOT/packaging/$METAINFO" ] || die "no metainfo at packaging/$METAINFO" say "Validating desktop entry" desktop-file-validate "$REPO_ROOT/packaging/$PKG.desktop" # --------------------------------------------------------------- stage ----- say "Staging $stage" rm -rf "$stage" mkdir -p "$stage" for bin in "${BINARIES[@]}"; do install -Dm755 "$REPO_ROOT/target/release/$bin" "$stage/usr/bin/$bin" done install -Dm644 "$REPO_ROOT/packaging/$PKG.desktop" "$stage/usr/share/applications/$PKG.desktop" install_docs "$stage" install_icons "$stage" # AppStream metadata, so software centres show a real listing rather than a bare # package name. build-appimage.sh ships the identical file and is where it gets # validated - appstreamcli is not something a stock Debian install has, and this # script deliberately needs nothing beyond dpkg-deb and desktop-file-utils. install_metainfo "$stage" # Debian wants man pages and the changelog compressed, with no gzip timestamp so # repeat builds are byte-identical. quicksearch-cli.1 is a one-line .so stub # pointing at quicksearch.1, which documents both binaries. # # The .TH version field is rewritten from $version on the way through, so the # footer of an installed page tracks [workspace.package] version instead of # needing a hand-edit every release. The stub has no .TH, so the sed is a # no-op there. install -dm755 "$stage/usr/share/man/man1" for page in "${BINARIES[@]}"; do sed "/^\.TH /s/\"quicksearch [^\"]*\"/\"quicksearch $version\"/" \ "$REPO_ROOT/packaging/$page.1" \ | gzip -9nc > "$stage/usr/share/man/man1/$page.1.gz" chmod 644 "$stage/usr/share/man/man1/$page.1.gz" done changelog_date="$(date -R ${SOURCE_DATE_EPOCH:+-u -d "@$SOURCE_DATE_EPOCH"})" # changelog.gz, not changelog.Debian.gz: with a native version there is no # separate Debian revision to log, and policy puts the one changelog here. gzip -9nc < "$stage/usr/share/doc/$PKG/changelog.gz" $PKG ($version) unstable; urgency=medium * Package build of $PKG $version. -- $maintainer $changelog_date EOF chmod 644 "$stage/usr/share/doc/$PKG/changelog.gz" # No config.toml is installed anywhere. Config::config_path() treats a # config.toml sitting next to the executable as portable mode and lets it # override the per-user config outright, so one in /usr/bin would hijack every # account on the machine. Config::load_from creates ~/.config/quicksearch/ # config.toml on first run instead. if [ "$do_strip" -eq 1 ]; then for bin in "${BINARIES[@]}"; do before="$(du -h "$stage/usr/bin/$bin" | cut -f1)" strip --strip-unneeded "$stage/usr/bin/$bin" say "Stripped $bin: $before -> $(du -h "$stage/usr/bin/$bin" | cut -f1)" done fi installed_size="$(du -ks "$stage" | cut -f1)" # ------------------------------------------------------------- control ----- # The dynamic section only names libc, libgcc, libm and libbz2: winit and glutin # dlopen the entire display stack, so dpkg-shlibdeps cannot see it and the list # below is maintained by hand. Re-derive it with # objdump -p target/release/quicksearch | grep NEEDED # strings -a target/release/quicksearch | grep -oE 'lib[A-Za-z0-9_+-]+\.so(\.[0-9]+)*' | sort -u # and map each soname to a package with `dpkg -S`. glibc_min="$(objdump -T "$primary_binary" | sed -n 's/.*GLIBC_\([0-9][0-9.]*\).*/\1/p' | sort -V | tail -1)" [ -n "$glibc_min" ] || die "could not determine the glibc version requirement" depends="libc6 (>= ${glibc_min}), libgcc-s1 (>= 3.0), libbz2-1.0" depends="$depends, libx11-6, libxcb1, libxcursor1, libxi6, libxrender1" depends="$depends, libxkbcommon0, libxkbcommon-x11-0" depends="$depends, libwayland-client0, libwayland-egl1" depends="$depends, libegl1, libgl1" # Required by policy for anything installing into the hicolor theme; it also # provides the dpkg trigger that refreshes the icon cache on install. depends="$depends, hicolor-icon-theme" # desktop-file-utils owns the /usr/share/applications trigger; dbus-bin provides # the dbus-send used by "reveal in folder"; xdg-utils provides the xdg-open # fallback; xdg-desktop-portal backs the native folder picker. None are needed # to search, so none are hard dependencies. # # The index-password "remember on this device" feature talks Secret Service # over the session bus with a statically linked libdbus (keyring's `vendored` # feature), so it adds no library dependency; without a Secret Service # provider (gnome-keyring, kwalletd) it simply falls back to prompting. recommends="desktop-file-utils, xdg-utils, dbus-bin, xdg-desktop-portal" install -dm755 "$stage/DEBIAN" cat > "$stage/DEBIAN/control" </dev/null rm -rf "$stage" echo dpkg-deb --info "$deb" echo say "Done: $deb" echo " install with: sudo apt install $deb" echo " inspect with: dpkg-deb --contents $deb"