You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: source/How-To-Guides/Ament-CMake-Documentation.rst
+92Lines changed: 92 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -671,3 +671,95 @@ Once added, you can register them using the ament_environment_hooks function in
671
671
)
672
672
673
673
Another example of using environment hooks for Gazebo plugin paths can be found in the official `ros_gz_project_template <https://github.com/gazebosim/ros_gz_project_template/tree/main/ros_gz_example_gazebo/hooks>`__.
674
+
675
+
API Version Management
676
+
----------------------
677
+
678
+
ROS 2 provides automatic version header generation through ``ament_generate_version_header``, which creates compile-time macros for API versioning and feature detection.
679
+
This is particularly useful for maintaining backward compatibility and conditionally enabling features based on library versions.
680
+
681
+
.. note::
682
+
683
+
The ``ament_generate_version_header`` functionality is designed for C, C++, and other C-based languages only.
684
+
It generates C/C++ header files with preprocessor macros and is not applicable to Python or other non-C-based packages.
685
+
686
+
Understanding auto-generated version macros
687
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
688
+
689
+
Many ROS 2 C/C++ packages (such as ``rclcpp``, ``rcl``, and ``rmw``) automatically generate version header files containing macros that expose the library's version information.
690
+
These version headers are generated from the ``package.xml`` file using the `ament_generate_version_header.cmake <https://github.com/ament/ament_cmake/blob/${ROS_DISTRO}/ament_cmake_gen_version_h/cmake/ament_generate_version_header.cmake>`__ script.
691
+
692
+
The generated version macros follow this naming convention:
693
+
694
+
- ``<PACKAGE_NAME>_VERSION_MAJOR``: Major version number
695
+
- ``<PACKAGE_NAME>_VERSION_MINOR``: Minor version number
696
+
- ``<PACKAGE_NAME>_VERSION_PATCH``: Patch version number
697
+
- ``<PACKAGE_NAME>_VERSION``: Combined version as a single integer (major * 10000 + minor * 100 + patch)
698
+
- ``<PACKAGE_NAME>_VERSION_STR``: String representation of the version (e.g., "1.2.3")
699
+
- ``<PACKAGE_NAME>_VERSION_GTE(major, minor, patch)``: Macro to check if version is greater than or equal to specified version
700
+
701
+
For example, ``rclcpp`` provides macros like:
702
+
703
+
- ``RCLCPP_VERSION_MAJOR``
704
+
- ``RCLCPP_VERSION_MINOR``
705
+
- ``RCLCPP_VERSION_PATCH``
706
+
- ``RCLCPP_VERSION``
707
+
- ``RCLCPP_VERSION_STR``
708
+
- ``RCLCPP_VERSION_GTE(major, minor, patch)``
709
+
710
+
Generating version headers for your package
711
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
712
+
713
+
To generate version headers for your own package, add the following to your ``CMakeLists.txt``:
714
+
715
+
.. code-block:: cmake
716
+
717
+
find_package(ament_cmake_gen_version_h REQUIRED)
718
+
ament_generate_version_header(my_library)
719
+
720
+
This generates a header file at ``<build_dir>/my_library/version.h`` that can be included in your code:
721
+
722
+
.. code-block:: cpp
723
+
724
+
#include "my_library/version.h"
725
+
726
+
The version information is automatically extracted from the ``<version>`` tag in your ``package.xml``.
727
+
728
+
By default, the generated header file is placed in the build directory under ``<package_name>/version.h``.
Version macros enable runtime and compile-time feature detection, which is essential for writing portable code across different ROS 2 distributions.
739
+
740
+
While ROS 2 guarantees ABI (Application Binary Interface) compatibility within the same distribution, new interfaces and features can be backported.
741
+
This means that within a single distribution, different API versions may be available depending on which patch release is installed.
742
+
Version macros allow developers to check if a specific feature is available before using it.
743
+
744
+
Example: Version checking
745
+
~~~~~~~~~~~~~~~~~~~~~~~~~
746
+
747
+
.. code-block:: cpp
748
+
749
+
#include "rclcpp/version.h"
750
+
751
+
// Check if new feature is available
752
+
#if RCLCPP_VERSION_GTE(28, 3, 0)
753
+
use_new_api_with_feature();
754
+
#else
755
+
use_old_api_without_feature();
756
+
#endif
757
+
758
+
Best practices
759
+
~~~~~~~~~~~~~~
760
+
761
+
- **Check before using new features**: Always use version macros when utilizing features that may not be available in older versions of a library.
762
+
- **Provide fallback implementations**: When possible, provide alternative implementations for older API versions to maintain backward compatibility.
763
+
- **Document version requirements**: Clearly document the minimum required versions for specific features in your package documentation.
764
+
- **Test across versions**: If your package needs to support multiple ROS 2 distributions, test it against the minimum supported version.
765
+
- **Use the GTE macro**: Prefer using the ``_VERSION_GTE(major, minor, patch)`` macro for version comparisons, as it provides a cleaner and more readable syntax than manually comparing individual version components.
0 commit comments