I’m trying to compile a ROS2 node from Visual Studio. Because I want to integrate to my own C++ compilation framework, I cannot simply use colcon build.
So I’m just trying to compile a ROS2 package from Visual Studio. I downloaded ROS2 “Humble”, unzipped it to C:ROS2ros2-windows.
Now, I created a simple package following the tutorial, and I compile it as follow:
C:ROS2ros2-windowslocal_setup.bat
cd C:ROS2SDE_workspace
cmake -G "Visual Studio 17 2022" ..srcmy_package -DCMAKE_INSTALL_PREFIX=C:ROS2SDE_workspaceinstall -DCMAKE_POLICY_DEFAULT_CMP0148=OLD
Then I open my_package.sln
and I can compile the project in Release
or Debug
and later run a package’s node using ros2 run ...
. Fine.
Now, I want to add a custom message to the project, so I add a .msg
and updated CMakeLists.txt
as proposed in the tutorial. But now, I can only compile my_package.sln
in Release
mode. When compiling in Debug
mode, I get the next error for my_package__rosidl_typesupport_fastrtps_c
and my_package__rosidl_typesupport_fastrtps_cpp
:
Erreur LNK1104 impossible d'ouvrir le fichier 'fastcdrd-1.0.lib'
I cannot find why VS tries to link this non-existing fastcdrd-1.0.lib
file…and this is my question!
Note1:
I dig into C:ROS2ros2-windows
for fastcdr
. Found:
find_library(FastCDR_LIBRARY_DEBUG
NAMES fastcdrd-${fastcdr_MAJOR_MINOR_VERSION}
HINTS "${fastcdr_DIR}/../..")
in C:ROS2ros2-windowssharefastrtps_cmake_modulecmakeModulesFindFastRTPS.cmake. But this file does not seem to be loaded because if I add a message(FATA_ERROR "Foo")
in there, cmake does not report any error.
Note2:
Linkage options for my_package__rosidl_typesupport_fastrtps_cpp
in Debug
is:
/OUT:"C:ROS2SDE_workspacebuildDebugmy_package__rosidl_typesupport_fastrtps_cpp.dll" /MANIFEST /NXCOMPAT /PDB:"C:/ROS2/SDE_workspace/build/Debug/my_package__rosidl_typesupport_fastrtps_cpp.pdb" /DYNAMICBASE "C:ROS2ros2-windowslibstd_msgs__rosidl_typesupport_fastrtps_cpp.lib" "C:ROS2ros2-windowslibbuiltin_interfaces__rosidl_typesupport_fastrtps_cpp.lib" "C:ROS2ros2-windowslibrosidl_typesupport_fastrtps_cpp.lib" "C:ROS2ros2-windowslibfastcdr-1.0.lib" "C:ROS2ros2-windowslibrmw.lib" "C:ROS2ros2-windowslibrosidl_runtime_c.lib" "C:ROS2ros2-windowslibrcutils.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "comdlg32.lib" "advapi32.lib" /IMPLIB:"C:/ROS2/SDE_workspace/build/Debug/my_package__rosidl_typesupport_fastrtps_cpp.lib" /DEBUG /DLL /MACHINE:X64 /INCREMENTAL /PGD:"C:ROS2SDE_workspacebuildDebugmy_package__rosidl_typesupport_fastrtps_cpp.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"my_package__rosidl_typesupport_fastrtps_cpp.dirDebugmy_package__rosidl_typesupport_fastrtps_cpp.dll.intermediate.manifest" /LTCGOUT:"my_package__rosidl_typesupport_fastrtps_cpp.dirDebugmy_package__rosidl_typesupport_fastrtps_cpp.iobj" /ERRORREPORT:PROMPT /ILK:"my_package__rosidl_typesupport_fastrtps_cpp.dirDebugmy_package__rosidl_typesupport_fastrtps_cpp.ilk" /NOLOGO /TLBID:1
It links to fastcdr-1.0.lib
, not fastcdrd-1.0.lib
.
If one wants to reproduce, my_package
folder contains:
my_package/include empty folder
my_package/msg/MyMessage.msg:
string name
my_package/src/my_node.cpp:
#include <chrono>
#include <functional>
#include <memory>
#include <string>
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
using namespace std::chrono_literals;
/* This example creates a subclass of Node and uses std::bind() to register a
* member function as a callback from the timer. */
class MinimalPublisher : public rclcpp::Node
{
public:
MinimalPublisher()
: Node("minimal_publisher"), count_(0)
{
publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
timer_ = this->create_wall_timer(
500ms, std::bind(&MinimalPublisher::timer_callback, this));
}
private:
void timer_callback()
{
auto message = std_msgs::msg::String();
message.data = "Hello, world! " + std::to_string(count_++);
RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
publisher_->publish(message);
}
rclcpp::TimerBase::SharedPtr timer_;
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
size_t count_;
};
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<MinimalPublisher>());
rclcpp::shutdown();
return 0;
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
project(my_package)
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
add_executable(talker src/my_node.cpp)
ament_target_dependencies(talker rclcpp std_msgs)
install(TARGETS
talker
DESTINATION lib/${PROJECT_NAME})
find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/MyMessage.msg"
DEPENDENCIES std_msgs
)
ament_package()
package.xml:
<?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>my_package</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="[email protected]">JP225611</maintainer>
<license>Apache-2.0</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>rclcpp</depend>
<depend>std_msgs</depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>