ns-3 网络模拟器教程。 第3章

ns-3 网络模拟器教程。 第3章
第1,2章

3 入门
3.1 概述
3.2 先决条件
3.2.1 下载 ns-3 版本作为源存档
3.3 使用Git下载ns-3
3.3.1 使用 Bake 加载 ns-3
3.4 组装ns-3
3.4.1 使用build.py构建
3.4.2 使用烘焙进行构建
3.4.3 使用 Waf 构建
3.5 测试ns-3
3.6 运行脚本
3.6.1 命令行参数
3.6.2 调试
3.6.3 工作目录

第3章

入门

本章旨在帮助读者做好准备,开始使用可能从未安装过 ns-3 的计算机。 它涵盖了支持的平台、先决条件、如何获取 ns-3、如何构建 ns-3 以及如何测试构建和运行简单的程序。

3.1 概述

ns-3 模拟器是作为协作软件库系统构建的。 在汇编过程中,用户程序的代码与这些库链接。 C++或Python编程语言用于编写自定义程序。

NS-3作为源代码分发,这意味着目标系统必须具有软件开发环境,以便首先构建库,然后构建用户程序。 原则上,ns-3 可以作为特定系统的现成库进行分发,并且将来它们可能会以这种方式进行分发。 但现在许多用户实际上是通过编辑 ns-3 本身来完成工作的,因此拥有构建库的源代码很有用。 如果有人愿意承担为操作系统创建现成的库和包的工作,请联系邮件列表 ns-开发者.

接下来,我们将了解下载和构建 ns-3 的三种方法。 第一个是从主站点下载并构建官方版本。 第二个是选择和组装基本 ns-3 安装的开发版本副本。 第三是使用额外的构建工具来加载 ns-3 的更多扩展。 由于工具略有不同,我们将逐一介绍。

有经验的 Linux 用户可能想知道为什么 ns-3 没有像大多数其他使用包管理器的库一样作为包提供? 尽管有适用于各种 Linux 发行版(例如 Debian)的二进制包,但大多数用户最终都会编辑库并必须自己重建 ns-3,因此拥有可用的源代码很方便。 因此,我们将重点关注从源代码安装。

对于大多数应用程序 ns-3 权限 不需要,建议使用非特权用户帐户。

3.2 先决条件

整套可用的 ns-3 库对第三方库有许多依赖项,但大多数情况下 ns-3 可以在支持几个常见(通常默认安装)组件的情况下构建和使用:C++ 编译器、 Python,源代码编辑器(例如, VIM, emacs的 или 月食),如果使用开发存储库,则使用 Git 版本控制系统。 大多数首次使用的用户无需担心他们的配置报告缺少某些 ns-3 高级功能,但对于那些想要完整安装的用户,该项目提供了一个 wiki,其中包含包含许多有用提示和技巧的页面。 其中一个页面是“安装”页面,其中包含各种系统的安装说明,可从以下位置获取: https://www.nsnam.org/wiki/Installation.

本 wiki 的先决条件部分解释了支持常见 ns-3 选项所需的软件包,并提供了用于在常见风格的 Linux 或 macOS 上安装它们的命令。

您可以利用这个机会探索 ns-3 wiki 页面或主网站: https://www.nsnam.org,因为那里有很多信息。 从最新版本的 ns-3 (ns-3.29) 开始,运行 ns-3 需要以下工具:

工具包/版本

  • C++编译器
    clang++ 或 g++(g++ 版本 4.9 或更高版本)
  • 蟒蛇
    python2 版本 >= 2.7.10,或 python3 版本 >=3.4
  • 混帐
    任何最新版本(访问 GitLab.com 上的 ns-3)
  • 焦油
    任何最新版本(用于解压 ns-3 版本)
  • 包压缩2
    任何最新版本(用于解压 ns-3 版本)

要检查 Python 的默认版本,请键入 python -V。 要检查 g++ 版本,请键入 g++ -v。 如果有任何工具丢失或太旧,请参阅 ns-3 wiki 页面上的安装指南。

从现在开始,我们假设读者正在运行Linux、MacOS或Linux模拟器,并且至少拥有上述工具。

3.2.1 下载 ns-3 版本作为源存档

这是想要下载并试验 ns-3 的最新版本和软件包版本的新用户的操作过程。 ns-3 版本作为压缩源档案发布,有时称为 压缩包. 压缩包 是一种特殊的软件存档格式,其中多个文件组合在一起。 存档通常是压缩的。 ns-3 启动过程通过 压缩包 很简单,你只需要选择一个版本,下载并解压它。

假设您作为用户想要在名为的本地目录中构建 ns-3 工作空间。 您可以通过在 Linux 控制台中输入以下内容来获取该版本的工作副本(当然,替换适当的版本号)

$ cd 
$ mkdir workspace 
$ cd workspace 
$ wget https://www.nsnam.org/release/ns-allinone-3.29.tar.bz2 
$ tar xjf ns-allinone-3.29.tar.bz2 

注意上面使用的实用程序 wget的,这是一个用于从 Internet 下载对象的命令行工具。 如果您尚未安装它,您可以使用浏览器来执行此操作。

按照这些步骤,您将进入 ns-allinone-3.29 目录,在那里您应该看到几个文件和目录

$ cd ns-allinone-3.29
$ ls
bake constants.py ns-3.29 README
build.py netanim-3.108 pybindgen-0.17.0.post58+ngcf00cc0 util.py

您现在已准备好构建 ns-3 基础发行版,并且可以继续阅读有关构建 ns-3 的部分。

3.3 使用Git下载ns-3

ns-3 代码可在 GitLab.com 上的 Git 存储库中找到,网址为 https://gitlab.com/nsnam/。 组 恩斯南 汇集了开源项目使用的各种存储库。

开始使用 Git 存储库的最简单方法是分叉或克隆环境 ns-3-蒜酮。 这是一组管理最常用 ns-3 子系统的加载和组装的脚本。 如果您是 Git 新手,您可能会对“fork”和“clone”这两个术语感到陌生; 如果是这样,我们建议您只需克隆(制作自己的副本)位于 GitLab.com 上的存储库,如下所示:

$ cd 
$ mkdir workspace 
$ cd workspace 
$ git clone https://gitlab.com/nsnam/ns-3-allinone.git 
$ cd ns-3-allinone 

在此阶段,您的目录视图 ns-3-蒜酮 与上面描述的发布存档目录略有不同。 它应该看起来像这样:

$ ls
build.py constants.py download.py README util.py

请注意,有一个脚本 下载.py,这将另外提取 ns-3 和随附的源代码。 您可以选择:下载最新的 ns-3 开发快照:

$ python download.py

或者更喜欢使用标志的 ns-3 版本 -n 指示版本号:

$ python download.py -n ns-3.29

这一步之后到目录 ns-3-蒜酮 将下载额外的存储库 ns-3, , pybindgen и 内塔尼姆.

注意
在一台干净的 Ubuntu16.04 机器上,我需要将命令更改为: $ sudo python3 download.py -n ns-3.29 (以下简称译者注)。

3.3.1 使用 Bake 加载 ns-3

以上两种方法(源存档或存储库 ns-3-蒜酮 通过 Git)对于获得带有多个插件的最简单的 ns-3 安装非常有用(pybindgen 生成 Python 绑定和 内塔尼姆 用于网络动画)。 ns-3-allinone 中默认提供的第三个存储库称为 .

是为 ns-3 项目开发的用于从多个存储库协调构建软件的工具。 可用于获取 ns-3 的开发版本,以及下载和构建 ns-3 发行版基本版本的扩展,例如环境 直接代码执行, CradleNetwork 模拟摇篮,创建新的 Python 绑定和各种 ns-3“应用程序”的能力。

注意
CradleNetwork 模拟 Cradle 是一个框架,允许您在网络模拟器中使用真实的 TCP/IP 网络堆栈。

如果您希望 ns-3 安装具有高级或附加功能,则可以遵循此安装路径。

在最新的 ns-3 版本中 已添加到 tar 版本中。 该版本包含一个配置文件,允许您在发布时下载当前的软件版本。 也就是说,例如,版本 随版本 ns-3.29 一起分发,可用于检索该版本 ns-3 或更早版本的组件,但不能用于检索更高版本的组件(如果包描述文件 烘焙配置文件 未更新)。

您还可以获得最新的副本 在 Linux 控制台中输入以下命令(假设您已安装 Git):

$ cd 
$ mkdir workspace 
$ cd workspace 
$ git clone https://gitlab.com/nsnam/bake.git

当您运行 git 命令时,您应该看到类似以下内容:

Cloning into 'bake'...
remote: Enumerating objects: 2086, done. 
remote: Counting objects: 100% (2086/2086), done. 
remote: Compressing objects: 100% (649/649), done. 
remote: Total 2086 (delta 1404), reused 2078 (delta 1399) 
Receiving objects: 100% (2086/2086), 2.68 MiB | 3.82 MiB/s, done. 
Resolving deltas: 100% (1404/1404), done.

命令完成后 克隆 你应该有一个名为 ,其内容应如下所示:

$ cd bake
$ ls
bake bakeconf.xml bake.py doc examples generate-binary.py test TODO

请注意,您已经加载了多个 Python 脚本,一个名为的 Python 模块 和一个 XML 配置文件。 下一步是使用这些脚本下载并构建您选择的 ns-3 发行版。 有多个自定义目标可用:

  1. ns-3.29:release对应的模块; 它将下载与 tarball 中的版本类似的组件;

  2. ns-3-dev:类似的模块,但使用开发树中的代码;

  3. ns-蒜酮-3.29:包含其他附加功能的模块,例如 Click 路由和网络模拟 Cradle、Openflow for ns-3。

  4. ns-3-蒜酮:与模块的release版本类似 ALLINONE,但用于开发代码。

注意
点击 — 用于创建路由器的模块化软件架构。

Openflow是一种用于管理路由器和交换机通过数据网络传输的数据处理过程的协议,实现软件定义的网络技术。

当前的开发快照(非发布)ns-3 可以在以下位置找到:https://gitlab.com/nsnam/ns-3-dev.git.

开发人员试图使这些存储库保持一致的工作顺序,但它们位于开发区域并包含未发布的代码,因此如果您不打算使用新功能,请选择正式版本。

您可以通过浏览存储库列表或访问 ns-3 Releases 网页来找到最新版本的代码:https://www.nsnam.org/releases/ 并单击最新版本链接。 在此示例中,我们将继续使用 ns-3.29。

现在,为了获取我们需要的 ns-3 组件,我们将使用该工具 。 我们先简单介绍一下这项工作 .

Bake 的工作原理是将包源加载到目录中 资源 并将库安装到构建目录中。 可以通过引用二进制文件来运行,但是如果你想运行 不是从下载的目录,建议添加路径 到您的路径(PATH 环境变量),例如如下(Linux bash shell 的示例)。 进入“bake”目录,然后设置以下环境变量:

$ export BAKE_HOME=`pwd` 
$ export PATH=$PATH:$BAKE_HOME:$BAKE_HOME/build/bin 
$ export PYTHONPATH=$PYTHONPATH:$BAKE_HOME:$BAKE_HOME/build/lib

这将把程序 烘焙.py 到 shell 路径,并允许其他程序找到它创建的可执行文件和库 。 在某些用例中 ,上述 PATH 和 PYTHONPATH 设置不是必需的,但 ns-3-allinone 的完整构建(带有附加包)通常需要它。

转到您的工作目录并在控制台中输入以下内容:

$ ./bake.py configure -e ns-3.29

接下来我们会问 检查我们是否有足够的工具来加载各种组件。 拨号:

$ ./bake.py check

您应该看到类似以下内容:

> Python - OK 
> GNU C++ compiler - OK 
> Mercurial - OK 
> Git - OK 
> Tar tool - OK 
> Unzip tool - OK 
> Make - OK 
> cMake - OK 
> patch tool - OK 
> Path searched for tools: /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin ...

特别是Mercurial、CVS、Git和Bazaar等上传工具在这一步中是必不可少的,因为它们可以让我们获取代码。 此时,请按照系统的常规方式安装缺少的工具(如果您知道如何操作)或联系系统管理员寻求帮助。

接下来,尝试下载该软件:

$ ./bake.py download

结果应该是这样的:

>> Searching for system dependency setuptools - OK 
>> Searching for system dependency libgoocanvas2 - OK 
>> Searching for system dependency gi-cairo - OK 
>> Searching for system dependency pygobject - OK 
>> Searching for system dependency pygraphviz - OK 
>> Searching for system dependency python-dev - OK 
>> Searching for system dependency qt - OK 
>> Searching for system dependency g++ - OK 
>> Downloading pybindgen-0.19.0.post4+ng823d8b2 (target directory:pybindgen) - OK 
>> Downloading netanim-3.108 - OK 
>> Downloading ns-3.29 - OK

这意味着已经下载了三个源。 现在转到源目录并输入 ls; 你应该看到:

$ cd source 
$ ls
netanim-3.108 ns-3.29 pybindgen

现在您已准备好构建 ns-3 发行版。

3.4 组装ns-3

与下载 ns-3 一样,构建 ns-3 有多种方法。 我们要强调的主要事情是 ns-3 是使用名为的构建工具构建的 WAF如下面所描述的。 大多数用户将使用 WAF,但是有一些方便的脚本可以帮助您开始或组织更复杂的构建。 所以请在阅读之前 WAF, 看一眼 构建.py 并组装 .

3.4.1 使用build.py构建

警告! 此构建步骤仅适用于如上所述获得的源存档版本; 并且不是通过 git 或 Baker 下载的。

使用发布存档时 压缩包ns-3-蒜酮 有一个方便的脚本可以使组件的组装变得更容易。 它称为 build.py。 该程序将以最有用的方式为您设置项目。 但是,请注意,更高级的设置和使用 ns-3 通常涉及使用 ns-3 自己的构建系统 Waf,本教程稍后将介绍该系统。

如果您使用下载 压缩包,然后在你的目录中 〜/工作区 名称类似的目录 ns-蒜酮-3.29。 输入以下内容:

$ ./build.py --enable-examples --enable-tests

打电话的时候 构建.py 我们使用命令行参数来构建本教程中使用的示例和测试,这些示例和测试在 ns-3 中默认不构建。 默认情况下,该程序还会构建所有可用的模块。 然后,如果您愿意,您可以在没有示例和测试的情况下构建 ns-3,或者排除您的工作不需要的模块。

当脚本构建您已加载的各个部分时,您将看到脚本显示的许多编译器输出消息。 首先,脚本将尝试构建动画师 内塔尼姆,然后是绑定生成器 pybindgen 最后是 ns-3。 该过程完成后,您应该看到以下内容:

Waf: Leaving directory '/path/to/workspace/ns-allinone-3.29/ns-3.29/build'
'build' finished successfully (6m25.032s) 

Modules built:
antenna                aodv                     applications
bridge                 buildings                config-store
core                   csma                     csma-layout
dsdv                   dsr                      energy 
fd-net-device          flow-monitor             internet
internet-apps          lr-wpan                  lte
mesh                   mobility                 mpi
netanim (no Python)    network                  nix-vector-routing 
olsr                   point-to-point           point-to-point-layout 
propagation            sixlowpan                spectrum 
stats                  tap-bridge               test (no Python) 
topology-read          traffic-control          uan 
virtual-net-device     visualizer               wave 
wifi                   wimax 

Modules not built (see ns-3 tutorial for explanation):
brite                  click                    openflow 
Leaving directory ./ns-3.29

在清单的最后三行中,我们看到一条有关未构建模块的消息:

Modules not built (see ns-3 tutorial for explanation):
brite                     click

这仅意味着某些依赖于外部库的 ns-3 模块可能尚未构建,或者不需要为此配置构建它们。 这并不意味着模拟器未组装或组装的模块无法正常工作。

3.4.2 使用烘焙进行构建

如果您使用上面的bake从项目存储库获取源代码,您可以继续使用它来构建ns-3。 拨号:

$ ./bake.py build

你应该看到类似的东西:

>> Building pybindgen-0.19.0.post4+ng823d8b2 - OK 
>> Building netanim-3.108 - OK 
>> Building ns-3.29 - OK

帮助:您还可以通过调用“bake.py deploy”同时执行下载和构建步骤。

组装所有组件可能会失败,但如果不需要组件,组装将继续。 例如,最近的一个可移植性问题是 演员表 可以通过工具组装 并非在所有平台上。 在这种情况下,将出现如下消息:

>> Building castxml - Problem 
> Problem: Optional dependency, module "castxml" failed
This may reduce the functionality of the final build.
However, bake will continue since "castxml" is not an essential dependency.
For more information call bake with -v or -vvv, for full verbose mode.

然而 演员表 仅当您想要创建更新的 Python 绑定时才需要。 对于大多数用户来说,不需要这样做(至少在他们更改 ns-3 之前),因此现在可以安全地忽略此类警告。

如果失败,以下命令将为您提供有关缺少依赖项的提示:

$ ./bake.py show

将列出您尝试构建的包的各种依赖项。

3.4.3 使用 Waf 构建

到目前为止,为了开始构建 ns-3,我们使用了以下脚本 构建.py,或工具 。 这些工具对于构建 ns-3 和维护库非常有用。 事实上,为了构建,他们运行构建工具 WAF 来自目录 ns-3。 WAF 使用 ns-3 源代码安装。 大多数用户很快就会直接使用来配置和组装 ns-3 WAF。 因此,要继续,请转到您最初创建的 ns-3 目录。

目前这并不是严格要求的,但回溯一下并了解如何更改项目配置将很有用。 您可以进行的最有用的配置更改可能是创建代码的优化版本。 默认情况下,您已将项目配置为构建调试版本。 让我们看一下创建优化构建的项目。 为了向 Waf 解释它应该进行包含示例和测试的优化构建,您需要运行以下命令:

$ ./waf clean 
$ ./waf configure --build-profile=optimized --enable-examples --enable-tests

这将启动 WAF 本地目录之外(为了您的方便)。 第一个命令清除以前的构建,这通常不是绝对必要的,但这是一个很好的做法(另请参阅下面的构建配置文件); 这将删除目录中先前创建的库和目标文件 建立/。 重新配置项目并且构建系统检查各种依赖项时,您应该看到类似于以下内容的输出:

Setting top to      : /home/ns3user/workspace/bake/source/ns-3-dev
Setting out to      : /home/ns3user/workspace/bake/source/ns-3-dev/build
Checking for 'gcc' (C compiler)        : /usr/bin/gcc 
Checking for cc version                : 7.3.0 
Checking for 'g++' (C++ compiler)      : /usr/bin/g++ 
Checking for compilation flag -march=native support : ok 
Checking for compilation flag -Wl,--soname=foo support : ok 
Checking for compilation flag -std=c++11 support       : ok 
Checking boost includes   : headers not found, please ,!provide a --boost-includes argument (see help) 
Checking boost includes   : headers not found, please ,!provide a --boost-includes argument (see help) 
Checking for program 'python'            : /usr/bin/python 
Checking for python version >= 2.3       : 2.7.15 python-config                                                                     : /usr/bin/python-config
Asking python-config for pyembed '--cflags --libs --ldflags' flags : yes
Testing pyembed configuration                                      : yes
Asking python-config for pyext '--cflags --libs --ldflags' flags   : yes
Testing pyext configuration                                        : yes

Checking for compilation flag -fvisibility=hidden support          : ok 
Checking for compilation flag -Wno-array-bounds support            : ok 
Checking for pybindgen location          : ../pybindgen ,!(guessed) 
Checking for python module 'pybindgen'   : 0.19.0. ,!post4+g823d8b2 
Checking for pybindgen version           : 0.19.0. ,!post4+g823d8b2 
Checking for code snippet                : yes 
Checking for types uint64_t and unsigned long equivalence : no 
Checking for code snippet                                 : no 
Checking for types uint64_t and unsigned long long equivalence     : yes 
Checking for the apidefs that can be used for Python bindings                       : gcc-LP64 
Checking for internal GCC cxxabi         : complete 
Checking for python module 'pygccxml'    : not found 
Checking for click location              : not found 
Checking for program 'pkg-config'        : /usr/bin/pkg- ,!config 
Checking for 'gtk+-3.0'                  : not found 
Checking for 'libxml-2.0'                : yes 
checking for uint128_t                   : not found 
checking for __uint128_t                 : yes 
Checking high precision implementation   : 128-bit integer ,!(default) 
Checking for header stdint.h             : yes 
Checking for header inttypes.h           : yes 
Checking for header sys/inttypes.h       : not found 
Checking for header sys/types.h          : yes 
Checking for header sys/stat.h           : yes 
Checking for header dirent.h             : yes 
Checking for header stdlib.h             : yes 
Checking for header signal.h             : yes 
Checking for header pthread.h            : yes 
Checking for header stdint.h             : yes 
Checking for header inttypes.h           : yes 
Checking for header sys/inttypes.h       : not found
Checking for library rt                  : yes 
Checking for header sys/ioctl.h          : yes 
Checking for header net/if.h             : yes 
Checking for header net/ethernet.h       : yes 
Checking for header linux/if_tun.h       : yes 
Checking for header netpacket/packet.h   : yes 
Checking for NSC location                : not found 
Checking for 'sqlite3'                   : not found 
Checking for header linux/if_tun.h       : yes 
Checking for python module 'gi'          : 3.26.1 
Checking for python module 'gi.repository.GObject'      : ok 
Checking for python module 'cairo'                      : ok 
Checking for python module 'pygraphviz'                 : 1.4rc1 
Checking for python module 'gi.repository.Gtk'          : ok 
Checking for python module 'gi.repository.Gdk'          : ok 
Checking for python module 'gi.repository.Pango'        : ok 
Checking for python module 'gi.repository.GooCanvas'    : ok 
Checking for program 'sudo'                             : /usr/bin/sudo 
Checking for program 'valgrind'                         : not found 
Checking for 'gsl' : not found python-config            : not found 
Checking for compilation flag -fstrict-aliasing support : ok 
Checking for compilation flag -fstrict-aliasing support : ok 
Checking for compilation flag -Wstrict-aliasing support : ok 
Checking for compilation flag -Wstrict-aliasing support : ok 
Checking for program 'doxygen'                          : /usr/bin/doxygen
---- Summary of optional ns-3 features:
Build profile : optimized
Build directory : 
BRITE Integration : not enabled (BRITE not enabled (see option --with- ,!brite)) 
DES Metrics event collection : not enabled (defaults to disabled) 
Emulation FdNetDevice        : enabled 
Examples                     : enabled 
File descriptor NetDevice    : enabled 
GNU Scientific Library (GSL) : not enabled (GSL not found) 
Gcrypt library               : not enabled
(libgcrypt not found: you can use ,!libgcrypt-config to find its location.) GtkConfigStore               : not enabled (library 'gtk+-3.0 >= 3.0' not fou   nd)
MPI Support                  : not enabled (option --enable-mpi not selected)
ns-3 Click Integration       : not enabled (nsclick not enabled (see option --with- ,!nsclick))
ns-3 OpenFlow Integration   : not enabled (Required boost libraries not found) 
Network Simulation Cradle    : not enabled (NSC not found (see option --with-nsc))
PlanetLab FdNetDevice         : not enabled (PlanetLab operating system not detected ,!(see option --force-planetlab)) PyViz visualizer : enabled 
Python API Scanning Support   : not enabled (Missing 'pygccxml' Python module)
Python Bindings : enabled 
Real Time Simulator           : enabled 
SQlite stats data output      : not enabled (library 'sqlite3' not found)
Tap Bridge                    : enabled 
Tap FdNetDevice               : enabled
Tests                         : enabled 
Threading Primitives          : enabled 
Use sudo to set suid bit   : not enabled (option --enable-sudo not selected)
XmlIo                         : enabled
'configure' finished successfully (6.387s)

请注意上面列表的最后部分。 某些 ns-3 选项默认情况下未启用或需要系统支持才能正常运行。 例如,要启用 XmlTo,该库必须存在于系统上 libxml-2.0。 如果未找到该库且未启用相应的 ns-3 功能,则会显示一条消息。 另请注意,可以使用命令 须藤 为某些程序设置 suid 位“运行时设置组 ID”。 默认情况下未启用,因此此功能显示为“未启用”。 最后,要获取已启用选项的列表,请使用 WAF 带参数 --check-config.

现在让我们返回并切换回包含示例和测试的调试版本。

$ ./waf clean 
$ ./waf configure --build-profile=debug --enable-examples --enable-tests

构建系统现已设置完毕,您只需键入以下内容即可构建 ns-3 程序的调试版本:

$ ./waf

上述步骤可能迫使您两次构建 ns-3 系统的一部分,但现在您知道如何更改配置并构建优化的代码。

要检查给定项目配置哪个配置文件处于活动状态,可以使用以下命令:

$ ./waf --check-profile 
Waf: Entering directory `/path/to/ns-3-allinone/ns-3.29/build' 
Build profile: debug

上述场景 构建.py 也支持论证 --enable-examples и --enable-tests,但还有其他选择 WAF 它不直接支持。 例如,这是行不通的:

$ ./build.py --disable-python

反应会是这样的:

build.py: error: no such option: --disable-python

但是,特殊运算符 - - 可用于通过以下方式传递附加参数 WAF因此,代替上面的命令,以下命令将起作用:

$ ./build.py -- --disable-python

因为它生成了主命令 ./waf 配置 --disable-python。 这里有一些更多的介绍性提示 WAF.

处理构建错误

ns-3 版本在常见 Linux 和 MacOS 发行版上发布时可用的最新 C++ 编译器上进行了测试。 然而,随着时间的推移,新的发行版会发布新的编译器,而这些新的编译器往往对警告更加迂腐。 ns-3 将其构建配置为将所有警告视为错误,因此有时如果您在较新的系统上运行旧版本,编译器警告可能会停止构建。

例如,之前有一个针对 Fedora 3.28 的 ns-28 版本,其中包括一个新的主要版本 GCC (海湾合作委员会-8)。 在 Fedora 3.28 下构建 ns-28 或更早版本,安装 Gtk2+ 时,会出现以下错误:

/usr/include/gtk-2.0/gtk/gtkfilechooserbutton.h:59:8: error: unnecessary parentheses ,!in declaration of ‘__gtk_reserved1’ [-Werror=parentheses] void (*__gtk_reserved1);

在从 ns-3.28.1 开始的版本中, WAF 有一个选项可以解决这些问题。 它禁止在 g++ 和 clang++ 中设置“-Werror”标志。 这是“--disable-werror”选项,必须在配置期间应用:

$ ./waf configure --disable-werror --enable-examples --enable-tests

配置或组装

一些命令 WAF 仅在配置阶段有意义,有些仅在构建阶段有效。 例如,如果要使用 ns-3 仿真功能,可以启用该位设置 SUID 使用 须藤, 如上所述。 这将覆盖配置步骤命令,因此您可以使用以下命令更改配置,其中还包括示例和测试。

$ ./waf configure --enable-sudo --enable-examples --enable-tests

如果你这样做 WAF 将启动 须藤更改模拟代码套接字创建程序以使用权限运行 。 在 WAF 还有许多其他选项可用于配置和构建步骤。 要探索您的选项,请输入:

$ ./waf --help

在下一节中,我们将使用一些与测试相关的选项。

装配型材

我们已经了解了如何配置 WAF 用于装配 调试 и 优化:

$ ./waf --build-profile=debug

还有一个中间装配型材, 释放。 选项 -d 是同义词 --build-profile。 构建配置文件控制日志记录、断言和编译器优化开关的使用:

ns-3 网络模拟器教程。 第3章

如您所见,日志记录和断言仅在调试版本中可用。 建议的做法是在调试模式下开发脚本,然后在优化的构建配置文件中执行重复运行(用于统计或参数更改)。

如果您的代码只能在某些构建配置文件中运行,请使用代码包装器宏:

NS_BUILD_DEBUG (std::cout << "Part of an output line..." << std::flush; timer.Start ,!()); DoLongInvolvedComputation ();
NS_BUILD_DEBUG (timer.Stop (); std::cout << "Done: " << timer << std::endl;)

默认情况下 WAF 将构建工件放在构建目录中。 您可以使用选项指定不同的输出目录 - -out例如:

$ ./waf configure --out=my-build-dir

通过将其与构建配置文件相结合,您可以轻松地在不同的编译选项之间切换:

$ ./waf configure --build-profile=debug --out=build/debug
$ ./waf build
... 
$ ./waf configure --build-profile=optimized --out=build/optimized 
$ ./waf build
...

这允许您使用多个程序集,而不必每次都重写最新的程序集。 当您切换到另一个配置文件时, WAF 将仅编译它,而不完全重新编译所有内容。

当您以这种方式切换构建配置文件时,您需要小心每次都提供相同的配置选项。 定义几个环境变量将帮助您避免错误:

$ export NS3CONFIG="--enable-examples --enable-tests" 
$ export NS3DEBUG="--build-profile=debug --out=build/debug"
$ export NS3OPT=="--build-profile=optimized --out=build/optimized" 

$ ./waf configure $NS3CONFIG $NS3DEBUG
$ ./waf build 
... 
$ ./waf configure $NS3CONFIG $NS3OPT
$ ./waf build

编译器和标志

在上面的例子中 WAF 构建 ns-3 使用 GCC 中的 C++ 编译器( 克++)。 但是,您可以更改您使用的 WAF C++编译器,通过定义CXX环境变​​量。 例如,要使用C++编译器Clang、clang++,

$ CXX="clang++" ./waf configure 
$ ./waf build 

同样的方式也可以配置 WAF 使用分布式编译 分区:

$ CXX="distcc g++" ./waf configure 
$ ./waf build

有关 distcc 和分布式编译的更多信息可以在项目页面的文档部分找到。 要在配置 ns-3 时添加编译器标志,请使用 CXXFLAGS_EXTRA 环境变量。

安装

WAF 可用于在系统上的不同位置安装库。 默认情况下,编译的库和可执行文件位于目录中 建立,并且由于 Waf 知道这些库和可执行文件的位置,因此无需在其他地方安装这些库。

如果用户喜欢在构建目录之外安装,可以运行命令 ./waf 安装。 安装的默认前缀是 在/ usr /本地因此 ./waf 安装 将安装程序 在/ usr / local / bin目录,图书馆在 在/ usr / local / lib目录 和头文件在 /usr/local/包括。 超级用户权限通常需要设置默认前缀,因此典型的命令是 须藤 ./waf 安装。 启动时,Waf 将首先选择使用构建目录中的共享库,然后沿着本地环境中配置的库的路径查找库。 因此,在系统上安装库时,最好检查是否使用了正确的库。 用户可以通过在配置期间传递选项来选择使用不同的前缀进行安装 --prefix例如:

./waf configure --prefix=/opt/local

如果稍后,构建后,用户输入安装命令 ./waf,将使用前缀 /选择/本地.

团队 ./waf clean 如果安装将使用,则必须在重新配置项目之前使用 WAF 在不同的前缀下。

因此,要使用 ns-3 无需调用 ./waf install。 大多数用户不需要此命令,因为 WAF 将从构建目录中获取当前库,但如果某些用户的活动涉及使用 ns-3 目录之外的程序,则某些用户可能会发现这很有用。

瓦夫单曲

在 ns-3 源代码树的顶层,只有一个 Waf 脚本。 一旦开始工作,你会花很多时间在目录上 scratch/ 或更深入地src/... 同时必须运行 WAF。 你只需记住你在哪里然后跑就可以了 WAF 如下所示:

$ ../../../waf ...

但这会很乏味并且容易出错,所以有更好的解决方案。 一种常见的方法是使用文本编辑器,例如 emacs的 или VIM,其中打开两个终端会话,一个用于构建 ns-3,第二个用于编辑源代码。 如果你只有 压缩包,那么环境变量可以帮助:

$ export NS3DIR="$PWD" 
$ function waff { cd $NS3DIR && ./waf $* ; } 

$ cd scratch 
$ waff build

在模块目录中,可能会很想添加一个简单的 waf 脚本,例如 exec ../../waf。 “请不要那样做。” 这会让新手感到困惑,如果做得不好,会导致难以检测的构建错误。 上面显示的解决方案是应该使用的路径。

3.5 测试ns-3

您可以通过运行脚本来运行 ns-3 发行版的单元测试 ./测试.py:

$ ./test.py

这些测试与 WAF。 最终您应该看到一条消息:

92 of 92 tests passed (92 passed, 0 failed, 0 crashed, 0 valgrind errors)

这是识别 valgrind 崩溃、崩溃或错误的重要消息,表明代码存在问题或工具和代码之间不兼容。

您还将看到最终输出 WAF 以及运行每个测试的测试人员,看起来像这样:

Waf: Entering directory `/path/to/workspace/ns-3-allinone/ns-3-dev/build' 
Waf: Leaving directory `/path/to/workspace/ns-3-allinone/ns-3-dev/build' 
'build' finished successfully (1.799s) 

Modules built:
aodv           applications          bridge
click          config-store          core
csma           csma-layout           dsdv
emu            energy                flow-monitor
internet       lte                   mesh
mobility       mpi                   netanim
network        nix-vector-routing    ns3tcp
ns3wifi        olsr                  openflow
point-to-point point-to-point-layout propagation
spectrum       stats                 tap-bridge
template       test                  tools
topology-read  uan                   virtual-net-device
visualizer     wifi                  wimax

PASS: TestSuite ns3-wifi-interference
PASS: TestSuite histogram 

...

PASS: TestSuite object
PASS: TestSuite random-number-generators
92 of 92 tests passed (92 passed, 0 failed, 0 crashed, 0 valgrind errors)

用户通常运行此命令来快速验证 ns-3 发行版是否已正确构建。 (请注意,“PASS: ...”行的顺序可能不同,这是正常的。重要的是报告末尾的摘要行显示所有测试都已通过;没有测试失败或崩溃。)和 WAF测试文件 将在机器的可用处理器核心上并行工作。

3.6 运行脚本

我们通常在控制下运行脚本 WAF。 这允许构建系统确保共享库路径设置正确并且库在运行时可用。 要运行该程序,只需使用 WAF 带参数 - -run。 让我们运行 ns-3 相当于无处不在的程序 你好世界通过输入以下内容:

$ ./waf --run hello-simulator

Waf 将首先检查程序是否正确构建,并在必要时进行构建。 然后 WAF 将执行一个产生以下输出的程序。

Hello Simulator

恭喜! 您现在是 ns-3 用户了!

如果我没有看到结果,我该怎么办?

如果您看到消息 WAF表明构建成功完成,但您看不到输出 《你好模拟器》,那么有可能在 [Build-with-Waf] 部分中您将构建模式切换为 优化,但错过了切换回模式 调试。 本教程中使用的所有控制台输出都使用特殊的 ns-3 组件,该组件执行日志记录并用于将自定义消息打印到控制台。 当编译优化代码时,该组件的输出将自动禁用 - 它是“优化的”。 如果您没有看到“Hello Simulator”输出,请输入以下内容:

$ ./waf configure --build-profile=debug --enable-examples --enable-tests

定制 WAF 构建 ns-3 程序的调试版本,其中包括示例和测试。 然后,您应该通过键入以下内容来重建代码的当前调试版本

$ ./waf

现在如果你运行该程序 你好模拟器,您应该会看到预期的结果。

3.6.1 命令行参数

要将命令行参数传递给 ns-3 程序,请使用以下模式:

$ ./waf --run <ns3-program> --command-template="%s <args>"

代替到你的程序的名称和参数。 争论 - -command-templateWAF 本质上是构建实际命令行的秘诀 WAF 用于执行程序。 Waf 检查构建是否完成,设置共享库路径,然后使用提供的命令行模板并用程序名称替换 %s 占位符来调用可执行文件。 如果您发现此语法很复杂,有一个更简单的版本,其中涉及 ns-3 程序及其用单引号括起来的参数:

$ ./waf --run '<ns3-program> --arg1=value1 --arg2=value2 ...'

另一个特别有用的例子是有选择地运行测试套件。 我们假设有一个名为 mytest 的测试套件(实际上没有)。 上面我们使用./test.py脚本并行运行多个测试,其中重复调用测试程序 测试运行器。 称呼 测试运行器 直接运行一个测试:

$ ./waf --run test-runner --command-template="%s --suite=mytest --verbose"

参数将传递给程序 测试运行器。 由于 mytest 不存在,因此将生成错误消息。 要打印可用的测试运行程序选项,请输入:

$ ./waf --run test-runner --command-template="%s --help"

3.6.2 调试

要在另一个实用程序(例如调试器)下运行 ns-3 程序(例如, GDB)或内存测试工具(例如, 瓦尔格林德),使用类似的形式 - -command-template = "…"。 例如,在调试器中运行 GDB 你的 hello-simulator ns-3 程序带有参数:

$ ./waf --run=hello-simulator --command-template="gdb %s --args <args>"

请注意,ns-3 程序名称带有参数 - -run,以及管理实用程序(此处 GDB) 是参数中的第一个标记 - -command-template。 选项 - -args 报告 GDB命令行的其余部分属于“较低”程序。 (部分版本 GDB 不明白该选项 - -args。 在这种情况下,请从以下位置删除程序参数 - -command-template 并使用命令集 GDB ARGS.)我们可以结合这个配方和前一个配方在调试器下运行测试:

$ ./waf --run test-runner --command-template="gdb %s --args --suite=mytest --verbose"

3.6.3 工作目录

Waf 应从 ns-3 树顶部的位置启动。 该文件夹将成为写入输出文件的工作目录。 但是如果您想将这些文件保留在 ns-3 源代码树之外怎么办? 使用参数 - -cwd:

$ ./waf --cwd=...

您可能会发现在工作目录中获取输出文件更方便。 在这种情况下,以下间接措施会有所帮助:

$ function waff {
CWD="$PWD" 
cd $NS3DIR >/dev/null 
./waf --cwd="$CWD" $*
cd - >/dev/null 
}

该命令的先前版本的此修饰保留了当前工作目录,转到该目录 WAF然后指示 WAF 将工作目录更改回启动程序之前保存的当前工作目录。 我们提到团队 - -cwd 为了完整起见,大多数用户只是从顶级目录运行 Waf 并在那里生成输出文件。

续:第 4 章

来源: habr.com

添加评论