English 中文(简体)
• 在正确地点寻找绝食头盔档案
原标题:Make distutils look for numpy header files in the correct place

在我的安装中,numpy的arrayobject.h位于.../site-packages/numpy/core/include/numpy/arrayobject.h。我编写了一个使用numpy的微不足道的Cython脚本:

cimport numpy as np

def say_hello_to(name):
    print("Hello %s!" % name)

我还有以下的 distutils setup.py(从Cython 用户指南复制):

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [Extension("hello", ["hello.pyx"])]

setup(
  name =  Hello world app ,
  cmdclass = { build_ext : build_ext},
  ext_modules = ext_modules
)

当我尝试使用python setup.py build_ext --inplace构建时,Cython会尝试执行以下操作:

gcc -fno-strict-aliasing -Wno-long-double -no-cpp-precomp -mno-fused-madd 
-fno-common -dynamic -DNDEBUG -g -Os -Wall -Wstrict-prototypes -DMACOSX 
-I/usr/include/ffi -DENABLE_DTRACE -arch i386 -arch ppc -pipe 
-I/System/Library/Frameworks/Python.framework/Versions/2.5/include/python2.5 
-c hello.c -o build/temp.macosx-10.5-i386-2.5/hello.o

可以预见的是,这种方法无法找到arrayobject.h。我该如何使distutils使用正确的numpy包含文件位置(而不需用户定义$CFLAGS)?

最佳回答

使用numpy.get_include():

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy as np                           # <---- New line

ext_modules = [Extension("hello", ["hello.pyx"],
                                  include_dirs=[get_numpy_include()])]   # <---- New argument

setup(
  name =  Hello world app ,
  cmdclass = { build_ext : build_ext},       
  ext_modules = ext_modules
)
问题回答

@vebjorn-ljosa 给出的答案是正确的,但与 install_requires=[ numpy ] 结合使用时会导致问题。在这种情况下,您的 setup.py 需要导入 numpy,如果您尝试在没有运行 pip install numpy 的情况下 pip install 项目,则会导致错误。

如果您的项目依赖于numpy,并且希望numpy作为依赖自动安装,您需要在实际构建扩展时设置include_dirs。您可以通过子类化build_ext来实现这一点:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

class CustomBuildExtCommand(build_ext):
    """build_ext command for use when numpy headers are needed."""
    def run(self):

        # Import numpy here, only when headers are needed
        import numpy

        # Add numpy headers to include_dirs
        self.include_dirs.append(numpy.get_include())

        # Call original build_ext command
        build_ext.run(self)

ext_modules = [Extension("hello", ["hello.pyx"])]

setup(
  name =  Hello world app ,
  cmdclass = { build_ext : CustomBuildExtCommand},
  install_requires=[ numpy ],
  ext_modules = ext_modules
)

并且,你可以使用类似的骗子,作为自动安装的扶养手段,增加cy:

from distutils.core import setup
from distutils.extension import Extension

try:
    from Cython.setuptools import build_ext
except:
    # If we couldn t import Cython, use the normal setuptools
    # and look for a pre-compiled .c file instead of a .pyx file
    from setuptools.command.build_ext import build_ext
    ext_modules = [Extension("hello", ["hello.c"])]
else:
    # If we successfully imported Cython, look for a .pyx file
    ext_modules = [Extension("hello", ["hello.pyx"])]

class CustomBuildExtCommand(build_ext):
    """build_ext command for use when numpy headers are needed."""
    def run(self):

        # Import numpy here, only when headers are needed
        import numpy

        # Add numpy headers to include_dirs
        self.include_dirs.append(numpy.get_include())

        # Call original build_ext command
        build_ext.run(self)

setup(
  name =  Hello world app ,
  cmdclass = { build_ext : CustomBuildExtCommand},
  install_requires=[ cython ,  numpy ],
  ext_modules = ext_modules
)

注意:这些方法仅适用于 pip install .。这些方法不适用于 python setup.py installpython setup.py develop,因为这些命令会在您的项目之后安装依赖项,而不是之前。

对于不使用 Cython 的任何人,一个轻微修改 R_Beagrie 的解决方案,而不依赖它的方法是,如果您只是从 distutils.command.build_ext 导入 build_ext。

from distutils.core import setup
from distutils.extension import Extension
from distutils.command.build_ext import build_ext

class CustomBuildExtCommand(build_ext):
    """build_ext command for use when numpy headers are needed."""
    def run(self):

        # Import numpy here, only when headers are needed
        import numpy

        # Add numpy headers to include_dirs
        self.include_dirs.append(numpy.get_include())

        # Call original build_ext command
        build_ext.run(self)

ext_modules = [Extension("hello", ["hello.c"])]

setup(
  name =  Hello world app ,
  cmdclass = { build_ext : CustomBuildExtCommand},
  install_requires=[ numpy ],
  ext_modules = ext_modules
)




相关问题
Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...

An enterprise scheduler for python (like quartz)

I am looking for an enterprise tasks scheduler for python, like quartz is for Java. Requirements: Persistent: if the process restarts or the machine restarts, then all the jobs must stay there and ...

How to remove unique, then duplicate dictionaries in a list?

Given the following list that contains some duplicate and some unique dictionaries, what is the best method to remove unique dictionaries first, then reduce the duplicate dictionaries to single ...

What is suggested seed value to use with random.seed()?

Simple enough question: I m using python random module to generate random integers. I want to know what is the suggested value to use with the random.seed() function? Currently I am letting this ...

How can I make the PyDev editor selectively ignore errors?

I m using PyDev under Eclipse to write some Jython code. I ve got numerous instances where I need to do something like this: import com.work.project.component.client.Interface.ISubInterface as ...

How do I profile `paster serve` s startup time?

Python s paster serve app.ini is taking longer than I would like to be ready for the first request. I know how to profile requests with middleware, but how do I profile the initialization time? I ...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...

Converting Dictionary to List? [duplicate]

I m trying to convert a Python dictionary into a Python list, in order to perform some calculations. #My dictionary dict = {} dict[ Capital ]="London" dict[ Food ]="Fish&Chips" dict[ 2012 ]="...

热门标签