开发者

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

开发者 https://www.devze.com 2023-02-03 03:28 出处:网络
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 .tm

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 CM开发者_如何学JAVAake?

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.


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


Take a look on this CMake file of Wikipp lines 66-72

You basically need something like this:

add_custom_command(
   OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/view.cpp
   COMMAND cppcms_tmpl_cc
               view.tmpl
               -o ${CMAKE_CURRENT_BINARY_DIR}/view.cpp
   DEPENDS view.tmpl) 

Edit: Also if you want to improve compilation speed you may compile the view into shared object and load it dynamically.

This would also allow you not to restart application if you only changed the view, the shared object after recompilation would be automatically reloaded.

See: http://art-blog.no-ip.info/wikipp/en/page/cppcms_1x_config#views for more details.

0

精彩评论

暂无评论...
验证码 换一张
取 消