diff --git a/.github/workflows/rolling.yaml b/.github/workflows/rolling.yaml index 7482434..c50c91e 100644 --- a/.github/workflows/rolling.yaml +++ b/.github/workflows/rolling.yaml @@ -7,22 +7,28 @@ on: push: branches: - rolling + workflow_dispatch: jobs: build-and-test: - runs-on: ${{ matrix.os }} + runs-on: ubuntu-24.04 + env: + # Tests cannot create ~/.ros/log in the runner + ROS_LOG_DIR: /tmp/ros_log strategy: - matrix: - os: [ubuntu-26.04] fail-fast: false + matrix: + ros_distro: [jazzy, kilted] steps: - - uses: ros-tooling/setup-ros@0.7.16 + - uses: ros-tooling/setup-ros@0.7.19 with: - required-ros-distributions: rolling - - uses: ros-tooling/action-ros-ci@0.4.7 + required-ros-distributions: ${{ matrix.ros_distro }} + - name: Add the ROS libraries to the library path (needed by Kilted tests) + run: echo "LD_LIBRARY_PATH=/opt/ros/${{ matrix.ros_distro }}/lib:${LD_LIBRARY_PATH}" >> "$GITHUB_ENV" + - uses: ros-tooling/action-ros-ci@0.4.8 with: package-name: rossdl_cmake rossdl_simple_test system_a system_b application_1 application_2 application_3 - target-ros2-distro: rolling + target-ros2-distro: ${{ matrix.ros_distro }} colcon-defaults: | { "test": { diff --git a/rossdl_cmake/cmake/rossdl_generate_code.cmake b/rossdl_cmake/cmake/rossdl_generate_code.cmake index 5d8a62c..4b23d88 100644 --- a/rossdl_cmake/cmake/rossdl_generate_code.cmake +++ b/rossdl_cmake/cmake/rossdl_generate_code.cmake @@ -54,19 +54,16 @@ macro(rossdl_generate_code description_file) set(_code_tuple "${CMAKE_CURRENT_SOURCE_DIR}:${description_file}") endif() - ament_index_get_prefix_path(PACKAGES_INSTALL_PATHS) - set(ROSSDL_CMAKE_PATH "") - foreach(PACKAGES_INSTALL_PATH ${PACKAGES_INSTALL_PATHS}) - if(PACKAGES_INSTALL_PATH MATCHES "rossdl_cmake") - set(ROSSDL_CMAKE_PATH ${PACKAGES_INSTALL_PATH}) - endif() - endforeach() + # The templates are installed in /share/rossdl_cmake/resources and + # rossdl_cmake_DIR is /share/rossdl_cmake/cmake, for any install + # layout (isolated, merged, Debian or conda packages). + get_filename_component(ROSSDL_RESOURCES_DIR "${rossdl_cmake_DIR}/../resources" ABSOLUTE) file(READ ${_abs_file} ARTIFACTS_DESCRIPTION) ament_index_register_resource(rossdl_artifact_descriptions CONTENT ${ARTIFACTS_DESCRIPTION}) - set(RESOURCE_CPP ${ROSSDL_CMAKE_PATH}/share/rossdl_cmake/resources/nodes.cpp.em) - set(RESOURCE_HPP ${ROSSDL_CMAKE_PATH}/share/rossdl_cmake/resources/nodes.hpp.em) + set(RESOURCE_CPP ${ROSSDL_RESOURCES_DIR}/nodes.cpp.em) + set(RESOURCE_HPP ${ROSSDL_RESOURCES_DIR}/nodes.hpp.em) string(REGEX REPLACE ":([^:]*)$" "/\\1" _abs_file "${_code_tuple}") set(_header_out_file ${CMAKE_CURRENT_BINARY_DIR}/include/${PROJECT_NAME}/Nodes.hpp) diff --git a/rossdl_cmake/cmake/rossdl_generate_system.cmake b/rossdl_cmake/cmake/rossdl_generate_system.cmake index 4cfd59e..4eee36c 100644 --- a/rossdl_cmake/cmake/rossdl_generate_system.cmake +++ b/rossdl_cmake/cmake/rossdl_generate_system.cmake @@ -58,15 +58,12 @@ macro(rossdl_generate_system) # description_file systems) set(_code_tuple "${CMAKE_CURRENT_SOURCE_DIR}:${description_file}") endif() - ament_index_get_prefix_path(PACKAGES_INSTALL_PATHS) - set(ROSSDL_CMAKE_PATH "") - foreach(PACKAGES_INSTALL_PATH ${PACKAGES_INSTALL_PATHS}) - if(PACKAGES_INSTALL_PATH MATCHES "rossdl_cmake") - set(ROSSDL_CMAKE_PATH ${PACKAGES_INSTALL_PATH}) - endif() - endforeach() + # The templates are installed in /share/rossdl_cmake/resources and + # rossdl_cmake_DIR is /share/rossdl_cmake/cmake, for any install + # layout (isolated, merged, Debian or conda packages). + get_filename_component(ROSSDL_RESOURCES_DIR "${rossdl_cmake_DIR}/../resources" ABSOLUTE) - set(RESOURCE_LAUNCH ${ROSSDL_CMAKE_PATH}/share/rossdl_cmake/resources/launcher.py.em) + set(RESOURCE_LAUNCH ${ROSSDL_RESOURCES_DIR}/launcher.py.em) string(REGEX REPLACE ":([^:]*)$" "/\\1" _abs_file "${_code_tuple}") @@ -76,6 +73,16 @@ macro(rossdl_generate_system) # description_file systems) ament_index_get_resources(ROSSDL_ARTIFACTS rossdl_artifact_descriptions) ament_index_get_resources(ROSSDL_SYSTEMS rossdl_system_descriptions) + # The descriptions of this package are registered in its build space, so + # CMake sees them, but they are not installed yet, so the generator cannot + # read them from the ament index. Always use them as local files. + if(ROSSDL_ARTIFACTS) + list(REMOVE_ITEM ROSSDL_ARTIFACTS ${PROJECT_NAME}) + endif() + if(ROSSDL_SYSTEMS) + list(REMOVE_ITEM ROSSDL_SYSTEMS ${PROJECT_NAME}) + endif() + if(ROSSDL_ARTIFACTS) set(ROSSDL_ARTIFACTS_NO_VOID ${ROSSDL_ARTIFACTS}) endif() diff --git a/rossdl_cmake/package.xml b/rossdl_cmake/package.xml index 46daf2f..3db42ae 100644 --- a/rossdl_cmake/package.xml +++ b/rossdl_cmake/package.xml @@ -16,6 +16,9 @@ ament_cmake python3-empy + python3-yaml + ament_index_python + ros2run rclpy diff --git a/rossdl_cmake/rossdl_cmake/__init__.py b/rossdl_cmake/rossdl_cmake/__init__.py index a61987f..3d225f2 100644 --- a/rossdl_cmake/rossdl_cmake/__init__.py +++ b/rossdl_cmake/rossdl_cmake/__init__.py @@ -22,6 +22,33 @@ import yaml from yaml.loader import SafeLoader +def _create_interpreter(output): + """Create an EmPy interpreter, compatible with EmPy 3 and EmPy 4.""" + if hasattr(em, 'BUFFERED_OPT'): + # EmPy 3 (Ubuntu packages) + return em.Interpreter( + output=output, + options={ + em.BUFFERED_OPT: True, + em.RAW_OPT: True, + em.OVERRIDE_OPT: False, + }) + # EmPy 4 (conda-forge, pip) + return em.Interpreter( + output=output, + config=em.Configuration(useProxy=False), + dispatcher=False) + + +def _expand(interpreter, content, name, handle, data): + if hasattr(em, 'BUFFERED_OPT'): + interpreter.invoke('beforeFile', name=name, file=handle, locals=data) + interpreter.string(content, name, locals=data) + interpreter.invoke('afterFile') + else: + interpreter.string(content, locals=data) + + def read_description(file_in): with open(file_in) as f: @@ -199,19 +226,11 @@ def generate_file(package, artifacts_file, file_in, file_out): file_output = StringIO() content = '' try: - _interpreter = em.Interpreter( - output=file_output, - options={ - em.BUFFERED_OPT: True, - em.RAW_OPT: True, - }) + _interpreter = _create_interpreter(file_output) with open(file_in, 'r') as h: content = h.read() - _interpreter.invoke( - 'beforeFile', name=file_in, file=h, locals=data) - _interpreter.string(content, file_in, locals=data) - _interpreter.invoke('afterFile') + _expand(_interpreter, content, file_in, h, data) content = file_output.getvalue() except Exception as e: # noqa: F841 print( @@ -335,20 +354,11 @@ def generate_launch(package, file_in, launch_in, file_out, system, systems_data, content = '' try: em.Interpreter._wasProxyInstalled = False - _interpreter = em.Interpreter( - output=file_output, - options={ - em.BUFFERED_OPT: True, - em.RAW_OPT: True, - em.OVERRIDE_OPT: False, - }) + _interpreter = _create_interpreter(file_output) with open(launch_in, 'r') as h: content = h.read() - _interpreter.invoke( - 'beforeFile', name=file_in, file=h, locals=data_and_system) - _interpreter.string(content, launch_in, locals=data_and_system) - _interpreter.invoke('afterFile') + _expand(_interpreter, content, launch_in, h, data_and_system) content = file_output.getvalue() except Exception as e: # noqa: F841 print( diff --git a/rossdl_cmake/rossdl_cmake/__pycache__/__init__.cpython-314.pyc b/rossdl_cmake/rossdl_cmake/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000..6d43428 Binary files /dev/null and b/rossdl_cmake/rossdl_cmake/__pycache__/__init__.cpython-314.pyc differ