catkin-pkg: Catkin Package Library
catkin-pkg is a standalone Python library designed to support the Catkin build system, primarily used in the Robot Operating System (ROS) ecosystem. It provides functionalities for finding, introspecting, and managing Catkin packages within the file system, including parsing `package.xml` manifest files. The current version is 1.1.0, and it maintains an active development status with periodic releases.
Warnings
- gotcha Do not install `catkin-pkg-modules` from PyPI. The `catkin-pkg-modules` package exists on Debian/Ubuntu for specific Python 2/3 co-installation scenarios, but for pip installations, `catkin-pkg` provides all necessary Python modules. Installing `catkin-pkg-modules` via pip is unnecessary and was previously a duplicated effort.
- gotcha Mixing Catkin build tools (e.g., building with `catkin_make` or `catkin_make_isolated` and then `catkin build` from `catkin_tools`) can lead to an 'Inconsistent Environment' and unpredictable build failures due to cached configuration differences.
- gotcha Packages with incorrect or implicitly satisfied dependencies in their `package.xml` files (e.g., relying on side-effects of other packages in the same workspace) can fail to build or link correctly when using stricter build tools or migrating workspaces. Common errors include 'Unknown CMake command “catkin_package”' or missing headers/libraries.
- gotcha When using `catkin build` (part of `catkin_tools`), sometimes local changes to source files are not detected, leading to stale executables or libraries. This is often a caching issue in the build system.
Install
-
pip install catkin-pkg
Imports
- Package
from catkin_pkg.package import Package
- parse_package
from catkin_pkg.package import parse_package
- find_packages
from catkin_pkg.packages import find_packages
Quickstart
import os
import tempfile
import shutil
from pathlib import Path
from catkin_pkg.packages import find_packages
# Create a dummy catkin workspace for demonstration
temp_dir = Path(tempfile.mkdtemp())
workspace_path = temp_dir / "my_catkin_ws"
src_path = workspace_path / "src"
src_path.mkdir(parents=True, exist_ok=True)
# Create a dummy package A
pkg_a_path = src_path / "package_a"
pkg_a_path.mkdir(exist_ok=True)
(pkg_a_path / "package.xml").write_text("""<?xml version=\"1.0\"?>\n<package format=\"2\">\n <name>package_a</name>\n <version>0.1.0</version>\n <description>A dummy package A</description>\n <maintainer email=\"user@example.com\">User Name</maintainer>\n <license>MIT</license>\n <buildtool_depend>catkin</buildtool_depend>\n <depend>python3-catkin-pkg</depend>\n</package>""")
# Create a dummy package B depending on A
pkg_b_path = src_path / "package_b"
pkg_b_path.mkdir(exist_ok=True)
(pkg_b_path / "package.xml").write_text("""<?xml version=\"1.0\"?>\n<package format=\"2\">\n <name>package_b</name>\n <version>0.1.0</version>\n <description>A dummy package B</description>\n <maintainer email=\"user@example.com\">User Name</maintainer>\n <license>MIT</license>\n <buildtool_depend>catkin</buildtool_depend>\n <depend>package_a</depend>\n</package>""")
# Find and parse packages
print(f"Searching for packages in: {src_path}")
found_packages = find_packages(str(src_path))
print(f"Found {len(found_packages)} packages:")
for path, pkg in found_packages.items():
print(f"- Path: {path}")
print(f" Name: {pkg.name}")
print(f" Version: {pkg.version}")
print(f" Description: {pkg.description}")
print(f" Dependencies:")
for dep in pkg.buildtool_depends:
print(f" Buildtool: {dep.name}")
for dep in pkg.depends:
print(f" Runtime/Build: {dep.name}")
# Clean up the dummy workspace
shutil.rmtree(temp_dir)