命令`python setup.py build_ext --inplace`总是创建一个新目录

时间:2015-08-06 05:35:52

标签: python python-2.7 cython setup.py

假设我有一个像这样结构化的python包:

foo/
  __init__.py
  setup.py
  bar/
    __init__.py
    bar.pyx

setup.py的内容为

from distutils.core import setup
from Cython.Build import cythonize
import numpy as np

setup(
    ext_modules=cythonize("bar/bar.pyx"),
    include_dirs=[np.get_include()]
)

然后我就跑了

python setup.py build_ext --inplace

因为我需要将编译后的文件bar.so完全放在bar/中。但是上一个命令在foo/bar/下创建了一个新目录bar,并将bar.so放在那里,比如说,

foo/
  __init__.py
  setup.py
  bar/
    __init__.py
    bar.pyx
    foo/
      bar/
        bar.so

而我需要的是

foo/
  __init__.py
  setup.py
  bar/
    __init__.py
    bar.pyx
    bar.so

在我将foobar作为一个包后,发生了这些烦人的事情。如果我删除了foo/__init__.pybar/__init__.py,那么bar.so会显示在foo/中,仍然不会foo/bar/。我已经阅读了手册,但没有找到解决此问题的方法。

那么,如果我需要bar.so出现在正确的位置,同时保留两个__init__.py文件,该怎么办?

1 个答案:

答案 0 :(得分:3)

setup.py不应该包含在包中。您需要将程序包移动到一个目录:

foo/
  setup.py
  foo/
    __init__.py
    bar/
      __init__.py
      bar.pyx

这是我遇到的大多数软件包所遵循的结构。

至于scikit-learn,你曾经用过灵感:

我当然不确切知道scikit-learn正在使用多个setup.py文件做什么,但我会猜测并说外部setup.py正在使用(调用,导入)其他setup.py s,将子包的配置细节分发给那些单独的setup.py。它只是不太明显,因为(我认为)distutils / setuptools正在进行大量的这种导入。

因此,外部装置整体照顾包装,内部装置负责子包装的细节。

但最后,它仍然是另一层中的一个大setup.py个文件。尝试运行

python setup.py build_ext --inplace

在任何内部setup.py上,它会失败,或者什么都不做(至少在我给它的两次尝试中)。

因此,这些子包setup.py可能更适合被视为setup_config.py个文件。

作为一个有趣的结果,安装软件包会将这些setup.py文件保存在各自的子包中(以及sklearn中的文件)。当使用软件包时,也许有一些用处,但我想这只是scikit-learn设置过程的一个人工制品,并且包含了所有*.py个文件。