如何告诉distutils使用gcc?

cls*_*udt 53 python distutils compiler-errors cython

我想用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)
Run Code Online (Sandbox Code Playgroud)

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

cls ~/workspace/CythonOpenMP/src $ python3 setup.py build
Run Code Online (Sandbox Code Playgroud)

这个标志无法识别,因为编译器是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
Run Code Online (Sandbox Code Playgroud)

我没有尝试过指定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
Run Code Online (Sandbox Code Playgroud)

如何判断distutils使用gcc?

tim*_*imo 51

尝试使用os.environ在setup.py中设置"CC"环境变量.

  • `os.environ ["CC"] ="g ++ - 4.7"os.environ ["CXX"] ="g ++ - 4.7"`刚刚工作 (23认同)
  • 这对我不起作用.我的问题是`setup.py`想要使用`icc`.当我设置`CC = gcc`时,它确实尝试使用`gcc`,但它继续使用适用于`icc`的命令行参数,其中`-fp-model strict`,`gcc`不理解,和中止.所以看起来只是设置`CC`不是正确的方法. (4认同)
  • Distutils*不*检查CXX,因此设置可能会让您感到困惑.您可能希望删除添加"CXX"的建议,因为它具有误导性. (2认同)
  • 我还发现CC设置被部分忽略 (2认同)

Gau*_*lio 20

以防万一其他人在Windows下面临同样的问题(CC环境变量不会产生任何影响):

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

代码:

[build]
compiler = mingw32
Run Code Online (Sandbox Code Playgroud)
  • 从文件"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))
Run Code Online (Sandbox Code Playgroud)

变成这样:

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))
Run Code Online (Sandbox Code Playgroud)

如果您使用的是最近版本的gcc,那么第二点可能是必要的,其中已弃用的选项-mno-cygwin已被删除.

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


Set*_*ton 17

我刚看了一下distutils源代码,--compiler选项需要"unix","msvc","cygwin","mingw32","bcpp"或"emx".它通过检查CC环境变量来检查所需的编译器名称.尝试像这样调用build:

CC=gcc python setup.py build
Run Code Online (Sandbox Code Playgroud)

您不需要设置CXX,也不会检查.

  • 在构建系统中,如自动工具、CMake(生成 Makefile)和 Makefile。他们检查 CC 和 CXX 环境变量。然后在 makefile 中执行“$(CC) -c csource.c”或“$(CXX) -c cppsource.cpp”来创建目标文件。显然 distunitils 打破了这个惯例。这就是为什么我赞成你的答案,因为“你不需要设置 CXX”这句话解决了我的问题,但是许多使用上述构建工具的人会期望 CC 用于构建 C,CXX 用于构建 C++ 程序。 (2认同)