59

我想用 Cython 包装一个包含 C++ 和 OpenMP 代码的测试项目,并通过一个setup.py文件用 distutils 构建它。我的文件内容如下所示:

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)

-fopenmp标志与 gcc 一起用于针对 OpenMP 进行编译和链接。但是,如果我只是调用

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

此标志无法识别,因为编译器是 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

我没有成功地尝试指定 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

我如何告诉 distutils 使用 gcc?

4

6 回答 6

57

尝试使用 os.environ 从 setup.py 中设置“CC”环境变量。

于 2013-05-24T14:42:56.073 回答
22

以防其他人在 Windows 下遇到同样的问题(CC 环境变量没有任何影响):

  • 创建文件“C:\Python27\Lib\distutils\distutils.cfg”并在里面写:

代码 :

[build]
compiler = mingw32
  • 从文件 "C:\Python27\Lib\distutils\cygwinccompiler.py" 中删除 "-mno-cygwin" gcc 选项的所有实例:

这个 :

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

变成这样:

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

如果您使用的是最新版本的 gcc,则第二点可能是必要的,其中-mno-cygwin已删除不推荐使用的选项。

希望这会有所帮助,即使它与 OP 的实际需求没有直接关系(但仍与问题的标题相关......)

于 2013-05-24T17:02:00.360 回答
21

我只是看了一下distutils源代码,该--compiler选项需要“unix”、“msvc”、“cygwin”、“mingw32”、“bcpp”或“emx”。它通过检查CC环境变量来检查您想要的编译器名称。尝试像这样调用构建:

CC=gcc python setup.py build

你不需要设置CXX,它不会检查。

于 2013-05-24T14:43:58.270 回答
3

根据这个 wiki,3.4 之后的 Python 版本不再支持 MinGW。适用于 Windows 的 CPython 3.7 使用MSC v.1916. 当我尝试使用上述方法时distutils.cfg,我从 distutils: 中得到一个错误Unknown MS Compiler Version 1916。看起来它的cygwincompiler.py文件中有一个硬编码的 msvcr 库表(这也负责 MinGW),并且该文件已知的最后一个版本1600来自 VS2010 / MSVC 10.0。

于 2019-09-16T10:15:00.440 回答
0

试试这个: http: //mail.python.org/pipermail/distutils-sig/2002-August/002944.html

简而言之,您应该先尝试:python setup.py build --compiler=g++。

于 2013-05-24T14:28:01.807 回答
0

在linux上使用distutils.ccompilerdo os.environ('CC')='gcc'然后调用distutils.sysconfig.customize_compiler(compiler)

它会完成这项工作。

于 2022-02-09T01:59:18.100 回答