Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit

Permalink
Refactor C and C++ typesupport (#18)
Browse files Browse the repository at this point in the history
* Switch C++ type support generation pipeline.

* Adds outer C++ IDL templates.

* Adapts C++ msg & srv header templates.

* Adapts C++ msg & srv source templates.

* Switch C type support generation pipeline.

* Adds outer C IDL templates.

* Adapts C msg & srv header templates.

* Adapts C msg source template.

* Adapts C msg & srv source templates.

* Adds missing Python imports in templates.

* Converts IDL files to RTI Connext IDL files.

* Fixing typesupport generation issues.

* Uses rosidl_dds again for IDL2IDL conversion.

* Applies many fixes to C & C++ typesupport.

* Fixes for C++ srv templates.

* Many fixes to C & C++ type support.

* Yet more fixes to C & C++ type support.

* Fixes copyright dates.

* Adds back attribute to generated code constants.

* Adds missing type support for action messages.
  • Loading branch information
hidmic authored Dec 4, 2018
1 parent dab5a6b commit 61b804c
Show file tree
Hide file tree
Showing 20 changed files with 1,301 additions and 1,041 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@ def main(argv=sys.argv[1:]):
help='The location of the file containing the generator arguments')
args = parser.parse_args(argv)

generator_args = read_generator_arguments(args.generator_arguments_file)

try:
rc = generate_typesupport_connext_c(generator_args)
rc = generate_typesupport_connext_c(args.generator_arguments_file)
except UnknownMessageType as e:
print(str(e), file=sys.stderr)
return 1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2016 Open Source Robotics Foundation, Inc.
# Copyright 2016-2018 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -12,65 +12,31 @@
# See the License for the specific language governing permissions and
# limitations under the License.

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(_dds_idl_files "")
set(_dds_idl_base_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_dds_idl")
foreach(_idl_file ${rosidl_generate_interfaces_IDL_FILES})
get_filename_component(_extension "${_idl_file}" EXT)
if(_extension STREQUAL ".msg")
get_filename_component(_parent_folder "${_idl_file}" DIRECTORY)
get_filename_component(_parent_folder "${_parent_folder}" NAME)
get_filename_component(_name "${_idl_file}" NAME_WE)
list(APPEND _dds_idl_files
"${_dds_idl_base_path}/${PROJECT_NAME}/${_parent_folder}/dds_connext/${_name}_.idl")
endif()
endforeach()

set(_output_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_connext_c/${PROJECT_NAME}")
set(_dds_output_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_connext_cpp/${PROJECT_NAME}")
set(_dds_idl_base_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_dds_idl")

set(_dds_idl_files "")
set(_generated_files "")
set(_generated_external_files "")
foreach(_idl_file ${rosidl_generate_interfaces_IDL_FILES})
get_filename_component(_parent_folder "${_idl_file}" DIRECTORY)
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" _abs_idl_file "${_idl_tuple}")
get_filename_component(_parent_folder "${_abs_idl_file}" DIRECTORY)
get_filename_component(_parent_folder "${_parent_folder}" NAME)
get_filename_component(_extension "${_idl_file}" EXT)
get_filename_component(_msg_name "${_idl_file}" NAME_WE)
string_camel_case_to_lower_case_underscore("${_msg_name}" _header_name)
if(_extension STREQUAL ".msg" AND _msg_name MATCHES "Response$|Request$")
# Don't do anything
elseif(_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()
list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_msg_name}_.h")
list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_msg_name}_.cxx")
list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_msg_name}_Plugin.h")
list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_msg_name}_Plugin.cxx")
list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_msg_name}_Support.h")
list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_msg_name}_Support.cxx")
list(APPEND _generated_files "${_output_path}/${_parent_folder}/${_header_name}__rosidl_typesupport_connext_c.h")
list(APPEND _generated_files "${_output_path}/${_parent_folder}/dds_connext_c/${_header_name}__type_support_c.cpp")
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()
list(APPEND _generated_files "${_output_path}/${_parent_folder}/${_header_name}__rosidl_typesupport_connext_c.h")
list(APPEND _generated_files "${_output_path}/${_parent_folder}/dds_connext_c/${_header_name}__type_support_c.cpp")
list(APPEND _generated_files "${_output_path}/${_parent_folder}/dds_connext_c/${_header_name}__request__type_support_c.cpp")
list(APPEND _generated_files "${_output_path}/${_parent_folder}/dds_connext_c/${_header_name}__response__type_support_c.cpp")
else()
message(FATAL_ERROR "Interface file with unknown extension: ${_idl_file}")
endif()
get_filename_component(_idl_name "${_abs_idl_file}" NAME_WE)
# Turn idl name into file names
string_camel_case_to_lower_case_underscore("${_idl_name}" _header_name)
list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_idl_name}_.h")
list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_idl_name}_.cxx")
list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_idl_name}_Plugin.h")
list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_idl_name}_Plugin.cxx")
list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_idl_name}_Support.h")
list(APPEND _generated_external_files "${_dds_output_path}/${_parent_folder}/dds_connext/${_idl_name}_Support.cxx")
list(APPEND _generated_files "${_output_path}/${_parent_folder}/dds_connext/${_header_name}__type_support_c.cpp")
list(APPEND _generated_files "${_output_path}/${_parent_folder}/${_header_name}__rosidl_typesupport_connext_c.h")
list(APPEND _dds_idl_files "${_dds_idl_base_path}/${PROJECT_NAME}/${_parent_folder}/dds_connext/${_idl_name}_.idl")
endforeach()

# If not on Windows, disable some warnings with Connext's generated code
Expand Down Expand Up @@ -101,42 +67,37 @@ endif()
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")
get_filename_component(_parent_folder "${_idl_file}" DIRECTORY)
get_filename_component(_parent_folder "${_parent_folder}" NAME)
get_filename_component(_name "${_idl_file}" NAME_WE)
set(_abs_idl_file "${${_pkg_name}_DIR}/../${_parent_folder}/dds_connext/${_name}_.idl")
normalize_path(_abs_idl_file "${_abs_idl_file}")
list(APPEND _dependency_files "${_abs_idl_file}")
set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}")
normalize_path(_abs_idl_file "${_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()

set(target_dependencies
"${rosidl_typesupport_connext_c_BIN}"
${rosidl_typesupport_connext_c_GENERATOR_FILES}
"${rosidl_typesupport_connext_c_TEMPLATE_DIR}/idl__rosidl_typesupport_connext_c.h.em"
"${rosidl_typesupport_connext_c_TEMPLATE_DIR}/idl__dds_connext__type_support_c.cpp.em"
"${rosidl_typesupport_connext_c_TEMPLATE_DIR}/msg__rosidl_typesupport_connext_c.h.em"
"${rosidl_typesupport_connext_c_TEMPLATE_DIR}/msg__type_support_c.cpp.em"
"${rosidl_typesupport_connext_c_TEMPLATE_DIR}/srv__rosidl_typesupport_connext_c.h.em"
"${rosidl_typesupport_connext_c_TEMPLATE_DIR}/srv__type_support_c.cpp.em"
${_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()
endif()
endforeach()

set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_connext_c__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_connext_c_TEMPLATE_DIR}"
Expand All @@ -150,7 +111,7 @@ add_custom_command(
--generator-arguments-file "${generator_arguments_file}"
DEPENDS
${target_dependencies}
${generated_external_files}
${_generated_external_files}
${_dds_idl_files}
COMMENT "Generating C type support for RTI Connext"
VERBATIM
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// generated from rosidl_typesupport_connext_c/resource/idl__dds_connext__type_support_c.cpp.em
// with input from @(package_name):@(interface_path)
// generated code does not contain a copyright notice

@{
#######################################################################
# EmPy template for generating <idl>__type_support_c.cpp 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_c.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_c.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(
'msg__type_support_c.cpp.em',
package_name=package_name, interface_path=interface_path,
service=action.goal_request,
include_directives=include_directives
)
TEMPLATE(
'srv__type_support_c.cpp.em',
package_name=package_name, interface_path=interface_path,
service=action.goal_service,
include_directives=include_directives
)
TEMPLATE(
'msg__type_support_c.cpp.em',
package_name=package_name, interface_path=interface_path,
service=action.result_response,
include_directives=include_directives
)
TEMPLATE(
'srv__type_support_c.cpp.em',
package_name=package_name, interface_path=interface_path,
service=action.result_service,
include_directives=include_directives
)
TEMPLATE(
'msg__type_support_c.cpp.em',
package_name=package_name, interface_path=interface_path,
message=action.feedback,
include_directives=include_directives
)
TEMPLATE(
'msg__type_support_c.cpp.em',
package_name=package_name, interface_path=interface_path,
message=action.feedback_message,
include_directives=include_directives
)
}@
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// generated from rosidl_typesupport_connext_c/resource/idl__rosidl_typesupport_connext_c.h.em
// with input from @(package_name):@(interface_path)
// generated code does not contain a copyright notice

@{
#######################################################################
# EmPy template for generating <idl>__rosidl_typesupport_connext_c.h 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)
#######################################################################
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
include_parts = [package_name] + list(interface_path.parents[0].parts) + \
[convert_camel_case_to_lower_case_underscore(interface_path.stem)]
header_guard_variable = '__'.join([x.upper() for x in include_parts]) + \
'__ROSIDL_TYPESUPPORT_CONNEXT_C_H_'
include_directives = set()
}@

#ifndef @(header_guard_variable)
#define @(header_guard_variable)

@{
#######################################################################
# Handle message
#######################################################################
from rosidl_parser.definition import Message
for message in content.get_elements_of_type(Message):
TEMPLATE(
'msg__rosidl_typesupport_connext_c.h.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__rosidl_typesupport_connext_c.h.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__rosidl_typesupport_connext_c.h.em',
package_name=package_name, interface_path=interface_path, service=action.goal_service,
include_directives=include_directives
)
TEMPLATE(
'srv__rosidl_typesupport_connext_c.h.em',
package_name=package_name, interface_path=interface_path, service=action.result_service,
include_directives=include_directives
)
TEMPLATE(
'msg__rosidl_typesupport_connext_c.h.em',
package_name=package_name, interface_path=interface_path, message=action.feedback_message,
include_directives=include_directives
)
}@

#endif // @(header_guard_variable)
Original file line number Diff line number Diff line change
@@ -1,45 +1,36 @@
// generated from
// rosidl_typesupport_connext_c/resource/msg__rosidl_typesupport_connext_c.h.em
// generated code does not contain a copyright notice
@# Included from rosidl_typesupport_connext_c/resource/idl__rosidl_typesupport_connext_c.h.em

@#######################################################################
@# EmPy template for generating
@# <msg>__rosidl_typesupport_connext_c.h 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)
@#######################################################################
@
@{
header_guard_parts = [
spec.base_type.pkg_name, subfolder,
get_header_filename_from_msg_name(spec.base_type.type) + '__rosidl_typesupport_connext_c_h']
header_guard_variable = '__'.join([x.upper() for x in header_guard_parts]) + '_'
header_files = [
'rosidl_generator_c/message_type_support_struct.h',
'rosidl_typesupport_interface/macros.h',
package_name + '/msg/rosidl_typesupport_connext_c__visibility_control.h'
]
}@
#ifndef @(header_guard_variable)
#define @(header_guard_variable)

#include "rosidl_generator_c/message_type_support_struct.h"
#include "rosidl_typesupport_interface/macros.h"

#include "@(spec.base_type.pkg_name)/msg/rosidl_typesupport_connext_c__visibility_control.h"
@[for header_file in header_files]@
@[ if header_file in include_directives]@
// already included above
// @
@[ else]@
@{include_directives.add(header_file)}@
@[ end if]@
#include "@(header_file)"
@[end for]@

#ifdef __cplusplus
extern "C"
{
#endif

ROSIDL_TYPESUPPORT_CONNEXT_C_PUBLIC_@(spec.base_type.pkg_name)
ROSIDL_TYPESUPPORT_CONNEXT_C_PUBLIC_@(package_name)
const rosidl_message_type_support_t *
ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_connext_c, @(spec.base_type.pkg_name), @(subfolder), @(spec.base_type.type))();
ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(
rosidl_typesupport_connext_c,
@(', '.join([package_name] + list(interface_path.parents[0].parts))),
@(message.structure.type.name))();


#ifdef __cplusplus
}
#endif

#endif // @(header_guard_variable)
Loading

0 comments on commit 61b804c

Please sign in to comment.