Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start porting rosidl_typesupport_fastrtps_cpp to new IDL pipeline #15

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@
import argparse
import sys

from rosidl_cmake import extract_message_types
from rosidl_cmake import read_generator_arguments
from rosidl_parser import UnknownMessageType
from rosidl_typesupport_fastrtps_cpp import generate_cpp
from rosidl_typesupport_fastrtps_cpp import generate_dds_fastrtps_cpp
from rosidl_typesupport_fastrtps_cpp import parse_ros_interface_files


def main(argv=sys.argv[1:]):
Expand All @@ -19,42 +15,13 @@ def main(argv=sys.argv[1:]):
'--generator-arguments-file',
required=True,
help='The location of the file containing the generator arguments')
parser.add_argument(
'--dds-interface-base-path',
required=True,
help='The base location of the DDS interface files')
parser.add_argument(
'--idl-pp',
required=True,
help='The location of the IDL preprocessor')
args = parser.parse_args(argv)

generator_args = read_generator_arguments(args.generator_arguments_file)

message_specs, service_specs = parse_ros_interface_files(
generator_args['package_name'], generator_args['ros_interface_files'])

known_msg_types = extract_message_types(
generator_args['package_name'], generator_args['ros_interface_files'],
generator_args.get('ros_interface_dependencies', []))

try:
rc = generate_cpp(generator_args, message_specs, service_specs, known_msg_types)
return generate_cpp(args.generator_arguments_file)
except UnknownMessageType as e:
print(str(e), file=sys.stderr)
return 1
if rc:
return rc
return generate_dds_fastrtps_cpp(
generator_args['package_name'],
generator_args.get('additional_files', []),
args.dds_interface_base_path,
generator_args.get('ros_interface_dependencies', []),
generator_args['output_dir'],
args.idl_pp,
message_specs,
service_specs,
)


if __name__ == '__main__':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,57 +17,45 @@ find_package(fastcdr REQUIRED CONFIG)
find_package(fastrtps REQUIRED CONFIG)
find_package(FastRTPS REQUIRED MODULE)

set(_ros_idl_files "")
foreach(_idl_file ${rosidl_generate_interfaces_IDL_FILES})
get_filename_component(_extension "${_idl_file}" EXT)
# Skip .srv files
if(_extension STREQUAL ".msg")
list(APPEND _ros_idl_files "${_idl_file}")
endif()
endforeach()

set(_output_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_fastrtps_cpp/${PROJECT_NAME}")
set(_generated_files "")
foreach(_idl_file ${rosidl_generate_interfaces_IDL_FILES})
get_filename_component(_extension "${_idl_file}" EXT)
get_filename_component(_parent_folder "${_idl_file}" DIRECTORY)

# Create a list of files that will be generated from each IDL file
set(_generated_sources "")
foreach(_idl_tuple ${rosidl_generate_interfaces_IDL_TUPLES})
# Get second part of tuple which has form "msg/Name.idl" or "srv/Name.idl" or "action/Name.idl"
string(REGEX REPLACE ":([^:]*)$" "/\\1" _rel_idl_file "${_idl_tuple}")
get_filename_component(_parent_folder "${_rel_idl_file}" DIRECTORY)
get_filename_component(_parent_folder "${_parent_folder}" NAME)
get_filename_component(_msg_name "${_idl_file}" NAME_WE)
string_camel_case_to_lower_case_underscore("${_msg_name}" _header_name)
if(_extension STREQUAL ".msg")
set(_allowed_parent_folders "msg" "srv" "action")
if(NOT _parent_folder IN_LIST _allowed_parent_folders)
message(FATAL_ERROR "Interface file with unknown parent folder: ${_idl_file}")
endif()
elseif(_extension STREQUAL ".srv")
set(_allowed_parent_folders "srv" "action")
if(NOT _parent_folder IN_LIST _allowed_parent_folders)
message(FATAL_ERROR "Interface file with unknown parent folder: ${_idl_file}")
endif()
else()
message(FATAL_ERROR "Interface file with unknown extension: ${_idl_file}")
endif()
list(APPEND _generated_files "${_output_path}/${_parent_folder}/${_header_name}__rosidl_typesupport_fastrtps_cpp.hpp")
list(APPEND _generated_files "${_output_path}/${_parent_folder}/dds_fastrtps/${_header_name}__type_support.cpp")
get_filename_component(_idl_name "${_rel_idl_file}" NAME_WE)
# Turn idl name into file names
string_camel_case_to_lower_case_underscore("${_idl_name}" _header_name)
list(APPEND _generated_sources
"${_output_path}/${_parent_folder}/dds_fastrtps/${_header_name}__type_support.cpp"
"${_output_path}/${_parent_folder}/${_header_name}__rosidl_typesupport_fastrtps_cpp.hpp"
)
endforeach()

# Create a list of IDL files from other packages that this generator should depend on
set(_dependency_files "")
set(_dependencies "")
foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
foreach(_idl_file ${${_pkg_name}_INTERFACE_FILES})
get_filename_component(_extension "${_idl_file}" EXT)
if(_extension STREQUAL ".msg")
set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}")
normalize_path(_abs_idl_file "${_abs_idl_file}")
list(APPEND _dependency_files "${_abs_idl_file}")
list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}")
endif()
foreach(_idl_file ${${_pkg_name}_IDL_FILES})
# ${{_pkg_name}_DIR} is absolute path ending in 'share/<pkg_name>/cmake', so go back one
# directory for IDL files
set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}")
normalize_path(_abs_idl_file "${_abs_idl_file}")
list(APPEND _dependency_files "${_abs_idl_file}")
list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}")
endforeach()
endforeach()

# Create a list of templates and source files this generator uses, and check that they exist
set(target_dependencies
"${rosidl_typesupport_fastrtps_cpp_BIN}"
${rosidl_typesupport_fastrtps_cpp_GENERATOR_FILES}
"${rosidl_typesupport_fastrtps_cpp_TEMPLATE_DIR}/idl__rosidl_typesupport_fastrtps_cpp.hpp.em"
"${rosidl_typesupport_fastrtps_cpp_TEMPLATE_DIR}/idl__dds_fastrtps__type_support.cpp.em"
"${rosidl_typesupport_fastrtps_cpp_TEMPLATE_DIR}/msg__rosidl_typesupport_fastrtps_cpp.hpp.em"
"${rosidl_typesupport_fastrtps_cpp_TEMPLATE_DIR}/msg__type_support.cpp.em"
"${rosidl_typesupport_fastrtps_cpp_TEMPLATE_DIR}/srv__rosidl_typesupport_fastrtps_cpp.hpp.em"
Expand All @@ -76,31 +64,27 @@ set(target_dependencies
${_dependency_files})
foreach(dep ${target_dependencies})
if(NOT EXISTS "${dep}")
get_property(is_generated SOURCE "${dep}" PROPERTY GENERATED)
if(NOT ${_is_generated})
message(FATAL_ERROR "Target dependency '${dep}' does not exist")
endif()
message(FATAL_ERROR "Target dependency '${dep}' does not exist")
endif()
endforeach()

# Write all this to a file to work around command line length limitations on some platforms
set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_fastrtps_cpp__arguments.json")
rosidl_write_generator_arguments(
"${generator_arguments_file}"
PACKAGE_NAME "${PROJECT_NAME}"
ROS_INTERFACE_FILES "${rosidl_generate_interfaces_IDL_FILES}"
IDL_TUPLES "${rosidl_generate_interfaces_IDL_TUPLES}"
ROS_INTERFACE_DEPENDENCIES "${_dependencies}"
OUTPUT_DIR "${_output_path}"
TEMPLATE_DIR "${rosidl_typesupport_fastrtps_cpp_TEMPLATE_DIR}"
TARGET_DEPENDENCIES ${target_dependencies}
)

set(_idl_pp "")
# Add a command that invokes generator at build time
add_custom_command(
OUTPUT ${_generated_files}
OUTPUT ${_generated_sources}
COMMAND ${PYTHON_EXECUTABLE} ${rosidl_typesupport_fastrtps_cpp_BIN}
--generator-arguments-file "${generator_arguments_file}"
--dds-interface-base-path "${_dds_idl_base_path}"
--idl-pp "${_idl_pp}"
DEPENDS ${target_dependencies}
COMMENT "Generating C++ type support for eProsima Fast-RTPS"
VERBATIM
Expand All @@ -118,19 +102,27 @@ configure_file(

set(_target_suffix "__rosidl_typesupport_fastrtps_cpp")

# link_directories(${fastrtps_LIBRARY_DIRS})
# Create a library that builds the generated files
add_library(${rosidl_generate_interfaces_TARGET}${_target_suffix} SHARED
${_generated_files})
${_generated_sources})

# Change output library name if asked to
if(rosidl_generate_interfaces_LIBRARY_NAME)
set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix}
PROPERTIES OUTPUT_NAME "${rosidl_generate_interfaces_LIBRARY_NAME}${_target_suffix}")
endif()

# set C++ standard
set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix}
PROPERTIES CXX_STANDARD 14)

# Set flag for visibility macro
if(WIN32)
target_compile_definitions(${rosidl_generate_interfaces_TARGET}${_target_suffix}
PRIVATE "ROSIDL_TYPESUPPORT_FASTRTPS_CPP_BUILDING_DLL_${PROJECT_NAME}")
endif()

# Set compiler flags
if(NOT WIN32)
set(_target_compile_flags "-Wall -Wextra -Wpedantic")
else()
Expand All @@ -141,37 +133,49 @@ endif()
string(REPLACE ";" " " _target_compile_flags "${_target_compile_flags}")
set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix}
PROPERTIES COMPILE_FLAGS "${_target_compile_flags}")

# Include headers from other generators
target_include_directories(${rosidl_generate_interfaces_TARGET}${_target_suffix}
PUBLIC
${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_cpp
${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_fastrtps_cpp
)

ament_target_dependencies(${rosidl_generate_interfaces_TARGET}${_target_suffix}
"fastcdr"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding fastcdr here instead of the target_link_libraries below doesn't work since it changes the library link order. fastcdr must be linked after all the other libraries.

"fastrtps"
"rmw"
"rosidl_typesupport_fastrtps_cpp"
"rosidl_typesupport_interface")

# Depend on dependencies
foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
set(_msg_include_dir "${${_pkg_name}_DIR}/../../../include/${_pkg_name}/msg/dds_fastrtps")
set(_srv_include_dir "${${_pkg_name}_DIR}/../../../include/${_pkg_name}/srv/dds_fastrtps")
set(_action_include_dir "${${_pkg_name}_DIR}/../../../include/${_pkg_name}/action/dds_fastrtps")
normalize_path(_msg_include_dir "${_msg_include_dir}")
normalize_path(_srv_include_dir "${_srv_include_dir}")
normalize_path(_action_include_dir "${_action_include_dir}")
target_include_directories(${rosidl_generate_interfaces_TARGET}${_target_suffix}
PUBLIC
"${_msg_include_dir}"
"${_srv_include_dir}"
"${_action_include_dir}"
)
# TODO(sloretz) parent_folder/dds_fastrtps in template instead of here
# set(_msg_include_dir "${${_pkg_name}_DIR}/../../../include/${_pkg_name}/msg/dds_fastrtps")
# set(_srv_include_dir "${${_pkg_name}_DIR}/../../../include/${_pkg_name}/srv/dds_fastrtps")
# set(_action_include_dir "${${_pkg_name}_DIR}/../../../include/${_pkg_name}/action/dds_fastrtps")
# normalize_path(_msg_include_dir "${_msg_include_dir}")
# normalize_path(_srv_include_dir "${_srv_include_dir}")
# normalize_path(_action_include_dir "${_action_include_dir}")
# target_include_directories(${rosidl_generate_interfaces_TARGET}${_target_suffix}
# PUBLIC
# "${_msg_include_dir}"
# "${_srv_include_dir}"
# "${_action_include_dir}"
# )
ament_target_dependencies(${rosidl_generate_interfaces_TARGET}${_target_suffix}
${_pkg_name})
endforeach()
target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix} fastrtps fastcdr)

# target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix} fastrtps fastcdr)

# Make top level generation target depend on this library
add_dependencies(
${rosidl_generate_interfaces_TARGET}
${rosidl_generate_interfaces_TARGET}${_target_suffix}
)

# Make this library depend on target created by rosidl_generator_cpp
add_dependencies(
${rosidl_generate_interfaces_TARGET}${_target_suffix}
${rosidl_generate_interfaces_TARGET}__cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// generated from rosidl_typesupport_fastrtps_cpp/resource/idl__rosidl_typesupport_cpp.hpp.em
// generated code does not contain a copyright notice

@{
#######################################################################
# EmPy template for generating <idl>__rosidl_typesupport_cpp.hpp files
#
# Context:
# - package_name (string)
# - content (rosidl_parser.definition.IdlContent result of parsing IDL file)
# - interface_path (Path relative to the directory named after the package)
#######################################################################

include_directives = set()

#######################################################################
# Handle message
#######################################################################
from rosidl_parser.definition import Message
for message in content.get_elements_of_type(Message):
TEMPLATE(
'msg__type_support.cpp.em',
package_name=package_name, interface_path=interface_path, message=message,
include_directives=include_directives)

#######################################################################
# Handle service
#######################################################################
from rosidl_parser.definition import Service
for service in content.get_elements_of_type(Service):
TEMPLATE(
'srv__type_support.cpp.em',
package_name=package_name, interface_path=interface_path, service=service,
include_directives=include_directives)

#######################################################################
# Handle action
#######################################################################
from rosidl_parser.definition import Action
for action in content.get_elements_of_type(Action):
TEMPLATE(
'srv__type_support.cpp.em',
package_name=package_name, interface_path=interface_path, service=action.goal_service,
include_directives=include_directives)
TEMPLATE(
'srv__type_support.cpp.em',
package_name=package_name, interface_path=interface_path, service=action.result_service,
include_directives=include_directives)
TEMPLATE(
'msg__type_support.cpp.em',
package_name=package_name, interface_path=interface_path, message=action.feedback,
include_directives=include_directives)
}@
20 changes: 4 additions & 16 deletions rosidl_typesupport_fastrtps_cpp/resource/msg__type_support.cpp.em
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
// generated from rosidl_typesupport_fastrtps_cpp/resource/msg__type_support.cpp.em
// generated code does not contain a copyright notice

@#######################################################################
@# EmPy template for generating <msg>__type_support.cpp files
@#
@# Context:
@# - spec (rosidl_parser.MessageSpecification)
@# Parsed specification of the .msg file
@# - subfolder (string)
@# The subfolder / subnamespace of the message
@# Could be 'msg', 'srv' or 'action'
@# - get_header_filename_from_msg_name (function)
@#######################################################################
@
@# Included from rosidl_typesupport_fastrtps_cpp/resource/idl__dds_fastrtps__type_support.cpp.em


#include "@(spec.base_type.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.base_type.type))__rosidl_typesupport_fastrtps_cpp.hpp"

#include <limits>
Expand All @@ -29,7 +17,7 @@

// forward declaration of message dependencies and their conversion functions
@[for field in spec.fields]@
@[ if not field.type.is_primitive_type()]@
@[ if isinstance(field, rosidl_parser.NestedType)]@
namespace @(field.type.pkg_name)
{
namespace msg
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ if(NOT FastRTPS_FOUND)
else()
find_package(ament_cmake_core QUIET REQUIRED)
ament_register_extension(
"rosidl_generate_interfaces"
"rosidl_generate_idl_interfaces"
"rosidl_typesupport_fastrtps_cpp"
"rosidl_typesupport_fastrtps_cpp_generate_interfaces.cmake")

Expand Down
Loading