From 30329e5a9ce0352636293a303cc21b43a0b9e2fd Mon Sep 17 00:00:00 2001 From: James Prestwood Date: Wed, 19 Jun 2024 06:32:00 -0700 Subject: [PATCH] Create package whitelist from package.xml The prior mechanism to generate an ignore/include list was to use a static file at the workspace root. This doesn't play very well with our build system so instead use package.xml. Any package will now be included in the ros1_bridge build. This is done using a simple python script to parse package.xml which is then called by cmake (stdout of the script is the list). We then feed that list into a modified filter_packages() function that takes a list of include/ignore packages rather than using the static list. --- CMakeLists.txt | 19 +++++-- bin/ros1_bridge_generate_package_list | 16 ++++++ cmake/find_ignore_include_lists.cmake | 76 ++++++--------------------- 3 files changed, 49 insertions(+), 62 deletions(-) create mode 100755 bin/ros1_bridge_generate_package_list diff --git a/CMakeLists.txt b/CMakeLists.txt index 6829ed26..3f9e4b88 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,12 @@ cmake_minimum_required(VERSION 3.5) project(ros1_bridge) +execute_process( + COMMAND python3 bin/ros1_bridge_generate_package_list + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + OUTPUT_VARIABLE pkg_include_list +) + # Default to C++14 if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 14) @@ -56,7 +62,10 @@ find_package(xmlrpcpp REQUIRED) # find ROS 1 packages with messages / services include(cmake/find_ros1_interface_packages.cmake) find_ros1_interface_packages(ros1_message_packages) -filter_packages("ros1_message_packages") +filter_packages( + PKG_LIST "ros1_message_packages"} + INCLUDE ${pkg_include_list} +) set(prefixed_ros1_message_packages "") foreach(ros1_message_package ${ros1_message_packages}) @@ -141,7 +150,10 @@ list(APPEND generated_files "${generated_path}/get_mappings.cpp") # generate per interface compilation units to keep the memory usage low ament_index_get_resources(ros2_interface_packages "rosidl_interfaces") -filter_packages("ros2_interface_packages") +filter_packages( + PKG_LIST "ros2_interface_packages"} + INCLUDE ${pkg_include_list} +) # actionlib_msgs is deprecated, but we will quiet the warning until the bridge has support for # ROS actions: https://github.com/ros2/design/issues/195 @@ -170,6 +182,7 @@ endforeach() set(target_dependencies "bin/ros1_bridge_generate_factories" + "bin/ros1_bridge_generate_package_list" "resource/get_factory.cpp.em" "resource/get_mappings.cpp.em" "resource/interface_factories.cpp.em" @@ -184,7 +197,7 @@ add_custom_command( COMMAND Python3::Interpreter ARGS bin/ros1_bridge_generate_factories --output-path "${generated_path}" --template-dir resource - --pkg-includes '${BRIDGE_INCLUDE_PKGS}' + --pkg-includes '${pkg_include_list}' --pkg-ignores '${BRIDGE_IGNORE_PKGS}' DEPENDS ${target_dependencies} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/bin/ros1_bridge_generate_package_list b/bin/ros1_bridge_generate_package_list new file mode 100755 index 00000000..aa2b9a1d --- /dev/null +++ b/bin/ros1_bridge_generate_package_list @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 + +import sys +from catkin_pkg.package import parse_package + +def main(argv=sys.argv[1:]): + pkg = parse_package("package.xml") + packages = [] + + for depend in pkg["build_depends"]: + packages.append(depend.name) + + print(';'.join(packages), end='') + +if __name__ == '__main__': + sys.exit(main()) diff --git a/cmake/find_ignore_include_lists.cmake b/cmake/find_ignore_include_lists.cmake index 2a8010f7..210e1c04 100644 --- a/cmake/find_ignore_include_lists.cmake +++ b/cmake/find_ignore_include_lists.cmake @@ -1,68 +1,26 @@ -# Module/Package resp. message ignores and includes -# -# Finds lists of ROS modules/packages resp. messages that shall -# be included resp. ignored by the ROS bridge according to the -# following rules: -# - Include lists over ignore lists. I.e. if an include list is -# present, the ignore list will be ... well, ignored.) +function(filter_packages) + set(options "") + set(oneValueArgs PKG_LIST) + set(multiValueArgs INCLUDE IGNORE) -set(USE_PKG_IGNORE OFF) -set(USE_PKG_INCLUDE OFF) -set(USE_MSG_IGNORE OFF) -set(USE_MSG_INCLUDE OFF) + cmake_parse_arguments(FILTER_PACKAGES "${options}" + "${oneValueArgs}" "${multiValueArgs}", "${ARGN}") -set(BRIDGE_IGNORE_PKGS "") -set(BRIDGE_IGNORE_MSGS "") -set(BRIDGE_INCLUDE_PKGS "") -set(BRIDGE_INCLUDE_MSGS "") - -# File with packages to ignore/include in ROS 1 Bridge -set(BRIDGE_PACKAGE_IGNORE "${CMAKE_SOURCE_DIR}/../../../BridgePackageIgnore.List") -set(BRIDGE_PACKAGE_INCLUDE "${CMAKE_SOURCE_DIR}/../../../BridgePackageInclude.List") - -# File with messages to ignore/include in ROS 1 Bridge -set(BRIDGE_MSG_IGNORE "${CMAKE_SOURCE_DIR}/../../../BridgePackageIgnore.List") -set(BRIDGE_MSG_INCLUDE "${CMAKE_SOURCE_DIR}/../../../BridgePackageInclude.List") - -if(EXISTS "${BRIDGE_PACKAGE_INCLUDE}") - set(USE_PKG_INCLUDE ON) -else() # EXISTS "${BRIDGE_PACKAGE_INCLUDE}" - if(EXISTS "${BRIDGE_PACKAGE_IGNORE}") - set(USE_PKG_IGNORE ON) - endif() # EXISTS "${BRIDGE_PACKAGE_IGNORE}" -endif() # EXISTS "${BRIDGE_PACKAGE_INCLUDE}" - -if(${USE_PKG_INCLUDE}) - FILE(READ "${BRIDGE_PACKAGE_INCLUDE}" BRIDGE_INCLUDE_PKGS) - STRING(REGEX REPLACE ";" "\\\\;" BRIDGE_INCLUDE_PKGS "${BRIDGE_INCLUDE_PKGS}") - STRING(REGEX REPLACE "\n" ";" BRIDGE_INCLUDE_PKGS "${BRIDGE_INCLUDE_PKGS}") - list(REMOVE_DUPLICATES BRIDGE_INCLUDE_PKGS) - message(STATUS "Found package include list, including: ${BRIDGE_INCLUDE_PKGS}") -endif() # USE_PKG_INCLUDE - -if(${USE_PKG_IGNORE}) - FILE(READ "${BRIDGE_PACKAGE_IGNORE}" BRIDGE_IGNORE_PKGS) - STRING(REGEX REPLACE ";" "\\\\;" BRIDGE_IGNORE_PKGS "${BRIDGE_IGNORE_PKGS}") - STRING(REGEX REPLACE "\n" ";" BRIDGE_IGNORE_PKGS "${BRIDGE_IGNORE_PKGS}") - list(REMOVE_DUPLICATES BRIDGE_IGNORE_PKGS) - message(STATUS "Found package ignore list, ignoring: ${BRIDGE_IGNORE_PKGS}") -endif() # USE_PKG_IGNORE - -function(filter_packages pkg_list) - set(ros2_packages ${${pkg_list}}) - if(BRIDGE_INCLUDE_PKGS) + set(ros2_packages ${${FILTER_PACKAGES_PKG_LIST}}) + cmake_print_variables(ros2_packages) + if(FILTER_PACKAGES_INCLUDE) foreach(pkg ${ros2_packages}) - if(NOT ${pkg} IN_LIST BRIDGE_INCLUDE_PKGS) + if(NOT ${pkg} IN_LIST FILTER_PACKAGES_INCLUDE) list(REMOVE_ITEM ros2_packages ${pkg}) - endif(NOT ${pkg} IN_LIST BRIDGE_INCLUDE_PKGS) + endif(NOT ${pkg} IN_LIST FILTER_PACKAGES_INCLUDE) endforeach() - elseif(BRIDGE_IGNORE_PKGS) + elseif(FILTER_PACKAGES_IGNORE) foreach(pkg ${ros2_packages}) - if(${pkg} IN_LIST BRIDGE_IGNORE_PKGS) + if(${pkg} IN_LIST FILTER_PACKAGES_IGNORE) list(REMOVE_ITEM ros2_packages ${pkg}) - endif(${pkg} IN_LIST BRIDGE_IGNORE_PKGS) + endif(${pkg} IN_LIST FILTER_PACKAGES_IGNORE) endforeach() - endif(BRIDGE_INCLUDE_PKGS) - - set(${pkg_list} "${ros2_packages}" PARENT_SCOPE) + endif(FILTER_PACKAGES_INCLUDE) + + set(${FILTER_PACKAGES_PKG_LIST} "${ros2_packages}" PARENT_SCOPE) endfunction(filter_packages ros2_packages)