2013-05-24 24 views
43

Voglio racchiudere un progetto di test contenente codice C++ e OpenMP con Cython e lo costruisco con distutils tramite un file setup.py. Il contenuto del mio file è simile al seguente:Come dire a distutils di usare gcc?

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) 

La bandiera -fopenmp viene utilizzato con gcc per compilare e Link contro OpenMP. Tuttavia, se ho appena invoco

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

questo flag non viene riconosciuto, perché il compilatore è clang:

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 

ho provato senza successo per specificare gcc:

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 

Come può Dico a distutils di usare gcc?

risposta

36

Provare a impostare la variabile di ambiente "CC" dall'interno di setup.py con os.environ.

+13

'os.environ [" CC "] =" g ++ - 4.7 " os.environ [" CXX " ] = "g ++ - 4.7" 'appena funzionante – clstaudt

+2

Questo non funziona per me. Il mio problema è che 'setup.py' vuole usare' icc'. Quando imposto 'CC = gcc', prova a usare' gcc', ma continua ad usare gli argomenti della riga di comando appropriati per 'icc', tra cui' -fp-model strict' che 'gcc' non capisce, e abortisce. Quindi sembra che l'impostazione di 'CC' non sia il modo giusto per farlo. – amaurea

+1

Distutils * non * controlla CXX, quindi l'impostazione potrebbe finire per confonderti. Potresti voler rimuovere il suggerimento per aggiungere "CXX" poiché è fuorviante. – SethMMorton

-1

Prova questa: http://mail.python.org/pipermail/distutils-sig/2002-August/002944.html

In breve, sembra che si dovrebbe provare: python setup.py costruire --compiler = g ++ prima.

+0

Trovati anche questo, ma 'python setup.py build --compiler = g ++' dà lo stesso risultato come sopra. – clstaudt

+0

cosa succede se non si specifica la versione? –

+0

A meno che non ti fraintenda, è esattamente quello che ho provato. – clstaudt

13

Ho appena dato un'occhiata alla fonte distutils e l'opzione --compiler prevede "unix", "msvc", "cygwin", "mingw32", "bcpp" o "emx". Controlla il nome del compilatore desiderato controllando la variabile di ambiente CC. Prova a chiamare costruire in questo modo:

CC=gcc python setup.py build 

Non è necessario impostare CXX, non controlla per questo.

+1

Anche questo funziona. – clstaudt

+0

Su ubuntu 12.04 non guarda alla variabile ambientale CXX, non è quello che ci si aspetterebbe. (potrebbe essere il caso che non controlli su altre piattaforme sia ofcourse) – hetepeperfan

+0

@hetepeperfan Sto avendo difficoltà a capire il tuo commento. Sei d'accordo o in disaccordo con questa risposta? – SethMMorton

15

Nel caso in cui alcuni altri si trovano ad affrontare lo stesso problema sotto Windows (dove variabile d'ambiente CC non avrebbe alcun effetto):

  • Crea file "C: \ Python27 \ Lib \ distutils \ distutils.cfg "e scrivere questo all'interno:

Codice:

[build] 
compiler = mingw32 
  • rimuovere tutte le istanze di" - mno-cygwin" opzione di gcc da file "C: \ Python27 \ Lib \ distutils \ cygwinccompiler.py":

questo:

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

diventa questo:

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

Il secondo il punto può essere necessario nel caso in cui si stia utilizzando una versione recente di gcc, in cui è stata rimossa l'opzione deprecata -mno-cygwin.

Spero che questo aiuti anche se non è direttamente correlato alle esigenze reali dell'OP (ma è ancora correlato al titolo della domanda ...)

+0

In realtà stavo lottando con questo problema pochi minuti fa ma ora sono chiaro Grazie amico! e perché stiamo aggiungendo un nuovo file alle distutils? – thwildfire

+0

È 2014 ora e ho GCC versione 4.3.3 e versione di prova di Python 3.4. Ho implementato la tua soluzione senza risultati. Ho fatto lo stesso errore. Ho scritto '[build] compilatore = mingw32' nel file di configurazione ed eliminato' -mcygwin' ... –

+0

La mia risposta potrebbe essere superata. Questo è completamente possibile. Mi dispiace se questo è il caso, ma è da tanto che non lavoro su prodotti per la portabilità sotto Windows (rigoroso "lavoro Linux" per mesi), e in realtà non sarò in grado di aiutarti con questo, giusto ora ... Assicurati di aver creato 'distutils.cfg' nel posto giusto (i requisiti potrebbero essere cambiati per questo file). Hai provato a compilare usando direttamente 'python3 setup.py build --compiler = mingw32'? –

-1

Si può provare a installare anaconda ENV:

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

compilazione con:

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