架构 x86_64 的未定义符号 - Mavericks (Yosemite, El Capitan...)

Posted

技术标签:

【中文标题】架构 x86_64 的未定义符号 - Mavericks (Yosemite, El Capitan...)【英文标题】:Undefined symbols for architecture x86_64 - Mavericks (Yosemite, El Capitan...) 【发布时间】:2014-09-21 02:38:42 【问题描述】:

编辑:

如果你中了这个帖子,你可能想直接跳到答案


我今天早上早些时候发了一篇关于我的困惑的帖子

machine type (C++ librairies) : i386 vs x86_64

但我想我犯了一个不准确的错误。所以我决定举一个我遇到的但我无法理解的情况的例子。

第 1 步

我在机器 A 上构建了一个库,这是一台 2 岁的 Mac,OS x 10.7.5(我猜是 64 位;我的猜测是基于您将在下面的附加信息中看到的命令)使用以下文件。

一个头文件 SimpleClass.hpp:

#ifndef SIMPLECLASS_HPP
#define SIMPLECLASS_HPP

class SimpleClass

public:
  SimpleClass();
  SimpleClass(const SimpleClass& orig);
  virtual ~SimpleClass();
private:

 ;

#endif  /* SIMPLECLASS_HPP */

一个源文件SimpleClass.cpp:

#include "SimpleClass.h"
#include <iostream>

SimpleClass::SimpleClass()

  std::cout << "A new instance of Simple Class was created" << std::endl;


SimpleClass::SimpleClass(const SimpleClass& orig)



SimpleClass::~SimpleClass()


我使用

创建库
~/cpp_test$ clang++ -c -o SC.o -I SimpleClass.hpp SimpleClass.cpp

~/cpp_test$ ar rcs libtest_sc.a SC.o

机器 A 的附加信息:

~/cpp_test$ clang++ --version
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin11.4.2
~/cpp_test$ uname -m
x86_64
~/cpp_test$ uname -p
i386
~/cpp_test$ lipo -info libtest_sc.a 
input file libtest_sc.a is not a fat file
Non-fat file: libtest_sc.a is architecture: x86_64

第 2 步

我将 SimpleClass.hpp 和库复制到另一台机器 B,它是一台 5 岁的 mac,我认为是 32 位的 osx 10.6.7。我编写了以下 hello 文件来测试库

#include <iostream>
#include "SimpleClass.hpp"

int main()

  std::cout << "Hello World!" << std::endl;
  SimpleClass testObj;
  return 0;
 

令人惊讶的是,与图书馆链接没有问题,我得到了。

[~/Downloads/Gmail-9]$ g++ -o hello -L. -ltest_sc hello.cpp
[~/Downloads/Gmail-9]$ ./hello
Hello World!
A new instance of Simple Class was created

机器 B 的附加信息:

[~/Downloads/Gmail-9]$ uname -m
i386
[~/Downloads/Gmail-9]$ uname -p
i386
[~/Downloads/Gmail-9]$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

第 3 步

我在机器 C 上使用相同的头文件和 hello 文件再次复制相同的库,这是一个新的 10.9.2 的 mac,我认为是 64 位。

令人惊讶的是我有链接问题

MacBook-Pro:testcpp$ g++ -o hello -L. -ltest_sc hello.cpp

Undefined symbols for architecture x86_64:
  "std::ostream::operator<<(std::ostream& (*)(std::ostream&))", referenced from:
      SimpleClass::SimpleClass() in libtest_sc.a(SC.o)
  "std::ios_base::Init::Init()", referenced from:
      ___cxx_global_var_init in libtest_sc.a(SC.o)
  "std::ios_base::Init::~Init()", referenced from:
      ___cxx_global_var_init in libtest_sc.a(SC.o)
  "std::cout", referenced from:
      SimpleClass::SimpleClass() in libtest_sc.a(SC.o)
  "std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)", referenced from:  
      SimpleClass::SimpleClass() in libtest_sc.a(SC.o)
  "std::basic_ostream<char, std::char_traits<char> >& std::operator<<<std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)", referenced from:
      SimpleClass::SimpleClass() in libtest_sc.a(SC.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

关于机器 C 的附加信息

g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix

MacBook-Pro:testcpp$ uname -m
x86_64
MacBook-Pro:testcpp$ uname -p
i386

我本来预计 32 位机器 B 的链接问题而不是 64 位机器 C 的链接问题,但我得到了相反的结果。谁能解释一下我在这里缺少什么?

编辑(第 4 步)

在机器 C 上,当我将选项 -stdlib=libstdc++ 添加到 g++ 命令时,“未定义符号”错误消失并且可执行文件正常运行。使用 -v 选项运行 g++ 让我注意到默认的 stdliblibc++ 而不是 libstdc++。所以看起来虽然机器 A 和机器 C 都是 64 位,但它们默认不使用相同的 stdlib,这导致了错误 Undefined symbols for architecture x86_64

【问题讨论】:

在您的目标文件上运行 file。您很快就会看到发生了什么。 试试g++ -o hello hello.cpp -L. -ltest_sc(不同的参数顺序)。还可以在使用文件之前尝试在文件上运行file 和/或lipo -info,而不是在将它们复制到某个位置之前。 @CarlNorum 感谢您抽出宝贵时间。 file libtest_sc.a libtest_sc.a: current ar archive random library file file SC.o SC.o: Mach-O 64-bit object x86_64 我不确定我应该如何使用这些信息。我可以理解我的目标文件是 64 位的。不过没什么新意... @n.m.谢谢你的时间。我尝试了这个命令以及其他命令,但我仍然得到相同的结果。在库上使用 lipo -info 的 Alos 在 3 台机器上返回相同的内容。 【参考方案1】:

我遇到的所有问题,都给了

Undefined symbols for architecture x86_64

是因为某些库是用 libstdc++ 编译的,不能用于用 libc++

编译/链接的代码

libc++ 实际上是自 Mavericks 以来 clang 使用的默认新库,但是可以使用与经典 libstdc++ 相同的 clang(无需安装旧 gcc)进行编译,方法是使用选项

-stdlib=libstdc++


对于那些使用 Boost 的人,也可以通过下载源代码并使用(编译时)而不是经典的来在 mavericks 上使用通过 libstdc++ 编译/链接的 boost 库

./b2

以下

./b2 cxxflags="-stdlib=libstdc++" linkflags="-stdlib=libstdc++"


对于那些使用 Cmake 的人,您可能需要在适当的 cmake 文件中添加类似于:

find_library (LIBSTDCXX NAMES stdc++)

add_compile_options(-stdlib=libstdc++)

target_link_libraries($PROJECT_NAME $LIBSTDCXX $YOUR_OTHER_LIBRARIES))

【讨论】:

我遇到了类似的问题,我使用的是开源库。我在linux上使用了这个库,我没有问题。现在我试图在mac上使用这个库,但我得到Undefined symbols for architecture x86_64:,它指向调用其中一个类函数。有小费吗?我应该在哪里包含 -stdlib=libstdc++? 具体来说,是在“make”步骤。命令“make -stdlib=libstdc++”对我有用。【参考方案2】:

我有点懒,不会读这篇文章,所以请随意投反对票...

我认为您正在尝试构建一个胖 32/64 位库...

您有几种方法可以做到这一点,一种是使用 32 位显式构建,而使用 64 位显式构建...然后使用 lipo 将它们组合起来。

考虑名义上的 C++ 代码存储在 main.cpp 中

然后:

grady$ clang++ main.cpp -m64 -o64.out
grady$ file 64.out 
64.out: Mach-O 64-bit executable x86_64
grady$ clang++ main.cpp -m32 -o32.out
grady$ file 32.out 
32.out: Mach-O executable i386
grady$ lipo -arch i386 32.out -arch x86_64 64.out -create -output fat.out
grady$ file fat.out
fat.out: Mach-O universal binary with 2 architectures
fat.out (for architecture i386):    Mach-O executable i386
fat.out (for architecture x86_64):  Mach-O 64-bit executable x86_64

或者你通常可以使用一些苹果工具的快捷方式:

grady$ clang++ main.cpp -arch i386 -arch x86_64  -ofat2.out
grady$ file fat2.out 
fat2.out: Mach-O universal binary with 2 architectures
fat2.out (for architecture i386):   Mach-O executable i386
fat2.out (for architecture x86_64): Mach-O 64-bit executable x86_64

【讨论】:

我很确定我不应该这样做,但我会赞成这一点,因为您是目前尝试回答我的问题的少数人之一(尽管您无法阅读问题,哈哈)。我从你的回答中学到了一些我不知道的东西。但是,这与我的问题无关。还是谢谢 不,你不应该。我知道并非所有人都有足够的时间阅读我的“Salade Niçoise”:P 我觉得最简单的解释是第一次编译和第二次编译都是32位的 可能是 libstdC++ 与 libC++ 的问题? 我不知道您是否阅读了我的最后一次编辑,但是是的,这似乎是对机器 C 上发生的事情的解释

以上是关于架构 x86_64 的未定义符号 - Mavericks (Yosemite, El Capitan...)的主要内容,如果未能解决你的问题,请参考以下文章

GoogleMapsSDK:架构 x86_64 的未定义符号

Cordova - 架构 x86_64 的未定义符号

架构 x86_64 的未定义符号:MqtUtil

切换到调试时架构 x86_64 的未定义符号

Xcode 错误 - 架构 x86_64 的未定义符号?

GraphicsMagick,架构 x86_64 的未定义符号