2016-11-22 3 views
2

Also bin ich dabei, meinen Laptop durch das Fenster zu werfen, aus dem Fenster, und gehen Sie und brennen Apple HQ.Python3, Boost-Python und Cpp Linker-Fehler

Siehe Updates Unten:

Ich kann nicht python3, Boost-Python und Klappern arbeiten miteinander bekommen. Der Fehler ich bin stecken läuft:

clang++ <FLAGS/INCLUDES> -o hello.so hello.cpp 

Ruft die Antwort:

Undefined symbols for architecture x86_64: 
    "__Py_NoneStruct", referenced from: 
     boost::python::api::object::object() in hello-0c512e.o 
    "_main", referenced from: 
    implicit entry/start for main executable 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
make: *** [hello] Error 1 

Jede Hilfe sehr wäre sehr geschätzt. Ich denke, ich habe alles Notwendige aufgenommen. Lassen Sie es mich wissen, wenn Sie zusätzliche Informationen benötigen.

Das Setup:

  • OSX 10.11.6 (El Capi-s # @%)
  • Must verwenden Xcode 7.3 (und entsprechende CLT): Anforderung von NVIDIA für CUDA-Programmierung (installiert) . >/Usr/bin/python
  • /usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/ -
  • Muss Python3 (Homebrew installiert)
    • brew install python3
    • which python verwenden Versionen/3.5/include/python3.5m
    • Ich habe einen Alias ​​für python3.5 eingerichtet (siehe unten).
  • mit boost-Python (Homebrew installiert)
    • brew install boost
    • brew install boost-python --with-python3 --without-python
    • /usr/local/Cellar/boost-python/1.62.0/
  • LLVM Verwendung 3.9.0 (Homebrew installiert)
    • brew install llvm --universal

Jetzt ein paar hilfreiche Dinge, die man sich nur wünschen kann:

Clang ++:

Apple LLVM version 7.3.0 (clang-703.0.29) 
Target: x86_64-apple-darwin15.6.0 
Thread model: posix 
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin 

FLAGS und beinhaltet in Make-Datei:

CPPFLAGS = -g -Wall -std=c++11 -stdlib=libc++ 
LDHEADERS = -I/usr/local/opt/llvm/include 
LDLIBS = -L/usr/local/opt/llvm/lib 
BOOSTHEADERS = -I/usr/local/Cellar/boost/1.62.0/include/boost 
BOOSTLIBS = -L/usr/local/Cellar/boost-python/1.62.0/lib 
PYTHONHEADERS = -I/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/include/python3.5m 
PYTHONLIBS = -L/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib 

Und schließlich, der Code, den ich zu kompilieren versuche:

hallo.cav

#include <boost/python.hpp> 

struct World 
{ 
    void set(std::string msg) { this->msg = msg; } 
    std::string greet() { return msg; } 
    std::string msg; 
}; 

using namespace boost::python; 

BOOST_PYTHON_MODULE(hello) 
{ 
    class_<World>("World") 
     .def("greet", &World::greet) 
     .def("set", &World::set) 
    ; 
}; 

Antwort

2

Nach viel Kummer und Schmerz, ICH HABE DIE ANTWORT!

Für alle, die OSX und Homebrew verwenden, hier ist, wie Sie es tun.

  1. brew install python3 Python3 hat UCS4 native (Unicode), die ein wesentlicher Teil dieses Prozesses ist. Wenn Sie Python2 benötigen, stellen Sie sicher, dass es für UCS4 konfiguriert ist, da es nativ UCS2 ist.
  2. brew install boost Zuerst den allgemeinen Boost installieren.
  3. brew install boost-python --with-python3 --without-python Dies installiert Boost-Python für Python3 OHNE Python2. Sie können diese Optionen ändern, wenn Sie Python2 benötigen.
  4. brew install llvm --universal Stellen Sie sicher, dass Sie llvm installiert haben, dieses sollte clang ++ enthalten, das den Compiler verwendet, den wir verwenden werden (nicht den Xcode).
  5. Erstellen Sie ein Makefile (siehe unten), das die Verzeichnisse für all Ihre Python und Boost-Header/Bibliotheken enthält, und enthält die Bibliotheken, die Sie verwenden möchten. (Dies ist, was mich stolperte, ich hatte die Verzeichnisse, aber nicht angegeben, welche Bibliothek in diesem Verzeichnis der Compiler verwenden sollte).

Mein Make-Datei:

# compiler flags: 
# -g adds debugging information to the executable file 
# -Wall turns on most, but not all, compiler warnings 

COMPILER = /usr/local/Cellar/llvm/3.9.0/bin/clang++ 
CPPFLAGS = -g -Wall -std=c++11 -stdlib=libc++ 

# Python and BoostPython links. 
BOOSTHEADERS = -I/usr/local/Cellar/boost/1.62.0/include/boost 
BOOSTLIBRARIES = -L/usr/local/Cellar/boost-python/1.62.0/lib/ 
# This is the boost library we want to use, there are also libraries for multithreading etc. 
# All we do is find the file libboost_python3.a and link it by taking away the 'lib' and '.a'. 
BOOSTLIB = -lboost_python3 
PYTHONHEADERS = -I/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/include/python3.5m 
PYTHONLIBRARIES = -L/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib 
# Link to python3.5 library, the same as we did for boost. 
PYTHONLIB = -lpython3.5 

# Collect links. 
LIBRARIES = $(BOOSTLIBRARIES) $(PYTHONLIBRARIES) $(PYTHONLIB) $(BOOSTLIB) 
HEADERS = $(BOOSTHEADERS) $(PYTHONHEADERS) 

# Build target. 
TARGET = hello 


# BEGIN MAKE 
all: $(TARGET) 

$(TARGET): $(TARGET).cpp 
    # Note that '-shared' creates a library that is accessible. 
    $(COMPILER) -shared $(LIBRARIES) $(HEADERS) $(TARGET).cpp -o $(TARGET).so 

clean: 
    $(RM) $(TARGET) 

Dann alles, was Sie tun müssen, ist Ihr Make-Datei mit allen Einschlüssen und alles sollte süß laufen :) Ich hoffe, das jemand und entfernt ich versucht hatte, den Schmerz hilft zu bekommen insertProfanity Boost arbeiten.

+0

Große Antwort! Ich versuche, an einer Befehlszeile zu arbeiten, die für das gleiche äquivalent ist, aber ich stoße auf dieses Problem. 'Undefinierte Symbole für die Architektur x86_64: " _PyUnicode_FromStringAndSize ", referenziert von: boost :: python :: to_python_value , std :: __ 1 :: allocator > const &> :: operator() (std :: __ 1 :: basic_string , std :: __ 1 :: Zuweiser > const &) const in ctor-40d36f.o ld: Symbol (e) nicht für Architektur gefunden x86_64 clang: error: linker-Befehl fehlgeschlagen mit Exitcode 1 (mit -v wird der Aufruf angezeigt) ' –

+0

Befehlszeile:' g ++ classes.cpp -I/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versionen/3.6/include/python3.6m -L/usr/local/Keller/boost-python/1.64.0/lib -lboost_python3 -lpython -o classes.so -shared' –

3

nicht genug Punkte, um einen Kommentar so leider werde ich als Antwort posten, da nicht allzu lange her, ich durch diesen gleichen Linkerfehler Zeug würde mit kurbeln.

Meine Vermutung ist, dass dies scheint ein Python Linker Problem zu sein, als zu einem Boost- Linker Problem gegenüber. Ich sehe, dass Sie die Python einschließlich zu Ihrem CXX_INCLUDE_PATH hinzugefügt haben, aber was ist mit Ihrer Python-Bibliothek?

Wenn der Pfad, den Sie oben erwähnt haben (der lange Pfad in Ihrer CXX_INCLUDE_PATH -Variable), wo Ihre Includes sind, dann sollte [that_long_path]/Versions/3.5/lib wo sich Ihre Python-Bibliotheken befinden. Fügen Sie diese Bibliothek, wenn Sie Ihren Build-Befehl ausführen, indem Sie

clang++ -g -v -std=c++11 -stdlib=libc++ -L/[that_long_path]/Versions/3.5/lib -lpython3.5m hello.cpp -o hello.so 

Die -L Flag teilt dem Compiler das Verzeichnis aufzunehmen, während die -l Flag den Compiler erzählt die folgende Bibliothek aufzunehmen. Alternativ können Sie einfach fügen Sie diesen lib Pfad zu Ihrem aktuellen CXX_INCLUDE PATH, die dann wie folgt aussehen würde:

export CXX_INCLUDE_PATH="/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/include/python3.5m:/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib" 

Auch stellen Sie sicher, dass alle relevanten Schub enthalten sind, einschließlich Pfade und Bibliothekspfade, wenn Sie den Build-Befehl ausführen zu vermeiden noch mehr Linkerfehler (wenn Boost in einem Standardverzeichnis wie usr/local/[some_place] nicht installiert

Dann diesen neuen Build-Befehl ausführen (ohne die -std and -stdlib Flaggen der Lage zu tun.

clang++ -g -v -std=c++11 -stdlib=lib++ -lpython3.5m -o hello.so hello.cpp 

Zusammenfassend: 1) Fügen Sie Ihre Python-Header-Dateien (die Sie scheinen zu haben) 2) Fügen Sie Ihre Python-Bibliothek Datei (s) (die Sie scheinen zu fehlen) 3) Enthalten Sie alle relevanten Boost-Bibliotheken und der Boost Include-Verzeichnis (das ist ein wenig außerhalb des Umfangs dieser Frage, aber immer noch erwähnenswert)

Hoffe das hilft.

+0

Ich habe versucht, wie Sie gesagt haben. Ich habe 'export CPLUS_INCLUDE_PATH ="/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/include/python3.5m' mit '/usr/local/Cellar/python3/3.5 eingeschlossen .2_3/Frameworks/Python.framework/Versions/3.5/lib' und '/ usr/local/Cellar/boost-python/1.62.0/lib', aber ich erhalte immer noch den gleichen Fehler wie der von Ihnen erwähnte Build-Befehl (mit und ohne die std-libs) – NineTails

+0

Sollte ich die dynamischen Python-Bibliotheken hinzufügen oder die Python-Dateien im lib-Ordner? Ich füge alles hinzu, was ich mir vorstellen kann, aber immer noch kein Glück – NineTails

+0

Nun, ich kann dir nicht geben Ein Beispiel für "jeden" Anwendungsfall, ich kann Ihnen einfach helfen, was bei mir mit Boost 1.62.0 und einem clang ++ Compiler für El Captain lief. Einige schlagen vor, die Boost-Header und .dylibs in/usr/local/include und manuell zu kopieren/usr/local/lib Ich schlage vor, dies in Ihrem Makefile oder CMake zu tun (wird einen weiteren Kommentar hinzufügen, um es weiter zu erklären) – ralston