Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

cmake

cppcms

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.

like image 464
augustin Avatar asked Jan 10 '11 03:01

augustin


Video Answer


1 Answers

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

like image 94
galymzhan Avatar answered Oct 10 '22 02:10

galymzhan