gcc 使用clang编译ns3会导致未定义的符号链接器错误

mlmc2os5  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(71)

我已经下载了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中,并试图通过在DropPreambleEvent函数中示例化phy-entity.cc:528内部的Ipv4Header ipHeader;来使用该头文件中的Ipv4Header类时,我得到以下编译错误:

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)


我正在一台针对ARM的带有clang的MacBook M2 Pro上编译。当我在一台带有gcc的x86_64 Linux服务器上做同样的事情时,它可以工作。
我真的很想让这个工作,这样我就可以在当地工作。我已经投入了一些时间,并发现了以下内容

  • 由于未修改的ns3模拟器在Mac上编译,因此导致问题的不是ARM平台
  • ns3编译了一堆独立的动态库
  • 我现在最好的猜测是,Ipv4Header定义是与PhyEntity不同的库的一部分,因此它不能调用构造函数
  • 可能gcc允许动态库中的这种未定义的符号,只要最终的可执行文件链接了所有的符号,就应该没问题,对吗?
  • 我已经尝试按照this post配置clang以允许相同的操作
  • 也就是说,我已经将环境变量OTHER_LDFLAGS设置为-undefined dynamic_lookup并重新编译,但没有用

我没办法了。我能试试吗?

zkure5ic

zkure5ic1#

我让它运行。对于那些在我之后有类似麻烦的人:
我了解到ns 3核心是模块化的(如果你已经知道了,请原谅我,我正在学习),所以wifi模块和互联网模块之间没有直接的联系。模块被编译成动态库,这样你就可以挑选你需要的东西。从软件架构的Angular 来看,这对我来说是完全有意义的。
在我的项目中,我们已经改变了wifi模块的代码(如在最初的帖子中所述),通过包括来自互联网模块的Ipv4Header之类的东西。
要在使用clang/arm编译时实现这一点,您需要通过向src/wifi/CMakeLists.txt添加1行来显式链接internet库和wifi库,在build_lib(...)下必须添加

build_lib(
    LIBNAME wifi
    ...
    LIBRARIES_TO_LINK
    ...
    ${libinternet}
    ...
)

字符串
这可能是糟糕的编码风格,因为我们打破了库之间的隔离;我们将接受它用于手头的任务。
我仍然不明白的是为什么Linux系统上的gcc/x86_64不需要这个。不知何故,它决定自己链接这个库?如果有人能向我解释这是如何/为什么工作的,我很乐意听到它。

相关问题