Developer Guide
This guide is intended for developers who want to contribute to the cbp project or understand its
internal workings.
- Developer Guide
Development Environment
Requirements
- Zig compiler (>= 0.13.0)
- Rust toolchain (stable)
- Git (with LFS support)
ghcommand (GitHub CLI)- Python 3 (>= 3.7) and uv
- Build tools
- cmake
- ninja
- jq
- meson
Setup Build Environment
- Zig
# Download and install Zig
mkdir -p $HOME/share
cd $HOME/share
# linux and macOS
# zvm
curl https://raw.githubusercontent.com/tristanisham/zvm/master/install.sh | bash
source $HOME/.bashrc
# need 0.14 for pthread on x86_64-windows-gnu
# https://github.com/ziglang/zig/issues/10989
zvm install 0.14.1
zvm install 0.13.0
zvm use 0.13.0
# # zigup
# curl -L https://github.com/marler8997/zigup/releases/download/v2025_01_02/zigup-x86_64-linux.tar.gz |
# tar xz &&
# mv zigup ~/bin/
# zigup fetch 0.14.0
# Verify Zig target
zig targets | jq .libc
# We use the following targets:
# x86_64-linux-gnu.2.17
# aarch64-macos-none
# x86_64-windows-gnu
- Rust
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
if grep -q -i RUST_PATH $HOME/.bashrc; then
echo "==> .bashrc already contains RUST_PATH"
else
echo "==> Updating .bashrc with RUST_PATH..."
RUST_PATH="export PATH=\"\$HOME/.cargo/bin:\$PATH\""
echo '# RUST_PATH' >> $HOME/.bashrc
echo $RUST_PATH >> $HOME/.bashrc
echo >> $HOME/.bashrc
fi
source $HOME/.bashrc
# Install cargo-zigbuild
cargo install --locked cargo-zigbuild
rustup target list
rustup target add x86_64-unknown-linux-gnu
rustup target add x86_64-unknown-linux-musl
rustup target add aarch64-apple-darwin
rustup target add x86_64-pc-windows-gnu
- vcpkg
mkdir -p $HOME/share
cd $HOME/share
# Download and extract vcpkg
curl -L https://github.com/microsoft/vcpkg/archive/refs/tags/2025.10.17.tar.gz |
tar xvz &&
mv vcpkg-* vcpkg
cd vcpkg
./bootstrap-vcpkg.sh -disableMetrics
# Set environment variables
if grep -q -i VCPKG_PATH $HOME/.bashrc; then
echo "==> .bashrc already contains VCPKG_PATH"
else
echo "==> Updating .bashrc with VCPKG_PATH..."
VCPKG_ROOT=
VCPKG_PATH=
echo '# VCPKG_PATH' >> $HOME/.bashrc
echo "export VCPKG_ROOT=\"\$HOME/share/vcpkg\"" >> $HOME/.bashrc
echo "export PATH=\"\$VCPKG_ROOT:\$PATH\"" >> $HOME/.bashrc
echo >> $HOME/.bashrc
fi
source $HOME/.bashrc
# List all available features for a package
vcpkg search bzip2
# Switch to the cbp building dir
# To install a vcpkg package
vcpkg install --debug --recurse \
--clean-buildtrees-after-build --clean-packages-after-build \
--overlay-ports=ports \
--overlay-triplets="$(cbp prefix triplets)" \
--x-buildtrees-root=vcpkg/buildtrees \
--downloads-root=vcpkg/downloads \
--x-install-root=vcpkg/installed \
--x-packages-root=vcpkg/packages \
zlib:x64-linux-zig
# To remove a vcpkg package
vcpkg remove --debug --recurse \
--overlay-ports=ports \
--overlay-triplets="$(cbp prefix triplets)" \
--x-buildtrees-root=vcpkg/buildtrees \
--downloads-root=vcpkg/downloads \
--x-install-root=vcpkg/installed \
--x-packages-root=vcpkg/packages \
zlib:x64-linux-zig
# Install zlib with custom target
# vcpkg install zlib:x64-linux-zig \
# --cmake-args="-DCMAKE_C_COMPILER_TARGET=aarch64-macos-none" \
# --cmake-args="-DCMAKE_CXX_COMPILER_TARGET=aarch64-macos-none"
- llvm
cd ~/share
# Download and install llvm
curl -o llvm.tar.xz -L https://github.com/llvm/llvm-project/releases/download/llvmorg-18.1.8/clang+llvm-18.1.8-arm64-apple-macos11.tar.xz
tar xvf llvm.tar.xz
mv clang+llvm-* llvm
# Remove quarantine attribute if exists (ignore errors)
for d in bin lib libexec; do
for f in llvm/${d}/*; do
xattr -d com.apple.quarantine "$f" 2>/dev/null || true
done
done
llvm/bin/lld --version
Other tools
cbp install cmake
cbp install ninja
cbp install uv
cbp install jq
cbp install python3.11
uv pip install --system meson
git lfs and gh
# linux
sudo apt install git-lfs
sudo apt install gh
# macos
brew install git-lfs
git lfs install
git lfs track "sources/*.tar.gz"
cbp itself
cargo install --path . --force # --offline
cargo test -- --test-threads=1
# build under WSL 2
mkdir -p /tmp/cargo
export CARGO_TARGET_DIR=/tmp/cargo
cargo build
cargo run --release --bin cbp init --dev
git log v0.3.13..HEAD > gitlog.txt
git diff v0.3.13 HEAD > gitdiff.txt
Project Structure
cbp/
|-- binaries/ # Build artifacts
|-- docs/ # Documentation
|-- scripts/ # Build scripts
| |-- common.sh # Shared build functions
| |-- tools/ # Helper scripts
| |-- *.sh # Package-specific build scripts
|-- sources/ # Source packages
|-- src/ # Rust source code
|-- tests/ # Rust test code
Build Process
Building Binary Packages
Binary packages are built using shell scripts in the scripts/ directory. Each package has its own
build script that sources common.sh for shared functionality.
Example build process:
- Source code is downloaded to
sources/ - Build script extracts and compiles the source
- Binaries are collected and packaged
- Resulting tarball is placed in
binaries/
Dynamic Library Dependencies
The binaries in this project have minimal dynamic library dependencies:
-
Core System Libraries
- linux-vdso.so.1 - Virtual dynamic shared object
- libc.so.6 - GNU C Library (glibc)
- libpthread.so.0 - POSIX threads library
- libdl.so.2 - Dynamic linking library
- /lib64/ld-linux-x86-64.so.2 - Dynamic linker/loader
-
C/C++ Runtime Libraries
- libstdc++.so.6 - GNU Standard C++ Library
- libm.so.6 - Math library
- libgcc_s.so.1 - GCC support library
Example of checking dependencies:
$ ldd ~/.cbp/bin/trimal
linux-vdso.so.1 (0x00007ffff4599000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f796772c000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f7967643000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f7967615000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7967403000)
/lib64/ld-linux-x86-64.so.2 (0x00007f79679b6000)
$ bash scripts/tools/deps.sh trimal
==> Dependencies for package trimal:
File: bin/readal
No additional dependencies
File: bin/statal
No additional dependencies
File: bin/trimal
No additional dependencies
$ bash scripts/tools/deps.sh muscle
==> Dependencies for package muscle:
File: bin/muscle
Static executable
$ bash scripts/tools/deps.sh bwa
==> Dependencies for package bwa:
File: bin/bwa
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007de17629d000)
Uploading Binaries
Binary packages are uploaded to a special “Binaries” release on GitHub, which is independent of
cbp’s version releases.
Create the Binaries release on GitHub if it doesn’t exist
gh release view Binaries
gh release create Binaries \
--title "Binary Packages" \
--notes "This release contains pre-built binary packages for various platforms." \
--prerelease
Upload Process
-
Build the binary package using the build script
bash scripts/zlib.sh linux -
The resulting tarball will be placed in
binaries/ls -l binaries/zlib.*.tar.gz -
GitHub CLI should be installed and authenticated by the repository owner
gh auth login # Verify authentication status gh auth status -
Upload to GitHub Release
# Upload with cbp command (recommended), which: # 1. Calculate MD5 hash for each file # 2. Upload files to GitHub Release # 3. Update release notes with new hashes cbp build upload binaries/zlib.*.tar.gz # Or upload manually with gh command # Note: This method does not update MD5 hashes gh release upload Binaries binaries/zlib.*.tar.gz --clobber
Download URLs
The binary packages will be available at fixed URLs:
https://github.com/wang-q/cbp/releases/download/Binaries/zlib.linux.tar.gz
https://github.com/wang-q/cbp/releases/download/Binaries/zlib.macos.tar.gz
Packages
cargo run --bin cbp build test --dir ~/.cbp arial
Contributing
Development Workflow
- Fork the repository
- Create a feature branch
- Make changes following the style guide
- Run tests and ensure they pass
- Submit a pull request
Adding a New Package
- Add source tarball to
sources/ - Create build script in
scripts/ - Test build on both Linux and macOS
- Add tests if applicable
- Update documentation
- Submit a pull request
Example build script templates:
- Build from source:
#!/bin/bash
# Source common build environment
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
# Extract source code
extract_source
# Build with the specified target architecture
make \
CC="zig cc -target ${TARGET_ARCH}" \
|| exit 1
# Collect binaries and create tarball
FN_TAR="${PROJ}.${OS_TYPE}.tar.gz"
cbp collect --mode bin -o "${FN_TAR}" program