zopen — Build and Packaging Guide
This document covers every way to build, install, and package zopen,
from a quick developer pip install through to a signed Debian source package.
Table of contents
- Repository layout
- Prerequisites
- Python packaging (pip / wheel)
- CMake build system
- 4.1 Concepts
- 4.2 Configure step
- 4.3 CMake options reference
- 4.4 CMake install-directory variables
- 4.5 Build step
- 4.6 Install step
- 4.7 Installed file layout
- 4.8 CMake targets reference
- CPack packaging
- Debian native packaging (
dpkg-buildpackage)- 6.1 How it works
- 6.2 Build the package
- 6.3 Inspect the package
- 6.4 Install and remove
- 6.5
debian/directory reference - 6.6 Maintainer scripts
- 6.7 Conffile handling
- 6.8 Building a source package
- Choosing a packaging method
- Versioning and release checklist
1. Repository layout
zopen/
├── zopen.py # Application source (single Python module)
├── pyproject.toml # Python packaging metadata (PEP 517/518/621)
├── CMakeLists.txt # Top-level CMake configuration
├── cmake/
│ └── packaging.cmake # CPack configuration (included by CMakeLists.txt)
├── config/
│ └── default.toml # System-wide config installed to /opt/etc/zopen/
├── debian/
│ ├── changelog # dpkg version history (required)
│ ├── control # Package metadata and dependencies
│ ├── copyright # Machine-readable licence statement
│ ├── rules # Build recipe (Makefile driven by dh)
│ ├── source/
│ │ └── format # Source package format declaration
│ ├── zopen.docs # List of documentation files for dh_installdocs
│ ├── postinst # Post-install maintainer script
│ └── postrm # Post-remove maintainer script
├── docs/
│ ├── user-guide.md
│ ├── design.md
│ └── build.md # This file
└── README.md
2. Prerequisites
All build paths
| Tool | Minimum version | Purpose |
|---|---|---|
| Python | 3.10+ | tomllib stdlib (3.11+); running the app |
| uv (recommended) or pip | 0.1.0+ or 22.0 | Python package installation |
Recommended: Install uv for faster, more reliable package management. It automatically handles virtual environments and has zero external dependencies.
Python wheel builds
| Tool | Install | Purpose |
|---|---|---|
python-build |
uv pip install build or apt install python3-build |
python -m build |
setuptools |
uv pip install setuptools>=68 or apt install python3-setuptools |
Build backend |
Recommended workflow with uv:
# Fast setup with uv (auto-creates venv, installs build tools)
uv venv --python 3.10
source .venv/bin/activate # or use 'uv run python ...'
uv pip install build setuptools
CMake builds
| Tool | Minimum version | Install |
|---|---|---|
| CMake | 3.20 | apt install cmake / download from cmake.org |
| Make or Ninja | any | apt install make / apt install ninja-build |
python-build |
— | Required when ZOPEN_BUILD_WHEEL=ON (default) |
Debian native packaging
| Tool | Install | Purpose |
|---|---|---|
debhelper |
apt install debhelper (≥ 13) |
dh helper framework |
dh-python |
apt install dh-python |
Python integration for dh |
python3-all |
apt install python3-all |
All installed Python 3 interpreters |
python3-setuptools |
apt install python3-setuptools |
Build backend |
fakeroot |
apt install fakeroot |
Build as non-root |
dpkg-dev |
included in dpkg |
dpkg-buildpackage, dpkg-deb |
Install everything at once on Debian/Ubuntu:
sudo apt-get install cmake debhelper dh-python python3-all \
python3-setuptools python3-build fakeroot
Optional runtime dependency (all methods)
# Recommended: using uv
uv pip install python-magic
# Or with standard pip
pip install python-magic
# Or with apt
sudo apt-get install python3-magic
3. Python packaging (uv pip / wheel)
3.1 Building a wheel
A wheel is a pre-built distribution archive (.whl). It contains the Python
module and entry-point metadata, ready for pip to install.
Using uv (recommended):
# Setup: create virtual environment and install build tools
uv venv --python 3.10
source .venv/bin/activate
uv pip install build
# Build a wheel (output goes to dist/)
python -m build --wheel
# Build both a wheel and a source distribution
python -m build
Using standard pip:
# Install the build frontend
pip install build
# Build a wheel (output goes to dist/)
python -m build --wheel
# Build both a wheel and a source distribution
python -m build
Output files:
dist/
├── zopen-0.6.5-py3-none-any.whl # wheel
└── zopen-0.6.5.tar.gz # source distribution
The wheel filename encodes:
zopen— package name0.6.5— versionpy3— Python 3 compatiblenone— not ABI-specific (pure Python)any— not platform-specific
3.2 Installing with uv pip (recommended)
uv pip provides fast, reliable package management with automatic virtual environment support.
# Install from the wheel file
uv pip install dist/zopen-0.6.5-py3-none-any.whl
# Install with the optional libmagic binding
uv pip install "dist/zopen-0.6.5-py3-none-any.whl[magic]"
# Install directly from source (builds wheel on the fly)
uv pip install .
uv pip install ".[magic]"
# Install for the current user only (no root needed)
uv pip install --user .
# Create and use a virtual environment with automatic activation
uv venv .venv
source .venv/bin/activate
uv pip install .
# Or use uv run to execute in venv without explicit activation
uv run python zopen.py --help
3.3 Installing with standard pip
If you prefer standard pip instead of uv:
# Install from the wheel file
pip install dist/zopen-0.6.5-py3-none-any.whl
# Install with the optional libmagic binding
pip install "dist/zopen-0.6.5-py3-none-any.whl[magic]"
# Install directly from source (builds wheel on the fly)
pip install .
pip install ".[magic]"
# Install for the current user only (no root needed)
pip install --user .
# Install into a virtual environment
python -m venv .venv
source .venv/bin/activate
pip install .
After installation, the zopen command is available in the active
environment’s bin/ directory.
3.4 Editable / developer install
An editable install creates a link back to the source file so changes take effect immediately without reinstalling:
Using uv (recommended):
uv pip install -e .
Using standard pip:
pip install -e .
3.5 pyproject.toml reference
[build-system]
requires = ["setuptools>=68"] # minimum version for pyproject.toml support
build-backend = "setuptools.build_meta"
[project]
name = "zopen"
version = "0.6.5"
description = "Smart file editor launcher …"
readme = "README.md" # shown on PyPI
requires-python = ">=3.10" # tomllib requires 3.11
license = "MIT" # SPDX expression
keywords = ["editor", "mime", "launcher", "cli"]
dependencies = [] # no mandatory runtime deps
[project.optional-dependencies]
magic = ["python-magic"] # install with uv pip install ".[magic]"
dev = ["pytest>=9.0", "coverage>=7.0"] # dev dependencies
[project.scripts]
zopen = "zopen:main" # creates bin/zopen → calls zopen.main()
[tool.setuptools]
py-modules = ["zopen"] # only package the zopen.py module
Key points:
py-modules = ["zopen"]tells setuptools to install onlyzopen.py, not any other.pyfiles it might find in the directory.[project.scripts]defines the console entry point. pip generates a thin wrapper script at install time that callszopen.main().dependencies = []— there are no mandatory runtime dependencies.python-magicis listed under[project.optional-dependencies].
4. CMake build system
4.1 Concepts
CMake manages the build in three separate phases:
| Phase | Command | What happens |
|---|---|---|
| Configure | cmake -S . -B build |
Detects Python, evaluates options, writes Makefiles |
| Build | cmake --build build |
Runs the wheel custom target |
| Install | cmake --install build |
Copies files to the prefix |
CMake also drives CPack (§5) and is used internally by dpkg-buildpackage
via the pybuild build system (§6).
4.2 Configure step
# Minimal — installs to /usr/local by default
cmake -S . -B build
# System install (Debian convention: binary under /usr, config under /etc)
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr
# Custom prefix (e.g. /opt/zopen)
cmake -S . -B build \
-DCMAKE_INSTALL_PREFIX=/opt/zopen \
-DZEDIT_SYSCONFDIR=/opt/zopen/etc
# Skip building the wheel (faster if you only need cmake --install)
cmake -S . -B build -DEDIT_BUILD_WHEEL=OFF
# Use pip instead of direct file copy for the install step
cmake -S . -B build -DEDIT_INSTALL_VIA_PIP=ON
# Use Ninja instead of Make
cmake -S . -B build -G Ninja
4.3 CMake options reference
All options are set with -D<OPTION>=<VALUE> on the configure command line.
| Option | Type | Default | Description |
|---|---|---|---|
CMAKE_INSTALL_PREFIX |
PATH | /usr/local |
Root of the installation tree. Use /usr for system packages. |
EDIT_BUILD_WHEEL |
BOOL | ON |
Build a Python wheel as part of the all target. Requires python -m build. |
EDIT_INSTALL_VIA_PIP |
BOOL | OFF |
Install via pip install --prefix instead of copying the script directly. Creates .dist-info metadata. |
ZOPEN_SYSCONFDIR |
PATH | /etc when prefix is /usr; ${prefix}/etc otherwise |
Directory that receives zopen/config.toml. Override to place the config outside the prefix. |
CMAKE_INSTALL_LIBDIR |
STRING | lib |
Set automatically to the multiarch path by dh. Pre-set here to suppress a GNUInstallDirs warning on LANGUAGES NONE projects. |
4.4 CMake install-directory variables
These variables are set by include(GNUInstallDirs) and control where each
component is installed. They are relative to CMAKE_INSTALL_PREFIX unless
they start with /.
| Variable | Resolved path (prefix /usr) |
Description |
|---|---|---|
CMAKE_INSTALL_BINDIR |
/usr/bin |
Executables |
CMAKE_INSTALL_SYSCONFDIR |
/etc (set by GNUInstallDirs when prefix = /usr) |
System config; overridden by ZOPEN_SYSCONFDIR |
CMAKE_INSTALL_DOCDIR |
/usr/share/doc/zopen |
Package documentation |
CMAKE_INSTALL_DATADIR |
/usr/share |
Read-only architecture-independent data |
4.5 Build step
cmake --build build # build all targets (wheel by default)
cmake --build build --target wheel # build only the wheel
cmake --build build --target deb # build wheel then generate .deb
cmake --build build --target tarball # build wheel then generate .tar.gz
cmake --build build --target clean # remove files produced by build targets
cmake --build build --target distclean # remove build dir + Python caches/archives
cmake --build build -j4 # parallel build (4 jobs)
cmake --build build --verbose # print full commands
The wheel target runs:
python3 -m build --wheel --no-isolation --outdir <build-dir>/dist
It is driven by a add_custom_command with these declared dependencies:
zopen.pypyproject.toml
CMake only rebuilds the wheel when one of these files changes (checked by timestamp).
4.6 Install step
# Install to the configured prefix
cmake --install build
# Install to a different prefix (overrides configure-time default)
cmake --install build --prefix /usr/local
# Staged install (useful for packaging — files go under DESTDIR)
DESTDIR=/tmp/staging cmake --install build --prefix /usr
# Install only specific components
cmake --install build --component Runtime
cmake --install build --component Config
cmake --install build --component Doc
DESTDIR behaviour: the install destination is
${DESTDIR}${CMAKE_INSTALL_PREFIX}/<relative-path>. For example, with
DESTDIR=/tmp/staging and prefix /usr, the binary lands at
/tmp/staging/opt/zopen/bin/zopen. The ZOPEN_SYSCONFDIR path (e.g. /etc) is
always absolute, so config ends up at /tmp/staging/opt/etc/zopen/config.toml.
4.7 Installed file layout
With CMAKE_INSTALL_PREFIX=/usr:
/opt/zopen/bin/zopen ← zopen.py (renamed, chmod +x)
/opt/etc/zopen/config.toml ← config/default.toml (renamed)
/opt/zopen/share/doc/zopen/README.md ← README.md
With CMAKE_INSTALL_PREFIX=/usr/local:
/usr/local/bin/zopen
/usr/local/opt/etc/zopen/config.toml
/opt/zopen/share/doc/zopen/README.md
4.8 CMake targets reference
| Target | Type | Description |
|---|---|---|
wheel |
Custom (ALL) | Build Python wheel via python -m build. |
deb |
Custom | Run CPack with the DEB generator. |
tarball |
Custom | Run CPack with the TGZ generator. |
package |
CPack built-in | Run CPack with all configured generators (DEB + TGZ). |
install |
CMake built-in | Install all components to the prefix. |
clean |
CMake built-in | Remove files produced by build targets (wheel, packages, etc.). |
distclean |
Custom | Remove the build directory and source-tree artifacts (__pycache__, *.egg-info, loose zopen-*.tar.gz/.deb archives). Restores the source tree to a fresh-clone state. See cmake/distclean.cmake. |
5. CPack packaging
CPack is CMake’s packaging tool. It uses the same install() rules to
determine the package contents, then wraps them with the generator’s
metadata format.
Configuration lives in cmake/packaging.cmake, which is include()d at the
end of CMakeLists.txt.
5.1 Generating a .deb with CPack
# Configure with /usr prefix (required for correct /etc placement)
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr
# Build the wheel first (default), then generate the .deb
cmake --build build --target deb
# Or invoke cpack directly from the build directory
cd build
cpack -G DEB
# Specify a custom output directory
cpack -G DEB --config CPackConfig.cmake -B /tmp/packages
Output: build/zopen-0.5.0-Linux.deb
The CPack DEB generator creates the package by:
- Running
cmake --installinto a staging directory. - Adding the
DEBIAN/controlfile from the CPack variables. - Adding
DEBIAN/postinstandDEBIAN/postrmfromCPACK_DEBIAN_PACKAGE_CONTROL_EXTRA. - Running
dpkg-deb --build.
The resulting package differs from the dpkg-buildpackage package (§6)
in a few ways:
| Feature | CPack DEB | dpkg-buildpackage |
|---|---|---|
Python .dist-info metadata |
No | Yes (via pybuild) |
Automatic python3:any dependency |
No | Yes (via dh_python3) |
changelog.Debian.gz in doc dir |
No | Yes |
conffiles registration |
No (not automatic) | Yes (automatic for /etc/) |
| Suitable for Debian upload | No | Yes |
Use CPack DEB for quick self-contained packages. Use dpkg-buildpackage for
packages intended for Debian/Ubuntu repositories.
5.2 Generating a .tar.gz with CPack
cmake --build build --target tarball
# or
cd build && cpack -G TGZ
Output: build/zopen-0.5.0-Linux.tar.gz
The tarball contains a pre-staged tree rooted at . mirroring what
cmake --install would place at the prefix. Unpack with:
tar -xzf zopen-0.5.0-Linux.tar.gz -C /usr/local --strip-components=1
5.3 Generating an .rpm with CPack
RPM generation is configured in cmake/packaging.cmake but requires
rpmbuild to be installed:
sudo apt-get install rpm # Debian/Ubuntu
# or
sudo dnf install rpm-build # Fedora/RHEL
cd build && cpack -G RPM
Output: build/zopen-0.5.0-Linux.rpm
5.4 CPack variables reference
All variables are set in cmake/packaging.cmake.
Common variables
| Variable | Value | Description |
|---|---|---|
CPACK_PACKAGE_NAME |
zopen |
Package name |
CPACK_PACKAGE_VERSION |
0.5.0 |
Taken from project(VERSION ...) |
CPACK_PACKAGE_CONTACT |
Maintainer <...> |
Maintainer string |
CPACK_PACKAGE_VENDOR |
Example Project |
Vendor name |
CPACK_PACKAGING_INSTALL_PREFIX |
/usr |
Prefix used inside the package |
CPACK_GENERATOR |
DEB;TGZ |
Default generators |
CPACK_COMPONENTS_ALL |
Runtime Config Doc |
Components included in packages |
DEB-specific variables
| Variable | Value | Description |
|---|---|---|
CPACK_DEBIAN_PACKAGE_ARCHITECTURE |
all |
all = architecture-independent |
CPACK_DEBIAN_PACKAGE_DEPENDS |
python3 (>= 3.11) |
Mandatory runtime deps |
CPACK_DEBIAN_PACKAGE_RECOMMENDS |
python3-magic |
Strongly recommended |
CPACK_DEBIAN_PACKAGE_SUGGESTS |
vim \| nano \| … |
Optional suggestions |
CPACK_DEBIAN_PACKAGE_SECTION |
utils |
Debian archive section |
CPACK_DEBIAN_PACKAGE_SHLIBDEPS |
OFF |
Disable shared-library scanner |
CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA |
debian/postinst debian/postrm |
Extra maintainer scripts |
RPM-specific variables
| Variable | Value | Description |
|---|---|---|
CPACK_RPM_PACKAGE_ARCHITECTURE |
noarch |
Architecture-independent |
CPACK_RPM_PACKAGE_LICENSE |
MIT |
SPDX licence identifier |
CPACK_RPM_PACKAGE_REQUIRES |
python3 >= 3.11 |
Mandatory runtime deps |
CPACK_RPM_PACKAGE_GROUP |
Applications/Editors |
RPM group classification |
6. Debian native packaging (dpkg-buildpackage)
This is the correct method for producing packages intended for a Debian or
Ubuntu repository. It produces a proper .deb with full Python integration
(entry-point scripts, .dist-info, python3:any dependency).
6.1 How it works
dpkg-buildpackage reads debian/rules and calls dh (debhelper). The
dh command sequences through a series of helper commands:
dh_auto_configure → cmake (via pybuild --buildsystem=cmake)
dh_auto_build → cmake --build (builds the wheel)
dh_auto_test → skipped (override_dh_auto_test)
dh_auto_install → cmake --install DESTDIR=debian/zopen/
+ install config/default.toml (override)
dh_python3 → rewrites shebang, computes python3:any dep
dh_installdocs → installs README.md and copyright
dh_installchangelogs → compresses and installs changelog
dh_compress → compresses man pages, changelogs
dh_fixperms → sets standard file permissions
dh_installdeb → installs DEBIAN/control, conffiles, postinst, postrm
dh_gencontrol → generates final DEBIAN/control with substitution vars
dh_builddeb → calls dpkg-deb --build
pybuild --buildsystem=cmake runs CMake in a private build directory
(.pybuild/cpython3_3.12_edit/build/) and passes Debian-standard variables:
-DCMAKE_INSTALL_PREFIX=/usr
-DCMAKE_INSTALL_SYSCONFDIR=/etc
-DCMAKE_INSTALL_LOCALSTATEDIR=/var
-DCMAKE_INSTALL_LIBDIR=lib/x86_64-linux-gnu
This is why the CMake ZOPEN_SYSCONFDIR logic (§4.3) correctly resolves
to /etc during the Debian build even though the source tree’s own
build/ directory was configured with a different prefix.
6.2 Build the package
# Binary-only package, no GPG signing (typical for local builds)
dpkg-buildpackage -us -uc -b
# Source + binary, no signing
dpkg-buildpackage -us -uc
# Binary only, sign with your GPG key
dpkg-buildpackage -b
# Equivalent with debuild
debuild -us -uc -b
# Parallel build
dpkg-buildpackage -us -uc -b -j4
# Skip tests
DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -us -uc -b
The output files are placed in the parent directory of the source tree:
../zedit_0.5.0-1_all.deb # binary package
../edit_0.1.0-1_amd64.buildinfo # build metadata
../edit_0.1.0-1_amd64.changes # upload description
6.3 Inspect the package
# Package metadata
dpkg-deb --info ../zedit_0.5.0-1_all.deb
# File list
dpkg-deb --contents ../zedit_0.5.0-1_all.deb
# Extract everything to a directory
dpkg-deb -x ../zedit_0.5.0-1_all.deb /tmp/zopen-extracted
# Inspect the control scripts
dpkg-deb -e ../zedit_0.5.0-1_all.deb /tmp/zopen-control
ls /tmp/zopen-control/
# Verify the conffiles list
cat /tmp/zopen-control/conffiles
6.4 Install and remove
# Install (also satisfies dependencies from apt)
sudo dpkg -i ../zedit_0.5.0-1_all.deb
sudo apt-get install -f # fix any unsatisfied deps
# Or with apt (if you have a local repo set up)
sudo apt-get install zopen
# Remove (keeps conffiles)
sudo apt-get remove zopen
# Remove and purge all conffiles (including /opt/etc/zopen/config.toml)
sudo apt-get purge zopen
# Check installed files
dpkg -L zopen
# Check package status
dpkg -s zopen
6.5 debian/ directory reference
debian/changelog
Required by dpkg. Must follow exact format. Parse with:
dpkg-parsechangelog
Format:
<source-name> (<version>-<debian-revision>) <distribution>; urgency=<level>
* Change entry.
-- Maintainer Name <email> Day, DD Mon YYYY HH:MM:SS +ZZZZ
When releasing a new version, prepend a new entry with dch or edit manually.
debian/control
Defines the source package (build metadata) and one or more binary packages (what gets installed).
| Field | Stanza | Description |
|---|---|---|
Source |
Source | Source package name |
Section |
Source | Debian archive section (utils, python, …) |
Priority |
Source | optional for most packages |
Maintainer |
Source | Name <email> |
Build-Depends |
Source | Packages needed at build time |
Standards-Version |
Source | Debian Policy version this package conforms to |
Rules-Requires-Root |
Source | no = can build without root (uses fakeroot) |
Package |
Binary | Binary package name |
Architecture |
Binary | all for pure Python packages |
Depends |
Binary | Runtime dependencies. ${python3:Depends} is filled in by dh_python3. ${misc:Depends} by debhelper. |
Recommends |
Binary | Installed by default unless --no-install-recommends |
Suggests |
Binary | Presented to user but not installed automatically |
debian/rules
A Makefile processed by dpkg-buildpackage. The single %: rule delegates
everything to dh:
export PYBUILD_NAME = zopen # tells pybuild which Python package this is
%:
dh $@ --with python3 --buildsystem=pybuild
override_dh_auto_install is used to install the config file in addition to
what pybuild’s cmake install does:
override_dh_auto_install:
dh_auto_install
install -Dm 0644 config/default.toml \
debian/edit/opt/etc/zopen/config.toml
override_dh_auto_test suppresses test failures (since no test suite exists):
override_dh_auto_test:
$(MAKE) -C . test 2>/dev/null || true
Important: debian/rules uses real tabs for indentation (Makefile
requirement). Spaces will cause missing separator errors.
debian/copyright
Machine-readable DEP-5 format. Must list every licence in the package.
Checked by lintian.
debian/source/format
3.0 (quilt) — the standard modern source format. Allows patches to be
managed with quilt.
debian/zopen.docs
One filename per line; dh_installdocs copies these to
/opt/zopen/share/doc/zopen/. Currently contains README.md.
debian/postinst / debian/postrm
See §6.6 below.
6.6 Maintainer scripts
Two maintainer scripts are shipped:
debian/postinst — runs after the package is installed or upgraded.
The configure action ensures /opt/etc/zopen exists:
case "$1" in
configure)
if [ ! -d /opt/etc/zopen ]; then mkdir -p /opt/etc/zopen; fi
;;
esac
The #DEBHELPER# token is replaced by debhelper-generated code (e.g., from
dh_installdebconf).
debian/postrm — runs after the package is removed. The purge
action removes the config directory:
case "$1" in
purge)
if [ -d /opt/etc/zopen ]; then rm -rf /opt/etc/zopen; fi
;;
esac
Maintainer script actions are called with these arguments:
| Script | Argument | When |
|---|---|---|
postinst |
configure <old-version> |
After fresh install or upgrade |
postrm |
remove |
After apt remove |
postrm |
purge |
After apt purge |
These scripts are also used by CPack DEB via
CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA.
6.7 Conffile handling
/opt/etc/zopen/config.toml is installed by both the cmake install rule and the
override_dh_auto_install rule. dh_installdebconf / dh_installdeb
automatically adds any file under debian/zopen/etc/ to DEBIAN/conffiles:
/opt/etc/zopen/config.toml
This tells dpkg that:
- The file is a configuration file managed by the package.
- If the sysadmin has modified it and a new package version ships a different
default,
dpkgwill prompt: “keep the local version or install the package maintainer’s version?” apt removekeeps the file; onlyapt purgeremoves it.
6.8 Building a source package
A source package is required to upload to a Debian or Ubuntu archive.
# Full source + binary build with signing
dpkg-buildpackage
# Source only (produces .dsc + .debian.tar.xz + .orig.tar.xz)
dpkg-buildpackage -S
# Create the orig tarball first (if not already present)
git archive HEAD --prefix=zopen-0.5.0/ | gzip > ../edit_0.1.0.orig.tar.gz
# Use debuild for a more complete workflow
debuild -S -sa # -sa = include orig tarball even if unchanged
7. Choosing a packaging method
| Scenario | Recommended method |
|---|---|
| Quick developer install on any platform | pip install . |
Install with full Python metadata (.dist-info) |
pip install . or cmake -DEDIT_INSTALL_VIA_PIP=ON |
| System install without a package manager | cmake --install with --prefix /usr/local |
Local .deb for distribution to Debian/Ubuntu systems |
dpkg-buildpackage -us -uc -b |
.deb for upload to a Debian/Ubuntu repository |
dpkg-buildpackage (with GPG signing) |
| Cross-platform tarball | cmake --build build --target tarball (CPack TGZ) |
| RPM for Fedora/RHEL/SUSE | cmake --build build + cpack -G RPM |
| CI: build artefact for testing | python -m build --wheel |
8. Versioning and release checklist
The version number appears in these files and must be updated consistently:
| File | Field | Current value |
|---|---|---|
pyproject.toml |
[project] version |
0.6.5 |
CMakeLists.txt |
project(zopen VERSION ...) |
0.6.5 |
debian/changelog |
First entry version | 0.6.5-1 |
The debian/changelog version has a Debian revision suffix (-1). It is
incremented independently of the upstream version for packaging-only changes.
Release steps
-
Update the version in all three files above.
- Add a
debian/changelogentry (usedchor edit manually):dch -v 0.2.0-1 "New upstream release." - Tag the release in version control:
git tag -s v0.2.0 -m "Release 0.2.0" - Build and test all artefacts:
# Clean slate — use the distclean target if a build dir already exists, # or just remove it manually for a first-time build cmake --build build --target distclean # or: rm -rf build # Python wheel python -m build --wheel pip install dist/zopen-0.2.0-py3-none-any.whl zopen --version # confirm # CMake + CPack cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr cmake --build build cmake --build build --target deb dpkg-deb --info build/zopen-0.2.0-Linux.deb # dpkg-buildpackage dpkg-buildpackage -us -uc -b dpkg-deb --info ../edit_0.2.0-1_all.deb - Run
lintianto check the Debian package for policy violations:lintian ../edit_0.2.0-1_all.deb lintian --pedantic ../edit_0.2.0-1_all.deb - Upload wheel to PyPI:
twine upload dist/zopen-0.2.0-py3-none-any.whl - Upload
.dscto a Debian repository (if applicable):dput <repository> ../edit_0.2.0-1_amd64.changes