2010-03-04 19 views
37

Trong bản cài đặt của tôi, số arrayobject.h của numpy nằm ở …/site-packages/numpy/core/include/numpy/arrayobject.h. Tôi đã viết một kịch bản Cython tầm thường mà sử dụng NumPy:Làm cho các rãnh tìm kiếm các tệp tiêu đề có khối u ở đúng vị trí

cimport numpy as np 

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

Tôi cũng có distutils sau setup.py (sao chép từ Cython user guide):

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 
) 

Khi tôi cố gắng xây dựng với python setup.py build_ext --inplace, Cython cố gắng làm như sau:

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 

Dự đoán, điều này không thể tìm thấy arrayobject.h. Làm thế nào tôi có thể làm cho distutils sử dụng vị trí chính xác của các tập tin bao gồm nhiều (mà không làm cho người dùng xác định $ CFLAGS)?

Trả lời

56

Sử dụng 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"])] 

setup(
    name = 'Hello world app', 
    cmdclass = {'build_ext': build_ext}, 
    include_dirs = [np.get_include()],   # <---- New line 
    ext_modules = ext_modules 
) 
+2

Tôi có cùng một vấn đề khi sử dụng ma thuật '%% cython' trong sổ ghi chép ipython .. Tôi tự hỏi liệu có sửa chữa dễ dàng cho điều đó không – pbreach

+1

Đối với bất kỳ ai xem đây là ví dụ cho' nonumpy' công việc liên quan, định nghĩa của 'numpy.get_include' là [ở đây] (https://github.com/numpy/numpy/blob/56678fe56dce97871bb49febf0b2c0206541eada/numpy/lib/utils.py#L18). –

+2

Tôi đã phải di chuyển dòng 'include_dirs' bên trong lệnh' Extension' để làm cho nó hoạt động với cython 0,24 –

8

Câu trả lời được đưa ra bởi @ vebjorn-ljosa là đúng, nhưng nó gây ra vấn đề khi sử dụng kết hợp với install_requires=['numpy']. Trong trường hợp này, setup.py của bạn cần phải nhập gọn gàng, điều này sẽ gây ra lỗi nếu bạn cố gắng pip install dự án của mình mà không cần chạy pip install numpy trước tiên.

Nếu dự án của bạn phụ thuộc vào yếu tố và bạn muốn cài đặt tự động dưới dạng phụ thuộc, bạn chỉ cần đặt include_dirs khi tiện ích mở rộng của bạn thực sự được tạo. Bạn có thể làm điều này bằng cách subclassing 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 
) 

Và bạn có thể sử dụng một thủ thuật tương tự để thêm cython như một sự phụ thuộc tự động cài đặt:

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 
) 

Lưu ý: các phương pháp chỉ làm việc với pip install .. Chúng sẽ không hoạt động cho python setup.py install hoặc python setup.py develop như trong các lệnh này khiến cho các phụ thuộc được cài đặt sau dự án của bạn, thay vì trước đó.

Các vấn đề liên quan