编译

研究源码的一种方法是将它编译为调试版本, 然后可以加断点调试, 也可以查看运行过程中的输出信息.
参考: https://intel.github.io/hyperscan/dev-reference/getting_started.html

:::info 这里以 4.6.0 版本为准. 主要基于 Linux/macOS 系统, Windows 上编译方法本文最后. :::

第3方依赖库

编译 Hyperscan 需要以下依赖库, 这些库可以通过系统的包管理器安装.

  1. =========== =========== ==========================
  2. 依赖项 版本 说明
  3. =========== =========== ==========================
  4. CMake >=2.8.11
  5. Ragel 6.9
  6. Python 2.7
  7. Boost >=1.57 仅需要头文件,无需编译
  8. Pcap >=0.8 Optional: 仅用于示例程序
  9. SQLite ? Optional: 用于编译hsbench
  10. =========== =========== ==========================

注意:

  • boost不需要编译安装, 如果通过系统包管理工具(yum/apt-get)安装的版本无法满足版本需要, 则需要下载源码包, 解压后执行类似
    ln -s /home/zzq/boost_1_59_0/boost hyperscan-4.6.0/include/boost
    的命令创建符号链接, 注意 boost 库路径需要是绝对路径, 否则可能找不到. 或者使用下文描述的 BOOST_ROOT 选项
  • pcap 库会依赖 flex 和 bison

    CMake配置

    Hyperscan 编译支持的 CMake 选项主要有:
    1. ======================= ========================================================
    2. 参数 描述
    3. ======================= ========================================================
    4. CMAKE_C_COMPILER C compiler to use. Default is /usr/bin/cc.
    5. CMAKE_CXX_COMPILER C++ compiler to use. Default is /usr/bin/c++.
    6. CMAKE_INSTALL_PREFIX Install directory for install target
    7. CMAKE_BUILD_TYPE Define which kind of build to generate. Valid options are
    8. Debug, Release, RelWithDebInfo, and MinSizeRel. Default is RelWithDebInfo.
    9. BUILD_SHARED_LIBS Build Hyperscan as a shared library instead of the default static library.
    10. BUILD_STATIC_AND_SHARED Build both static and shared Hyperscan libs. Default off.
    11. BOOST_ROOT Location of Boost source tree.
    12. DEBUG_OUTPUT Enable very verbose debug output. Default off.
    13. FAT_RUNTIME Build the fat runtime. Default true on Linux, not available elsewhere.
    14. OPTIMISE Turns off compiler optimizations(默认TRUE)
    15. ======================= ========================================================

注意:
FAT_RUNTIME 是 4.4 版本引入的新特性, 即在编译时同时编译出针对若干种 CPU 的运行时, 这个开关(在编译 Release 版本时)默认是打开的. fat runtime 目前仅支持 Linux. 如果编译早期版本, 或者想要显式指定 target architecture, 应在 CMAKE_C_FLAGSCMAKE_CXX_FLAGS中使用 -march 选项, 例如
cmake -DCMAKE_C_FLAGS="-march=corei7" -DCMAKE_CXX_FLAGS="-march=corei7 <hyperscan-source-path>

编译过程

假设在用户根目录下的 hs_build 下面编译 hyperscan, 源码在 ~/hyperscan-4.6.0 , 编译为调试版本的动态链接库(还打开了调试信息输出):

  1. $ cd ~
  2. $ mkdir hs_build
  3. $ cd hs_build
  4. $ cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=on -DDEBUG_OUTPUT=on -DBOOST_ROOT=/Users/zzq/dev/pkg/boost_1_59_0 ../hyperscan
  5. #别忘了最后有个点
  6. $ cmake --build .

生成的 .so 文件放在 hs_build/lib 目录.

生成dump信息

hyperscan 代码大量使用了 dump 来进行调试, 不过默认情况下 dump 选项是关闭的, 打开 dump 功能 hyperscan 会输出大量信息和文件, 对分析源码很有帮助. Grey 类有两个成员, 用来控制 dump 信息的输出.

  • dumpFlags dump 选项. 所有的 dump flags 如下所示(见 src/grey.h )

    1. enum DumpFlags {
    2. DUMP_NONE = 0,
    3. DUMP_BASICS = 1 << 0, // Dump basic textual data
    4. DUMP_PARSE = 1 << 1, // Dump component tree to .txt
    5. DUMP_INT_GRAPH = 1 << 2, // Dump non-implementation graphs
    6. DUMP_IMPL = 1 << 3 // Dump implementation graphs
    7. };

    它在构造函数中被初始化为 0, hyperscan 代码的其他部分也没有修改过此值. 因此要输出 dump 信息, 需要修改 src/grey.cpp , 把此值改为 >0 的值, 建议改成 0xf.

  • dumpPath dump文件保存路径. dumpFlags 不为 DUMP_NONE 时, hyperscan 会把某些文件 dump 到此位置, 这个成员默认没有初始化, 如果只修改 dumpFlags, hyperscan 运行时会崩溃. 可以修改成”./“.

dump 打开之后, hyperscan 在运行时会输出很多 dot 文件, 可以使用 graphviz 工具直接查看其所表示的图形, 或者将其转换成图片格式. 这些图形会对我们理解内部机制有很大的帮助.

加速编译过程

hyperscan 编译需要较长的时间, 修改主目录下的 CMakeLists.txt , 配置其不编译某些代码, 可以提高一些编译速度.

比如, 搜索add_subdirectory, 注释掉 util, unit, tools, examples 等子目录的编译:

  1. #add_subdirectory(util)
  2. #add_subdirectory(unit)
  3. add_subdirectory(doc/dev-reference)
  4. if (EXISTS ${CMAKE_SOURCE_DIR}/tools/CMakeLists.txt)
  5. #add_subdirectory(tools)
  6. endif()
  7. if(NOT WIN32)
  8. #add_subdirectory(examples)
  9. endif()

生成源码文档

hyperscan 的代码注释使用 Doxygen 风格, 对源码生成文档可以有助于我们理解源码。

  1. /src下运行 doxygen -g , 生成 Doxyfile 文件
  2. 参考这篇文章 https://www.ibm.com/developerworks/cn/aix/library/au-learningdoxygen/index.html, 修改 Doxyfile, 建议开启 dot 支持并装好 graphviz, 以生成形象的图表
  3. 运行 doxygen Doxyfile 生成文档

在Windows上编译

这里所用的环境是 Windows 11, Visual Studio 2019.

目录结构

  • D:\dev\opensource\hyperscan-5.4.0 hyperscan 源码目录
  • D:\dev\opensource\hyperscan-build hyperscan 编译目录
  • D:\dev\opensource\hyperscan-libs 依赖项存放目录

    准备Ragel

    编译 Hyperscan 需要 Ragel 支持, 到官网(http://www.colm.net/open-source/ragel/) 下载软件包, 解压到 D:/dev/opensource/hyperscan-libs.
    编译 Ragel 需要 Linux 下 make 等工具, Windows 不支持, 可使用 Cygwin 工具来编译. 它一般是一个在线安装工具, 安装前可选择要安装的项, 选择 gcc/make 相关项即可. 很久以前, 在线安装 Cygwin 非常慢, 但现在在安装前可以选择连接国内服务器(如 163), 速度是很快的.

安装好之后, 将 Cygwin bin 目录(如C:\cygwin64\bin)添加到系统 PATH.
打开 Cygwin64 Terminal, 进入 Ragel 源码目录, 像在 Linux 上一样编译:

  1. zzq@hp /cygdrive/d
  2. $ cd dev/opensource/hyperscan-libs/ragel-6.10
  3. $ ./configure
  4. $ make

编译好之后, 可执行文件 ragel 位于 D:\dev\opensource\hyperscan-libs\ragel-6.10\ragel目录中.

准备Boost库

到 Boost 官网(https://www.boost.org/)下载 Boost 软件包, 解压后同样放到 D:/dev/opensource/hyperscan-libs.

开始编译

在 Windows 11 上点击视窗图标, 搜索 developer command, 找到 Developer Command Prompt for VS 2019并运行
HNK{QSZ()OL%GD3`5SMIZGS.png
将刚才编译好的 Ragel 所在目录加入 PATH, 否则编译时找不到

  1. >set PATH=%PATH%;D:\dev\opensource\hyperscan-libs\ragel-6.10\ragel

然后定位到编译目录, 开始编译

  1. C:\Program Files (x86)\Microsoft Visual Studio\2019\Community>d:
  2. D:\>cd dev\opensource\hyperscan-build
  3. D:\dev\opensource\hyperscan-build>cmake -G "Visual Studio 16 2019" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_SHARED_LIBS=on -DBOOST_ROOT=D:\dev\opensource\hyperscan-libs\boost_1_80_0 ..\hyperscan-5.4.0
  4. D:\dev\opensource\hyperscan-build>cmake --build .

编译好之后, 在编译目录 bin 子目录下会生成可执行文件

  1. D:\dev\opensource\hyperscan-build\bin>ls -l
  2. total 341664
  3. -rwxrwx---+ 1 zzq None 14641152 Oct 18 18:55 hs.dll
  4. -rwxrwx---+ 1 zzq None 148582400 Oct 18 18:55 hs.pdb
  5. -rwxrwx---+ 1 zzq None 1000960 Oct 18 18:55 hs_runtime.dll
  6. -rwxrwx---+ 1 zzq None 1986560 Oct 18 18:55 hs_runtime.pdb
  7. -rwxrwx---+ 1 zzq None 14774272 Oct 18 18:55 hscheck.exe
  8. -rwxrwx---+ 1 zzq None 149663744 Oct 18 18:55 hscheck.pdb
  9. -rwxrwx---+ 1 zzq None 3869696 Oct 18 18:55 unit-hyperscan.exe
  10. -rwxrwx---+ 1 zzq None 15339520 Oct 18 18:55 unit-hyperscan.pdb

可运行 unit-hyperscan来检查编译好的 hyperscan 是否正确.

参考