架构 x86_64 的未定义符号 - 小牛队(优胜美地、埃尔卡皮坦...) [英] Undefined symbols for architecture x86_64 - Mavericks (Yosemite, El Capitan...)

查看:34
本文介绍了架构 x86_64 的未定义符号 - 小牛队(优胜美地、埃尔卡皮坦...)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果你看到这篇文章,你可能想直接跳到答案

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

I sent a post about my confusion earlier this morning

机器类型(C++ 库):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.

第一步

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

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.

一个标题 SimpleClass.hpp:

A header SimpleClass.hpp:

#ifndef SIMPLECLASS_HPP
#define SIMPLECLASS_HPP

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

} ;

#endif  /* SIMPLECLASS_HPP */

一个源文件 SimpleClass.cpp:

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

我使用

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

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

关于机器 A 的附加信息:

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

第 2 步

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

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

关于机器 B 的附加信息:

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.

第 3 步

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

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)

关于机器 C 的附加信息

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

我原以为 32 位机器 B 的链接问题,而不是 64 位机器 C 的链接问题,但我得到了相反的结果.谁能解释一下我在这里遗漏了什么?

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?

编辑(第 4 步)

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

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.

推荐答案

我遇到的所有问题

架构 x86_64 的未定义符号

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

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++ 实际上是自 Mavericks 以来由 clang 使用的默认新库,但是可以使用相同的 clang(无需安装旧的 gcc)和经典的 libstdc++ 进行编译,方法是使用选项

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++

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

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

以下

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

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

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

find_library (LIBSTDCXX NAMES stdc++)

add_compile_options(-stdlib=libstdc++)

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

这篇关于架构 x86_64 的未定义符号 - 小牛队(优胜美地、埃尔卡皮坦...)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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