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

Note

Don’t forget to run ./xbps-src clean in between failed builds. While it may not be necessary in this case, skipping it can cause issues in other scenarios, especially when editing the template.

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

We have resolved the oniguruma error, but when we try to build our new template, this happens:

=> 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.81.0_1: found (https://repo-default.voidlinux.org/current)
   [host] cargo-auditable-0.6.4_1: found (https://repo-default.voidlinux.org/current)
   [target] oniguruma-devel-6.9.9_1: found (/host/binpkgs)
=> bat-0.24.0_1: installing host dependencies: pkg-config-0.29.2_3 cargo-1.81.0_1 cargo-auditable-0.6.4_1 ...
=> bat-0.24.0_1: installing target dependencies: oniguruma-devel-6.9.9_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 cfg-if v1.0.0
   Compiling serde v1.0.163
   Compiling jobserver v0.1.25
   Compiling utf8parse v0.2.1
   Compiling linux-raw-sys v0.4.5
   Compiling cc v1.0.73
   Compiling bitflags v2.4.0
   Compiling anstyle-parse v0.2.0
   Compiling tinyvec_macros v0.1.0
   Compiling anstyle v1.0.0
   Compiling itoa v1.0.3
   Compiling autocfg v1.1.0
   Compiling libz-sys v1.1.8
   Compiling colorchoice v1.0.0
   Compiling syn v1.0.104
   Compiling proc-macro-hack v0.5.19
   Compiling anstyle-query v1.0.0
   Compiling log v0.4.17
   Compiling anstream v0.6.4
   Compiling indexmap v1.9.1
   Compiling onig_sys v69.8.1
   Compiling sys-info v0.9.1
   Compiling tinyvec v1.6.0
   Compiling strsim v0.10.0
   Compiling terminal_size v0.3.0
   Compiling crc32fast v1.3.2
   Compiling clap_lex v0.5.0
   Compiling clap_builder v4.4.6
   Compiling unicode-normalization v0.1.22
   Compiling serde_derive v1.0.163
   Compiling libgit2-sys v0.16.1+1.7.1
   Compiling aho-corasick v1.0.1
   Compiling regex-syntax v0.7.2
   Compiling unicode-bidi v0.3.8
   Compiling safemem v0.3.3
   Compiling thiserror v1.0.40
   Compiling num_threads v0.1.6
   Compiling fnv v1.0.7
   Compiling adler v1.0.2
   Compiling hashbrown v0.12.3
   Compiling ryu v1.0.11
   Compiling percent-encoding v2.2.0
   Compiling regex-automata v0.3.7
   Compiling serde_json v1.0.85
   Compiling same-file v1.0.6
   Compiling lazy_static v1.4.0
   Compiling bstr v1.6.0
   Compiling form_urlencoded v1.1.0
   Compiling regex v1.8.3
   Compiling miniz_oxide v0.7.1
   Compiling time v0.3.14
   Compiling line-wrap v0.1.1
   Compiling idna v0.3.0
   Compiling git-version-macro v0.3.5
   Compiling clap v4.4.6
   Compiling thiserror-impl v1.0.40
   Compiling quick-xml v0.28.1
   Compiling aho-corasick v0.7.19
   Compiling hashbrown v0.14.1
   Compiling bytemuck v1.12.1
   Compiling base64 v0.21.0
   Compiling equivalent v1.0.1
   Compiling semver v1.0.17
   Compiling once_cell v1.18.0
   Compiling linked-hash-map v0.5.6
   Compiling bugreport v0.5.0
   Compiling bitflags v1.3.2
   Compiling onig v6.4.0
   Compiling yaml-rust v0.4.5
   Compiling plist v1.4.3
   Compiling indexmap v2.0.2
   Compiling rgb v0.8.34
   Compiling globset v0.4.10
   Compiling flate2 v1.0.27
   Compiling bat v0.24.0 (/builddir/bat-0.24.0)
   Compiling git-version v0.3.5
   Compiling url v2.3.1
   Compiling bincode v1.3.3
   Compiling walkdir v2.3.3
   Compiling unsafe-libyaml v0.2.9
   Compiling unicode-width v0.1.10
   Compiling termcolor v1.1.3
   Compiling std_prelude v0.2.12
   Compiling regex-syntax v0.6.27
   Compiling shell-escape v0.1.5
   Compiling home v0.5.5
   Compiling etcetera v0.8.0
   Compiling serde_yaml v0.9.25
   Compiling grep-cli v0.1.9
   Compiling syntect v5.0.0
   Compiling path_abs v0.5.1
   Compiling console v0.15.5
   Compiling ansi_colours v1.2.1
   Compiling clircle v0.4.0
   Compiling encoding_rs v0.8.33
   Compiling content_inspector v0.2.4
   Compiling bytesize v1.3.0
   Compiling nu-ansi-term v0.49.0
   Compiling wild v2.1.0
   Compiling shell-words v1.1.0
The following warnings were emitted during compilation:

warning: libgit2-sys@0.16.1+1.7.1: failed to probe system libgit2: `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS="1" PKG_CONFIG_ALLOW_SYSTEM_LIBS="1" "pkg-config" "--libs" "--cflags" "libgit2" "libgit2 >= 1.7.1" "libgit2 < 1.8.0"` did not exit successfully: exit status: 1

error: failed to run custom build command for `libgit2-sys v0.16.1+1.7.1`

Caused by:
  process didn't exit successfully: `/builddir/bat-0.24.0/target/release/build/libgit2-sys-d54ac9ce2edbdeb8/build-script-build` (exit status: 101)
  --- stdout
  cargo:rerun-if-env-changed=LIBGIT2_NO_VENDOR
  cargo:rerun-if-env-changed=LIBGIT2_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=LIBGIT2_STATIC
  cargo:rerun-if-env-changed=LIBGIT2_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
  cargo:warning=failed to probe system libgit2: `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS="1" PKG_CONFIG_ALLOW_SYSTEM_LIBS="1" "pkg-config" "--libs" "--cflags" "libgit2" "libgit2 >= 1.7.1" "libgit2 < 1.8.0"` did not exit successfully: exit status: 1
  error: could not find system library 'libgit2' required by the 'libgit2-sys' crate

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


  --- stderr
  thread 'main' panicked at /host/cargo/registry/src/index.crates.io-6f17d22bba15001f/libgit2-sys-0.16.1+1.7.1/build.rs:39:13:
  The environment variable `LIBGIT2_NO_VENDOR` has been set but no compatible system libgit2 could be found.
  The build is now aborting. To disable, unset the variable or use `LIBGIT2_NO_VENDOR=0`.

  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} ${make_build_args}' exited with 101
=> ERROR:   in do_build() at common/build-style/cargo.sh:8

Like oniguruma, we’ll need to add libgit2-devel to makedepends:

# Template file for 'bat'
pkgname=bat
version=0.24.0
revision=1
hostmakedepends="pkg-config"
makedepends="oniguruma-devel libgit2-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

We have put both -devel libraries into makedepends, but the user also needs the (shared) libraries in the runtime, their non--devel versions 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. The same holds true for libgit2.

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 and libgit2) 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 ${DESTDIR}/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 libgit2-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 libgit2-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 libgit2-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 libgit2-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 libgit2-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
}

And that’s it!

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 libgit2-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=2
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_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
}

The templates are almost identical, which is good.

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).