2013-05-24 7 views
43

Ich möchte ein Testprojekt, das C++ - und OpenMP-Code enthält, mit Cython umhüllen und mit distutils über eine Datei setup.py erstellen. Der Inhalt meiner Datei sieht wie folgt aus:Wie man distuts erklärt, gcc zu benutzen?

from distutils.core import setup 
from distutils.extension import Extension 
from Cython.Build import cythonize 
from Cython.Distutils import build_ext 


modules = [Extension("Interface", 
        ["Interface.pyx", "Parallel.cpp"], 
        language = "c++", 
        extra_compile_args=["-fopenmp"], 
        extra_link_args=["-fopenmp"])] 

for e in modules: 
    e.cython_directives = {"embedsignature" : True} 

setup(name="Interface", 
    cmdclass={"build_ext": build_ext}, 
    ext_modules=modules) 

Die -fopenmp Flagge mit gcc verwendet wird, zu kompilieren und Link gegen OpenMP. Allerdings, wenn ich rufe nur

cls ~/workspace/CythonOpenMP/src $ python3 setup.py build 

dieses Flag nicht erkannt wird, weil der Compiler Klirren ist:

running build 
running build_ext 
skipping 'Interface.cpp' Cython extension (up-to-date) 
building 'Interface' extension 
cc -Wno-unused-result -fno-common -dynamic -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I/usr/local/include -I/usr/local/opt/sqlite/include -I/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/include/python3.3m -c Interface.cpp -o build/temp.macosx-10.8-x86_64-3.3/Interface.o -fopenmp 
clang: warning: argument unused during compilation: '-fopenmp' 
cc -Wno-unused-result -fno-common -dynamic -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I/usr/local/include -I/usr/local/opt/sqlite/include -I/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/include/python3.3m -c Parallel.cpp -o build/temp.macosx-10.8-x86_64-3.3/Parallel.o -fopenmp 
clang: warning: argument unused during compilation: '-fopenmp' 
Parallel.cpp:24:10: warning: unknown pragma ignored [-Wunknown-pragmas] 
     #pragma omp parallel for 
       ^
1 warning generated. 
c++ -bundle -undefined dynamic_lookup -L/usr/local/lib -L/usr/local/opt/sqlite/lib build/temp.macosx-10.8-x86_64-3.3/Interface.o build/temp.macosx-10.8-x86_64-3.3/Parallel.o -o build/lib.macosx-10.8-x86_64-3.3/Interface.so -fopenmp 
ld: library not found for -lgomp 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
error: command 'c++' failed with exit status 1 

Ich habe versucht, unsucessfully gcc angeben:

cls ~/workspace/CythonOpenMP/src $ python3 setup.py build --compiler=g++-4.7 
running build 
running build_ext 
error: don't know how to compile C/C++ code on platform 'posix' with 'g++-4.7' compiler 

Wie kann Ich sage distuts, gcc zu verwenden? diese

Antwort

36

Versuchen Sie, die Umgebungsvariable "CC" aus der Datei setup.py mit os.environ zu setzen.

+13

'os.environ [" CC "] =" g ++ - 4.7 " os.environ [" CXX " ] = "g ++ - 4.7" 'hat gerade funktioniert – clstaudt

+2

Das funktioniert nicht für mich. Mein Problem ist, dass 'setup.py'' icc' verwenden möchte. Wenn ich 'CC = gcc' einstelle, versucht es' gcc' zu verwenden, aber es verwendet weiterhin die Befehlszeilenargumente, die für 'icc' geeignet sind, darunter' -fp-model strict', das 'gcc' nicht versteht. und bricht ab. Es sieht also so aus, als wäre die Einstellung "CC" nicht der richtige Weg. – amaurea

+1

Distutils überprüft * nicht * auf CXX, so dass Sie sich am Ende verwirren können. Möglicherweise möchten Sie den Vorschlag entfernen, um "CXX" hinzuzufügen, da es irreführend ist. – SethMMorton

13

Ich habe gerade einen Blick auf die distutils Quelle, und die --compiler Option erwartet "Unix", "msvc", "Cygwin", "Mingw32", "Bcpp" oder "EMX". Es prüft den gewünschten Compilernamen, indem er die Umgebungsvariable CC überprüft. Versuchen Sie calling wie diese bauen:

CC=gcc python setup.py build 

Sie brauchen nicht CXX zu setzen, es prüft nicht dafür.

+1

Das funktioniert auch. – clstaudt

+0

Auf Ubuntu 12.04 sieht es wirklich nicht die CXX-Umgebungsvariable, das ist nicht das, was man erwarten würde. (könnte der Fall sein, dass es natürlich nicht auf anderen Plattformen überprüft) – hetepeperfan

+0

@hetepeperfan Ich habe eine schwere Zeit, Ihren Kommentar zu verstehen. Stimmen Sie dieser Antwort zu oder nicht? – SethMMorton

15

Nur für den Fall einige andere stehen vor dem gleichen Problem unter Windows (wo CC-Umgebungsvariable keine Auswirkungen haben würde):

  • erstellen Datei „C: \ Python27 \ Lib \ distutils \ distutils.cfg "und schreiben diese innen:

Code:

[build] 
compiler = mingw32 
  • alle Instanzen entfernen von" - mno-Cygwin“gcc-Option aus der Datei "C: \ Python27 \ Lib \ distutils \ cygwinccompiler.py":

Dieses:

self.set_executables(compiler='gcc -mno-cygwin -O -Wall', 
         compiler_so='gcc -mno-cygwin -mdll -O -Wall', 
         compiler_cxx='g++ -mno-cygwin -O -Wall', 
         linker_exe='gcc -mno-cygwin', 
         linker_so='%s -mno-cygwin %s %s' 
            % (self.linker_dll, shared_option, 
             entry_point)) 

Wird dies:

self.set_executables(compiler='gcc -O -Wall', 
        compiler_so='gcc -mdll -O -Wall', 
        compiler_cxx='g++ -O -Wall', 
        linker_exe='gcc', 
        linker_so='%s %s %s' 
           % (self.linker_dll, shared_option, 
            entry_point)) 

Die zweite point kann erforderlich sein, wenn Sie eine aktuelle Version von gcc verwenden, in der die veraltete Option -mno-cygwin entfernt wurde.

Hoffe, das wird auch dann helfen, wenn es nicht direkt mit den OP-realen Bedürfnissen verbunden ist (aber immer noch mit dem Titel der Frage verbunden ist ...))

+0

Ich hatte vor ein paar Minuten tatsächlich mit diesem Problem zu kämpfen, aber ich bin jetzt klar, danke Mann! Und warum fügen wir den Distutils eine neue Datei hinzu? – thwildfire

+0

Es ist jetzt 2014, und ich habe GCC Version 4.3.3 und Python Version 3.4. Ich habe Ihre Lösung ohne Ergebnisse implementiert. Ich bekomme den gleichen Fehler. Ich schrieb '[bauen] Compiler = mingw32' in die Konfigurationsdatei und löschte' -mcygwin' ... –

+0

Meine Antwort könnte veraltet sein. Das ist komplett möglich. Es tut mir leid, wenn das der Fall ist, aber es ist schon lange her, dass ich nicht mehr an Portabilitäts-Tools unter Windows gearbeitet habe (strenge "Linux-Arbeit" seit Monaten), und ich kann Ihnen tatsächlich nicht helfen now ... Stellen Sie sicher, dass Sie 'distutils.cfg' an der richtigen Stelle erstellt haben (die Anforderungen haben sich möglicherweise für diese Datei geändert). Haben Sie versucht, direkt mit 'python3 setup.py build --compiler = mingw32' zu kompilieren? –

-1

können Sie versuchen, anaconda env zu installieren:

conda create -n py35a python=3.5 numpy scipy matplotlib pandas gcc anaconda 

bauen mit:

zsh -c ". activate py35a && gcc --version && python setup.py build_ext --inplace"