用于OS X的openmp的Python C扩展

时间:2016-10-25 08:17:48

标签: python c gcc clang

我为C程序创建了一个python扩展。在linux中,使用gcc,一切正常,可以安装扩展名:

sudo python setup.py install

但是当我尝试在OS X中使用它时:

海湾合作委员会4.7:

我使用macports安装了gcc 4.9,并在setup.py文件中添加了这一行

import os
os.environ["CC"]="gcc-mp-4.9"

当我输入sudo python setup.py install

我收到此错误:

unrecognized command line option '-Wshorten-64-to-32'

我一直在寻找解决方案,每个人都说"使用clang代替gcc"解决这个问题。

Clang 3.8:

我还安装了clang 3.8(在OS X中安装了3.5但它没有openmp)我修改了文件setup.py:

import os
os.environ["CC"]="clang-mp-3.8"

我得到了这个错误:

unknown argument: '-mno-fused-madd'

在某些论坛中,我找到了一个可能的解决方案,为CFLAGS设置一个空值:

sudo CFLAGS="" python setup.py install

但我收到了一个新错误:

library not found for -lgomp

我使用-fopenmp,但我不知道调用-fgomp的原因。在一些论坛上,人们说我必须使用gcc而不是clang,所以我再次站在起点。

我想在OS X中找到一个容易解决这个扩展的解决方案,因为我想创建一个可以被任何人轻松安装的扩展。

1 个答案:

答案 0 :(得分:1)

我有类似的问题。 Python是使用clang构建的,并使用特定于clang的CFLAGS:

>>> import sysconfig
>>> sysconfig.get_config_var("CFLAGS")
'-fno-strict-aliasing -fno-common -dynamic -arch x86_64
-arch i386 -g -Os -pipe -fno-common -fno-strict-aliasing
-fwrapv -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall
-Wstrict-prototypes -Wshorten-64-to-32 -DNDEBUG -g
-fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE'

Distutils将此信息复制到" UnixCCCompiler"实例,用于进行扩展。但是,正如您所发现的那样,-Wshorten-64-to-32是特定的。

我的解决方案是修改distutils构建扩展的方式。下面从命令行参数列表中删除该选项,以便在调用实际编译代码之前传递给编译器。 (您的代码可能不需要那么复杂。我支持多个编译器和配置。)

def _is_gcc(compiler):
    return "gcc" in compiler or "g++" in compiler

class build_ext_subclass( build_ext ):
    def build_extensions(self):
        c = self.compiler.compiler_type
        if c == "unix":
            compiler_args = self.compiler.compiler
            c = compiler_args[0]  # get the compiler name (argv0)
            if _is_gcc(c):
                names = [c, "gcc"]
                # Fix up a problem on older Mac machines where Python
                # was compiled with clang-specific options:
                #  error: unrecognized command line option '-Wshorten-64-to-32'
                compiler_so_args = self.compiler.compiler_so
                for args in (compiler_args, compiler_so_args):
                    if "-Wshorten-64-to-32" in args:
                        del args[args.index("-Wshorten-64-to-32")]

        build_ext.build_extensions(self)

然后告诉setup()使用这个新的子类来构建扩展:

setup(name = ...
      cmdclass = {"build_ext": build_ext_subclass},
     )