diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d5162faf..49106dd5 100755 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - platform: [teensy41, teensy40, teensy36, teensy35, teensy31, due, zero, olimex_e407, esp32dev, nanorp2040connect, portenta_h7_m7, teensy41_eth, nanorp2040connect_wifi, portenta_h7_m7_wifi, esp32dev_wifi, esp32dev_ethernet, portenta_h7_m7_humble, portenta_h7_m7_jazzy, portenta_h7_m7_kilted, portenta_h7_m7_rolling, teensy41_custom, pico, pico2] + platform: [teensy41, teensy40, teensy36, teensy35, teensy31, due, zero, olimex_e407, esp32dev, nanorp2040connect, portenta_h7_m7, teensy41_eth, nanorp2040connect_wifi, portenta_h7_m7_wifi, esp32dev_wifi, esp32dev_ethernet, portenta_h7_m7_humble, portenta_h7_m7_jazzy, portenta_h7_m7_kilted, portenta_h7_m7_lyrical, portenta_h7_m7_rolling, teensy41_custom, pico, pico2] steps: - uses: actions/checkout@v5 diff --git a/README.md b/README.md index 4fd14929..cf6e0646 100755 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ The target ROS 2 distribution can be configured with the `board_microros_distro - `humble` - `jazzy` - `kilted` *(default value)* + - `lyrical` - `rolling` ### Transport configuration diff --git a/ci/platformio.ini b/ci/platformio.ini index 44c4532a..50f95ec2 100644 --- a/ci/platformio.ini +++ b/ci/platformio.ini @@ -28,6 +28,16 @@ board_microros_distro = kilted lib_deps = ../ +; Lyrical test +[env:portenta_h7_m7_lyrical] +platform = ststm32 +board = portenta_h7_m7 +framework = arduino +board_microros_transport = serial +board_microros_distro = lyrical +lib_deps = + ../ + ; Rolling test [env:portenta_h7_m7_rolling] platform = ststm32 @@ -206,3 +216,4 @@ framework = arduino board_microros_transport = custom lib_deps = ../ + diff --git a/ci/src/main.cpp b/ci/src/main.cpp index 4d4909ff..b3824bcd 100644 --- a/ci/src/main.cpp +++ b/ci/src/main.cpp @@ -126,7 +126,7 @@ void setup() { &timer, &support, RCL_MS_TO_NS(100), - timer_callback)); + (rcl_timer_callback_t) timer_callback)); // create executor RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator)); diff --git a/extra_script.py b/extra_script.py index d6b029fd..95196917 100644 --- a/extra_script.py +++ b/extra_script.py @@ -104,12 +104,13 @@ def build_microros(*args, **kwargs): env['CC'], env['CXX'], env['AR'], - "{} {} -DCLOCK_MONOTONIC=0 -D'__attribute__(x)='".format(' '.join(env['CFLAGS']), ' '.join(env['CCFLAGS'])), + "{} {} -Wno-error=implicit-function-declaration -DCLOCK_MONOTONIC=0 -D'__attribute__(x)='".format(' '.join(env['CFLAGS']), ' '.join(env['CCFLAGS'])), "{} {} -fno-rtti -DCLOCK_MONOTONIC=0 -D'__attribute__(x)='".format(' '.join(env['CXXFLAGS']), ' '.join(env['CCFLAGS'])) ) python_env_path = env['PROJECT_CORE_DIR'] + "/penv/bin/activate" builder = library_builder.Build(library_folder=main_path, packages_folder=extra_packages_path, distro=microros_distro, python_env=python_env_path) + builder.env = env.get("ENV", os.environ.copy()) builder.run('{}/metas/{}'.format(main_path, selected_board_meta), cmake_toolchain.path, microros_user_meta) ####################################################### diff --git a/microros_utils/library_builder.py b/microros_utils/library_builder.py index d1bda806..e950c99e 100644 --- a/microros_utils/library_builder.py +++ b/microros_utils/library_builder.py @@ -52,7 +52,7 @@ def __init__(self, library_folder, packages_folder, distro, python_env): self.includes = self.library_path+ '/include' self.library_name = "microros" self.python_env = python_env - self.env = {} + self.env = None def run(self, meta, toolchain, user_meta = ""): if os.path.exists(self.library): @@ -84,68 +84,59 @@ def check_env(self): if (RMW_IMPLEMENTATION): os.environ['RMW_IMPLEMENTATION'] = "rmw_microxrcedds" - self.env = os.environ.copy() - def download_dev_environment(self): - os.makedirs(self.dev_src_folder, exist_ok=True) print("Downloading micro-ROS dev dependencies") - for repo in Sources.dev_environments[self.distro]: - repo.clone(self.dev_src_folder) - print("\t - Downloaded {}".format(repo.name)) - self.dev_packages.extend(repo.get_packages()) + self.dev_packages = Sources.dev_environments[self.distro] + for p in self.dev_packages: + p.clone(self.dev_src_folder) + print("\t - Downloaded {}".format(p.name)) def build_dev_environment(self): print("Building micro-ROS dev dependencies") - - # Fix build: Ignore rmw_test_fixture_implementation in rolling - touch_command = '' - if self.distro in ('rolling', 'kilted'): - touch_command = 'touch src/ament_cmake_ros/rmw_test_fixture_implementation/COLCON_IGNORE && ' - - command = "cd {} && {} . {} && colcon build --cmake-args -DBUILD_TESTING=OFF -DPython3_EXECUTABLE=`which python`".format(self.dev_folder, touch_command, self.python_env) - result = run_cmd(command, env=self.env) + self.patch_dev_sources() + + colcon_command = '. {} && colcon build --merge-install --packages-ignore-regex=.*_cpp --cmake-args -DPython3_EXECUTABLE=`which python` -DBUILD_TESTING=OFF'.format(self.python_env) + command = "cd {} && {}".format(self.dev_folder, colcon_command) + result = run_cmd(command) if 0 != result.returncode: - print("Build dev micro-ROS environment failed: \n {}".format(result.stderr.decode("utf-8"))) + print("Build dev micro-ROS environment failed: \n{}".format(result.stderr.decode("utf-8"))) sys.exit(1) def download_mcu_environment(self): - os.makedirs(self.mcu_src_folder, exist_ok=True) print("Downloading micro-ROS library") - for repo in Sources.mcu_environments[self.distro]: - repo.clone(self.mcu_src_folder) - self.mcu_packages.extend(repo.get_packages()) - for package in repo.get_packages(): - if package.name in Sources.ignore_packages[self.distro] or package.name.endswith("_cpp"): - package.ignore() - - print('\t - Downloaded {}{}'.format(package.name, " (ignored)" if package.ignored else "")) - - self.download_extra_packages() - - def download_extra_packages(self): - if not os.path.exists(self.packages_folder): - print("\t - Extra packages folder not found, skipping...") - return - - print("Checking extra packages") + self.mcu_packages = Sources.mcu_environments[self.distro] + for p in self.mcu_packages: + p.clone(self.mcu_src_folder) + if p.name in Sources.ignore_packages[self.distro]: + p.ignore() + print("\t - Downloaded {} (ignored)".format(p.name)) + else: + print("\t - Downloaded {}".format(p.name)) # Load and clone repositories from extra_packages.repos file - extra_repos = self.get_repositories_from_yaml("{}/extra_packages.repos".format(self.packages_folder)) - for repo_name in extra_repos: - repo_values = extra_repos[repo_name] - version = repo_values['version'] if 'version' in repo_values else None - Repository(repo_name, repo_values['url'], self.distro, version).clone(self.mcu_src_folder) - print("\t - Downloaded {}".format(repo_name)) + if os.path.exists(self.packages_folder): + extra_repos = self.get_repositories_from_yaml("{}/extra_packages.repos".format(self.packages_folder)) + for repo_name in extra_repos: + repo_values = extra_repos[repo_name] + version = repo_values['version'] if 'version' in repo_values else None + Repository(repo_name, repo_values['url'], self.distro, version).clone(self.mcu_src_folder) + print("\t - Downloaded {}".format(repo_name)) + + extra_folders = os.listdir(self.packages_folder) + if 'extra_packages.repos' in extra_folders: + extra_folders.remove('extra_packages.repos') - extra_folders = os.listdir(self.packages_folder) - if 'extra_packages.repos' in extra_folders: - extra_folders.remove('extra_packages.repos') + for folder in extra_folders: + print("\t - Adding {}".format(folder)) - for folder in extra_folders: - print("\t - Adding {}".format(folder)) + shutil.copytree(self.packages_folder, self.mcu_src_folder, ignore=shutil.ignore_patterns('extra_packages.repos'), dirs_exist_ok=True) - shutil.copytree(self.packages_folder, self.mcu_src_folder, ignore=shutil.ignore_patterns('extra_packages.repos'), dirs_exist_ok=True) + # Apply COLCON_IGNORE for ignored packages + for root, dirs, files in os.walk(self.mcu_src_folder): + if os.path.basename(root) in Sources.ignore_packages.get(self.distro, []): + with open(os.path.join(root, "COLCON_IGNORE"), "w") as f: + pass def get_repositories_from_yaml(self, yaml_file): repos = {} @@ -166,13 +157,14 @@ def get_repositories_from_yaml(self, yaml_file): except KeyError as e: continue repos[path] = repo - except (yaml.YAMLError, KeyError, TypeError) as e: - print("Error on {}: {}".format(yaml_file, e)) - finally: - return repos + except (yaml.YAMLError, KeyError, TypeError, FileNotFoundError) as e: + pass + return repos def build_mcu_environment(self, meta_file, toolchain_file, user_meta = ""): print("Building micro-ROS library") + if self.distro in ("lyrical", "rolling"): + self.patch_mcu_sources() common_meta_path = self.library_folder + '/metas/common.meta' colcon_command = '. {} && colcon build --merge-install --packages-ignore-regex=.*_cpp --metas {} {} {} --cmake-args -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=OFF -DTHIRDPARTY=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE={} -DPython3_EXECUTABLE=`which python`'.format(self.python_env, common_meta_path, meta_file, user_meta, toolchain_file) @@ -213,13 +205,48 @@ def package_mcu_library(self): # Copy includes shutil.copytree(self.build_folder + "/mcu/install/include", self.includes) - # Fix include paths + if self.distro in ("lyrical", "rolling"): + timer_h = os.path.join(self.includes, "rclc", "timer.h") + if os.path.exists(timer_h): + with open(timer_h, "r") as f_t: + ct = f_t.read() + if "rclc_timer_init_default2" not in ct: + decl = """ +/** + * Initializes a rcl timer with default clock. + * + * \\param[inout] timer a preallocated rcl_timer_t + * \\param[in] support the rclc_support_t object + * \\param[in] timeout_ns the time out in nanoseconds of the timer + * \\param[in] callback the callback of the timer + * \\return `RCL_RET_OK` if the timer was successfully initialized + * \\return `RCL_RET_INVALID_ARGUMENT` if any null pointer as argument + * \\return `RCL_RET_ERROR` in case of other error + */ +RCLC_PUBLIC +rcl_ret_t +rclc_timer_init_default( + rcl_timer_t * timer, + rclc_support_t * support, + const uint64_t timeout_ns, + const rcl_timer_callback_t callback); +""" + decl_compat = """ +#define rclc_timer_init_default(timer, support, timeout_ns, callback) \\ + rclc_timer_init_default2(timer, support, timeout_ns, (rcl_timer_callback_t)(callback), true) + +#define rclc_timer_init_default2(timer, support, timeout_ns, callback, autostart) \\ + rcl_timer_init2(timer, &(support)->clock, &(support)->context, timeout_ns, (rcl_timer_callback_t)(callback), *(support)->allocator, autostart) +""" + ct = ct.replace(decl, decl_compat) + with open(timer_h, "w") as f_t: + f_t.write(ct) + + # Fix include paths for repeated nested folders include_folders = os.listdir(self.includes) - for folder in include_folders: folder_path = self.includes + "/{}".format(folder) repeated_path = folder_path + "/{}".format(folder) - if os.path.exists(repeated_path): shutil.copytree(repeated_path, folder_path, copy_function=shutil.move, dirs_exist_ok=True) shutil.rmtree(repeated_path) @@ -229,9 +256,207 @@ def resolve_binutils_path(self): homebrew_binutils_path = "/opt/homebrew/opt/binutils/bin/" if os.path.exists(homebrew_binutils_path): return homebrew_binutils_path - print("ERROR: GNU binutils not found. ({}) Please install binutils with homebrew: brew install binutils" .format(homebrew_binutils_path)) sys.exit(1) + path = os.getenv('PATH', '') + for p in path.split(':'): + if p.endswith('arm-none-eabi/bin'): + return p + "/" return "" + + def patch_dev_sources(self): + # 1. Ignore test packages in dev sources + for p in ["rmw_test_fixture", "rmw_test_fixture_implementation", "domain_coordinator"]: + p_dir = os.path.join(self.dev_src_folder, "ament_cmake_ros", p) + if os.path.exists(p_dir): + with open(os.path.join(p_dir, "COLCON_IGNORE"), "w") as f: + pass + + # 2. Relax C/C++ standards for embedded MCU cross-compilers (e.g. GCC 7.2.1 on Portenta) + defaults_cmake = os.path.join(self.dev_src_folder, "ament_cmake_ros", "ament_cmake_ros_core", "cmake", "ament_ros_defaults.cmake") + if os.path.exists(defaults_cmake): + with open(defaults_cmake, "r") as f: + dc = f.read() + dc = dc.replace("cxx_std_20", "cxx_std_17").replace("c_std_17", "c_std_11") + with open(defaults_cmake, "w") as f: + f.write(dc) + + all_cmake = os.path.join(self.dev_src_folder, "ament_cmake", "ament_cmake_core", "cmake", "core", "all.cmake") + if os.path.exists(all_cmake): + with open(all_cmake, "r") as f: + ac = f.read() + if "macro(ament_target_dependencies" not in ac: + macro_def = """ + +# Compatibility ament_target_dependencies macro for micro-ROS +macro(ament_target_dependencies target) + cmake_parse_arguments(_ARG "SYSTEM;INTERFACE;PUBLIC;PRIVATE" "" "" ${ARGN}) + set(_dependencies ${_ARG_UNPARSED_ARGUMENTS}) + foreach(_dep ${_dependencies}) + find_package(${_dep} QUIET) + if(TARGET ${_dep}) + if(_ARG_INTERFACE) + target_link_libraries(${target} INTERFACE ${_dep}) + elseif(_ARG_PUBLIC) + target_link_libraries(${target} PUBLIC ${_dep}) + else() + target_link_libraries(${target} PRIVATE ${_dep}) + endif() + elseif(TARGET ${_dep}::${_dep}) + if(_ARG_INTERFACE) + target_link_libraries(${target} INTERFACE ${_dep}::${_dep}) + elseif(_ARG_PUBLIC) + target_link_libraries(${target} PUBLIC ${_dep}::${_dep}) + else() + target_link_libraries(${target} PRIVATE ${_dep}::${_dep}) + endif() + endif() + if(${_dep}_INCLUDE_DIRS) + if(_ARG_INTERFACE) + target_include_directories(${target} INTERFACE ${${_dep}_INCLUDE_DIRS}) + elseif(_ARG_PUBLIC) + target_include_directories(${target} PUBLIC ${${_dep}_INCLUDE_DIRS}) + else() + target_include_directories(${target} PRIVATE ${${_dep}_INCLUDE_DIRS}) + endif() + endif() + if(${_dep}_LIBRARIES) + if(_ARG_INTERFACE) + target_link_libraries(${target} INTERFACE ${${_dep}_LIBRARIES}) + elseif(_ARG_PUBLIC) + target_link_libraries(${target} PUBLIC ${${_dep}_LIBRARIES}) + else() + target_link_libraries(${target} PRIVATE ${${_dep}_LIBRARIES}) + endif() + endif() + endforeach() +endmacro() +""" + with open(all_cmake, "a") as f: + f.write(macro_def) + + def patch_mcu_sources(self): + # 1. Patch rcutils base64.c for no thread support + base64_c = os.path.join(self.mcu_src_folder, "rcutils", "src", "base64.c") + if os.path.exists(base64_c): + with open(base64_c, "r") as f: + bc = f.read() + if "RCUTILS_NO_THREAD_SUPPORT" not in bc: + target1 = "#ifdef _WIN32\nstatic INIT_ONCE base64_map_initialization_once = INIT_ONCE_STATIC_INIT;" + rep1 = "#if defined(RCUTILS_NO_THREAD_SUPPORT)\nstatic bool base64_map_initialized = false;\n#elif defined(_WIN32)\nstatic INIT_ONCE base64_map_initialization_once = INIT_ONCE_STATIC_INIT;" + target2 = "#else\n pthread_once(&base64_map_initialization_once, initialize_base64_map);\n#endif" + rep2 = "#elif defined(RCUTILS_NO_THREAD_SUPPORT)\n if (!base64_map_initialized) { initialize_base64_map(); base64_map_initialized = true; }\n#else\n pthread_once(&base64_map_initialization_once, initialize_base64_map);\n#endif" + bc = bc.replace(target1, rep1).replace(target2, rep2) + with open(base64_c, "w") as f: + f.write(bc) + + # 2. Patch rosidl_buffer CMakeLists.txt and buffer.hpp + for b_dir in ["rosidl", "rosidl_core"]: + buffer_cmake = os.path.join(self.mcu_src_folder, b_dir, "rosidl_buffer", "CMakeLists.txt") + if os.path.exists(buffer_cmake): + with open(buffer_cmake, "r") as f: + bc = f.read() + bc_lines = [] + changed_cmake = False + for line in bc.splitlines(True): + if "target_link_libraries" in line and ("ament_cmake_ros_core::ament_ros_cxx_standard" in line or "ament_ros_cxx_standard" in line or "PRIVATE )" in line or "PRIVATE )" in line): + bc_lines.append("target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17)\n") + changed_cmake = True + else: + bc_lines.append(line) + if changed_cmake: + with open(buffer_cmake, "w") as f: + f.write("".join(bc_lines)) + + buffer_hpp = os.path.join(self.mcu_src_folder, b_dir, "rosidl_buffer", "include", "rosidl_buffer", "buffer.hpp") + if os.path.exists(buffer_hpp): + with open(buffer_hpp, "r") as f: + bh = f.read() + modified_bh = False + if "std::is_same_v" in bh: + bh = bh.replace("if constexpr (std::is_same_v>)", "if (std::is_same>::value)") + bh = bh.replace("std::is_same_v>", "std::is_same>::value") + modified_bh = True + if "__EXCEPTIONS" not in bh: + orig_throw1 = ' throw std::invalid_argument("Buffer implementation must not be null");' + patch_throw1 = '#if __EXCEPTIONS || defined(__cpp_exceptions)\n throw std::invalid_argument("Buffer implementation must not be null");\n#endif' + bh = bh.replace(orig_throw1, patch_throw1) + + orig_fn = """ void throw_if_not_cpu_backend() const + { + if (!cpu_impl_) { + throw std::runtime_error( + "Operation requires CPU backend. Current backend: " + + impl_->get_backend_type() + + ". Use to_vector() for explicit conversion to CPU."); + } + }""" + patch_fn = """ void throw_if_not_cpu_backend() const + { +#if __EXCEPTIONS || defined(__cpp_exceptions) + if (!cpu_impl_) { + throw std::runtime_error( + "Operation requires CPU backend. Current backend: " + + impl_->get_backend_type() + + ". Use to_vector() for explicit conversion to CPU."); + } +#endif + }""" + bh = bh.replace(orig_fn, patch_fn) + modified_bh = True + if modified_bh: + with open(buffer_hpp, "w") as f: + f.write(bh) + + # 3. Patch rclc timer.c for rcl_timer_init2 + timer_c = os.path.join(self.mcu_src_folder, "rclc", "rclc", "src", "rclc", "timer.c") + if os.path.exists(timer_c): + with open(timer_c, "r") as f: + tc = f.read() + if "rcl_timer_init2" not in tc: + target_timer = """ rcl_ret_t rc = rcl_timer_init( + timer, + &support->clock, + &support->context, + timeout_ns, + callback, + (*support->allocator));""" + rep_timer = """ rcl_ret_t rc = rcl_timer_init2( + timer, + &support->clock, + &support->context, + timeout_ns, + callback, + (*support->allocator), + true);""" + tc = tc.replace(target_timer, rep_timer) + with open(timer_c, "w") as f: + f.write(tc) + + # 4. Patch rclc_lifecycle for rcl_lifecycle_state_machine_init clock parameter + lc_c = os.path.join(self.mcu_src_folder, "rclc", "rclc_lifecycle", "src", "rclc_lifecycle", "rclc_lifecycle.c") + if os.path.exists(lc_c): + with open(lc_c, "r") as f: + lcc = f.read() + if "lifecycle_clock" not in lcc: + target_lc = """ rcl_ret_t rcl_ret = rcl_lifecycle_state_machine_init( + state_machine, + node, + ROSIDL_GET_MSG_TYPE_SUPPORT(lifecycle_msgs, msg, TransitionEvent),""" + rep_lc = """ static rcl_clock_t lifecycle_clock; + static bool lifecycle_clock_initialized = false; + if (!lifecycle_clock_initialized) { + rcl_ros_clock_init(&lifecycle_clock, allocator); + lifecycle_clock_initialized = true; + } + + rcl_ret_t rcl_ret = rcl_lifecycle_state_machine_init( + state_machine, + node, + &lifecycle_clock, + ROSIDL_GET_MSG_TYPE_SUPPORT(lifecycle_msgs, msg, TransitionEvent),""" + lcc = "#include \n" + lcc.replace(target_lc, rep_lc) + with open(lc_c, "w") as f: + f.write(lcc) diff --git a/microros_utils/repositories.py b/microros_utils/repositories.py index bb7b0ac4..760f1216 100644 --- a/microros_utils/repositories.py +++ b/microros_utils/repositories.py @@ -107,6 +107,14 @@ class Sources: Repository("ament_cmake_ros", "https://github.com/ros2/ament_cmake_ros", "kilted"), Repository("ament_index", "https://github.com/ament/ament_index", "kilted") ], + 'lyrical': [ + Repository("ament_cmake", "https://github.com/ament/ament_cmake", "lyrical"), + Repository("ament_lint", "https://github.com/ament/ament_lint", "lyrical"), + Repository("ament_package", "https://github.com/ament/ament_package", "lyrical"), + Repository("googletest", "https://github.com/ament/googletest", "lyrical"), + Repository("ament_cmake_ros", "https://github.com/ros2/ament_cmake_ros", "lyrical"), + Repository("ament_index", "https://github.com/ament/ament_index", "lyrical") + ], 'rolling': [ Repository("ament_cmake", "https://github.com/ament/ament_cmake", "rolling"), Repository("ament_lint", "https://github.com/ament/ament_lint", "rolling"), @@ -212,6 +220,30 @@ class Sources: Repository("rcl_logging", "https://github.com/ros2/rcl_logging", "kilted"), Repository("ros2_tracing", "https://github.com/ros2/ros2_tracing", "kilted"), ], + 'lyrical': [ + Repository("micro-CDR", "https://github.com/eProsima/micro-CDR", "lyrical", "ros2"), + Repository("Micro-XRCE-DDS-Client", "https://github.com/eProsima/Micro-XRCE-DDS-Client", "lyrical", "ros2"), + Repository("rcl", "https://github.com/micro-ROS/rcl", "lyrical"), + Repository("rclc", "https://github.com/ros2/rclc", "lyrical", "master"), + Repository("micro_ros_utilities", "https://github.com/micro-ROS/micro_ros_utilities", "lyrical", "rolling"), + Repository("rcutils", "https://github.com/micro-ROS/rcutils", "lyrical"), + Repository("micro_ros_msgs", "https://github.com/micro-ROS/micro_ros_msgs", "lyrical", "rolling"), + Repository("rmw-microxrcedds", "https://github.com/micro-ROS/rmw-microxrcedds", "lyrical", "rolling"), + Repository("rosidl_typesupport", "https://github.com/micro-ROS/rosidl_typesupport", "lyrical"), + Repository("rosidl_typesupport_microxrcedds", "https://github.com/micro-ROS/rosidl_typesupport_microxrcedds", "lyrical", "rolling"), + Repository("rosidl", "https://github.com/ros2/rosidl", "lyrical"), + Repository("rosidl_dynamic_typesupport", "https://github.com/ros2/rosidl_dynamic_typesupport", "lyrical"), + Repository("rosidl_core", "https://github.com/ros2/rosidl_core", "lyrical"), + Repository("rmw", "https://github.com/ros2/rmw", "lyrical"), + Repository("rcl_interfaces", "https://github.com/ros2/rcl_interfaces", "lyrical"), + Repository("rosidl_defaults", "https://github.com/ros2/rosidl_defaults", "lyrical"), + Repository("unique_identifier_msgs", "https://github.com/ros2/unique_identifier_msgs", "lyrical"), + Repository("common_interfaces", "https://github.com/ros2/common_interfaces", "lyrical"), + Repository("test_interface_files", "https://github.com/ros2/test_interface_files", "lyrical"), + Repository("rmw_implementation", "https://github.com/ros2/rmw_implementation", "lyrical"), + Repository("rcl_logging", "https://github.com/ros2/rcl_logging", "lyrical"), + Repository("ros2_tracing", "https://github.com/ros2/ros2_tracing", "lyrical"), + ], 'rolling': [ Repository("micro-CDR", "https://github.com/eProsima/micro-CDR", "rolling", "ros2"), Repository("Micro-XRCE-DDS-Client", "https://github.com/eProsima/Micro-XRCE-DDS-Client", "rolling", "ros2"), @@ -243,5 +275,6 @@ class Sources: 'iron': ['test_tracetools', 'rcl_logging_spdlog', 'rcl_yaml_param_parser', 'rclc_examples'], 'jazzy': ['test_tracetools', 'rcl_logging_spdlog', 'rcl_yaml_param_parser', 'rclc_examples', 'lttngpy'], 'kilted': ['test_tracetools', 'rcl_logging_spdlog', 'rcl_yaml_param_parser', 'rclc_examples', 'lttngpy', 'rmw_security_common'], - 'rolling': ['test_tracetools', 'rcl_logging_spdlog', 'rcl_yaml_param_parser', 'rclc_examples', 'lttngpy', 'rmw_security_common'] + 'lyrical': ['test_tracetools', 'rcl_logging_spdlog', 'rcl_logging_implementation', 'rcl_yaml_param_parser', 'rclc_examples', 'lttngpy', 'rmw_security_common', 'rosidl_buffer_py', 'test_rmw_implementation', 'rosidl_buffer_backend_registry'], + 'rolling': ['test_tracetools', 'rcl_logging_spdlog', 'rcl_logging_implementation', 'rcl_yaml_param_parser', 'rclc_examples', 'lttngpy', 'rmw_security_common', 'rosidl_buffer_py', 'test_rmw_implementation', 'rosidl_buffer_backend_registry'] }