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

问题描述 投票:0回答:1

我已经下载了

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
        并重新编译,但没有效果

我没有主意了。我可以尝试什么?

c++ gcc clang linker-errors ns-3
1个回答
0
投票

我已经运行了。对于那些在我之后遇到类似问题的人:

我了解到 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
不需要这个。它以某种方式确定自己链接到这个库中?如果有人可以向我解释这是如何/为什么有效的,我很想听听。

© www.soinside.com 2019 - 2024. All rights reserved.