Open michaelchi08 opened 1 year ago
i'm using foxy
Hi @michaelchi08
Im not that fluent with cmake either, but here are some pointers based on my understanding.
where are these variables set rcldotnet_common_ASSEMBLIES_DLL, i'm assuming these are the locations for cmake to go and find the dlls !?
The variables are set in the correspoinding find_package()
function call. When sourcing your workspace that was built with colcon
/ament
the CMAKE_PREFIX_PATH
gets populated to include the right directories for find_package()
to find an ament_cmake_export_assemblies-extras.cmake
for that package that defines those variables
find_package(rcldotnet_common REQUIRED)
find_package(std_msgs REQUIRED)
find_package(std_srvs REQUIRED)
find_package(rcldotnet REQUIRED)
$ echo $CMAKE_PREFIX_PATH
[...]:$YOUR_ROS2_DOTNET_WS/install/rcldotnet_common:[...]
$ cat $YOUR_ROS2_DOTNET_WS/install/rcldotnet_common/share/rcldotnet_common/cmake/ament_cmake_export_assemblies-extras.cmake
# generated from ament_cmake_export_assemblies/cmake/template/ament_cmake_export_assemblies.cmake.in
set(_exported_assemblies_dll "${rcldotnet_common_DIR}/../../../lib/rcldotnet_common/dotnet/rcldotnet_common.dll")
# append absolute assemblies to rcldotnet_common_ASSEMBLIES_DLL
# warn about not existing paths
if(NOT "${_exported_assemblies_dll} " STREQUAL " ")
find_package(ament_cmake_core QUIET REQUIRED)
foreach(_exported_assembly_dll ${_exported_assemblies_dll})
if(NOT EXISTS "${_exported_assembly_dll}")
message(WARNING "Package 'rcldotnet_common' exports the DLL assembly '${_exported_assembly_dll}' which doesn't exist")
endif()
normalize_path(_exported_assembly_dll "${_exported_assembly_dll}")
list(APPEND rcldotnet_common_ASSEMBLIES_DLL "${_exported_assembly_dll}")
endforeach()
endif()
set(_exported_assemblies_nuget "")
# append absolute assemblies to rcldotnet_common_ASSEMBLIES_NUGET
# warn about not existing paths
if(NOT "${_exported_assemblies_nuget} " STREQUAL " ")
find_package(ament_cmake_core QUIET REQUIRED)
foreach(_exported_assembly_nuget ${_exported_assemblies_nuget})
if(NOT EXISTS "${_exported_assembly_nuget}")
message(WARNING "Package 'rcldotnet_common' exports the NuGet assembly '${_exported_assembly_nuget}' which doesn't exist")
endif()
normalize_path(_exported_assembly_nuget "${_exported_assembly_nuget}")
list(APPEND rcldotnet_common_ASSEMBLIES_NUGET "${_exported_assembly_nuget}")
endforeach()
endif()
This is for consuming dotnet libraries built using colcon
/ament
as part of your ROS2 workspace. If you want to build dotnet libraries as part of your workspace see how the rcldotnet_common
ROS package is set up as an example: https://github.com/ros2-dotnet/ros2_dotnet/tree/master/rcldotnet_common
You most likely want to include some library of yours that was built outside of a ROS2 workspace. For this you can either include the absolute path in the _assemblies_dep_dlls
using either hardcoded paths in your project or maybe using an environment variable and string concat functions in cmake.
The better variant would be to include your external dotnet libraries as NuGet packages in the CMakeLists.txt
:
The test for rcldotnet do it like this: https://github.com/ros2-dotnet/ros2_dotnet/blob/master/rcldotnet/CMakeLists.txt#L100-L109
Here would be the cange for the talker example:
add_dotnet_executable(rcldotnet_talker
RCLDotnetTalker.cs
INCLUDE_DLLS
${_assemblies_dep_dlls}
INCLUDE_REFERENCES
"Newtonsoft.Json=13.0.3-beta1"
)
The NuGet packages don't need to be public, you can use our own private package feed or configure a folder where dotnet restore searches for them.
*.csproj
We use another mechanism in our internal code to build executables and libraries inside ROS workspaces, but using *.csproj
files to specify NuGet packages and other dotnet project settings. This is the branch we are using internally (not yet upstramed): https://github.com/schiller-de/dotnet_cmake_module/commits/feature-include-csproj. See this PR for our fork for more description on how this works: https://github.com/schiller-de/dotnet_cmake_module/pull/1.
Thanks for the response and explanation @hoffmann-stefan . I tried the following(absolute reference for a quick try):
add_dotnet_executable(rcldotnet_talker RCLDotnetTalker.cs INCLUDE_DLLS ${_assemblies_dep_dlls} INCLUDE_REFERENCES "/home/ros/Projects/hello/Motion.dll" )
but got this build error..
'starting >>> sensor_msgs_py
--- stderr: rcldotnet_examples
Included assemblies: /home/ros/ros2_dotnet_ws/install/rcldotnet_common/lib/rcldotnet_common/dotnet/rcldotnet_common.dll;/home/ros/ros2_dotnet_ws/install/rcldotnet/lib/rcldotnet/dotnet/rcldotnet_assemblies.dll;/home/ros/ros2_dotnet_ws/install/std_msgs/lib/std_msgs/dotnet/std_msgs_assemblies.dll;/home/ros/ros2_dotnet_ws/install/rcldotnet/lib/rcldotnet/dotnet/rcldotnet_assemblies.dll
CMake Error at /home/ros/ros2_dotnet_ws/install/dotnet_cmake_module/share/dotnet_cmake_module/cmake/Modules/dotnet/UseCSharpProjectBuilder.cmake:41 (list):
list index: 1 out of range (-1, 0)
Call Stack (most recent call first):
/home/ros/ros2_dotnet_ws/install/dotnet_cmake_module/share/dotnet_cmake_module/cmake/Modules/FindDotNETExtra.cmake:47 (csharp_add_project)
CMakeLists.txt:27 (add_dotnet_executable)
CMake Error at /home/ros/ros2_dotnet_ws/install/dotnet_cmake_module/share/dotnet_cmake_module/cmake/Modules/dotnet/UseCSharpProjectBuilder.cmake:41 (list): list index: 1 out of range (-1, 0) Call Stack (most recent call first): /home/ros/ros2_dotnet_ws/install/dotnet_cmake_module/share/dotnet_cmake_module/cmake/Modules/FindDotNETExtra.cmake:47 (csharp_add_project) CMakeLists.txt:34 (add_dotnet_executable)
Failed <<< rcldotnet_examples [0.65s, exited with code 2]'
@michaelchi08
The dll's need to go into the INCLUDE_DLLS
parameter not into INCLUDE_REFERENCES
. INCLUDE_REFERENCES
are only for NuGet packages.
Something like that:
set(_assemblies_dep_dlls
${rcldotnet_common_ASSEMBLIES_DLL}
${rcldotnet_ASSEMBLIES_DLL}
${std_msgs_ASSEMBLIES_DLL}
${rcldotnet_ASSEMBLIES_DLL}
"/home/ros/Projects/hello/Motion.dll"
)
add_dotnet_executable(rcldotnet_talker RCLDotnetTalker.cs INCLUDE_DLLS ${_assemblies_dep_dlls})
Some other tip:
Use colcon build --event-handlers console_direct+
to print out all errors directly. If it get's to build the C# code using dotnet build
the output won't be visible by default. colcon only prints stderr, but the dotnet tool only outputs to stdout.
Hi,
Thanks for providing this project for developers who want to use C# to build ros2 apps. I'm new to cmake and i wanted to add my own library dll to the publisher and listener node. What do i need to add to cmakelists so it finds the dll and its location?
where are these variables set rcldotnet_common_ASSEMBLIES_DLL, i'm assuming these are the locations for cmake to go and find the dlls !?
set(_assemblies_dep_dlls ${rcldotnet_common_ASSEMBLIES_DLL} ${rcldotnet_ASSEMBLIES_DLL} ${std_msgs_ASSEMBLIES_DLL} ${rcldotnet_ASSEMBLIES_DLL} )
Thanks for your help, Michael