admin 管理员组

文章数量: 1184232

1. 为什么要在Windows上折腾Fast DDS?

如果你正在接触机器人、自动驾驶或者分布式实时系统,那你大概率绕不开一个词: DDS 。数据分发服务,简单来说,就是一种让不同软件模块、甚至不同机器之间,能像在同一个“数据黑板”上读写信息一样高效通信的中间件。而 Fast DDS ,作为DDS规范的一个高性能C++实现,不仅是开源界的明星,更是ROS 2默认的通信“大动脉”。

那为什么我们非得在Windows上从源码开始编译它呢?直接下载编译好的二进制库不香吗?我刚开始也是这么想的,直到在实际项目里踩了几个坑。首先,预编译的库往往绑定特定的Visual Studio版本和运行时库,和你项目里其他第三方库一链接,版本冲突、运行时错误就来了,排查起来能让人头秃。其次,如果你想启用一些特定功能,比如安全模块、统计模块,或者想用最新的特性分支,源码编译几乎是唯一的选择。最后,对于想深入理解Fast DDS内部机制,甚至打算做二次开发的兄弟来说,能成功编译并通过调试跟踪代码,是必经之路。

所以,这篇实战指南,就是把我自己在Windows上反复折腾、踩坑、最终跑通的全过程记录下来。目标很明确: 从零开始,带你走通Fast DDS在Windows平台上的源码获取、依赖编译、核心库构建、安装配置,直到跑通第一个HelloWorld示例 。我会尽量把每个步骤的细节、可能遇到的坑和解决方案都讲清楚,让你能一次成功,把精力更多地花在应用开发上,而不是和环境搏斗。

2. 战前准备:搭建你的Windows编译工坊

在开始敲命令之前,咱们得先把“厨房”收拾好,把该有的“锅碗瓢盆”备齐。在Windows上编译C++项目,尤其是Fast DDS这种有多个依赖的,工具链的选择和配置至关重要。

2.1 核心武器:Visual Studio与CMake

Visual Studio 是我们的主力编译器。我强烈推荐使用 Visual Studio 2019 或 2022 的社区版或更高版本,它们对C++标准支持更好。安装时,务必勾选“ 使用C++的桌面开发 ”工作负载,这会包含MSVC编译器、链接器、Windows SDK以及CMake支持等全套工具。别小看这一步,漏装了后面会报各种找不到头文件或库的诡异错误。

CMake 是项目的构建系统生成器。去官网下载最新稳定版的安装程序,安装时记得勾选“ Add CMake to the system PATH for all users ”,这样在命令行里就能直接用了。我习惯用CMake的命令行模式,配合VS的编译器,这样流程清晰,也方便写脚本自动化。

2.2 辅助工具:Git与包管理器

Git 是获取源码的必备工具。Fast DDS及其依赖库都托管在GitHub上,我们需要用它来克隆代码和子模块。同样,安装时把Git加入系统PATH。

Chocolatey 是一个Windows下的命令行包管理器,有点像Linux上的apt或yum。我们可以用它来快速安装一些系统级的依赖,比如后面可能会用到的 wget 。以管理员身份打开PowerShell,执行以下命令安装:

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('))

安装好后,可以用 choco install wget -y 来安装wget。

2.3 规划你的工作目录

保持源码和构建目录的整洁非常重要。我建议建立一个清晰的工作目录结构,例如:

E:\Dev\FastDDS_Build\
├── source\          # 存放所有克隆的源码
├── build\           # 存放所有构建的中间文件和结果
└── install\         # 统一的安装目录,存放最终的头文件和库

在命令提示符或PowerShell中,先创建并进入这个目录:

mkdir E:\Dev\FastDDS_Build
cd /d E:\Dev\FastDDS_Build
mkdir source build install
cd source

接下来,所有克隆和编译操作都将在这个框架下进行。统一的 install 目录能让你在后续配置自己项目时,库路径非常清晰。

3. 攻克堡垒:按顺序编译核心依赖库

Fast DDS不是单打独斗的,它依赖几个关键的第三方库。我们必须先把它们编译好。这里我选择手动编译每个依赖,而不是依赖CMake自动下载,这样可控性最强,也方便排查问题。

3.1 第一关:内存分配器 foonathan_memory

这个库提供了一个高效的、STL兼容的内存分配器,Fast DDS用它来管理内存,以获得更可预测的性能。我们首先编译它。

  1. 克隆代码 :在刚才的 source 目录下,执行:

    git clone  foonathan_memory
    cd foonathan_memory
    

    为了稳定性,我建议切到一个稳定标签,比如 git checkout v0.7-3

  2. 配置与生成 :我们使用CMake的“Out-of-Source Build”方式,在单独的 build 目录中构建。

    mkdir build
    cd build
    cmake .. -DFOONATHAN_MEMORY_BUILD_EXAMPLES=OFF -DFOONATHAN_MEMORY_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=E:\Dev\FastDDS_Build\install -A x64
    

    解释一下关键参数:

    • -A x64 :指定生成64位项目,这是必须的,确保和后续一致。
    • -DCMAKE_INSTALL_PREFIX :指定安装目录,编译好的库和头文件会复制到这里。
    • -D..._BUILD_EXAMPLES/TESTS=OFF :关闭示例和测试编译,加快速度。
  3. 编译与安装

    cmake --build . --config Release --target install
    

    这条命令会启动MSVC编译器,以 Release 配置进行编译,并将最终产物安装到指定的 install 目录。完成后,你可以在 E:\Dev\FastDDS_Build\install 下看到 include lib 文件夹。

3.2 第二关:序列化库 Fast-CDR

Fast-CDR是Fast DDS用于数据序列化/反序列化的核心库,它负责将内存中的数据结构转换成能在网络上传输的字节流。

  1. 克隆代码 :回到 source 目录,克隆Fast-CDR:

    cd ..\..\
    git clone  fastcdr
    cd fastcdr
    git checkout v2.1.2 # 选择一个与Fast DDS兼容的版本,例如2.1.x
    
  2. 配置与安装

    mkdir build
    cd build
    cmake .. -DCMAKE_INSTALL_PREFIX=E:\Dev\FastDDS_Build\install -A x64
    cmake --build . --config Release --target install
    

    这个过程和编译foonathan_memory类似。安装后,相关文件会合并到之前的 install 目录中。

3.3 第三关:XML解析器 TinyXML2

Fast DDS使用XML文件进行配置,TinyXML2是一个轻量高效的XML解析库。

  1. 克隆代码

    cd ..\..\
    git clone  tinyxml2
    cd tinyxml2
    
  2. 配置与安装

    mkdir build
    cd build
    cmake .. -DCMAKE_INSTALL_PREFIX=E:\Dev\FastDDS_Build\install -A x64 -DBUILD_SHARED_LIBS=OFF
    cmake --build . --config Release --target install
    

    这里我加了一个 -DBUILD_SHARED_LIBS=OFF ,意思是编译成静态库( .lib )。在Windows上,静态库链接有时比动态库(DLL)更省心,避免运行时找不到DLL的问题。你可以根据喜好选择ON或OFF。

3.4 可选依赖:Asio与OpenSSL

Asio 是一个强大的网络编程库,Fast DDS的TCP传输层依赖它。好消息是,Fast DDS的源码包里已经自带了一个Asio子模块,我们编译主库时会自动使用,通常无需单独处理。

OpenSSL 如果你需要启用Fast DDS的安全功能(加密、认证),则需要先安装OpenSSL。可以从OpenSSL官网下载Windows预编译包,安装后记住其路径,在编译Fast DDS时通过 -DOPENSSL_ROOT_DIR 参数指定。

至此,三大核心依赖库已经准备就绪,整齐地躺在我们的 install 目录里。接下来就是主角登场了。

4. 终极目标:编译与安装Fast DDS核心库

现在,我们有了坚实的“地基”,可以开始建造Fast DDS这座“主楼”了。

4.1 获取Fast DDS源码

  1. 克隆主仓库与子模块 :回到 source 目录。

    cd ..\..\source
    git clone  fastdds
    cd fastdds
    

    我建议切换到一个长期支持(LTS)版本或稳定标签,比如 git checkout v2.14.0 ,这能保证更好的稳定性。

    git checkout v2.14.0
    
  2. 初始化子模块 :Fast DDS使用Git子模块来管理一些内置的第三方代码,如Asio。

    git submodule update --init --recursive
    

    这一步会拉取 thirdparty/asio 等目录的内容。

4.2 配置CMake构建选项

这是最关键的一步,CMake的配置参数决定了最终生成的库包含哪些功能。

mkdir build
cd build

然后执行CMake配置命令。下面是一个我经过验证的、功能比较全面的配置:

cmake .. -A x64 ^
  -DCMAKE_INSTALL_PREFIX=E:\Dev\FastDDS_Build\install ^
  -DCMAKE_PREFIX_PATH=E:\Dev\FastDDS_Build\install ^
  -DTHIRDPARTY=ON ^
  -DSECURITY=OFF ^
  -DNO_TLS=ON ^
  -DCOMPILE_EXAMPLES=ON ^
  -DBUILD_SHARED_LIBS=ON ^
  -DEPROSIMA_BUILD=ON

让我逐一解释这些“开关”:

  • -DCMAKE_PREFIX_PATH :告诉CMake去哪里寻找我们刚刚编译好的依赖库(foonathan_memory, fastcdr, tinyxml2)。CMake会在这个路径下自动查找。
  • -DTHIRDPARTY=ON :允许CMake使用我们提供的第三方库,而不是尝试自己去下载。
  • -DSECURITY=OFF :默认关闭安全模块。除非你需要,否则先关闭以简化编译。
  • -DNO_TLS=ON :禁用TLS传输安全。如果没装OpenSSL,这个必须打开,否则会报错。
  • -DCOMPILE_EXAMPLES=ON :编译官方示例。 强烈建议打开 ,这是验证编译是否成功的最佳方式。
  • -DBUILD_SHARED_LIBS=ON :将Fast DDS本身也编译成动态链接库(DLL)。生成DLL和静态LIB两种,方便不同场景使用。
  • -DEPROSIMA_BUILD=ON :启用eProsima的内部构建模式,会打开一些有用的调试和示例选项。

4.3 编译、测试与安装

配置成功后,你会看到CMake输出总结,列出了哪些功能被启用。接下来开始编译:

cmake --build . --config Release --target install

这个过程视电脑性能而定,可能需要几分钟到十几分钟。如果一切顺利,最终的头文件( .hpp )、导入库( .lib )和动态库( .dll )都会被复制到 E:\Dev\FastDDS_Build\install

验证安装 :安装完成后,立刻去 install 目录下的 bin 文件夹看看。你应该能看到 fastdds fastrtps 等相关的DLL文件,以及一些示例程序的可执行文件,比如 HelloWorldExample.exe 。在 lib 文件夹下能看到对应的 .lib 文件。这就说明编译安装基本成功了。

5. 实战检验:运行你的第一个Fast DDS程序

理论说得再多,不如跑个例子看看。我们就用Fast DDS自带的HelloWorld示例来验证整个环境。

5.1 定位并运行示例程序

在Fast DDS的构建目录里,示例程序已经被编译好了。我们直接运行发布者和订阅者。

  1. 打开两个 命令提示符 (CMD)或 PowerShell 窗口。
  2. 在两个窗口中,都先切换到Fast DDS的构建目录下的示例程序位置:
    cd E:\Dev\FastDDS_Build\source\fastdds\build\examples\cpp\dds\HelloWorldExample
    
  3. 在第一个窗口中,运行 订阅者
    .\Debug\HelloWorldExample subscriber
    
    (如果你的编译配置是Release,则路径是 .\Release\...
  4. 在第二个窗口中,运行 发布者
    .\Debug\HelloWorldExample publisher
    

如果一切正常,你应该会在发布者窗口看到不断打印发送的消息,而在订阅者窗口看到接收到的消息。恭喜你!这意味着从库到应用程序的整个链路都打通了。

5.2 在Visual Studio中创建你自己的项目

光跑例子不够,我们得学会在自己的项目里用上Fast DDS。这里以创建一个新的Visual Studio控制台项目为例。

  1. 创建新项目 :打开Visual Studio,创建新的“控制台应用”项目,命名为 MyFastDDSApp
  2. 配置项目属性 :这是核心步骤。
    • C/C++ -> 常规 -> 附加包含目录 :添加Fast DDS安装目录下的 include 文件夹。例如: E:\Dev\FastDDS_Build\install\include
    • 链接器 -> 常规 -> 附加库目录 :添加Fast DDS安装目录下的 lib 文件夹。例如: E:\Dev\FastDDS_Build\install\lib
    • 链接器 -> 输入 -> 附加依赖项 :添加需要链接的库文件。至少需要:
      fastcdr.lib
      fastrtps.lib
      
      如果你编译了共享内存传输或其他模块,可能还需要添加对应的lib。
    • C/C++ -> 预处理器 -> 预处理器定义 :添加 FASTCDR_DYN_LINK FASTDDS_DYN_LINK 。这告诉编译器我们使用的是DLL动态链接版本。如果你用的是静态库,则不需要这两个定义,但需要定义 FASTCDR_STATIC_LINK FASTDDS_STATIC_LINK
  3. 复制运行时DLL :将 install\bin 目录下的 fastcdr.dll fastrtps.dll 等所有DLL文件,复制到你的项目生成的可执行文件( .exe )所在的目录(通常是 项目目录\x64\Debug\ )。或者更规范的做法是,在系统PATH环境变量中加入 install\bin 目录。
  4. 编写代码 :现在,你就可以在你的 main.cpp 里引用Fast DDS的头文件,比如 #include <fastdds/dds/domain/DomainParticipant.hpp> ,并开始编写发布者或订阅者代码了。你可以参考 examples 目录下的源码作为模板。

6. 避坑指南:常见问题与解决方案

这条路我走过,知道哪里容易崴脚。下面是一些你很可能遇到的问题及解决办法。

问题一:CMake配置时,找不到依赖库(如foonathan_memory)。

  • 症状 :CMake报错 Could NOT find foonathan_memory
  • 解决 :确保 -DCMAKE_PREFIX_PATH 参数正确指向了你统一安装的目录( E:\Dev\FastDDS_Build\install )。并且确认你已经成功编译并 install 了该依赖库。

问题二:编译链接时,报“无法解析的外部符号”错误。

  • 症状 :一堆 LNK2001 LNK2019 错误,提示某些函数找不到。
  • 解决
    1. 检查 附加依赖项 里的库名是否正确、完整。库名可能带有后缀,如 fastrtps-2.14.lib
    2. 确保你的项目平台(x64)和编译的库平台一致。全程都要用x64。
    3. 检查 预处理器定义 。如果使用DLL,必须添加 FASTCDR_DYN_LINK FASTDDS_DYN_LINK ;如果使用静态库,则不能加这两个,并且要确保编译依赖库时也用的是静态库( -DBUILD_SHARED_LIBS=OFF ),否则会混用导致冲突。

问题三:程序运行时崩溃,提示“找不到xxx.dll”。

  • 症状 :编译成功,但运行exe时弹窗报错。
  • 解决 :这是最经典的Windows DLL问题。确保所有必需的DLL( fastcdr.dll , fastrtps.dll 等)都在可执行文件的同级目录,或者其路径已在系统的PATH环境变量中。用 dumpbin /dependents your_program.exe 命令可以查看你的程序依赖哪些DLL。

问题四:示例程序运行后,发布者和订阅者无法通信(匹配不上)。

  • 症状 :双方都启动了,但都显示 matched_ 为0,没有数据收发。
  • 解决
    1. 检查防火墙设置,是否阻止了程序的网络通信。在开发时,可以暂时关闭防火墙测试。
    2. 确保双方使用了相同的 域ID (Domain ID,默认为0)。在创建 DomainParticipant 时检查第一个参数。
    3. 确保双方订阅和发布的 主题名 (Topic Name)完全一致,包括大小写。

问题五:想用CMake GUI进行图形化配置。

  • 当然可以。打开CMake GUI,在“Where is the source code”选择Fast DDS源码目录,在“Where to build the binaries”选择新建的 build 目录。点击Configure,选择Visual Studio版本和平台(x64)。第一次配置会报红,显示找不到依赖。这时,你需要手动在列表中指定 foonathan_memory_DIR fastcdr_DIR tinyxml2_DIR 等变量的路径,指向它们各自的 build 目录或 install 目录下的 lib/cmake 子目录。配置成功后点Generate,即可在 build 目录生成 .sln 文件,用Visual Studio打开编译即可。

整个流程走下来,你可能需要花费一两个小时,但一旦环境配通,后面就是一马平川。Fast DDS的强大功能,如丰富的QoS策略、共享内存传输、发现服务器等,就等着你在自己的项目中探索和使用了。记住,遇到问题别慌,多看看编译输出的错误信息,大部分都能在网上找到线索。祝你在分布式系统的世界里玩得开心!

本文标签: 例如 文件 编程