Учебник по симулятору сети ns-3. Глава 3



главы 1,2


3 Приступая к работе
3.1 Обзор
3.2 Предварительные условия
3.2.1 Загрузка релиза ns-3 в виде архива исходников
3.3 Скачивание ns-3 с помощью Git
3.3.1 Загрузка ns-3 с помощью Bake
3.4 Сборка ns-3
3.4.1 Сборка с помощью build.py
3.4.2 Сборка с Bake
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-developers.


Далее мы рассмотрим три способа загрузки и сборки ns?3. Первый заключается в том, чтобы загрузить и построить официальный релиз с основного сайта. Второй — это отбор и сборка копий девелоперских версий базовой установки ns?3. Третий — использование дополнительных инструментов сборки для загрузки большего количества расширений для ns?3. Мы пройдемся по каждому, так как инструменты немного отличаются.


Опытные пользователи Linux могут задаться вопросом, почему ns?3 не предоставляется в виде пакета, как большинство других библиотек, использующих менеджер пакетов? Несмотря на то, что существуют бинарные пакеты для различных дистрибутивов Linux (например, Debian), большинство пользователей в конечном итоге редактируют библиотеки и вынуждены сами пересобирать ns?3, поэтому доступность исходного кода удобна. По этой причине мы уделим внимание установке из исходного кода.


Для большинства применений ns?3 права root не нужны, рекомендуется использовать непривилегированную учетную запись пользователя.


3.2 Предварительные условия


Весь набор доступных библиотек ns?3 имеет ряд зависимостей от сторонних библиотек, но по большей части ns?3 может быть собран и использоваться с поддержкой нескольких распространенных (часто установленных по умолчанию) компонентов: компилятор C++, Python, редактор исходного кода (например, vim, emacs или Eclipse) и, если используются репозитории разработки, системы контроля версий Git. Большинству начинающих пользователей не нужно беспокоиться, если их конфигурация сообщает о некоторых недостающих дополнительных функциях ns?3, но для тех, кто желает полной установки, проект предоставляет вики, которая включает в себя страницы со множеством полезных советов и подсказок. Одной из таких страниц является страница «Установка» с инструкциями по установке для различные системы, доступные по адресу: https://www.nsnam.org/wiki/Installation.


Раздел «Предварительные условия» этой вики-страницы объясняет, какие пакеты требуются для поддержки общих опций ns?3, а также предоставляет команды, используемые для их установки в распространенных вариантах Linux или macOS.


Вы можете воспользоваться такой возможностью, как изучение вики-страницы ns?3 или основного веб-сайта: https://www.nsnam.org, так как там много информации. Начиная с последней версии ns?3 (ns?3.29), для запуска ns?3 необходимы следующие инструменты:


Инструмент Пакет/версия


  • Компилятор C++
    clang++ или g++ (g++ версия 4.9 или больше)
  • Python
    python2 версия >= 2.7.10, или python3 версия >=3.4
  • Git
    любая последняя версия (для доступа к ns?3 на GitLab.com)
  • tar
    любая последняя версия (для распаковки релиза ns?3)
  • bunzip2
    любая свежая версия (для распаковки релиза ns?3)

Чтобы проверить версию Python установленную по умолчанию, введите python -V. Чтобы проверить версию g++, введите g++ -v. Если какие-то инструменты отсутствуют или слишком старые, обратитесь к руководству по установке на вики-странице ns?3.


С этого момента, мы полагаем, что читатель работает в Linux, MacOS или эмуляторе окружения Linux, и имеет по крайней мере вышеуказанные инструменты.


3.2.1 Загрузка релиза ns-3 в виде архива исходников


Это способ действий нового пользователя, который хочет загрузить и поэкспериментировать с последними релизными и пакетными версиями ns?3. Релизы ns?3 публикуются в виде сжатых архивов исходников, иногда называемых tarball. tarball — это особый формат программного архива, в котором несколько файлов объединены вместе. Архив обычно сжат. Процесс загрузки ns?3 через tarball прост, вам только нужно выбрать релиз, скачать и распаковать его.


Предположим, что вы, как пользователь, хотите собрать ns?3 в локальной директории с именем workspace. Вы сможете получить рабочую копию релиза, введя в консоли 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, которая является инструментом командной строки для скачивания объектов из Интернета. Если вы не устанавливали его, то можете использовать для этого браузер.


Следуя этим шагам, вы перейдете в директорию 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 Скачивание ns-3 с помощью Git


Код ns?3 доступен в репозиториях Git на сервисе GitLab.com по адресу https://gitlab.com/nsnam/. Группа nsnam объединяет различные репозитории, используемые проектом с открытым исходным кодом.


Самый простой способ начать использовать репозитории Git — это сделать форк или клонировать окружение ns?3-allinone. Это набор скриптов, который управляет загрузкой и сборкой наиболее часто используемых подсистем ns?3. Если вы новичок в Git, термины "форк" и "клонирование" могут быть вам незнакомы; если это так, мы рекомендуем вам просто клон (создайте свою собственную копию) хранилища, находящегося на GitLab.com, следующим образом:


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

На этом этапе вид вашей директории ns?3-allinone немного отличается от описанной выше директории с архивом релиза. Она должна выглядеть примерно так:


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

Обратите внимание на наличие скрипта download.py, который дополнительно извлечет ns?3 и сопутствующий исходный код. Здесь у вас есть выбор: либо загрузить самый последний снапшот разработки ns?3:


$ python download.py

или предпочесть релиз ns?3, используя флаг -n для указания номера релиза:


$ python download.py -n ns-3.29

После этого шага в директорию ns?3-allinone будут загружены дополнительные репозитории ns?3, bake, pybindgen и netanim.


Примечание
На машине с чистой Ubuntu16.04 мне потребовалось изменить команду к такому виду: $ sudo python3 download.py -n ns-3.29 (здесь и далее примечания переводчика).


3.3.1 Загрузка ns-3 с помощью Bake


Два вышеупомянутых метода (архив исходников или репозиторий ns?3-allinone через Git) полезны для получения наиболее простой установки ns?3 с несколькими аддонами(pybindgen для генерации привязок Python и netanim для анимирования сети). Третий репозиторий, предоставляемый по умолчанию в ns?3-allinone, называется bake.


Bake — это инструмент для скоординированной сборки программного обеспечения из нескольких репозиториев, разработанный для проекта ns?3. Bake может использоваться для получения девелоперских версий ns?3, а также для загрузки и сборки расширений базовой версии дистрибутива ns?3, таких как среда Direct Code Execution, CradleNetwork Simulation Cradle, возможность создания новых привязок Python и различные «приложения» ns?3.


Примечание
CradleNetwork Simulation Cradle — фреймворк, который позволяет внутри сетевого симулятора использовать реальные сетевые стеки TCP / IP.


Если вы предполагаете, что ваша установка ns?3 должна иметь расширенные или дополнительные функции, вы можете следовать этому пути установки.


В последних релизах ns?3 Bake был добавлен в tar-релиз. В релиз включен файл конфигурации, позволяющий скачивать актуальные на момент создания релиза версии программного обеспечения. То есть, например, версия Bake, которая распространяется с релизом ns?3.29, может использоваться для получения компонентов для этого релиза ns?3 или ранее, но не может использоваться для извлечения компонентов для более поздних релизов (если файл описания пакета bakeconf.xml не обновлен).


Вы также можете получить самую свежую копию bake, введя следующую команду в вашу консоль 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.

После завершения команды clone у вас должна появиться директория с именем bake, содержимое которой должно выглядеть примерно так:


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

Обратите внимание, что вы загрузили несколько скриптов Python, модуль Python с именем bake и файл конфигурации XML. Следующим шагом будет использование этих скриптов для загрузки и сборки дистрибутива ns?3 по вашему выбору. Доступно несколько целей настройки:


  1. ns?3.29: модуль, соответствующий релизу; он будет загружать компоненты, аналогичные релизу в tarball;


  2. ns?3-dev: аналогичный модуль, но с использованием кода из дерева разработки;


  3. ns-allinone-3.29: модуль, который включает в себя другие дополнительные функции, такие как Click маршрутизация и Network Simulation Cradle, Openflow для ns-3.


  4. ns?3-allinone: аналогично релизной версии модуля allinone, но для кода разработки.



Примечание
Click — модульная программная архитектура для создания маршрутизаторов.


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. Скажем несколько вводных слов о работе Bake.


Bake работает, загружая исходники пакетов в директорию source и устанавливая библиотеки в сборочную директорию. Bake можно запустить, ссылаясь на двоичный файл, но если вы хотите запускать Bake не из директории, в которую он был загружен, желательно добавить путь к bake в ваш путь (переменную окружения PATH), например, следующим образом (пример для оболочки Linux bash). Перейдите в директорию «bake», а затем установите следующие переменные среды:


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

Это поместит программу bake.py в путь оболочки и позволит другим программам находить исполняемые файлы и библиотеки, которые создал bake. В некоторых случаях использования bake, описанная выше установка PATH и PYTHONPATH не требуется, но для полной сборки ns?3-allinone (с дополнительными пакетами) она обычно нужна.


Зайдите в рабочую директорию и введите в консоли следующее:


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

Далее мы попросим Bake проверить, достаточно ли у нас инструментов для загрузки различных компонентов. Наберите:


$ ./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

Это будет означать, что были скачаны три исходника. Теперь перейдите в директорию source и введите 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, взгляните на build.py и сборку с bake.


3.4.1 Сборка с помощью build.py


Внимание! Этот шаг сборки доступен только из версии исходного архива, полученной как описанной выше; а не скачанной через git или bake.


При работе с релизным архивом tarball, в ns?3?allinone имеется удобный сценарий, который может упростить сборку компонентов. Он называется build.py. Эта программа настроит проект для вас наиболее полезным способом. Тем не менее, обратите внимание, что более сложные настройки и работа с ns?3 обычно включают использование собственной системы сборки ns?3, Waf, которая будет представлена позже в этом руководстве.


Если вы сделали загрузку с помощью tarball, то в вашей директории ~/workspace должна появиться директория с именем что-то вроде ns-allinone-3.29. Введите следующее:


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

При вызове build.py мы применили аргументы командной строки для того, чтобы собрать используемые в этом руководстве примеры и тесты, которые в ns?3 по умолчанию не собираются. По умолчанию, программа также строит все доступные модули. Потом, если пожелаете, Вы можете собрать ns?3 без примеров и тестов или исключить модули, которые не нужны для вашей работы.


Вы увидите много выходных сообщений компилятора, отображаемых скриптом при сборке различных загруженных вами частей. Сначала скрипт попытается собрать аниматор netanim, затем генератор привязок 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


Если выше для получения исходного кода из репозиториев проекта вы использовали 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».


При сборке всех компонентов возможны сбои, но сборка будет продолжена если компонент не является обязательным. Например, недавняя проблема с переносимостью заключалась в том, что castxml может быть собран инструментом bake не на всех платформах. В этом случае появится сообщение вида:


>> 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.

Однако castxml необходим только в том случае, если вы хотите создать обновленные привязки Python. Для большинства пользователей в этом нет нужды (по крайне мере до тех пор, пока они не станут изменять ns?3), поэтому такие предупреждения пока можно безопасно игнорировать.


Если произойдет сбой, то следующая команда даст вам подсказку об отсутствующих зависимостях:


$ ./bake.py show

Будут перечислены различные зависимости пакетов, которые вы пытаетесь собрать.


3.4.3 Сборка с Waf


До этого момента, чтобы начать сборку ns?3, мы использовали либо скрипт build.py, либо инструмент bake. Эти инструменты полезны для сборки 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 вне локальной директории (для вашего удобства). Первая команда выполняет очистку от предыдущей сборки, она обычно не является строго необходимой, но это хорошая практика (также см. профили сборки ниже); это удалит ранее созданные библиотеки и объектные файлы находящиеся в директории build/. Когда проект перенастроен и система сборки выполняет проверку различных зависимостей, вы должны увидеть вывод, похожий на следующий:


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 не была бы включена, то будет отображено сообщение. Также обратите внимание, что есть возможность использовать команду sudo для установки бита suid«установка ID группы во время выполнения» у определенных программ. Он по умолчанию не включен, и поэтому эта функция отображается как «не включена» («not enabled»). Наконец, чтобы получить список включенных опций, используйте 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

Рассмотренный выше сценарий build.py также поддерживает аргументы --enable-examples и --enable-tests, но другие опции Waf он не поддерживает напрямую. Например, это работать не будет:


$ ./build.py --disable-python

реакция будет такой:


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

Тем не менее, специальный оператор -?- может использоваться для передачи дополнительных параметров через waf, поэтому вместо вышеупомянутого будет работать следующая команда:


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

поскольку она генерирует основную команду ./waf configure --disable-python. Вот еще несколько вводных советов о Waf.


Обработка ошибок сборки


Релизы ns?3 протестированы на самых последних компиляторах C++, доступных в момент релиза на распространенных дистрибутивах Linux и MacOS. Однако, со временем, выпускаются новые дистрибутивы с новыми компиляторами, и эти более новые компиляторы, как правило, более педантичны в отношении предупреждений. ns?3 настраивает свою сборку для обработки всех предупреждений как ошибок, поэтому иногда, если вы используете более старую версию в более новой системе, предупреждение компилятора может остановить сборку.


Например, ранее был релиз ns?3.28 для Fedora 28, которая включала новую мажорную версию gcc (gcc-8). Сборка релиза ns?3.28 или более ранних версий под Fedora 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 доступна опция для решения этих проблем. Она отключает установку флага «-Werror» в g++ и clang ++. Это опция «--disable-werror», она должна применяться во время конфигурирования:


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

Конфигурировать или собирать


Некоторые команды Waf имеют смысл только в фазе конфигурирования, а некоторые действуют только в фазе сборки. Например, если вы хотите использовать функции эмуляции ns?3, то можете включить установку бита suid используя sudo, как описано выше. Это отменит команды этапа конфигурации, и таким образом вы сможете изменить конфигурацию используя следующую команду, которая также включает в себя примеры и тесты.


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

Если вы сделаете это, Waf запустит sudo, чтобы изменить программы создания сокетов кода эмуляции для запуска с правами root. В Waf доступно множество других опций для этапов конфигурации и сборки. Чтобы изучить варианты, введите:


$ ./waf --help

В следующем разделе мы будем использовать некоторые опции, связанные с тестированием.


Профили сборки


Мы уже видели, как можно настроить Waf для сборок debug и optimized:


$ ./waf --build-profile=debug

Также есть промежуточный профиль сборки, release. Опция -d является синонимом --build-profile. Профиль сборки управляет использованием журналирования, утверждений (assertions) и ключей оптимизации компилятора:



Как можно видеть, журналирование и утверждения доступны только в отладочных сборках. Рекомендуемая практика заключается в разработке вашего сценария в режиме отладки, затем выполнение повторные прогонов (для статистики или изменения параметров) в оптимизированном профиле сборки.


Если у вас есть код, который должен выполняться только в определенных профилях сборки, используйте макрос Code Wrapper Macro:


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 использует C++ компилятор из GCC ( g++). Тем не менее, можно изменить используемый Waf C++ компилятор, путем определения переменной среды CXX. Например, чтобы использовать С++ компилятор Clang, clang++,


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

Аналогичным образом можно настроить Waf для использования распределенной компиляции с помощью distcc:


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

Более подробную информацию о distcc и распределенной компиляции можно найти на странице проекта в разделе «Документация». Чтобы при конфигурировании ns?3 добавить флаги компилятора, используйте переменную среды CXXFLAGS_EXTRA .


Установка


Waf может использоваться для установки библиотек в разные места системы. По умолчанию, собранные библиотеки и исполняемые файлы находится в директории build, и поскольку Waf знает расположение этих библиотек и исполняемых файлов, нет необходимости устанавливать библиотеки куда либо еще.


Если пользователи предпочитают установку вне директории сборки, они могут выполнить команду ./waf install. По умолчанию префикс для установки — /usr/local, поэтому ./waf install будет устанавливать программы в /usr/local/bin, библиотеки в /usr/local/lib и заголовочные файлы в /usr/local/include. Права суперпользователя обычно необходимо устанавливать с префиксом по умолчанию, поэтому типичная команда будет sudo ./waf install. При запуске, Waf сначала предпочтет использовать общие библиотеки в директории сборки, затем будет искать библиотеки по пути к библиотекам, настроенным в локальном окружении. Так что при установке библиотек в систему хорошая практика -проверить, что используются нужные библиотеки. Пользователи могут выбрать установку с другим префиксом, передав во время конфигурирования опцию --prefix, например:


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

Если позже, после сборки, пользователь введет команду установки ./waf, будет использован префикс /opt/local.


Команда ./waf clean должна использоваться до перенастройки проекта, если для установки будет использоваться Waf под другим префиксом.


Таким образом, для использования ns?3 нет необходимости вызывать ./waf install. Большинству пользователей эта команда не понадобится, поскольку Waf подхватит текущие библиотеки из директории сборки, но некоторые пользователи могут найти это полезным, если их деятельность включает в себя работу с программами вне директории ns?3.


Waf единый


На верхнем уровне дерева исходного кода ns?3 существует только один Waf-скрипт. Начав работать, вы будете проводить много времени в директории scratch/ или глубже, вsrc/... и при этом иметь необходимость запускать Waf. Вы можете просто помнить, где вы, и запустить Waf следующим образом:


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

но это будет утомительно и подвержено ошибкам, поэтому есть лучшие решения. Одним из распространенных способов является использование текстового редактора, такого как emacs или vim, в котором открываются две терминальных сессии, одна используется для сборки ns?3, а вторая для редактирования исходного кода. Если у вас есть только tarball, то может помочь переменная окружения:


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

$ cd scratch 
$ waff build

В директории модуля может показаться заманчивым добавить тривиальный сценарий waf по образцу exec ../../waf. Пожалуйста, не делайте этого. Это сбивает с толку новичков, а при плохом выполнении приводит к труднообнаруживаемым ошибкам сборки. Решения показанные выше это путь, который следует использовать.


3.5 Тестирование ns-3


Вы можете выполнить модульные тесты дистрибутива ns?3, запустив скрипт ./test.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, и test.py будут распараллеливать работу по доступным ядрам процессора машины.


3.6 Запуск скрипта


Обычно мы запускаем скрипты под контролем Waf. Это позволяет системе сборки гарантировать, что пути к общей библиотеке установлены правильно и что библиотеки доступны во время выполнения. Чтобы запустить программу, просто используйте Waf с параметром -?-run. Запустим для ns?3 эквивалент вездесущей программы hello world, набрав следующее:


$ ./waf --run hello-simulator

Waf сначала проверит, что программа собрана правильно, и при необходимости выполняет сборку. Затем Waf выполнит программу, которая выполнит следующий вывод.


Hello Simulator

Поздравляем! Теперь вы пользователь ns?3!


Что мне делать, если я не вижу результат?


Если вы видите сообщения Waf, указывающие, что сборка была успешно завершена, но не видите вывод «Hello Simulator», то есть вероятность, что вы в разделе [Сборка-с-Waf] переключили свой режим сборки на optimized, но пропустили обратное переключение в режим debug. Весь вывод консоли, используемый в этом руководстве, использует специальный компонент ns?3, который выполняет запись лога, и применяется для печати пользовательских сообщений в консоль. Вывод из этого компонента автоматически отключен при компиляции оптимизированного кода — он «оптимизирован». Если вы не видите вывод «Hello Simulator», введите следующее:


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

чтобы настроить Waf на сборку отладочных версий программ ns?3, которые включают примеры и тесты. Затем Вы должны пересобрать актуальную отладочную версию кода, набрав


$ ./waf

Теперь, если вы запустите программу hello-simulator, вы должны увидеть ожидаемый результат.


3.6.1 Аргументы командной строки


Чтобы передать аргументы командной строки в программу ns?3, используйте такой шаблон:


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

Замените <ns3-program> на имя вашей программы и на аргументы. Аргумент -?-command-template для Waf — это, по сути, рецепт для построения фактической командной строки Waf используемой для выполнения программы. Waf проверяет, что сборка завершена, устанавливает пути к общей библиотеке, затем используя предоставленный шаблон командной строки и подставляя имя программы вместо заполнителя %s, вызывает исполняемый файл. Если вам такой синтаксис покажется сложным, существует более простой вариант, который включает в себя программу ns?3 и её аргументы заключенные в одинарные кавычки:

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

Другим, особенно полезным, примером является выборочный запуск наборов тестов. Давайте предположим, что существует тестовый набор (suite) mytest (на самом деле его нет). Выше мы использовали скрипт ./test.py для параллельного запуска целого ряда тестов, который многократно вызывает программу тестирования test-runner. Вызов test-runner напрямую для выполнения одного теста:


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

Аргументы будут переданы программе test-runner. Поскольку mytest не существует, будет генерироваться сообщение об ошибке. Чтобы напечатать доступные параметры test-runner введите:


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

3.6.2 Отладка


Для запуска программ ns?3 под управлением другой утилиты, такой как отладчик (например, gdb) или инструмент проверки памяти (например, valgrind), используйте аналогичную форму -?-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




К сожалению, не доступен сервер mySQL