提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
1. 源码下载
GitLab 下载地址:nsnam / ns-3-allinone · GitLab
官网下载地址:nsnam / ns-3-allinone · release
下载解压:
wget https://www.nsnam.org/releases/ns-allinone-3.40.tar.bz2
tar -jxvf ns-allinone-3.40.tar.bz2 ns-allinone-3.40
2. 配置 ns-3
配置 ns-3 时会生成一个 Summary 来描述可编译的模块
图中 OFF (not requested) 表示模块未使能,OFF (missing dependency) 则表示模块的依赖不全而未使能,在windows上安装和使用ns-3.38的一种方法 - 知乎 (zhihu.com) 中整理了各模块的依赖项和使能该模块的方法。
2.1 基础依赖
这里简单搬运:
# 必装
sudo apt install g++ python3 cmake ninja-build git -y
sudo apt install python3-pip -y
# 推荐
sudo apt install ccache -y
sudo apt install clang-format clang-tidy -y
sudo apt install gdb valgrind -y
python3 -m pip install --user cppyy
sudo apt install mercurial -y
sudo apt install cmake-format -y
# 可选
sudo apt install tcpdump wireshark -y
sudo apt install sqlite sqlite3 libsqlite3-dev -y
sudo apt install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools -y
sudo apt install openmpi-bin openmpi-common openmpi-doc libopenmpi-dev -y
sudo apt install doxygen graphviz imagemagick -y
sudo apt install python3-sphinx dia imagemagick texlive dvipng latexmk texlive-extra-utils texlive-latex-extra texlive-font-utils -y
sudo apt install libeigen3-dev -y
sudo apt install gsl-bin libgsl-dev libgslcblas0 -y
sudo apt install libxml2 libxml2-dev -y
sudo apt install libgtk-3-dev -y
sudo apt install lxc-utils lxc-templates vtun uml-utilities ebtables bridge-utils -y
sudo apt install libxml2 libxml2-dev libboost-all-dev -y
sudo apt install gir1.2-goocanvas-2.0 python3-gi python3-gi-cairo python3-pygraphviz gir1.2-gtk-3.0 ipython3 -y
2.2 使能模块 以 BRITE Integration
为例
返回 ns-3.40
的上一级文件夹,执行
hg clone http://code.nsnam.org/BRITE
cd BRITE
make
cd ..
# 配置 ns-3
cd ns-3.40
/ns3 configure --with-brite=/home/usrname/path/ns-allinone-3.40/BRITE
2.3 netanim 的编译与 Qt 依赖
netanim
是一个基于 Qt 的网络可视化程序,在使用 ./build.py
编译时默认先编译 netanim
,如果不使用该组件,可以直接进入 ns-3.40
使用 ./ns3 build
编译。开发者使用的 Qt 版本要高于 Ubuntu apt 默认安装的 Qt 版本,里面调用的新版函数将导致编译失败,如 error: ‘class QFontMetrics’ has no member named 'horizontalAdvance'
,这是由 width
函数被替换为 horizontalAdvance
导致的 。
这里给出两个解决方案:
- 修改源代码,将高版本 Qt 替换的内容替换回来,参考 ns3.39编译时报错与解决_包括netanim-3.109(NetAnim)_Mr_liu_666的博客-CSDN博客.
- 升级 Qt 版本(推荐),可以参考我的另一篇博客 编译源码安装 Qt 5.15.
4. 编译
进入解压好的目录,查看 README.md
中的编译指令
-
官网下载:
./build.py --enable-examples --enable-tests
-
GitLab 下载:
./download.py ./build.py --enable-examples --enable-tests
5. 测试
./ns3 run hello-simulator
Hello Simulator
./ns3 run first
At time +2s client sent 1024 bytes to 10.1.1.2 port 9 At time +2.00369s server received 1024 bytes from 10.1.1.1 port 49153 At time +2.00369s server sent 1024 bytes to 10.1.1.1 port 49153 At time +2.00737s client received 1024 bytes from 10.1.1.2 port 9
注意,老版本的运行方法是 ./waf --run hello-simulator
,新版本的运行方法是 ./ns3 run
。
此外,运行的仿真文件存储在 scratch
文件夹下,测试该文件下的内容(根据 build/scratch
下的文件结构运行):
./ns3 run scratch/scratch-simulator
Scratch Simulator
./ns3 run scratch/subdir/scratch-subdir
Scratch Subdir
6. 配置 VsCode 开发环境
参考:【ns-3】VS Code开发环境配置_ns3环境配置_大笨牛@的博客-CSDN博客
可以参考上面的链接配置 Vscode 环境,配置过程中出现 Ctrl + Shift + P 导航失败的问题,可以直接在 .vscode 文件夹下创建对应的文件,插件也是能够识别到这些配置的。
这是我的配置:
c_cpp_properties.json
(这里的 includePath 我感觉要和build
文件夹下的内容保持一致,不同版本可能不同,compileCommands
是配置 clangd 插件用到的,后面会提到){ "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/build/include/**", "${workspaceFolder}/build/include/ns3/**" ], "defines": [], "compilerPath": "/usr/bin/gcc", "cStandard": "gnu11", "cppStandard": "gnu++14", "intelliSenseMode": "linux-gcc-x64", "compileCommands": "${workspaceFolder}/compile_commands.json" } ], "version": 4 }
launch.json
可能是我装了 gdb 和 lldb 的缘故,lauch 和 testrunner 都有两套,大家可以只复制configurations
中的第一个即可,这里要注意将ns3-dev
改为ns3.40
,然后后面的${input:buildType}
要和编译时build-profile
对应,总之就是要和build/scratch
文件夹下的程序名称对齐即可,例如ns3.40-scratch-simulator-debug
,我们就要将 “program” 改为"${workspaceFolder}/build/${relativeFileDirname}/ns3.40-${fileBasenameNoExtension}-debug"
。{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch from scratch", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/${relativeFileDirname}/ns3.40-${fileBasenameNoExtension}-${input:buildType}", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "preLaunchTask": "Build", "environment": [ { "name": "LD_LIBRARY_PATH", "value": "${workspaceFolder}/build/lib/" } ], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] }, { "name": "(lldb) Launch from scratch", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/${relativeFileDirname}/ns3.40-${fileBasenameNoExtension}-${input:buildType}", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "preLaunchTask": "Build", "environment": [ { "name": "LD_LIBRARY_PATH", "value": "${workspaceFolder}/build/lib/" } ], "externalConsole": false, "MIMode": "lldb" }, { "name": "(gdb) Launch testrunner", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/utils/ns3.40-test-runner-${input:buildType}", "args": [ "--suite=${selectedText}" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", "preLaunchTask": "Build", "environment": [ { "name": "LD_LIBRARY_PATH", "value": "${workspaceFolder}/build/lib/" } ], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] }, { "name": "(lldb) Launch testrunner", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/utils/ns3.40-test-runner-${input:buildType}", "args": [ "--suite=${selectedText}" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", "preLaunchTask": "Build", "environment": [ { "name": "LD_LIBRARY_PATH", "value": "${workspaceFolder}/build/lib/" } ], "externalConsole": false, "MIMode": "lldb" } ], "inputs": [ { "type": "pickString", "id": "buildType", "description": "What is the build option?", "options": [ "debug", "default", "optimized", "release", "minsizerel" ], "default": "default" } ] }
tasks.json
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "Build", "type": "shell", "command": "./ns3", "group": { "kind": "build", "isDefault": true } }, { "label": "Run tests", "type": "shell", "command": "./test.py", "group": { "kind": "test", "isDefault": true } } ] }
最后:
Ctrl + Shift + B
编译,F5
调试
7. clangd 插件
clangd
插件会根据编译时生成的 compile_commands.json
建立一个索引数据库,然后快速的完成跳转和补全,实测要比 intelligence
插件快很多。
# 安装生成 compile_commands.json 的插件
sudo apt install bear
# 配置 ns3, 这里 build-profile 可选 debug 还是 release, 后面是只把实例和测试文件一同编译
./ns3 configure --build-profile=release --enable-examples --enable-tests
# 生成 compile_commands.json
bear ./ns3 build
然后安装 clangd
插件,下载 clangd-linux-16.0.2.zip
unzip clangd-linux-16.0.2.zip
cd clangd_16.0.2/bin/ # 该文件夹下有 clangd
pwd # /home/zhangbochun/tools/clangd_16.0.2/bin
配置 clangd 插件的 Arguments:
配置 clangd 路径:
Clangd: Path
/home/zhangbochun/tools/clangd/clangd_16.0.2/bin/clangd
记得在 c_cpp_properties.json
中设置 “compileCommands”,来定位 compile_commands.json
。
完成配置后,clangd 插件会自动激活创建数据库,存储在 .cache
文件夹下,建立完成后就可以丝滑的完成跳转了: