it-swarm.com.de

Undefinierte Symbole für Architektur x86_64 - Mavericks (Yosemite, El Capitan ...)

EDIT: 

Wenn Sie auf diesen Beitrag fallen, können Sie direkt zur Antwort springen


Ich habe heute morgen einen Post wegen meiner Verwirrung geschickt

Maschinentyp (C++ - Bibliotheken): i386 vs x86_64

Aber ich schätze, ich habe einen Fehler gemacht, weil ich nicht genau war. Also entschied ich mich, ein Beispiel für Situationen zu geben, die ich sehe und die ich nicht verstehen kann.

SCHRITT 1

Ich baue eine Bibliothek auf Maschine A, einem 2 Jahre alten Mac mit OS X 10.7.5 (von dem ich denke, dass er 64 Bit ist; meine Vermutung basiert auf den Befehlen, die Sie unten in "Zusätzliche Informationen" finden), und verwendet die folgenden Dateien.

Ein Header SimpleClass.hpp:

#ifndef SIMPLECLASS_HPP
#define SIMPLECLASS_HPP

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

} ;

#endif  /* SIMPLECLASS_HPP */

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

Ich erstelle die Bibliothek mit 

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

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

Weitere Infos zu Maschine 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

SCHRITT 2

Ich kopiere SimpleClass.hpp sowie die Bibliothek auf einen anderen Rechner B, einen 5 Jahre alten Mac mit osx 10.6.7, von dem ich glaube, dass er 32 Bit ist. Und ich schreibe die folgende Hello-Datei, um die Bibliothek zu testen

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

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

Überraschenderweise keine Probleme beim Linken mit der Bibliothek und ich bekomme.

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

Weitere Infos zu Maschine 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.

SCHRITT 3

Ich kopiere die gleiche Bibliothek noch einmal mit dem gleichen Header und der gleichen Hello-Datei auf Maschine C, das ist ein neuer Mac mit 10.9.2, von dem ich glaube, dass er 64 Bit ist.

Überraschenderweise habe ich Verbindungsprobleme

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)

Zusätzliche Informationen zu Maschine 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

Ich hätte das Verbindungsproblem mit Maschine B, das 32 Bit ist, und nicht mit Maschine C, die 64 Bit ist, erwartet, aber ich habe das Gegenteil bekommen. Kann mir bitte jemand erklären, was mir hier fehlt?

BEARBEITEN (SCHRITT 4)

Wenn ich auf dem Computer C die Option g++ zum Befehl -stdlib=libstdc++ hinzufüge, verschwindet der Fehler "undefined symbols" und die ausführbare Datei wird ordnungsgemäß ausgeführt. Beim Ausführen von g ++ mit der Option -v konnte ich feststellen, dass stdlib standardmäßig libc++und nicht libstdc++ war. Es scheint also so zu sein, dass, obwohl Maschine A und Maschine C beide 64 Bits sind, sie nicht standardmäßig dasselbe stdlib verwenden, was den Fehler Undefined symbols for architecture x86_64 verursacht hat.

17
Issam T.

Alle Probleme, die ich hatte, die gab

Undefined symbols for architecture x86_64

waren auf die Tatsache zurückzuführen, dass einige Bibliotheken mit libstdc ++ kompiliert wurden und nicht für Code verwendet werden konnten, der mit libc ++ kompiliert/verknüpft ist

tatsächlich ist libc ++ die neue Standardbibliothek, die clang seit Mavericks verwendet. Mit der Option ist es jedoch möglich, mit demselben Clang zu kompilieren (es muss kein alter gcc installiert werden)

-stdlib=libstdc++


Für diejenigen, die Boost verwenden, ist es auch möglich, Boost-Bibliotheken auf Außenseitern zu haben, die mit libstdc ++ kompiliert/verknüpft sind, indem die Quelle heruntergeladen und (beim Kompilieren) anstelle der klassischen verwendet wird

./b2

folgende

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


Wenn Sie Cmake verwenden, möchten Sie möglicherweise Folgendes in die entsprechende cmake-Datei einfügen:

find_library (LIBSTDCXX NAMES stdc++)

und

add_compile_options(-stdlib=libstdc++)

und

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

20
Issam T.

Ich bin irgendwie faul und werde das nicht lesen, also zögern Sie nicht, abzustimmen ...

Ich denke, Sie versuchen, eine fette 32/64-Bit-Bibliothek aufzubauen ...

sie haben mehrere Möglichkeiten, dies zu tun, eine, wenn Sie explizit mit 32-Bit und explizit mit 64-Bit erstellen ... und dann mit lipo kombinieren.

beachten Sie, dass nominaler C++ - Code in main.cpp gespeichert ist

dann:

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

oder Sie können im Allgemeinen einige Verknüpfungen mit Apple-Tools verwenden:

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
0
Grady Player