GeneralCode
GeneralCode

Reputation: 964

How to use Sphinx in a Python project that depends on being built in place?

I have a large mostly Python project that I am trying to document. Part of this project is dependent on C++ source code which is made accessible via Cython.

When running the code like normal it runs fine, but in trying to do auto documenting with Sphinx I have run into issues. I think this guy had the right idea, but I cant make it work.

My Makefile looks like this

# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS    ?=
SPHINXBUILD   ?= sphinx-build
SOURCEDIR     = .
BUILDDIR      = _build

# Put it first so that "make" without argument is like "make help".
help:
    @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
    @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

How can I tell Sphinx to run python setup.py build_ext --inplace and then reference the output .so file(s) before analyzing the code?

Thank you for your time.

Upvotes: 2

Views: 544

Answers (1)

yakton
yakton

Reputation: 36

You would want to add the step from the answer you linked as part of the Makefile generated from sphinx to before any sphinx specific command was executed.

# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS    ?=
SPHINXBUILD   ?= sphinx-build
SOURCEDIR     = .
BUILDDIR      = _build

# Put it first so that "make" without argument is like "make help".
help:
    @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
    @cd /path/to/setup.py; python setup.py build_ext --inplace
    @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

Adding it above the catch-all command that sphinx generates means that the build command to generate cython code would be executed prior to the the sphinx related command.

I would suggest instead to structure the project directory to be more standard to what is used in python. Instead of having documentation be in the same directory as the source code instead have a separate directory for source code and documentation.

root directory/
  myproject/ (source code for Cython module)
  libs/ (generated .so files from Cython)
  tests/ (directory to hold test cases that should run after building)
    __init__.py
  docs/
    Makefile (from sphinx)
  Makefile (project)
  setup.py

The Makefile for the project would be responsible for building the source code and then building the documentation. Its Makefile would look similar to below:

.all:
    @python setup.py build_ext 
    @cd tests; $(MAKE) python -m unittest
    @cd docs; $(MAKE) html

The first part of all would generate the source code (and should be updated to place the .so files generated to the libs/ folder). The second part would go into the tests/ directory and run unittests (example with python's unittest library). The third part would go into the docs/ directory and run make for the target html using the Makefile generated by Sphinx. To do this you would also want to update the tests and docs to include libs/ in their path so that way they can import the .so files generated from the build. (Note: @ symbol prevents the line from being output to the console. This should be omitted if it is desired to be seen as part of a build)

Upvotes: 2

Related Questions