在distutils构建的C扩展中使用Sphinx
我写了一个Python模块,其中包含一个用C语言编写的子模块:这个模块叫做 foo
,而C部分叫做 foo._bar
。它的结构大致是这样的:
src/
foo/__init__.py <- contains the public stuff
foo/_bar/bar.c <- the C extension
doc/ <- Sphinx configuration
conf.py
...
foo/__init__.py
文件会导入 _bar
,这样可以增强它的功能,而有用的内容则在 foo
模块中展示。当模块构建完成后,这一切都能正常工作,但显然在未编译的状态下是无法使用的,因为 _bar
在未构建时是不存在的。
我想用Sphinx来为这个项目做文档,并且希望在 foo
模块上使用 autodoc 扩展。这意味着我需要在生成文档之前先构建项目。
由于我使用distutils来构建,构建后的模块会放在一个名字不固定的目录 build/lib.linux-ARCH-PYVERSION
中——这就意味着我不能直接把这个目录写死在Sphinx的 conf.py
文件里。
那么,我该如何配置我的distutils setup.py
脚本,以便在构建好的模块上运行Sphinx构建器呢?
为了完整性,这里是对 setup
的调用('假'东西是自定义的构建器,它们是 build
和 build_ext
的子类):
setup(cmdclass = {
'fake': fake,
'build_ext_fake' : build_ext_fake
},
package_dir = {'': 'src'},
packages = ['foo'],
name = 'foo',
version = '0.1',
description = desc,
ext_modules = [module_real])
2 个回答
2
有更简单的方法来获取构建目录的名字:
>>> from distutils.util import get_platform
>>> get_platform()
'linux-x86_64'
我就不多说了,你可以自己完成字符串的拼接 :)
解决你问题的另一种方法是,在你的 setup.py 文件旁边创建一个 setup.cfg 文件,内容如下:
[build_ext]
inplace = 1
这样做会把你的扩展模块放在它的父包目录下。Sphinx 应该能找到它。
5
既然distutils可以自动找到构建路径,那为什么不直接用它呢?
import distutils.command.build
from distutils.dist import Distribution
b = distutils.command.build.build(Distribution())
b.initialize_options()
b.finalize_options()
print b.build_temp
# If you're building a library, you might need:
print b.build_lib
# Other values of interest are:
b.build_purelib
b.build_platlib
b.build_scripts
b.build_base
虽然distutils的文档不多,但这里有一些简短的介绍,告诉你有哪些类型的构建。