您正在阅读的是旧版本但仍受支持的 ROS 2 文档。 Jazzy.
视窗技巧和窍门
ROS 2 支持 Windows 10 作为一级平台,这意味着所有进入 ROS 2 内核的代码都必须支持 Windows。对于那些习惯于在 Linux 或其他类 Unix 系统上进行传统开发的人来说,在 Windows 上进行开发可能是一个小小的挑战。本文档旨在阐述其中的一些差异。
最大路径长度
默认情况下,Windows 有一个 最大路径长度 共 260 个字符。实际上,其中 4 个字符总是被驱动器字母、冒号、首字母反斜线和最后的 NULL 字符使用。这意味着只有 256 个字符可用于 数额 路径的所有部分。这对 ROS 2 有两个实际影响:
有些 ROS 2 内部路径名相当长。因此,我们始终建议为 ROS 2 目录的根目录使用简短的路径名,例如
C:\dev
.从源代码构建 ROS 2 时,colcon 的默认隔离构建模式会生成很长的路径名。为避免这些超长路径名,请使用
--合并安装
在 Windows 上运行时。
备注:可以将 Windows 改为更长的最大路径长度。请参见 本条 了解更多信息。
符号可见度
Microsoft Visual C++ 编译器(MSVC)只有在明确导出动态链接库(DLL)中的符号时,才会公开这些符号。clang 和 gcc 编译器也有同样的选项,但默认情况下是关闭的。因此,当以前在 Linux 上编译的库在 Windows 上编译时,其他库可能无法解析外部符号。下面是一些常见的错误信息示例,这些错误信息可能是由于符号未被暴露而导致的:
错误 C2448:'__属性__':函数式初始化器似乎是函数定义
'可见性':未找到标识符
CMake Error at C:/ws_ros2/install/random_numbers/share/random_numbers/cmake/ament_cmake_export_libraries-extras.cmake:48 (message):
包 'random_numbers'导出了库 'random_numbers',该库用于
找不到
符号可见性也会影响二进制加载。如果发现可组合节点无法运行或 Qt 展示台无法工作,可能是因为托管进程无法从二进制文件中找到预期的符号导出。要在 Windows 上诊断这种情况,Windows 开发人员工具包括一个名为 Gflags 的程序,用于启用各种选项。其中一个选项名为 装载机卡扣 可让您在调试时检测加载故障。更多信息,请访问微软文档 Gflags 和 装载机卡扣.
在 Windows 上导出符号的两种解决方案是可见性控制头和 导出所有符号
属性。微软建议 ROS 开发人员使用可见性控制头(Visibility Control Headers)来控制二进制文件中符号的导出。可见性控制头(Visibility Control Headers)可对符号导出宏进行更多控制,并提供其他好处,包括缩小二进制文件尺寸和缩短链接时间。
可见性控制标题
可见性控制头文件头文件的目的是为每个共享库定义一个宏,正确地将符号声明为 dllimport 或 dllexport。这取决于共享库是被使用还是被构建。宏中的逻辑还将编译器考虑在内,包括选择适当语法的逻辑。编译器 GCC 可见性文档 其中包括如何在库中添加显式符号可见性的逐步说明,"从而获得最高质量的代码,最大限度地减少二进制文件大小、加载时间和链接时间"。一个名为 visibility_control.h
可以放在 包括
文件夹,如下例所示。下面的示例显示了如何为一个 my_lib
库中有一个名为 示例类
.为库的 include 文件夹添加可见性标头。在宏中使用库名时会使用模板逻辑,使其在项目中独一无二。在另一个库中、 我的资料库
将被替换为图书馆名称。
#ifndef MY_LIB__VISIBILITY_CONTROL_H_
#define MY_LIB__VISIBILITY_CONTROL_H_
#if defined _WIN32 || defined __CYGWIN__
#ifdef __GNUC__
#define MY_LIB_EXPORT __attribute__ ((dllexport))
#define MY_LIB_IMPORT __attribute__ ((dllimport))
#else
#define MY_LIB_EXPORT __declspec(dllexport)
#define MY_LIB_IMPORT __declspec(dllimport)
#endif
#ifdef MY_LIB_BUILDING_LIBRARY
#define MY_LIB_PUBLIC MY_LIB_EXPORT
#else
#define MY_LIB_PUBLIC MY_LIB_IMPORT
#endif
#define MY_LIB_PUBLIC_TYPE MY_LIB_PUBLIC
#define MY_LIB_LOCAL
#else
// Linux 可见性设置
#define MY_LIB_PUBLIC_TYPE
#endif
#endif // my_lib__visibility_control_h_
有关该标头的完整示例,请参见 rviz_rendering.
要使用宏,请添加 MY_LIB_PUBLIC
在需要让外部库看到的符号之前。例如
班级 MY_LIB_PUBLIC 示例类 {}
MY_LIB_PUBLIC 空白 示例函数 (){}
为了使用正确导出的符号构建库,您需要在 CMakeLists.txt 文件中添加以下内容:
目标编译定义(${项目名称}
私人 "MY_LIB_BUILDING_LIBRARY";)
WINDOWS_EXPORT_ALL_SYMBOLS 目标属性
CMake 实现了 导出所有符号
属性,可以自动导出函数符号。有关其工作原理的更多详情,请参阅 WINDOWS_EXPORT_ALL_SYMBOLS CMake 文档.在 CMakeLists 文件中添加以下内容即可实现该属性:
设置目标属性(${LIB_NAME} 物业 导出所有符号 真)
如果 CMakeLists 文件中有多个库,则需要调用 设置目标属性
分别对它们进行处理。
请注意,Windows 下的二进制文件只能导出 65 536 个符号。如果二进制文件导出的符号超过了这个数量,就会出错,这时应该使用可见性控制头。在全局数据符号的情况下,此方法有一个例外。例如,像下面这样的全局静态数据成员。
类 示例类
{
公:
天电 缢 int 全球数据数;
在这种情况下,必须明确应用 dllimprort/dllexport。这可以使用生成_export_header 来实现,如下文所述: 使用 CMake export all 新功能在 Windows 上创建 dll,无需 declspec().
最后,重要的是,导出符号的头文件必须包含在至少一个 .cpp
文件,这样宏才会被展开并放入生成的二进制文件中。否则,这些符号仍无法调用。
调试构建
在 Windows 上以调试模式创建程序时,有几件非常重要的事情会发生变化。首先,所有 DLL 都会 _d
会自动附加到库名称中。因此,如果库名为 libfoo.dll
,在调试模式下将是 libfoo_d.dll
.Windows 上的动态链接器也知道要查找这种形式的库,所以不会找到不带 _d
前缀。此外,Windows 在调试模式下会开启一整套编译时和运行时检查,这比 Release 版本的构建要严格得多。因此,在许多拉取请求中运行 Windows 调试构建和测试是个好主意。
正斜线与反斜线
在 Windows 中,默认路径分隔符是反斜线 (\
与正斜线 (/
) 用于 Linux 和 macOS。大多数 Windows 应用程序接口都可以将二者作为路径分隔符来处理,但这并不普遍。例如 cmd.exe
shell 只能在使用反斜杠字符时进行制表符补全,而不能使用正斜杠。为了最大限度地兼容 Windows,在 Windows 中应始终使用反斜杠作为路径分隔符。
修补卖方软件包
在 ROS 2 中销售软件包时,经常需要打补丁来修复错误、添加功能等。典型的方法是修改 外部项目添加
调用,以添加一个 补丁
命令,使用 补丁
可执行文件。遗憾的是 补丁
由 chocolatey 提供的可执行文件需要管理员权限才能运行。变通方法是使用 笨蛋 应用-补丁
将补丁应用到外部项目时。
笨蛋 应用-补丁
有自己的问题,因为它只有在应用于 git 仓库时才能正常工作。因此,外部项目应始终使用 GIT
方法获取项目,然后使用 PATCH_COMMAND
调用 笨蛋 应用-补丁
.
使用上述所有功能的示例如下:
外部项目添加(我的图书馆${版本}
GIT_REPOSITORY https://github.com/lib/mylibrary.git
GIT_TAG ${版本}
GIT_CONFIG advice.detachedHead=false
# 因 https://gitlab.kitware.com/cmake/cmake/-/issues/16419 而抑制 git 更新
# 详见 https://github.com/ament/uncrustify_vendor/pull/22
更新命令 "";
超时 600
CMAKE_ARGS
-dcmake_install_prefix=${cmake_current_binary_dir}/${项目名称}安装
${额外参数}
-Wno-dev
PATCH_COMMAND
${CMAKE_COMMAND} -E 目录 <SOURCE_DIR>; 笨蛋 应用 -p1 --忽略空间变化 --whitespace=nowarn ${cmake_current_source_dir}/install-patch.diff
)
Windows 慢计时器(一般速度慢)
一般来说,在 Windows 上运行的软件要比在 Linux 上运行的软件慢得多。这是由多种因素造成的,包括默认的时间片(每 20 毫秒,根据 文献资料)、运行的反病毒和反恶意软件进程的数量,以及运行的后台进程的数量。因此,测试应 从不 在 Windows 平台上,测试时间应该很紧。所有测试都应该有宽松的超时时间,并只期望事件最终发生(这也能防止测试在 Linux 上变得不稳定)。
贝壳
Windows 上主要有两种命令行 shell:古老的 cmd.exe
和 PowerShell。
cmd.exe
是最接近旧 DOS shell 的命令 shell,但功能大大增强。它完全基于文本,只能理解 DOS/Windows 批次
文件
PowerShell 是一种较新的基于对象的 shell,微软推荐大多数新应用程序使用这种 shell。它能理解 ps1
文件进行配置。
ROS 2 同时支持 cmd.exe
和 PowerShell,因此任何更改(尤其是对诸如 动情
或 胶管
) 都应进行测试。