架构的未定义符号x86_64 - Mavericks(Yosemite,El Capitan ...) [英] Undefined symbols for architecture x86_64 - Mavericks (Yosemite, El Capitan...)

查看:273
本文介绍了架构的未定义符号x86_64 - Mavericks(Yosemite,El Capitan ...)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:



如果您对这则讯息感兴趣,可以直接跳到答案






我今天早上就发送了一篇关于我的混乱的帖子



机器类型(C ++ librairies):i386与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 :

  #includeSimpleClass.h
#include< iostream>

SimpleClass :: SimpleClass()
{
std :: cout< 创建了简单类的新实例< std :: endl;
}

SimpleClass :: SimpleClass(const SimpleClass& orig)
{
}

SimpleClass ::〜SimpleClass $ b {
}

我使用


创建库

 〜/ 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版本4.2(clang-425.0.28)(基于LLVM 3.2svn)
目标:x86_64-apple-darwin11.4.2
〜/ cpp_test $ uname -m
x86_64
〜/ cpp_test $ uname -p
i386
〜/ cpp_test $ lipo - 信息libtest_sc.a
输入文件libtest_sc.a不是胖文件
非脂肪文件:libtest_sc.a是architecture:x86_64

第2步



我将SimpleClass.hpp以及库复制到另一台机器B是一个5岁的mac与osx 10.6.7,我相信是32位。我写了以下hello文件来测试库

  #include< iostream> 
#includeSimpleClass.hpp

int main()
{
std :: cout< 你好,世界! << std :: endl;
SimpleClass testObj;
return 0;令人惊讶的是,在链接库和我得到的时候没有问题。

  [〜/ Downloads / Gmail-9] $ g ++ -o hello -L。 -ltest_sc hello.cpp 
[〜/ Downloads / Gmail-9] $ ./hello
Hello World!
创建Simple类的新实例

机器B上的其他信息:

  [〜/ Downloads / Gmail-9] $ uname -m 
i386
[〜/ Downloads / 9] $ uname -p
i386
[〜/ Downloads / Gmail-9] $ g ++ --version
i686-apple-darwin10-g ++ - 4.2.1 (Apple Inc. build 5666)(点3)
版权所有(C)2007 Free Software Foundation,Inc.
这是免费软件;请参阅复制条件的来源。有NO
保修;甚至不适用于适销性或特定用途的适用性。

STEP 3



我再次使用相同的标题和hello文件在机器C上复制同一库,这是一个新的Mac 10.9.2,我相信是64位。



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

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

架构x86_64的未定义符号:
std :: ostream :: operator<<(std :: ostream&(*)(std :: ostream& ),引用自:
libtest_sc.a(SC.o)中的SimpleClass :: SimpleClass()
std :: ios_base :: Init :: Init(),引用自:
___cxx_global_var_init在libtest_sc.a(SC.o)
std :: ios_base :: Init ::〜Init(),引用自:
___cxx_global_var_init在libtest_sc.a(SC.o)
std :: cout,引用自:
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>>&),引用自:
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 *),引用自:
libtest_sc.a(SC.o)中的SimpleClass :: SimpleClass()
ld:没有为架构x86_64 $ b找到符号$ b clang:error:linker命令失败,退出代码1(使用-v查看调用)

有关机器C的其他信息

  g ++ --version 
配置为:--prefix = / Applications / Xcode.app / Contents / Developer / usr --with-gxx-include-dir = / usr / include / c ++ / 4.2.1
Apple LLVM版本5.1(clang-503.0.40)(基于LLVM 3.4svn)
目标:x86_64-apple-darwin13.1.0
线程模型:posix

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



我希望机器B的链接问题是



编辑(第4步)

strong>



在机器C上,当我添加到 g ++ 命令选项 stdlib = libstdc ++ ,undefined symbols错误消失,可执行文件正确运行。使用选项-v运行g ++可以让我注意到默认的 stdlib libc ++ ,而不是 libstdc ++ 。所以看来虽然机器A和机器C都是64位,它们不使用相同的 stdlib 默认情况下导致错误未定义的符号对于架构x86_64

解决方案

所有的问题,我给了



架构x86_64



的未定义符号是由于某些库是用 libstdc ++ 编译的,不能用于与 libc ++ 编译/链接的代码



libc ++实际上是由 Mavericks 使用的默认新库,但是可以使用选项

使用相同的clang(不需要安装旧的gcc)与经典的libstdc ++编译,

-stdlib = libstdc ++






对于那些使用Boost的用户,也可以通过下载源代码并使用(编译时)而不是经典的


$来编译/链接到libstdc ++ b $ b

./ 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))


EDIT :

If you fall on this post, you may want to jump directly to the answer


I sent a post about my confusion earlier this morning

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

But I guess I did a mistake by being not precise. So I decided to give an example of situations I face and that I can not understand.

STEP 1

I build a library on machine A, a 2 years old mac with OS x 10.7.5 (that I guess is 64 bits; my guess being based on the commands you will see below in Additional Info) using the following files.

A header SimpleClass.hpp:

#ifndef SIMPLECLASS_HPP
#define SIMPLECLASS_HPP

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

} ;

#endif  /* SIMPLECLASS_HPP */

A source file 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()
{
}

I create the library using

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

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

Additional info on machine 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

STEP 2

I copy SimpleClass.hpp as well as the library to another machine B that is a 5 years old mac with osx 10.6.7 that I believe is 32 bits. And I write the following hello file to test the library

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

int main()
{
  std::cout << "Hello World!" << std::endl;
  SimpleClass testObj;
  return 0;
} 

Surprisingly, no problems at linking with the library and I get.

[~/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

Additional info on Machine 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.

STEP 3

I copy the same library again with the same header and hello file on Machine C that is a new mac with 10.9.2 that I believe is 64 bits.

Surprisingly I have linking problems

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)

Additional Info on Machine 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

I would have expected the linking problem with machine B that is 32bits and not with machine C that is 64bits but I got the opposite. Can anyone please explain what I am missing here?

EDIT (STEP 4)

On machine C, when I add to the g++ command the option -stdlib=libstdc++, the "undefined symbols" error disappear and the executable is running correctly. Running g++ with the option -v allowed me to notice the default stdlib was libc++and not libstdc++. So it seems that although the machine A and machine C are both 64 bits they don't use the same stdlib by default which caused the error Undefined symbols for architecture x86_64.

解决方案

All the issues I had, that were giving

Undefined symbols for architecture x86_64

were due to the fact that some libraries were compiled with libstdc++ and could not be used for code that is compiled/linked with libc++

libc++ is in fact the default new library used by clang since Mavericks, however it is possible to compile with the same clang (no need to install an old gcc) with the classical libstdc++ by using the option

-stdlib=libstdc++


For those who use Boost it is also possible to have boost libraries on mavericks that are compiled/linked with libstdc++ by downloading the source and using (when compiling it) instead of the classical

./b2

the following

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


For those using Cmake, you may want to add in the adequate cmake file something similar to:

find_library (LIBSTDCXX NAMES stdc++)

and

add_compile_options(-stdlib=libstdc++)

and

target_link_libraries(${PROJECT_NAME} ${LIBSTDCXX} ${YOUR_OTHER_LIBRARIES))

这篇关于架构的未定义符号x86_64 - Mavericks(Yosemite,El Capitan ...)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆