I have written a Python module including a submodule written in C: the module itself is called foo
and the C part is foo._bar
. The structure looks like:
src/
foo/__init__.py <- contains the public stuff
foo/_bar/bar.c <- the C extension
doc/ <- Sphinx configuration
conf.py
...
foo/__init__.py
imports _bar
to augment it, and the useful stuff is exposed in the 开发者_运维问答foo
module. This works fine when it's built, but obviously won't work in uncompiled form, since _bar
doesn't exist until it's built.
I'd like to use Sphinx to document the project, and use the autodoc extension on the foo
module. This means I need to build the project before I can build the documentation.
Since I build with distutils, the built module ends up in some variably named dir build/lib.linux-ARCH-PYVERSION
— which means I can't just hard-code the directory into a Sphinx' conf.py
.
So how do I configure my distutils setup.py
script to run the Sphinx builder over the built module?
For completeness, here's the call to setup
(the 'fake' things are custom builders that subclass build
and 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])
Since distutils has a way of figuring out the variable build path, why not just use it?
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
Even thought the distutils docs are sparse, here you'll find one-liners about what kinds of build are there.
There are simpler ways to get the build dir name:
>>> from distutils.util import get_platform
>>> get_platform()
'linux-x86_64'
I’ll let you finish the string concatenation :)
Another way to solve your problem is to create a setup.cfg file alongside your setup.py with this content:
[build_ext]
inplace = 1
This will build your extension modules in its parent package directory. Sphinx should see it.
精彩评论