Packaging bat

bat is a cat clone with extra features written in Rust (and using the Cargo build system).

If you want to follow along, run this:

rm -r srcpkgs/bat

Gathering info

To package bat, we first need to gather the metadata needed in the template. Most of it is in their repository: https://github.com/sharkdp/bat

  • latest version: 0.24.0 (not v0.24.0)

  • build_style: the Cargo build system is used (this is common for Rust projects) so cargo is appropriate

  • short_desc: Cat(1) clone with syntax highlighting and Git integration

  • license: bat has two licenses, Apache-2.0 and MIT:

    license

    Multiple licenses should be separated by “, “ like this:

    license="Apache-2.0, MIT"
    
  • homepage: the project has no custom homepage, https://github.com/sharkdp/bat is sufficient

  • changelog: the repo has a CHANGELOG.md file, so we should link to it.

    Remember that plaintext changelogs are preferred:

    Bad

    changelog=https://github.com/sharkdp/bat/blob/master/CHANGELOG.md

    Good

    changelog=https://raw.githubusercontent.com/sharkdp/bat/master/CHANGELOG.md

  • distfiles: bat’s release has a lot of files in it:

    bat release

    Prebuilt archives cannot be used in void-packages. So you must copy the Source code (tar.gz) link.

    Don’t forget to replace the version with ${version}:

    Bad

    https://github.com/sharkdp/bat/archive/refs/tags/v0.24.0.tar.gz

    Good

    https://github.com/sharkdp/bat/archive/refs/tags/v${version}.tar.gz

Creating the template

We can use xnew to create the template and fill out what we know:

# Template file for 'bat'
pkgname=bat
version=0.24.0
revision=1
build_style=cargo
short_desc="Cat(1) clone with syntax highlighting and Git integration"
maintainer="meator <meator.dev@gmail.com>"
license="Apache-2.0, MIT"
homepage="https://github.com/sharkdp/bat"
changelog="https://raw.githubusercontent.com/sharkdp/bat/master/CHANGELOG.md"
distfiles="https://github.com/sharkdp/bat/archive/refs/tags/v${version}.tar.gz"
checksum=badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadb

We use

xgensum -i bat

to get checksum (-i flag modifies the template in place):

# Template file for 'bat'
pkgname=bat
version=0.24.0
revision=1
build_style=cargo
short_desc="Cat(1) clone with syntax highlighting and Git integration"
maintainer="meator <meator.dev@gmail.com>"
license="Apache-2.0, MIT"
homepage="https://github.com/sharkdp/bat"
changelog="https://raw.githubusercontent.com/sharkdp/bat/master/CHANGELOG.md"
distfiles="https://github.com/sharkdp/bat/archive/refs/tags/v${version}.tar.gz"
checksum=907554a9eff239f256ee8fe05a922aad84febe4fe10a499def72a4557e9eedfb

Testing, troubleshooting & dependency hunting

We can now try to build it:

./xbps-src pkg bat

The following error arises:

=> xbps-src: updating repositories for host (x86_64)...
[*] Updating repository `https://repo-default.voidlinux.org/current/bootstrap/x86_64-repodata' ...
[*] Updating repository `https://repo-default.voidlinux.org/current/x86_64-repodata' ...
[*] Updating repository `https://repo-default.voidlinux.org/current/nonfree/x86_64-repodata' ...
[*] Updating repository `https://repo-default.voidlinux.org/current/debug/x86_64-repodata' ...
[*] Updating repository `https://repo-default.voidlinux.org/current/multilib/bootstrap/x86_64-repodata' ...
[*] Updating repository `https://repo-default.voidlinux.org/current/multilib/x86_64-repodata' ...
[*] Updating repository `https://repo-default.voidlinux.org/current/multilib/nonfree/x86_64-repodata' ...
=> xbps-src: updating software in / masterdir...
=> xbps-src: cleaning up / masterdir...
=> bat-0.24.0_1: removing autodeps, please wait...
=> bat-0.24.0_1: building with [cargo] [rust] for x86_64...
   [host] cargo-1.76.0_1: found (https://repo-default.voidlinux.org/current)
   [host] cargo-auditable-0.6.2_1: found (https://repo-default.voidlinux.org/current)
=> bat-0.24.0_1: installing host dependencies: cargo-1.76.0_1 cargo-auditable-0.6.2_1 ...
=> bat-0.24.0_1: running do-fetch hook: 00-distfiles ...
=> bat-0.24.0_1: running do-extract hook: 00-distfiles ...
=> bat-0.24.0_1: extracting distfile(s), please wait...
=> bat-0.24.0_1: running do-patch hook: 00-patches ...
=> bat-0.24.0_1: running pre-configure hook: 00-gnu-configure-asneeded ...
=> bat-0.24.0_1: running pre-configure hook: 01-override-config ...
=> bat-0.24.0_1: running pre-configure hook: 02-script-wrapper ...
=> bat-0.24.0_1: running pre-build hook: 02-script-wrapper ...
=> bat-0.24.0_1: running do_build ...
   Compiling libc v0.2.147
   Compiling proc-macro2 v1.0.66
   Compiling quote v1.0.26
   Compiling unicode-ident v1.0.4
   Compiling pkg-config v0.3.25
   Compiling memchr v2.5.0
   Compiling rustix v0.38.11
   Compiling syn v2.0.12
   Compiling jobserver v0.1.25
   Compiling cc v1.0.73
   Compiling cfg-if v1.0.0
   Compiling serde v1.0.163
   Compiling utf8parse v0.2.1
   Compiling linux-raw-sys v0.4.5
   Compiling bitflags v2.4.0
   Compiling anstyle-parse v0.2.0
   Compiling log v0.4.17
   Compiling tinyvec_macros v0.1.0
   Compiling proc-macro-hack v0.5.19
   Compiling itoa v1.0.3
   Compiling anstyle-query v1.0.0
   Compiling libz-sys v1.1.8
   Compiling autocfg v1.1.0
   Compiling syn v1.0.104
   Compiling anstyle v1.0.0
   Compiling colorchoice v1.0.0
   Compiling indexmap v1.9.1
   Compiling anstream v0.6.4
   Compiling sys-info v0.9.1
   Compiling onig_sys v69.8.1
   Compiling tinyvec v1.6.0
   Compiling terminal_size v0.3.0
   Compiling crc32fast v1.3.2
   Compiling clap_lex v0.5.0
   Compiling strsim v0.10.0
   Compiling unicode-normalization v0.1.22
   Compiling serde_derive v1.0.163
   Compiling clap_builder v4.4.6
error: failed to run custom build command for `onig_sys v69.8.1`

Caused by:
  process didn't exit successfully: `/builddir/bat-0.24.0/target/release/build/onig_sys-87cb5ba460ba7160/build-script-build` (exit status: 101)
  --- stdout
  cargo:rerun-if-env-changed=RUSTONIG_DYNAMIC_LIBONIG
  cargo:rerun-if-env-changed=RUSTONIG_STATIC_LIBONIG
  cargo:rerun-if-env-changed=RUSTONIG_SYSTEM_LIBONIG
  cargo:rerun-if-env-changed=ONIGURUMA_NO_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=ONIGURUMA_STATIC
  cargo:rerun-if-env-changed=ONIGURUMA_DYNAMIC
  cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC
  cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR

  --- stderr
  thread 'main' panicked at /host/cargo/registry/src/index.crates.io-6f17d22bba15001f/onig_sys-69.8.1/build.rs:253:17:
  Unable to find oniguruma in pkg-config, and RUSTONIG_SYSTEM_LIBONIG is set: Could not run `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS="1" PKG_CONFIG_ALLOW_SYSTEM_LIBS="1" "pkg-config" "--libs" "--cflags" "oniguruma" "oniguruma >= 6.9.3"`
  The pkg-config command could not be found.

  Most likely, you need to install a pkg-config package for your OS.
  Try `apt install pkg-config`, or `yum install pkg-config`,
  or `pkg install pkg-config` depending on your distribution.

  If you've already installed it, ensure the pkg-config command is one of the
  directories in the PATH environment variable.

  If you did not expect this build to link to a pre-installed system library,
  then check documentation of the onig_sys crate for an option to
  build the library from source, or disable features or dependencies
  that require pkg-config.
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
=> ERROR: bat-0.24.0_1: do_build: '${make_cmd} build --release --locked --target ${RUST_TARGET} ${configure_args}' exited with 101
=> ERROR:   in do_build() at common/build-style/cargo.sh:8

This is a pretty nice error message. It clearly explains that it didn’t find pkg-config. pkg-config needs to run on the host, so it belongs to hostmakedepends.

# Template file for 'bat'
pkgname=bat
version=0.24.0
revision=1
hostmakedepends=pkg-config
build_style=cargo
short_desc="Cat(1) clone with syntax highlighting and Git integration"
maintainer="meator <meator.dev@gmail.com>"
license="Apache-2.0, MIT"
homepage="https://github.com/sharkdp/bat"
changelog="https://raw.githubusercontent.com/sharkdp/bat/master/CHANGELOG.md"
distfiles="https://github.com/sharkdp/bat/archive/refs/tags/v${version}.tar.gz"
checksum=907554a9eff239f256ee8fe05a922aad84febe4fe10a499def72a4557e9eedfb

The following error arises:

=> xbps-src: updating repositories for host (x86_64)...
[*] Updating repository `https://repo-default.voidlinux.org/current/bootstrap/x86_64-repodata' ...
[*] Updating repository `https://repo-default.voidlinux.org/current/x86_64-repodata' ...
[*] Updating repository `https://repo-default.voidlinux.org/current/nonfree/x86_64-repodata' ...
[*] Updating repository `https://repo-default.voidlinux.org/current/debug/x86_64-repodata' ...
[*] Updating repository `https://repo-default.voidlinux.org/current/multilib/bootstrap/x86_64-repodata' ...
[*] Updating repository `https://repo-default.voidlinux.org/current/multilib/x86_64-repodata' ...
[*] Updating repository `https://repo-default.voidlinux.org/current/multilib/nonfree/x86_64-repodata' ...
=> xbps-src: updating software in / masterdir...
=> xbps-src: cleaning up / masterdir...
=> bat-0.24.0_1: removing autodeps, please wait...
=> bat-0.24.0_1: building with [cargo] [rust] for x86_64...
   [host] pkg-config-0.29.2_3: found (https://repo-default.voidlinux.org/current)
   [host] cargo-1.76.0_1: found (https://repo-default.voidlinux.org/current)
   [host] cargo-auditable-0.6.2_1: found (https://repo-default.voidlinux.org/current)
=> bat-0.24.0_1: installing host dependencies: pkg-config-0.29.2_3 cargo-1.76.0_1 cargo-auditable-0.6.2_1 ...
=> bat-0.24.0_1: running do-fetch hook: 00-distfiles ...
=> bat-0.24.0_1: running do-extract hook: 00-distfiles ...
=> bat-0.24.0_1: extracting distfile(s), please wait...
=> bat-0.24.0_1: running do-patch hook: 00-patches ...
=> bat-0.24.0_1: running pre-configure hook: 00-gnu-configure-asneeded ...
=> bat-0.24.0_1: running pre-configure hook: 01-override-config ...
=> bat-0.24.0_1: running pre-configure hook: 02-script-wrapper ...
=> bat-0.24.0_1: running pre-build hook: 02-script-wrapper ...
=> bat-0.24.0_1: running do_build ...
   Compiling libc v0.2.147
   Compiling proc-macro2 v1.0.66
   Compiling quote v1.0.26
   Compiling unicode-ident v1.0.4
   Compiling rustix v0.38.11
   Compiling memchr v2.5.0
   Compiling pkg-config v0.3.25
   Compiling syn v2.0.12
   Compiling jobserver v0.1.25
   Compiling cc v1.0.73
   Compiling cfg-if v1.0.0
   Compiling serde v1.0.163
   Compiling bitflags v2.4.0
   Compiling linux-raw-sys v0.4.5
   Compiling utf8parse v0.2.1
   Compiling anstyle-parse v0.2.0
   Compiling log v0.4.17
   Compiling autocfg v1.1.0
   Compiling colorchoice v1.0.0
   Compiling proc-macro-hack v0.5.19
   Compiling libz-sys v1.1.8
   Compiling anstyle-query v1.0.0
   Compiling tinyvec_macros v0.1.0
   Compiling anstyle v1.0.0
   Compiling syn v1.0.104
   Compiling itoa v1.0.3
   Compiling anstream v0.6.4
   Compiling tinyvec v1.6.0
   Compiling sys-info v0.9.1
   Compiling onig_sys v69.8.1
   Compiling indexmap v1.9.1
   Compiling strsim v0.10.0
   Compiling terminal_size v0.3.0
   Compiling clap_lex v0.5.0
   Compiling crc32fast v1.3.2
   Compiling clap_builder v4.4.6
   Compiling unicode-normalization v0.1.22
error: failed to run custom build command for `onig_sys v69.8.1`

Caused by:
  process didn't exit successfully: `/builddir/bat-0.24.0/target/release/build/onig_sys-87cb5ba460ba7160/build-script-build` (exit status: 101)
  --- stdout
  cargo:rerun-if-env-changed=RUSTONIG_DYNAMIC_LIBONIG
  cargo:rerun-if-env-changed=RUSTONIG_STATIC_LIBONIG
  cargo:rerun-if-env-changed=RUSTONIG_SYSTEM_LIBONIG
  cargo:rerun-if-env-changed=ONIGURUMA_NO_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=ONIGURUMA_STATIC
  cargo:rerun-if-env-changed=ONIGURUMA_DYNAMIC
  cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC
  cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_PATH
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-unknown-linux-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_unknown_linux_gnu
  cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR

  --- stderr
  thread 'main' panicked at /host/cargo/registry/src/index.crates.io-6f17d22bba15001f/onig_sys-69.8.1/build.rs:253:17:
  Unable to find oniguruma in pkg-config, and RUSTONIG_SYSTEM_LIBONIG is set: `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS="1" PKG_CONFIG_ALLOW_SYSTEM_LIBS="1" "pkg-config" "--libs" "--cflags" "oniguruma" "oniguruma >= 6.9.3"` did not exit successfully: exit status: 1
  error: could not find system library 'oniguruma' required by the 'onig_sys' crate

  --- stderr
  Package oniguruma was not found in the pkg-config search path.
  Perhaps you should add the directory containing `oniguruma.pc'
  to the PKG_CONFIG_PATH environment variable
  No package 'oniguruma' found
  Package oniguruma was not found in the pkg-config search path.
  Perhaps you should add the directory containing `oniguruma.pc'
  to the PKG_CONFIG_PATH environment variable
  No package 'oniguruma' found

  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
=> ERROR: bat-0.24.0_1: do_build: '${make_cmd} build --release --locked --target ${RUST_TARGET} ${configure_args}' exited with 101
=> ERROR:   in do_build() at common/build-style/cargo.sh:8

It’s missing the oniguruma dependency. It’s a library, so it belongs to makedepends.

bat needs this library for compilation. It needs header files, pkg-config files and other stuff that isn’t normally included in a library and that is usually needed only for compilation (which we’re doing now). So we need oniguruma-devel.

Primarily -devel packages should appear in makedepends. This is an important rule of dependency hunting in xbps-src.

# Template file for 'bat'
pkgname=bat
version=0.24.0
revision=1
hostmakedepends=pkg-config
makedepends=oniguruma-devel
build_style=cargo
short_desc="Cat(1) clone with syntax highlighting and Git integration"
maintainer="meator <meator.dev@gmail.com>"
license="Apache-2.0, MIT"
homepage="https://github.com/sharkdp/bat"
changelog="https://raw.githubusercontent.com/sharkdp/bat/master/CHANGELOG.md"
distfiles="https://github.com/sharkdp/bat/archive/refs/tags/v${version}.tar.gz"
checksum=907554a9eff239f256ee8fe05a922aad84febe4fe10a499def72a4557e9eedfb

Note: Don’t forget to ./xbps-src clean the masterdir in between failed builds.

We have put oniguruma-devel to hostmakedepends, but the user also needs the library in the runtime, it must be in depends. But that is not necessary, because xbps-src is smart.

Shlib dependencies

This is described in Packaging oniguruma in detail.

To compile the bat package which depends on library oniguruma, bat must have oniguruma-devel in its hostmakedepends. But oniguruma must be installed alongside bat for bat to work because oniguruma provides shared libraries bat needs.

When a program is linked against a shared library, the program “remembers” which library it has been linked to. It marks the SONAME of the library in the executable. The details of this process are beyond the scope of this tutorial.

xbps-src reads the SONAMEs of the executables and libraries in $DESTDIR. It can detect runtime dependencies (like oniguruma) based on this information.

This means that you don’t usually have to specify libraries in depends. Only “external” runtime dependencies like some other programs are usually specified there.

Warning

Interpreted programming languages like Python cannot have shlib dependency detection due to the way they work. You have to specify all depends dependencies for them. This is further described later in packaging rofimoji.

Some progress

The template works. But it could be improved.

xlint returns this:

bat:6: Place makedepends= after build_style=
bat:10: license 'MIT', but no use of vlicense

The first warning is easy to fix, the second one requires some explanation:

Installing licenses

Some licenses (namely AGPL, MIT, BSD, ISC, X11, and custom licenses) require the license to be installed alongside the program to make users aware of it.

Licenses are installed in /usr/share/licenses. xbps-src includes a helper function called vlicense that installs the file it is supplied with to usr/share/licenses/<pkgname>. This is what the xlint warning is referring to. It is usually called in post_install()

# Template file for 'bat'
pkgname=bat
version=0.24.0
revision=1
build_style=cargo
hostmakedepends=pkg-config
makedepends=oniguruma-devel
short_desc="Cat(1) clone with syntax highlighting and Git integration"
maintainer="meator <meator.dev@gmail.com>"
license="Apache-2.0, MIT"
homepage="https://github.com/sharkdp/bat"
changelog="https://raw.githubusercontent.com/sharkdp/bat/master/CHANGELOG.md"
distfiles="https://github.com/sharkdp/bat/archive/refs/tags/v${version}.tar.gz"
checksum=907554a9eff239f256ee8fe05a922aad84febe4fe10a499def72a4557e9eedfb

post_install() {
	vlicense LICENSE-MIT
}

Installing supplementary files

Some projects include useful data files like man pages and shell completions. Their build system might not install them, they may have to be installed manually.

Since they are data files and they do not have to be compiled, installing them is very simple. They just have to be copied to $DESTDIR.

bat provides a manpage, but it is generated during the build process1. It gets put into

masterdir-x86_64/builddir/bat-0.24.0/target/x86_64-unknown-linux-gnu/release/build/bat-4df82ff77e13ab15/out/assets/manual/bat.1

on my computer which is impractical. The directory name is very long and it contains a UID (here 4df82ff77e13ab15).

If you inspect bat’s build system closely, you might stumble upon pull request #25152 and BAT_ASSETS_GEN_DIR detection code in bat's build system. This shows us that bat provides a way to override the directory by setting the BAT_ASSETS_GEN_DIR environmental variable.

But how would you set an environmental variable in a template? The template is “just a bash script”, so the correct way is to use export:

# Template file for 'bat'
pkgname=bat
version=0.24.0
revision=1
build_style=cargo
hostmakedepends=pkg-config
makedepends=oniguruma-devel
short_desc="Cat(1) clone with syntax highlighting and Git integration"
maintainer="meator <meator.dev@gmail.com>"
license="Apache-2.0, MIT"
homepage="https://github.com/sharkdp/bat"
changelog="https://raw.githubusercontent.com/sharkdp/bat/master/CHANGELOG.md"
distfiles="https://github.com/sharkdp/bat/archive/refs/tags/v${version}.tar.gz"
checksum=907554a9eff239f256ee8fe05a922aad84febe4fe10a499def72a4557e9eedfb

export BAT_ASSETS_GEN_DIR="${XBPS_BUILDDIR}/${pkgname}-${version}"

post_install() {
	vlicense LICENSE-MIT
}

This is a useful trick by the way.

BAT_ASSETS_GEN_DIR uses XBPS_BUILDDIR, pkgname and version variables. pkgname and version are defined in the template and XBPS_BUILDDIR is a useful variable (one of many) provided by xbps-src. See the Manual for more info.

The manpage will now be in assets/manual/bat.1 (relative to $wrksrc) which is much more practical. You can now install it like this:

# Template file for 'bat'
pkgname=bat
version=0.24.0
revision=1
build_style=cargo
hostmakedepends=pkg-config
makedepends=oniguruma-devel
short_desc="Cat(1) clone with syntax highlighting and Git integration"
maintainer="meator <meator.dev@gmail.com>"
license="Apache-2.0, MIT"
homepage="https://github.com/sharkdp/bat"
changelog="https://raw.githubusercontent.com/sharkdp/bat/master/CHANGELOG.md"
distfiles="https://github.com/sharkdp/bat/archive/refs/tags/v${version}.tar.gz"
checksum=907554a9eff239f256ee8fe05a922aad84febe4fe10a499def72a4557e9eedfb

export BAT_ASSETS_GEN_DIR="${XBPS_BUILDDIR}/${pkgname}-${version}"

post_install() {
	vlicense LICENSE-MIT
	mv assets/manual/bat.1 $DESTDIR/usr/share/man/man1
}

But installing manpages is a common operation, so xbps-src provides a helper for it. There are several helpers for installing things. They include vman, vdoc, vconf, vlicense (used above) and vcompletion. You can read more in the Manual.

Here’s the template with vman:

# Template file for 'bat'
pkgname=bat
version=0.24.0
revision=1
build_style=cargo
hostmakedepends=pkg-config
makedepends=oniguruma-devel
short_desc="Cat(1) clone with syntax highlighting and Git integration"
maintainer="meator <meator.dev@gmail.com>"
license="Apache-2.0, MIT"
homepage="https://github.com/sharkdp/bat"
changelog="https://raw.githubusercontent.com/sharkdp/bat/master/CHANGELOG.md"
distfiles="https://github.com/sharkdp/bat/archive/refs/tags/v${version}.tar.gz"
checksum=907554a9eff239f256ee8fe05a922aad84febe4fe10a499def72a4557e9eedfb

export BAT_ASSETS_GEN_DIR="${XBPS_BUILDDIR}/${pkgname}-${version}"

post_install() {
	vlicense LICENSE-MIT
	vman assets/manual/bat.1
}

bat also provides shell completions. They are generated too, but the path has been fixed already, so they’ll end up in assets/completions/bat.fish, assets/completions/bat.zsh and assets/completions/bat.bash. Now that you know that xbps-src has helpers for this, you don’t even have to know where these should be installed.

The vcompletion helper requires the type of completion script as the second argument. This is best presented in practice:

# Template file for 'bat'
pkgname=bat
version=0.24.0
revision=1
build_style=cargo
hostmakedepends=pkg-config
makedepends=oniguruma-devel
short_desc="Cat(1) clone with syntax highlighting and Git integration"
maintainer="meator <meator.dev@gmail.com>"
license="Apache-2.0, MIT"
homepage="https://github.com/sharkdp/bat"
changelog="https://raw.githubusercontent.com/sharkdp/bat/master/CHANGELOG.md"
distfiles="https://github.com/sharkdp/bat/archive/refs/tags/v${version}.tar.gz"
checksum=907554a9eff239f256ee8fe05a922aad84febe4fe10a499def72a4557e9eedfb

export BAT_ASSETS_GEN_DIR="${XBPS_BUILDDIR}/${pkgname}-${version}"

post_install() {
	vlicense LICENSE-MIT
	vman assets/manual/bat.1
	vcompletion assets/completions/bat.fish fish
	vcompletion assets/completions/bat.zsh zsh
	vcompletion assets/completions/bat.bash bash
}

Comparing with the upstream template

This is our template:

# Template file for 'bat'
pkgname=bat
version=0.24.0
revision=1
build_style=cargo
hostmakedepends=pkg-config
makedepends=oniguruma-devel
short_desc="Cat(1) clone with syntax highlighting and Git integration"
maintainer="meator <meator.dev@gmail.com>"
license="Apache-2.0, MIT"
homepage="https://github.com/sharkdp/bat"
changelog="https://raw.githubusercontent.com/sharkdp/bat/master/CHANGELOG.md"
distfiles="https://github.com/sharkdp/bat/archive/refs/tags/v${version}.tar.gz"
checksum=907554a9eff239f256ee8fe05a922aad84febe4fe10a499def72a4557e9eedfb

export BAT_ASSETS_GEN_DIR="${XBPS_BUILDDIR}/${pkgname}-${version}"

post_install() {
	vlicense LICENSE-MIT
	vman assets/manual/bat.1
	vcompletion assets/completions/bat.fish fish
	vcompletion assets/completions/bat.zsh zsh
	vcompletion assets/completions/bat.bash bash
}

This is the upstream template (at the time of writing this article):

# Template file for 'bat'
pkgname=bat
version=0.24.0
revision=1
build_style=cargo
hostmakedepends="pkg-config"
makedepends="libgit2-devel oniguruma-devel"
short_desc="Cat(1) clone with syntax highlighting and Git integration"
maintainer="John <me@johnnynator.dev>"
license="Apache-2.0, MIT"
homepage="https://github.com/sharkdp/bat"
changelog="https://raw.githubusercontent.com/sharkdp/bat/master/CHANGELOG.md"
distfiles="https://github.com/sharkdp/bat/archive/refs/tags/v${version}.tar.gz"
checksum=907554a9eff239f256ee8fe05a922aad84febe4fe10a499def72a4557e9eedfb

export BAT_ASSETS_GEN_DIR="${XBPS_BUILDDIR}/${pkgname}-${version}"

post_patch() {
	cargo update --package git2@0.18.0 --precise 0.17.2
}

post_install() {
	vlicense LICENSE-MIT
	vdoc README.md
	vman assets/manual/bat.1
	vcompletion assets/completions/bat.fish fish
	vcompletion assets/completions/bat.zsh zsh
	vcompletion assets/completions/bat.bash bash
}

with the following patch:

diff --git a/Cargo.toml b/Cargo.toml
index e31fbc3..cc4cdf9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -69,7 +69,7 @@ os_str_bytes = { version = "~6.4", optional = true }
 run_script = { version = "^0.10.0", optional = true}
 
 [dependencies.git2]
-version = "0.18"
+version = "0.17"
 optional = true
 default-features = false
 

The templates are similar, which is good. The official one tries to override a libgit2 dependency with the packaged libgit2-devel. Our template just pulls this dependency with the rest.

It also includes a patch to make the XBPS version of libgit2 work in bat.

What now?

You might be wondering how the SHLIB detection works. This is best explained while packaging a library. The next part of this tutorial packages oniguruma, a dependency of bat:

Packaging oniguruma


1

This is a bat-specific thing. Other projects might have their data files in the repository without the need for generation. The packaging process is the same, you just vman or vcompletion the files.

2

This pull request was made by tranzystorekk, a Void Linux contributor at the time of writing this tutorial. It’s nice to see a fellow Voider improving the projects they’re packaging. You should take inspiration from this if you have the know-how (and if upstream needs fixing).