Simplifying OpenOCD Deployment with a Debian Package

Instead of manually copying binaries and dependencies across machines, you can package OpenOCD into a Debian .deb archive. This post walks through creating a custom package to simplify installation and distribution.

Andre Leppik

In the last two posts (1, 2), we looked into compiling OpenOCD from source and how to run the resulting binaries. While that works, I was not a fan of manually copying files between machines and juggling all the dependencies. There has to be an easier way, right? Of course, by packaging everything into a Debian .deb file. With these packages, installation becomes clean and repeatable. Let’s go ahead and create our own openocd.deb package for the ARM64 platforms.

Building the Package

First, install the required tools for working with Debian packages:

sudo apt install -y dpkg-dev debhelper devscripts

Next we set up the package directory structure. Our package will be called pxg-openocd, with the following structure:

  • DEBIAN contains package metadata files
  • /usr/bin contains the compiled binary file
  • /usr/share/openocd/scripts contains the OpenOCD scripts
mkdir -p pxg-openocd/DEBIAN
mkdir -p pxg-openocd/usr/bin
mkdir -p pxg-openocd/usr/share/openocd/scripts

Now copy the binary and script files from the OpenOCD repository:

cp openocd/src/openocd pxg-openocd/usr/bin/
cp -r openocd/tcl/* pxg-openocd/usr/share/openocd/scripts/

For the control file, which defines package metadata and installation requirements, we need to specify package metadata and dependencies. Last time, we used objdump to list the required libraries (see the Installing Needed Libraries in the last post). Create the control file inside the DEBIAN directory and add the dependencies and other metadata as shown below:

Package: pxg-openocd
Version: 0.12.0+dev-g66ea46184
Section: embedded
Priority: optional
Architecture: arm64
Depends: libc6 (>= 2.29), libusb-1.0-0, libhidapi-hidraw0, libjim0.81
Maintainer: Make Package <info@makeprogress.ee>
Description: OpenOCD for ARM64
 A custom build of Open On-Chip Debugger (OpenOCD) for ARM64 systems.

Most of the fields are self-explanatory. The Package field, however, must have a unique name on our system and is ideally lowercase.

The Version field in a Debian package specifies the software's release number. It typically follows the format: [upstreamversion]-[debianrevision], where upstream_version is the original software version, and debian_revision (if present) indicates Debian-specific modifications. For our custom build, we can use a descriptive version like 0.12.0+dev-g[git_hash] to indicate the source commit.

Our custom package is almost ready, but before we build it we need to ensure that the files have the correct permissions. Files are set to 644 (readable by all, writable only by the owner) to prevent unauthorized modifications, while directories use 755 (readable and executable by all, writable only by the owner) to ensure controlled access to their contents.

find pxg-openocd/ -type f -exec chmod 644 {} + 
find pxg-openocd/ -type d -exec chmod 755 {} +

Finally, build the .deb package:

dpkg-deb --root-owner-group --build pxg-openocd
ℹ️ Note: --root-owner-group makes dpkg-deb set all files in the package to be owned by root:root, regardless of the current user building the .deb. It’s necessary because Debian packages are expected to install files owned by root:root.

And that's it, we have a installable Debian package!

Jeremy Clarkson Fist Pump

Validating the Package

Although we built the package without errors, we should somehow validate it. Luckily, there is a handy tool called lintian which checks Debian packages against packaging rules and reports issues.

$ lintian pxg-openocd.deb 
E: pxg-openocd: no-changelog usr/share/doc/pxg-openocd/changelog.Debian.gz (non-native package)
E: pxg-openocd: no-copyright-file
E: pxg-openocd: unstripped-binary-or-object [usr/bin/openocd]
W: pxg-openocd: no-manual-page [usr/bin/openocd]

It seems that we have some issues, errors marked as E and warnings marked as W. These errors should not affect our package’s installation and usage, but leaving them unfixed feels....wrong. Let's fix them!

Fixing Missing Files

The no-changelog error means we’re missing a properly formatted changelog file. It must be named changelog.Debian, compressed, and placed in pxg-openocd/usr/share/doc/pxg-openocd/

We start by creating a changelog.Debian file:

cat > "pxg-openocd/usr/share/doc/pxg-openocd/changelog.Debian" <<EOF
pxg-openocd (0.12.0+dev-g66ea46184) unstable; urgency=medium

  * Built from source, git HASH 66ea46184.

 -- Make Progress <info@makeprogress.ee> $(date -R)
EOF

gzip -9 -n "pxg-openocd/usr/share/doc/pxg-openocd/changelog.Debian"

Next, we compress the change log:

gzip -9 -n "pxg-openocd/usr/share/doc/pxg-openocd/changelog.Debian"

For the missing copyright file we can reuse OpenOCD’s official copyright file and place it in the same directory.

Stripping Debug Symbols

The unstripped-binary-or-object error means that we built the binary with debug information enabled. We do not need to rebuild the whole binary, we can just strip the debug symbols from the binary.

strip pxg-openocd/usr/bin/openocd

Don’t forget to re-apply file permissions afterward, as we did at the beginning. Once built we should now see only one warning, which we can ignore. ദ്ദി(ᵔᗜᵔ)

Installing and Running the Package

With the package built we can deploy it on the Raspberry Pi by copying the .deb file to the target system and install it with:

sudo apt install ./pxg-openocd.deb

The tool is now available on our system. We can verify the installation with:

$ openocd --version
Open On-Chip Debugger 0.12.0+dev-02117-g66ea46184 (2025-08-05-18:02)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html

To update the package, bump the Version field in the control file, rebuild the package, and reinstall the new .deb using the same command.

And when you no longer need the tool, uninstalling via apt ensures all files are removed cleanly, avoiding orphaned files.

$ sudo apt remove pxg-openocd
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
.....
(Reading database ... 201412 files and directories currently installed.)
Removing pxg-openocd (0.12.0+dev-g66ea46184) ...

Whats Next?

We already have a nice setup for our tool, but there’s one more improvement we can make. Next time, we’ll look at publishing the package to our own hosted Debian registry, so we can install it on our target machines directly from our registry.

Enjoyed This Post?

Love tinkering with embedded systems and hands-on projects? Join our email list, and we’ll share our latest posts, tips, and discoveries with you - no spam, just the good stuff!

Join the List!
Need help with embedded systems development?

Whether you're building something new, fixing stability issues, or automating what slows your team down — we can help.