scpeters: CI is green now, but I haven't tested it locally. I'm guessing that it won't ever produce `<depend>` tags in the output since I didn't adapt the [merge logic for run_depends](https://github.com/ros-infrastructure/catkin_pkg/blob/master/src/catkin_pkg/package.py#L108-L113) to the `depends` tag.
scpeters: I just squashed some of the embarrassing commits. It should be ready for review.
dirk-thomas: > CI is green now, but I haven't tested it locally.
> It should be ready for review.

Please go ahead and test the changes locally before requesting a review.
scpeters: Here's what it generates for the [beginner_tutorials package.xml](http://wiki.ros.org/ROS/Tutorials/catkin/CreatingPackage#Creating_a_catkin_Package) when I run it locally:

~~~
<?xml version="1.0"?>
<package format="2">
  <name>beginner_tutorials</name>
  <version>0.0.0</version>
  <description>The beginner_tutorials package</description>

  <!-- One maintainer tag required, multiple allowed, one person per tag -->
  <!-- Example:  -->
  <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
  <maintainer email="scpeters@todo.todo">scpeters</maintainer>


  <!-- One license tag required, multiple allowed, one license per tag -->
  <!-- Commonly used license strings: -->
  <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
  <license>TODO</license>


  <!-- Url tags are optional, but multiple are allowed, one per tag -->
  <!-- Optional attribute type can be: website, bugtracker, or repository -->
  <!-- Example: -->
  <!-- <url type="website">http://wiki.ros.org/beginner_tutorials</url> -->


  <!-- Author tags are optional, multiple are allowed, one per tag -->
  <!-- Authors do not have to be maintainers, but could be -->
  <!-- Example: -->
  <!-- <author email="jane.doe@example.com">Jane Doe</author> -->


  <!-- The *depend tags are used to specify dependencies -->
  <!-- Dependencies can be catkin packages or system dependencies -->
  <!-- Examples: -->
  <!-- Use build_depend for packages you need at compile time: -->
  <!--   <build_depend>message_generation</build_depend> -->
  <!-- Use build_export_depend for packages you need in order to build against this package: -->
  <!--   <build_export_depend>message_generation</build_export_depend> -->
  <!-- Use buildtool_depend for build tool packages: -->
  <!--   <buildtool_depend>catkin</buildtool_depend> -->
  <!-- Use doc_depend for packages you need only for building documentation: -->
  <!--   <doc_depend>gtest</doc_depend> -->
  <!-- Use exec_depend for packages you need at runtime: -->
  <!--   <exec_depend>message_runtime</exec_depend> -->
  <!-- Use test_depend for packages you need only for testing: -->
  <!--   <test_depend>gtest</test_depend> -->
  <!-- Use depend as a shortcut for packages that are both build and runtime dependencies -->
  <!--   <depend>roscpp</depend> -->
  <!--   Note that this is equivalent to the following: -->
  <!--   <build_depend>roscpp</build_depend> -->
  <!--   <build_export_depend>roscpp</build_export_depend> -->
  <!--   <exec_depend>roscpp</exec_depend> -->
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>


  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <!-- Other tools can request additional information be placed here -->

  </export>
</package>
~~~

It would be nicer if it grouped them into the `<depend>` tag.
scpeters: @dirk-thomas I have tested it locally.
dirk-thomas: > I have tested it locally.

That is great.

Currently I have to focus on ROS 2 related task so it might take a bit until I will have the time to review this. Sorry.
diff --git a/src/catkin_pkg/package_templates.py b/src/catkin_pkg/package_templates.py
index f5b405d..5dc0dde 100644
--- a/src/catkin_pkg/package_templates.py
+++ b/src/catkin_pkg/package_templates.py
@@ -92,8 +92,9 @@ class PackageTemplate(Package):
         catkin_deps = list(catkin_deps or [])
         catkin_deps.sort()
         pkg_catkin_deps = []
+        depends = []
         build_depends = []
-        run_depends = []
+        exec_depends = []
         buildtool_depends = [Dependency('catkin')]
         for dep in catkin_deps:
             if dep.lower() == 'catkin':
@@ -111,12 +112,11 @@ class PackageTemplate(Package):
             if dep.lower() == 'message_runtime':
                 if not 'message_generation' in catkin_deps:
                     sys.stderr.write('WARNING: Packages with messages or services should depend on both message_generation and message_runtime\n')
-                run_depends.append(Dependency('message_runtime'))
+                exec_depends.append(Dependency('message_runtime'))
                 continue
             pkg_catkin_deps.append(Dependency(dep))
         for dep in pkg_catkin_deps:
-            build_depends.append(dep)
-            run_depends.append(dep)
+            depends.append(dep)
         if boost_comps:
             if not system_deps:
                 system_deps = ['boost']
@@ -124,15 +124,17 @@ class PackageTemplate(Package):
                 system_deps.append('boost')
         for dep in system_deps or []:
             if not dep.lower().startswith('python-'):
-                build_depends.append(Dependency(dep))
-            run_depends.append(Dependency(dep))
+                depends.append(Dependency(dep))
+            else:
+                exec_depends.append(Dependency(dep))
         package_temp = PackageTemplate(
             name=package_name,
             version=version or '0.0.0',
             description=description or 'The %s package' % package_name,
             buildtool_depends=buildtool_depends,
             build_depends=build_depends,
-            run_depends=run_depends,
+            depends=depends,
+            exec_depends=exec_depends,
             catkin_deps=catkin_deps,
             system_deps=system_deps,
             boost_comps=boost_comps,
@@ -390,14 +392,15 @@ def create_package_xml(package_template, rosdistro, meta=False):
     dependencies = []
     dep_map = {
         'build_depend': package_template.build_depends,
+        'build_export_depend': package_template.build_export_depends,
         'buildtool_depend': package_template.buildtool_depends,
-        'run_depend': package_template.run_depends,
+        'exec_depend': package_template.exec_depends,
         'test_depend': package_template.test_depends,
         'conflict': package_template.conflicts,
         'replace': package_template.replaces
     }
-    for dep_type in ['buildtool_depend', 'build_depend', 'run_depend',
-                     'test_depend', 'conflict', 'replace']:
+    for dep_type in ['buildtool_depend', 'build_depend', 'build_export_depend',
+                     'exec_depend', 'test_depend', 'conflict', 'replace']:
         for dep in sorted(dep_map[dep_type], key=lambda x: x.name):
             if 'depend' in dep_type:
                 dep_tag = _create_depend_tag(
diff --git a/src/catkin_pkg/templates/CMakeLists.txt.in b/src/catkin_pkg/templates/CMakeLists.txt.in
index be37947..1e67b7c 100644
--- a/src/catkin_pkg/templates/CMakeLists.txt.in
+++ b/src/catkin_pkg/templates/CMakeLists.txt.in
@@ -94,7 +94,7 @@ find_package(catkin REQUIRED@components)
 ###################################
 ## The catkin_package macro generates cmake config files for your package
 ## Declare things to be passed to dependent projects
-## INCLUDE_DIRS: uncomment this if you package contains header files
+## INCLUDE_DIRS: uncomment this if your package contains header files
 ## LIBRARIES: libraries you create in this project that dependent projects also need
 ## CATKIN_DEPENDS: catkin_packages dependent projects also need
 ## DEPENDS: system dependencies of this project that dependent projects also need
diff --git a/src/catkin_pkg/templates/package.xml.in b/src/catkin_pkg/templates/package.xml.in
index bdf167a..5c7e0ba 100644
--- a/src/catkin_pkg/templates/package.xml.in
+++ b/src/catkin_pkg/templates/package.xml.in
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<package>
+<package format="2">
   <name>@name</name>
   <version@version_abi>@version</version>
   <description>@description</description>
@@ -26,17 +26,26 @@
   <!-- <author email="jane.doe@@example.com">Jane Doe</author> -->
 @authors
 
-  <!-- The *_depend tags are used to specify dependencies -->
+  <!-- The *depend tags are used to specify dependencies -->
   <!-- Dependencies can be catkin packages or system dependencies -->
   <!-- Examples: -->
+  <!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
+  <!--   <depend>roscpp</depend> -->
+  <!--   Note that this is equivalent to the following: -->
+  <!--   <build_depend>roscpp</build_depend> -->
+  <!--   <exec_depend>roscpp</exec_depend> -->
   <!-- Use build_depend for packages you need at compile time: -->
   <!--   <build_depend>message_generation</build_depend> -->
+  <!-- Use build_export_depend for packages you need in order to build against this package: -->
+  <!--   <build_export_depend>message_generation</build_export_depend> -->
   <!-- Use buildtool_depend for build tool packages: -->
   <!--   <buildtool_depend>catkin</buildtool_depend> -->
-  <!-- Use run_depend for packages you need at runtime: -->
-  <!--   <run_depend>message_runtime</run_depend> -->
+  <!-- Use exec_depend for packages you need at runtime: -->
+  <!--   <exec_depend>message_runtime</exec_depend> -->
   <!-- Use test_depend for packages you need only for testing: -->
   <!--   <test_depend>gtest</test_depend> -->
+  <!-- Use doc_depend for packages you need only for building documentation: -->
+  <!--   <doc_depend>doxygen</doc_depend> -->
 @dependencies
 
   <!-- The export tag contains other, unspecified, tags -->

catkin_create_pkg: start using package.xml format 2
diff --git a/test/test_templates.py b/test/test_templates.py
index ef5f913..ed2a5b6 100644
--- a/test/test_templates.py
+++ b/test/test_templates.py
@@ -156,7 +156,7 @@ class TemplateTest(unittest.TestCase):
     def test_parse_generated(self):
         maint = self.get_maintainer()
         pack = PackageTemplate(name='bar',
-                               package_format=1,
+                               package_format=2,
                                version='0.0.0',
                                version_abi='pabi',
                                urls=[Url('foo')],
@@ -207,7 +207,7 @@ class TemplateTest(unittest.TestCase):
         # test with multiple attributes filled
         maint = self.get_maintainer()
         pack = PackageTemplate(name='bar',
-                               package_format=1,
+                               package_format=2,
                                version='0.0.0',
                                version_abi='pabi',
                                description='pdesc',

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-mock mock
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
-e git+https://github.com/ros-infrastructure/catkin_pkg.git@6cc8d7998803ea8d2e70c5243a6b0dad9c8589dc#egg=catkin_pkg
docutils==0.21.2
exceptiongroup==1.2.2
iniconfig==2.1.0
mock==5.2.0
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
pytest-mock==3.14.0
python-dateutil==2.9.0.post0
six==1.17.0
tomli==2.2.1

name: catkin_pkg
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - argparse==1.4.0
      - docutils==0.21.2
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - mock==5.2.0
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - pytest-mock==3.14.0
      - python-dateutil==2.9.0.post0
      - six==1.17.0
      - tomli==2.2.1
prefix: /opt/conda/envs/catkin_pkg

test/test_templates.py::TemplateTest::test_parse_generated test/test_templates.py::TemplateTest::test_parse_generated_multi
test/test_templates.py::TemplateTest::test_create_cmakelists test/test_templates.py::TemplateTest::test_create_include_macro test/test_templates.py::TemplateTest::test_create_package test/test_templates.py::TemplateTest::test_create_package_template test/test_templates.py::TemplateTest::test_create_package_xml test/test_templates.py::TemplateTest::test_create_targetlib_args test/test_templates.py::TemplateTest::test_safe_write_files
src/catkin_pkg/package_templates.py src/catkin_pkg/templates/package.xml.in src/catkin_pkg/templates/CMakeLists.txt.in
src/catkin_pkg/package_templates.py src/catkin_pkg/templates/package.xml.in src/catkin_pkg/templates/CMakeLists.txt.in