【问题标题】:Undefined symbols for architecture arm64 in MacOSMacOS 中架构 arm64 的未定义符号
【发布时间】:2022-01-14 20:14:31
【问题描述】:

在我编写两个函数 xxxx 作为 uni 工作的一部分时发生以下错误。我使用的 IDE 是 Visual Studio Code

问题是当我尝试编译文件夹code/myIO中的单个文件时,它抛出了一个错误:

(我已经用 ($) 替换了文件夹的路径。我保证问题不存在)

cd ($) && clang++ r.cpp -o ($)/r -D LOCAL -Wall -O2 -fsanitize=undefined

Undefined symbols for architecture arm64:
  "_Tp::INT", referenced from:
      split(char const*, _Tp*) in r-ebf422.o
  "_Tp::fmt", referenced from:
      split(char const*, _Tp*) in r-ebf422.o
  "_Tp::str", referenced from:
      split(char const*, _Tp*) in r-ebf422.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

而且,当我尝试链接一些文件时,发生了类似的错误。

clang++ -shared -o libmystdio.so myscanf.o myprintf.o
Undefined symbols for architecture arm64:
  "_Tp::INT", referenced from:
      split(char const*, _Tp*) in myscanf.o
      split(char const*, _Tp*) in myprintf.o
  "_Tp::fmt", referenced from:
      split(char const*, _Tp*) in myscanf.o
      split(char const*, _Tp*) in myprintf.o
  "_Tp::str", referenced from:
      split(char const*, _Tp*) in myscanf.o
      split(char const*, _Tp*) in myprintf.o
  "_Tp::LONG", referenced from:
      split(char const*, _Tp*) in myscanf.o
      split(char const*, _Tp*) in myprintf.o
  "_Tp::LONGLONG", referenced from:
      split(char const*, _Tp*) in myscanf.o
      split(char const*, _Tp*) in myprintf.o
  "_out_buf", referenced from:
      myprintf(char const*, ...) in myprintf.o
  "_out_idx", referenced from:
      myprintf(char const*, ...) in myprintf.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [libmystdio.so] Error 1

如果你想知道我写了什么,please click here。不过还没写完,不知道你会不会有兴趣...(我做了几个cmet,大部分都是中文的,给我的队友看)

而且,文件夹 code 中的文件不受影响。可以正常编译运行。只有code/myIO文件夹出错了。

这是我的 clang++ 版本:

clang++ -v
Apple clang version 12.0.5 (clang-1205.0.22.11)
Target: arm64-apple-darwin20.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

提前感谢您的帮助!

【问题讨论】:

标签: c++ macos


【解决方案1】:

你有一个没有定义的声明。

utilities.h 有:

class _Tp {
  // [...]
public:
  // [...]
  static const int INT = 1, SHORT = 2, LONG = 3, LONGLONG = 4,
      FLOAT = 10, DOUBLE = 11, LONGDOUBLE = 12;

用初始化器声明_Tp::INT 等,但没有定义它们。如果您 ODR 使用这些值,那么您需要对它们进行定义,这意味着需要指定一个位置来保存程序中这些常量的内存字节。[0]

执行此操作的正常方法是匹配 utilities.cpp 与:

const int _Tp::INT;
const int _Tp::SHORT;
const int _Tp::LONG;
const int _Tp::LONGLONG;
const int _Tp::FLOAT;
const int _Tp::DOUBLE;
const int _Tp::LONGDOUBLE;

但在您的情况下,您可能需要考虑切换到枚举!为此,您可以写信utilities.h

class _Tp {
  // [...]
public:
  // [...]
  enum { INT = 1, SHORT = 2, LONG = 3, LONGLONG = 4,
      FLOAT = 10, DOUBLE = 11, LONGDOUBLE = 12 };

那么你不需要utilities.cpp

[0] 有一种特殊情况允许 ODR 使用整数类型的值而无需在狭窄的环境中定义,但我建议程序员不要依赖它。非专家对代码进行了无害的更改,并得到一个令人困惑的链接错误。

【讨论】:

  • 它确实奏效了!我现在可以编译r.cpp了。
  • 很高兴听到它!
  • 很抱歉再次给您带来困扰,但是当我在项目文件中修复了这些问题并再次构建它时,关于“_out_buf”和“_out_idx”的错误仍然存​​在。令人困惑的是,我并没有用这个名字定义一个变量或函数。事实上,“out_buf”和“out_idx”是在main.cpp中定义的,extern char out_buf[]extern int out_idx已经被添加到了myprintf.cpp。我问过我的导师,但他没有弄清楚原因。
  • 前导 _ 始终出现在 Mac 上,这只是 C 和 C++ 代码平台 ABI 的一部分。在 Mac 上通过 clang 或 gcc 编译时,您的变量和函数名称将在目标文件中以 _ 为前缀。它不链接的原因可能是makefile中的“libmystdio.so”规则试图将myprintf.o组合成一个共享对象(注意,在Mac上应该命名为.dylib)而不包括main.cpp在哪里在哪里定义 out_bufout_idx
猜你喜欢
  • 2013-10-13
  • 1970-01-01
  • 2021-08-23
  • 2021-07-25
  • 2018-11-14
  • 2015-12-05
相关资源
最近更新 更多