[CMake] adding automatic handling of dependencies for swig-generated modules

Sébastien Barthélémy barthelemy at crans.org
Mon Jan 28 09:39:58 EST 2013


Hello all,

swig supports the -MM option which lists a module dependencies (C/C++
headers and other ".i" interface files). I'd like to use it in order
to let cmake know about these dependencies without user intervention.
In addition to reducing the user burden, that would also help managing
dependencies on files which are outside of the current cmake project.
For instance when a swig module extends another one.

Currently, the user has to list these dependencies in a
SWIG_MODULE_${modulename}_EXTRA_DEPS variable. If a user  changes the
.i file to add a #include line, he should also edit the CMakeLists.txt
file to add the corresponding header to the list. Editing the
CMakeLists.txt will cause make to run cmake again, hence the new
dependency will be taken into account.

Apparently, there was an attempt already:
http://public.kitware.com/Bug/view.php?id=4147

Its inner workings are simple:

 * first, in swig_add_module, call swig -MM on the interface file, in
order to gather the dependencies,

 * then use add_custom_command to generate the wrapper code (call swig
without -MM) whenever a dependency changes.

I see two shortcomings with this implementation (please correct me if I'm wrong)

 *  swig -MM fails if it cannot find an header, hence it should be
called *after* the headers generation. Because of this problem, the
patch was reverted. I fear the only solution here is to let the user
list these generated dependencies explicitly, and make the swig -MM
call depend on them. We could use the
SWIG_MODULE_${modulename}_EXTRA_DEPS variable for this.

 * swig -MM is only called when cmake is run. If the user changes the
interface file to add a %include, make will call swig to generate the
wrappers, but won't call swig -MM again. So the new dependency will go
unnoticed.

This last problem is probably trickier. Maybe we could use a single
add_custom_command, which would

 * call swig -MM
 * compare the dependencies it gets against its current ones. If the
two sets differ, call cmake,
 * call swig to generate the wrappers

But I'm not sure about how to save the "current dependencies" and
about the conditional call to cmake.
Maybe swig --MM could output to a file, whose (content) change would
trigger cmake?

I'm pretty sure this is a quite common scenario, is there a canonical
solution? Or another module doing the same kind of dependency analysis
where I should look for inspiration?

Regards,
-- Sébastien


More information about the CMake mailing list