2、环境搭建与编译:Linux环境下的SOEM编译、Windows环境下的SOEM编译、CMakeLists.txt深度解析、依赖库分析

好,咱们正式开始动手了。

上一章聊了SOEM是什么、能干什么。这一章,咱们得把环境搭起来,把代码编译通过。说白了,就是让SOEM在你的电脑上先跑起来。

我个人习惯,拿到一个开源协议栈,第一件事不是读代码,而是先编译。编译通过了,心里才有底。你想想看,代码再漂亮,编译不过全是白搭。

2.1 Linux环境下的SOEM编译

Linux下编译SOEM,其实非常简单。我最早接触SOEM是在Ubuntu 16.04上,那时候踩了不少坑。现在好多了,CMake已经非常成熟。

第一步:安装依赖

SOEM在Linux上依赖两个东西:一个是CMake,一个是libpcap。libpcap是用来抓网络包的,SOEM底层通过它来收发EtherCAT帧。

sudo apt-get update
sudo apt-get install cmake libpcap-dev

嗯,这里要注意。有些老版本的Ubuntu,libpcap-dev的版本可能比较低,但不影响SOEM编译。我在项目中遇到过,用Ubuntu 18.04编译SOEM 1.3.1,完全没问题。

第二步:下载源码并编译

git clone https://github.com/OpenEtherCATsociety/SOEM.git
cd SOEM
mkdir build && cd build
cmake ..
make

就这么简单。编译完成后,你会在build目录下看到libsoem.so这个动态库,以及一些测试程序。

小技巧: 我个人习惯用 cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. 来指定安装路径。这样后续开发时,头文件和库文件都在标准位置,省去很多麻烦。

2.2 Windows环境下的SOEM编译

Windows下编译SOEM,说实话,比Linux麻烦一点。主要是因为Windows没有原生的libpcap,需要装WinPcap或Npcap。

第一步:安装工具链

我推荐用Visual Studio 2019或2022。当然,MinGW也行,但我个人更习惯VS。

第二步:安装WinPcap开发包

去WinPcap官网下载开发者包。安装后,记住安装路径,一般是 C:\WpdPack

第三步:CMake配置

打开CMake GUI,源码目录选SOEM根目录,构建目录选build。点击Configure,选择Visual Studio生成器。

这时候CMake会报错,说找不到libpcap。别慌,你需要手动设置两个变量:

  • PCAP_INCLUDE_DIR:指向 C:\WpdPack\Include
  • PCAP_LIBRARY:指向 C:\WpdPack\Lib\x64\wpcap.lib

设置好后,再点Configure,应该就绿了。然后Generate,Open Project,在VS里编译即可。

避坑指南: 我曾经在Windows上折腾了一整天,就是因为WinPcap和Npcap的64位库混用了。记住,如果你的VS编译的是x64程序,一定要用x64版本的wpcap.lib。32位和64位不能混用!

2.3 CMakeLists.txt深度解析

好,编译通过了。但咱们不能就这么算了。你得知道CMakeLists.txt里到底写了什么。我带你一行一行看。

SOEM根目录下的CMakeLists.txt,大概200多行。核心逻辑其实就几块:

第一块:项目定义

cmake_minimum_required(VERSION 2.8)
project(soem VERSION 1.4.0 LANGUAGES C)

这里指定了最低CMake版本和项目名称。SOEM是用纯C写的,所以只启用C语言。

第二块:依赖查找

find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
    pkg_check_modules(PCAP libpcap)
endif()

if(NOT PCAP_FOUND)
    find_path(PCAP_INCLUDE_DIR pcap.h)
    find_library(PCAP_LIBRARY pcap)
endif()

这段代码很有意思。它先用pkg-config找libpcap,找不到再用find_path和find_library。为什么要这样?

我解释一下:pkg-config是Linux下的标准方式,但Windows下没有。所以SOEM做了兼容处理。你在Windows下手动设置PCAP_INCLUDE_DIR和PCAP_LIBRARY,就是绕过了pkg-config,直接告诉CMake库在哪。

第三块:源文件组织

set(SOEM_SRC
    osal/osal.c
    osal/linux/osal_linux.c
    ethercatbase.c
    ethercatcoe.c
    ethercatconfig.c
    ethercatdc.c
    ethercatmain.c
    ethercatprint.c
    ...)

这里把所有源文件列出来了。注意看,osal/linux/osal_linux.c是Linux平台特有的。如果是Windows,会换成osal/windows/osal_win32.c。这就是SOEM跨平台的秘密——通过OSAL层隔离平台差异。

第四块:库和目标

add_library(soem SHARED ${SOEM_SRC})
target_link_libraries(soem ${PCAP_LIBRARY})
target_include_directories(soem PUBLIC ${PCAP_INCLUDE_DIR})

这里生成动态库libsoem.so,并链接libpcap。注意PUBLIC关键字,意思是使用soem库的其他项目,也会自动包含libpcap的头文件路径。

核心要点: SOEM的CMakeLists.txt设计得非常清晰。它把平台相关代码隔离在osal目录下,通过条件判断选择不同的源文件。这种设计思路,值得我们在自己的项目中借鉴。

2.4 依赖库分析

SOEM的依赖其实非常少。说白了,就一个libpcap。

libpcap是什么?

libpcap是Linux下的网络数据包捕获库。tcpdump、Wireshark底层都用它。SOEM用它来发送和接收EtherCAT帧。

你可能会问:为什么不用socket?

嗯,这个问题问得好。EtherCAT帧是直接在以太网层传输的,不经过TCP/IP协议栈。如果用socket,你只能发UDP/TCP包,没法发原始的以太网帧。而libpcap可以让你绕过协议栈,直接操作网络接口。

libpcap的核心API

SOEM只用到了libpcap的几个函数:

函数 作用
pcap_open_live 打开网络接口,准备抓包
pcap_sendpacket 发送原始以太网帧
pcap_next_ex 接收下一个数据包
pcap_close 关闭网络接口

你看,就这么几个函数。SOEM的底层网络操作,全靠它们。

个人经验: 我在调试EtherCAT通信时,经常用Wireshark抓包分析。Wireshark底层也是libpcap。所以,如果你熟悉libpcap,对理解SOEM的底层机制会很有帮助。

2.5 本章知识体系

为了让你更直观地理解本章内容,我画了一张图:

SOEM环境搭建与编译知识体系 Linux编译 安装libpcap-dev cmake && make 生成libsoem.so Windows编译 安装WinPcap/Npcap CMake手动配置路径 VS编译生成DLL CMakeLists.txt 项目定义与版本 依赖查找逻辑 源文件与库生成 核心依赖:libpcap(跨平台)

这张图把本章的核心内容串起来了。Linux和Windows两条路径,最终都依赖libpcap。而CMakeLists.txt就是连接源码和编译器的桥梁。

好了,环境搭建就讲到这里。编译通过只是第一步,下一章咱们要真正开始读代码了。到时候,我会带你从main函数开始,一步步走进SOEM的世界。


公众号:蓝海资料掘金营,微信deep3321