cmakecppcms

Cmake: how to run bash command only when a file is updated?


I am trying to write a CMakeLists.txt to speed up compilation.

The executable depends on a script generated .cpp file: I use the cppcms web application library which has a templating system where .tmpl must be converted to .cpp files during the compilation like this:

cppcms_tmpl_cc page.tmpl -o page.cpp

There are related questions that cover the use of bash commands within cmake:
How to run a command at compile time within Makefile generated by CMake?
CMake : how to use bash command in CMakeLists.txt
These questions cover most of my needs.

What I want to know, now, is how to tell cmake to run the above command and re-generate page.cpp every time page.tmpl itself has changed, and only then?

The goal obviously is to improve the compile time and have an up to date binary with the latest template.

(can a moderator add the cppcms tag?)

[Edit: I am actually trying to convert the following Makefile to cmake:

LIBS=-lcppcms -lconfig++ -lboost_filesystem-mt

all: clean gitbrowser

gitbrowser: main.cpp view.cpp content.hpp gitbrowser.cpp
       $(CXX) -Wall main.cpp gitbrowser.cpp view.cpp -o run ${LIBS}

view.cpp: page.tmpl content.hpp
       cppcms_tmpl_cc page.tmpl -o view.cpp

[Edit2: I added a note about the solution in the official cppcms wiki:
http://art-blog.no-ip.info/wikipp/en/page/cppcms_1x_howto#How.to.compile.the.templates.with.cmake.


Solution

  • now = get_now_time()
    time = get_last_upd_time()
    if (now > time)
      set (LAST_UPD_TIME time CACHE INTERNAL "Defines last update time of the file" FORCE)
      # run bash command here
    endif (now > time)
    

    get_now_time and get_last_upd_time are fictional functions, returning timestamps (I guess you can use bash commands to get those timestamps). Then you can compare them and store last modification timestamp into cache.

    However, this solution looks ugly for me, as I know if you properly define targets and dependencies between them CMake itself will take care of rebuilding only modified files, doesn't it? Could you show me target definitions?

    edit

    You can use following CMakeLists.txt (thougn I'm not sure, it's based on my project):

    # add main target, the executable file
    ADD_EXECUTABLE(gitbrowser main.cpp view.cpp content.hpp gitbrowser.cpp)
    # linking it with necessary libraries
    TARGET_LINK_LIBRARIES(gitbrowser "cppcms config++ boost_filesystem-mt")
    
    # add page.cpp target
    ADD_CUSTOM_COMMAND(
        OUTPUT page.cpp 
        COMMAND "cppcms_tmpl_cc page.tmpl -o view.cpp" 
        DEPENDS page.tmpl content.hpp
    )
    # and finally add dependency of the main target
    ADD_DEPENDENCIES(gitbrowser page.cpp)
    

    Good luck