Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
29b44b7
Initial implementation
esteve Feb 2, 2018
cae8d54
Crystal and more (#3)
lelongg May 5, 2019
515b1dc
Build on Dashing+ (#24)
nnarain Aug 24, 2020
6d8826b
Fix array type generation. And append an '_' to field names that an r…
nnarain Nov 11, 2020
0e94f69
Build system refactor (#64)
jhdcs Nov 22, 2021
34b005d
Use the ament_cargo build type (#73)
nnmm Feb 18, 2022
c5738a6
Message generation refactoring (#80)
nnmm Mar 18, 2022
dc37b06
Enable Clippy in CI (#83)
nnmm Mar 21, 2022
4e0632e
Bump every package to version 0.2 (#100)
nnmm Apr 17, 2022
382873b
Add serde support to messages (#131)
nnmm Apr 29, 2022
e661367
Generate Cargo.toml of message crate with an EmPy template, not CMake…
nnmm May 2, 2022
42b81ff
Add build.rs to messages to automatically find the message libraries …
nnmm May 10, 2022
ac8793e
feat: obtain interface version from cmake variable (#191)
wep21 Jun 7, 2022
1867740
Added support for clients and services (#146)
esteve Jul 8, 2022
850fa48
Fix path handling in rosidl_generator_rs on Windows (#228)
nnmm Jul 15, 2022
8a87cac
Small bugfix for sequences of WStrings (#240)
nnmm Jul 31, 2022
7f5faa9
Add support for constants to message generation (#269)
nnmm Sep 30, 2022
b0128c4
Bump package versions to 0.3 (#274)
nnmm Oct 3, 2022
df75c19
Add TYPE_NAME constant to messages and make error fields public (#277)
nnmm Oct 5, 2022
58d8523
Version 0.3.1 (#285)
nnmm Oct 17, 2022
0db3a63
Remove libc dependencies (#284)
Tacha-S Oct 18, 2022
fdc19d3
Swapped usage of rosidl_cmake over to the new rosidl_pycommon. (#297)
maspe36 Apr 6, 2023
96322cd
add serde big array support (fixed #327) (#328)
fawdlstty Aug 22, 2023
76dde39
Version 0.4.0 (#343)
esteve Nov 7, 2023
227a6ff
Revert "Version 0.4.0 (#343)" (#344)
esteve Nov 7, 2023
90f3ab9
Version 0.4.0 (#346)
esteve Nov 7, 2023
7f888ff
Version 0.4.1 (#353)
esteve Nov 28, 2023
b122fea
Add wchar support (#349)
maspe36 Jan 9, 2024
40e6971
Allow ros2_rust to be built within a distro workspace
mxgrey Mar 12, 2024
c6dba8f
Declare rust_packages only when installing Rust IDL bindings (#380)
mxgrey Mar 20, 2024
f59d00d
Action message support (#417)
nwn Oct 26, 2024
0c683f5
Update vendored interface packages (#423)
nwn Nov 15, 2024
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
44 changes: 44 additions & 0 deletions rosidl_generator_rs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
cmake_minimum_required(VERSION 3.5)

project(rosidl_generator_rs)

find_package(ament_cmake REQUIRED)
find_package(ament_cmake_python REQUIRED)
find_package(rosidl_generator_c REQUIRED)
find_package(rosidl_typesupport_interface REQUIRED)
find_package(rosidl_typesupport_introspection_c REQUIRED)

if("$ENV{ROS_DISTRO}" STRLESS_EQUAL "humble")
find_package(rosidl_cmake REQUIRED)
ament_export_dependencies(rosidl_cmake)
endif()

ament_export_dependencies(rmw)
ament_export_dependencies(rosidl_generator_c)

ament_index_register_resource("rosidl_generator_packages")
ament_index_register_resource("rosidl_runtime_packages")

ament_python_install_package(${PROJECT_NAME})

ament_package(
CONFIG_EXTRAS
"rosidl_generator_rs-extras.cmake.in"
"cmake/register_rs.cmake"
)

install(DIRECTORY cmake
DESTINATION share/${PROJECT_NAME})
ament_register_extension(
"rosidl_generate_idl_interfaces"
"rosidl_generator_rs"
"${PROJECT_SOURCE_DIR}/cmake/rosidl_generator_rs_generate_interfaces.cmake")

install(
PROGRAMS bin/rosidl_generator_rs
DESTINATION lib/rosidl_generator_rs
)
install(
DIRECTORY cmake resource
DESTINATION share/${PROJECT_NAME}
)
43 changes: 43 additions & 0 deletions rosidl_generator_rs/bin/rosidl_generator_rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env python3

import argparse
import os
import sys

try:
from rosidl_generator_rs import generate_rs
except ImportError:
# modifying sys.path and importing the Rust package with the same
# name as this script does not work on Windows
rosidl_generator_rs_root = os.path.dirname(os.path.dirname(__file__))
rosidl_generator_rs_module = os.path.join(
rosidl_generator_rs_root, 'rosidl_generator_rs', '__init__.py')
if not os.path.exists(rosidl_generator_rs_module):
raise
from importlib.machinery import SourceFileLoader

loader = SourceFileLoader('rosidl_generator_rs', rosidl_generator_rs_module)
rosidl_generator_rs = loader.load_module()
generate_rs = rosidl_generator_rs.generate_rs


def main(argv=sys.argv[1:]):
parser = argparse.ArgumentParser(description='Generate the Rust ROS interfaces.')
parser.add_argument(
'--generator-arguments-file',
required=True,
help='The location of the file containing the generator arguments')
parser.add_argument(
'--typesupport-impls',
required=True,
help='All the available typesupport implementations')
args = parser.parse_args(argv)

return generate_rs(
args.generator_arguments_file,
args.typesupport_impls,
)


if __name__ == '__main__':
sys.exit(main())
40 changes: 40 additions & 0 deletions rosidl_generator_rs/cmake/custom_command.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2017 Esteve Fernandez <esteve@apache.org>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

add_custom_command(
OUTPUT
${_generated_common_rs_files}
${_generated_msg_rs_files}
${_generated_srv_rs_files}
${_generated_action_rs_files}
COMMAND ${PYTHON_EXECUTABLE} ${rosidl_generator_rs_BIN}
--generator-arguments-file "${generator_arguments_file}"
--typesupport-impls "${_typesupport_impls}"
DEPENDS ${target_dependencies}
COMMENT "Generating Rust code for ROS interfaces"
VERBATIM
)

if(TARGET ${rosidl_generate_interfaces_TARGET}${_target_suffix})
message(WARNING "Custom target ${rosidl_generate_interfaces_TARGET}${_target_suffix} already exists")
else()
add_custom_target(
${rosidl_generate_interfaces_TARGET}${_target_suffix} ALL
DEPENDS
${_generated_common_rs_files}
${_generated_msg_rs_files}
${_generated_srv_rs_files}
${_generated_action_rs_files}
)
endif()
30 changes: 30 additions & 0 deletions rosidl_generator_rs/cmake/register_rs.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2016-2017 Esteve Fernandez <esteve@apache.org>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

macro(rosidl_generator_rs_extras BIN GENERATOR_FILES TEMPLATE_DIR)
find_package(ament_cmake_core QUIET REQUIRED)
ament_register_extension(
"rosidl_generate_idl_interfaces"
"rosidl_generator_rs"
"rosidl_generator_rs_generate_interfaces.cmake")

normalize_path(BIN "${BIN}")
set(rosidl_generator_rs_BIN "${BIN}")

normalize_path(GENERATOR_FILES "${GENERATOR_FILES}")
set(rosidl_generator_rs_GENERATOR_FILES "${GENERATOR_FILES}")

normalize_path(TEMPLATE_DIR "${TEMPLATE_DIR}")
set(rosidl_generator_rs_TEMPLATE_DIR "${TEMPLATE_DIR}")
endmacro()
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# Copyright 2016-2017 Esteve Fernandez <esteve@apache.org>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

if(NOT WIN32)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-undefined,error")
endif()
endif()

set(_output_path
"${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_rs/${PROJECT_NAME}")
set(_generated_common_rs_files "")

set(_generated_msg_rs_files "")
set(_generated_srv_rs_files "")
set(_generated_action_rs_files "")

set(_has_msg FALSE)
set(_has_srv FALSE)
set(_has_action FALSE)

foreach(_idl_file ${rosidl_generate_interfaces_ABS_IDL_FILES})
get_filename_component(_parent_folder "${_idl_file}" DIRECTORY)
get_filename_component(_parent_folder "${_parent_folder}" NAME)
get_filename_component(_module_name "${_idl_file}" NAME_WE)

if(_parent_folder STREQUAL "msg")
set(_has_msg TRUE)
set(_idl_files ${_idl_files} ${_idl_file})
elseif(_parent_folder STREQUAL "srv")
set(_has_srv TRUE)
set(_idl_files ${_idl_files} ${_idl_file})
elseif(_parent_folder STREQUAL "action")
set(_has_action TRUE)
set(_idl_files ${_idl_files} ${_idl_file})
else()
message(FATAL_ERROR "Interface file with unknown parent folder: ${_idl_file}")
endif()
endforeach()

list(APPEND _generated_common_rs_files
"${_output_path}/rust/src/lib.rs"
"${_output_path}/rust/build.rs"
"${_output_path}/rust/Cargo.toml"
)

if(${_has_msg})
list(APPEND _generated_msg_rs_files
"${_output_path}/rust/src/msg.rs"
)
endif()

if(${_has_srv})
list(APPEND _generated_srv_rs_files
"${_output_path}/rust/src/srv.rs"
)
endif()

if(${_has_action})
list(APPEND _generated_action_rs_files
"${_output_path}/rust/src/action.rs"
)
endif()

set(_dependency_files "")
set(_dependencies "")
foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
foreach(_idl_file ${${_pkg_name}_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_generator_rs_BIN}"
${rosidl_generator_rs_GENERATOR_FILES}
"${rosidl_generator_rs_TEMPLATE_DIR}/action.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/msg_idiomatic.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/msg_rmw.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/msg.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/srv_idiomatic.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/srv_rmw.rs.em"
"${rosidl_generator_rs_TEMPLATE_DIR}/srv.rs.em"
${rosidl_generate_interfaces_ABS_IDL_FILES}
${_idl_files}
${_dependency_files})
foreach(dep ${target_dependencies})
if(NOT EXISTS "${dep}")
message(FATAL_ERROR "Target dependency '${dep}' does not exist")
endif()
endforeach()

set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/rosidl_generator_rs__arguments.json")
rosidl_write_generator_arguments(
"${generator_arguments_file}"
PACKAGE_NAME "${PROJECT_NAME}"
IDL_TUPLES "${rosidl_generate_interfaces_IDL_TUPLES}"
ROS_INTERFACE_FILES "${_idl_files}"
ROS_INTERFACE_DEPENDENCIES "${_dependencies}"
OUTPUT_DIR "${_output_path}"
TEMPLATE_DIR "${rosidl_generator_rs_TEMPLATE_DIR}"
TARGET_DEPENDENCIES ${target_dependencies}
)

file(READ ${generator_arguments_file} contents)
string(REPLACE "\n}"
",\n \"package_version\": \"${${PROJECT_NAME}_VERSION}\"\n}" contents ${contents})
file(WRITE ${generator_arguments_file} ${contents})

file(MAKE_DIRECTORY "${_output_path}")

set(_target_suffix "__rs")

# needed to avoid multiple calls to the Rust generator trick copied from
# https://github.com/ros2/rosidl/blob/master/rosidl_generator_py/cmake/rosidl_generator_py_generate_interfaces.cmake
set(_subdir "${CMAKE_CURRENT_BINARY_DIR}/${rosidl_generate_interfaces_TARGET}${_target_suffix}")
file(MAKE_DIRECTORY "${_subdir}")
file(READ "${rosidl_generator_rs_DIR}/custom_command.cmake" _custom_command)
file(WRITE "${_subdir}/CMakeLists.txt" "${_custom_command}")
add_subdirectory("${_subdir}" ${rosidl_generate_interfaces_TARGET}${_target_suffix})

add_dependencies(${rosidl_generate_interfaces_TARGET} ${rosidl_generate_interfaces_TARGET}${_target_suffix})

set_property(
SOURCE
${_generated_common_rs_files}
${_generated_msg_rs_files}
${_generated_srv_rs_files}
${_generated_action_rs_files}
PROPERTY GENERATED 1)

set(_rsext_suffix "__rsext")
if(NOT rosidl_generate_interfaces_SKIP_INSTALL)
ament_index_register_resource("rust_packages")
install(
DIRECTORY "${_output_path}/rust"
DESTINATION "share/${PROJECT_NAME}"
)
endif()

if(BUILD_TESTING AND rosidl_generate_interfaces_ADD_LINTER_TESTS)
if(
NOT _generated_msg_rs_files STREQUAL "" OR
NOT _generated_srv_rs_files STREQUAL "" OR
NOT _generated_action_rs_files STREQUAL ""
)
# TODO(esteve): add linters for Rust files
endif()
endif()
42 changes: 42 additions & 0 deletions rosidl_generator_rs/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>rosidl_generator_rs</name>
<version>0.4.1</version>
<description>Generate the ROS interfaces in Rust.</description>
<maintainer email="esteve@apache.org">Esteve Fernandez</maintainer>
<license>Apache License 2.0</license>
<author email="esteve@apache.org">Esteve Fernandez</author>

<buildtool_depend>ament_cmake</buildtool_depend>
<buildtool_depend>ros_environment</buildtool_depend>

<buildtool_depend>rosidl_runtime_rs</buildtool_depend>

<buildtool_export_depend>ament_cmake</buildtool_export_depend>
<buildtool_export_depend>ros_environment</buildtool_export_depend>
<buildtool_export_depend condition="humble >= $ROS_DISTRO">rosidl_cmake</buildtool_export_depend>
<buildtool_export_depend condition="$ROS_DISTRO > humble">rosidl_pycommon</buildtool_export_depend>
<buildtool_export_depend>rosidl_runtime_rs</buildtool_export_depend>
<buildtool_export_depend>rosidl_typesupport_c</buildtool_export_depend>
<buildtool_export_depend>rosidl_typesupport_interface</buildtool_export_depend>

<!-- This is needed for the rosidl_message_type_support_t struct and visibility macros -->
<build_export_depend>rosidl_generator_c</build_export_depend>

<exec_depend>rosidl_parser</exec_depend>

<test_depend>ament_cmake_gtest</test_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<test_depend condition="humble >= $ROS_DISTRO">rosidl_cmake</test_depend>
<test_depend condition="$ROS_DISTRO > humble">rosidl_pycommon</test_depend>
<test_depend>rosidl_generator_c</test_depend>

<member_of_group>rosidl_generator_packages</member_of_group>
<member_of_group>rosidl_runtime_packages</member_of_group>

<export>
<build_type>ament_cmake</build_type>
</export>
</package>
20 changes: 20 additions & 0 deletions rosidl_generator_rs/resource/Cargo.toml.em
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "@(package_name)"
version = "@(package_version)"
edition = "2021"

[dependencies]
rosidl_runtime_rs = "0.4"
serde = { version = "1", optional = true, features = ["derive"] }
serde-big-array = { version = "0.5.1", optional = true }
@[for dep in dependency_packages]@
@(dep) = "*"
@[end for]@

[features]
@{
serde_features = ["dep:serde", "dep:serde-big-array", "rosidl_runtime_rs/serde"]
for dep in dependency_packages:
serde_features.append("{}/serde".format(dep))
}@
serde = @(serde_features)
Loading