[CMake] Building generated c++ code with py++ and boost.python

Brad King brad.king at kitware.com
Wed Oct 11 09:40:38 EDT 2006


Pecevski Dejan wrote:
> Hi,
> 
> As part of our build process which uses cmake, we want to generate
> wrapper c++ files from existing sources, for python interfacing (using
> Py++ and boost.python).
> The dependency we want to achieve is :
>    A1.cpp A2.cpp A3.cpp   A1.h A2.h A3.h  ...  <-----  Abase.h  generate.py
>   wrapLibrary.so  <-----  A1.cpp A2.cpp A3.cpp  baseLibrary.a
> where
>    - Abase.h is the header file containing the classes that are to be
> exposed in python (INCLUDES several header files from other directories)
>    - generate.py is the python script which parses Abase.h and produces
> the wrapper code from it
>   - A1.cpp A2.cpp A3.cpp  A1.h A2.h A3.h  - automatically generated
> wrapper c++ files
>   - wrapLibrary.so is the library which contains the compiled wrapper
> code along with the library which is wrapped (baseLibrary.a).
> Note that the automatically generated c++ file list are NOT KNOWN
> apriori (they are dependent on the contents of Abase.h and generate.py).
> 
> I have two questions on how to setup this with cmake:
> 1. To setup the first dependency rule properly, one should also add as
> dependencies the files that Abase.h file includes
>    so that when you change the code in these files, wrapper code is
> recreated. For example if Abase.h includes another header file B.h, and
> B.h (but not Abase.h)   is changed then the rule should be activated.
>    Is there some way to setup this in cmake?
>    It seems like the scanning mechanism for the dependencies of c++
> sources doesn't work for ADD_CUSTOM_TARGET.

Currently there is no way to hook up implicit dependency scanning for
custom commands or custom targets.  This is a known limitation that may
eventually be fixed.

You can fake it though by setting up the custom command to write a file
with its own dependencies when it runs.  The first time it will run
because the output doesn't exist.  As a side effect it should create a
file such as ${CMAKE_CURRENT_BINARY_DIR}/my_extra_deps.cmake containing

SET(MY_EXTRA_DEPS
  /path/to/some/file1.h
  /path/to/some/file2.h
  )

Then the CMakeLists.txt file that has the custom command in it can do:

INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/my_extra_deps.cmake OPTIONAL)
ADD_CUSTOM_COMMAND(
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/my_output.h
  COMMAND ... # command to generate output and my_extra_deps.cmake
  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/my_input.h ${MY_EXTRA_DEPS}
  )

This will cause cmake to re-run the next time make is run to regenerate
the rule with proper dependencies.

>   2. For the second rule to work, one should include dynamically the
> list of all generated files in the rule. The file list that is to be
> included can be retrieved with a FILE(GLOB ...) command (that is after
> they are created).
> I have some vague idea how to setup this with recursive calling of cmake
> commands, but I'm not really sure it can work out. Is this setup
> possible, and is there some elegant way to do this?

It is possible to have the custom command in the "outer" cmake generate
a source tree and then run "ctest --build-and-test" to drive building
the "inner" project.

FYI, we have many projects using CMake that do generated wrappers in
Python, Java, Tcl, etc...  Most of them don't need these two complicated
steps because they are organized to not have inter-dependencies among
wrappers across different classes.  There is a separate custom command
for each class wrapper instead of one script that generates all
wrappers.  That way all the dependencies are known to CMake.

You could try using CMake code to parse the headers to compute exactly
what files will be generated and their dependencies.

-Brad



More information about the CMake mailing list