[CMake] Embedding up-to-date version info in built library
Michael Wild
themiwi at gmail.com
Fri Dec 11 10:48:37 EST 2009
On 11. Dec, 2009, at 15:53 , Kolja Waschk wrote:
> Hi,
>
> I know that similar questions have been posted before, but as far as I
> have been able to follow, no real solution was ever given.
>
> The goal is to embed revision information in a C++ library "mylib".
>
> I already managed to use "create_custom_target" so that an external
> program is executed to create a "version.cc" file each time that "make
> mylib" (using GNU make) is called. The corresponding object is
> re-compiled and the library is put together from this plus 100 other
> object files.
>
> However, collecting all these object files takes some time, especially
> on a Windows host. Within the same source tree, we build applications
> using the library. Due to the forced version.cc update, this time is
> always taken, regardless whether only application code or library code
> changed. Now I tried hard to make my custom target (or custom command)
> dependend only on changes to the library code, but failed so far.
>
> Assume I have a list of all *.cc source files in variable SOURCES:
>
> Try #1: add_custom_command(OUTPUT version.cc DEPENDS ${SOURCES} ...)
>
> This isn't sufficient because it would ignore changes to the header
> files that ${SOURCES} depend on.
>
> Try #2: as above plus IMPLICIT_DEPENDS CXX ${SOURCES} ...
>
> As someone else here noted just a few days ago, the IMPLICIT_DEPENDS
> seems to work only if the ${SOURCES} come with full path info. Actually,
> it started to work after I added the path info in a foreach() loop to
> the list of sources. But another problem came up: Only the first single
> list item seems to be scanned for implicit dependencies. And I failed to
> come up with a list or command syntax that would allow me to have the
> other 99+ sources scanned as well.
>
> Try #3: gather the list of dependencies with output_required_files().
>
> It failed because output_required_files() seems to output empty files in
> any case, regardless of how input files are specified.
>
> Try #4: Build another library without the version information, make
> a custom_command to update version.cc with that library as a target and
> for POST_BUILD, and then create the actual library with version
> information dependent on the other library. That works, but now
> of course all the object files are compiled twice. But no library is
> recompiled if just app code changed. The app developer is happy while
> the lib developer gets his sleep ;)
>
> Now if you have any idea to workaround any of the problems described
> above, I't really appreciate your help! The solution should not be
> limited to Unix systems. I'm currently using CMake 2.6.4.
>
> Kolja
One question: Why do you need a add_custom_command with all those dependencies? Why does version.cc depend on all the source and header files? What do you write in your version.cc file? Is it something like this:
/* version.cc */
const char* const VERSION = "10.5.1";
/* end of version.cc */
If so, you don't need such an elaborate scheme, a file like this will do:
/* version.cc.in */
const char* const VERSION = "@VERSION@";
/* end of version.cc.in */
and then in your CMake code you do:
# CMakeLists.txt
# ... a lot of code ...
set(VERSION "10.5.1")
configure_file(version.cc.in ${CMAKE_BINARY_DIR}/version.cc @ONLY)
add_library(something src1 src2 src3 ${CMAKE_BINARY_DIR}/version.cc)
# ... some more code ...
Michael
More information about the CMake
mailing list