我已经下载了
ns-3.39
,使用解压并编译它
wget https://www.nsnam.org/releases/ns-allinone-3.39.tar.bz2
tar xfj ns-allinone-3.39.tar.bz2
cd ns-allinone-3.39/ns-3.39/
./ns3 configure --disable-examples --disable-tests -d default
./ns3 build
这个效果很好。
当我将
#include "ns3/ipv4-header.h"
添加到 ns-3.39/src/wifi/model/phy-entity.cc
并尝试通过在其 Ipv4Header
函数中实例化 Ipv4Header ipHeader;
内的 phy-entity.cc:528
来使用该标头中的 DropPreambleEvent
类时,我收到以下编译错误:
ld: Undefined symbols:
ns3::Ipv4Header::Ipv4Header(), referenced from:
ns3::PhyEntity::DropPreambleEvent(ns3::Ptr<ns3::WifiPpdu const>, ns3::WifiPhyRxfailureReason, ns3::Time) in phy-entity.cc.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)
我正在 MacBook M2 Pro 上进行编译,其中
clang
针对 ARM。当我使用 gcc
在 x86_64 Linux 服务器上执行完全相同的操作时,它可以工作。ns3
模拟器是在Mac上编译的,因此并不是ARM平台本身导致了问题ns3
编译一堆独立的动态库
Ipv4Header
定义是与 PhyEntity
不同的库的一部分,因此它无法调用构造函数gcc
允许动态库中存在此类未定义的符号,只要最终的可执行文件链接所有符号,这确实应该没问题,对吗?这篇文章配置
clang
以允许相同的操作
OTHER_LDFLAGS
设置为-undefined dynamic_lookup
并重新编译,但没有效果我没有主意了。我可以尝试什么?
我已经运行了。对于那些在我之后遇到类似问题的人:
我了解到 ns3 核心是按模块结构化的(请原谅我,如果您已经知道这一点,我正在学习),因此 wifi 模块和互联网模块之间没有直接链接。模块被编译成动态库,以便您可以选择您需要的模块。从软件架构的角度来看,这对我来说完全有意义。
在我的项目中,我们一直在更改 wifi 模块代码(如原始帖子中所述),包括来自互联网模块的
Ipv4Header
等内容。clang/arm
进行编译时实现此功能,您需要通过向 src/wifi/CMakeLists.txt
添加 1 行来显式链接互联网库与 wifi 库,在 build_lib(...)
下,您必须添加
build_lib(
LIBNAME wifi
...
LIBRARIES_TO_LINK
...
${libinternet}
...
)
这可能是不好的编码风格,因为我们打破了库之间的隔离;我们将接受它来完成手头的任务。
我仍然不明白的是为什么Linux系统上的
gcc/x86_64
不需要这个。它以某种方式确定自己链接到这个库中?如果有人可以向我解释这是如何/为什么有效的,我很想听听。