Je veux envelopper un projet de test contenant du code C++ et OpenMP avec Cython, et le construire avec distutils via un setup.py
fichier. Le contenu de mon fichier ressemble à ceci:
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)
Le -fopenmp
L'indicateur est utilisé avec gcc pour compiler et établir un lien avec OpenMP. Cependant, si j'invoque simplement
cls ~/workspace/CythonOpenMP/src $ python3 setup.py build
cet indicateur n'est pas reconnu, car le compilateur est 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
J'ai essayé sans succès de spécifier 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
Comment puis-je dire à distutils d'utiliser gcc?
Essayez de définir la variable d'environnement "CC" depuis l'intérieur de setup.py avec os.environ.
Juste au cas où d'autres seraient confrontés au même problème sous Windows (où la variable d'environnement CC n'aurait aucun effet):
Code:
[build]
compiler = mingw32
Cette :
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))
Devient ceci:
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))
Le deuxième point peut être nécessaire si vous utilisez une version récente de gcc, où l'option obsolète -mno-cygwin
a été retiré.
J'espère que cela vous aidera même si ce n'est pas directement lié aux besoins réels du PO (mais toujours lié au titre de la question ...)
Je viens de jeter un œil à la source distutils
, et l'option --compiler
Attend "unix", "msvc", "cygwin", "mingw32", "bcpp" ou "emx". Il vérifie le nom du compilateur souhaité en vérifiant la variable d'environnement CC
. Essayez d'appeler build comme ceci:
CC=gcc python setup.py build
Vous n'avez pas besoin de définir CXX
, il ne vérifie pas cela.