【问题标题】:Cmake: how to run bash command only when a file is updated?Cmake:如何仅在文件更新时运行 bash 命令?
【发布时间】:2011-01-10 03:46:24
【问题描述】:

我正在尝试编写一个 CMakeLists.txt 来加快编译速度。

可执行文件依赖于脚本生成的 .cpp 文件:我使用 cppcms Web 应用程序库,它有一个模板系统,其中 .tmpl 在编译期间必须转换为 .cpp 文件,如下所示:

cppcms_tmpl_cc page.tmpl -o page.cpp

有相关问题涉及cmake中bash命令的使用:
How to run a command at compile time within Makefile generated by CMake?
CMake : how to use bash command in CMakeLists.txt
这些问题涵盖了我的大部分需求。

我现在想知道的是,每次page.tmpl本身发生变化时,如何告诉cmake运行上述命令并重新生成page.cpp,然后才发生?

目标显然是改善编译时间并使用最新模板获得最新的二进制文件。

(版主可以加cppcms标签吗?)

[编辑:我实际上是在尝试将以下 Makefile 转换为 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:我在官方 cppcms wiki 中添加了关于解决方案的注释:
http://art-blog.no-ip.info/wikipp/en/page/cppcms_1x_howto#How.to.compile.the.templates.with.cmake

【问题讨论】:

    标签: cmake cppcms


    【解决方案1】:
    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_timeget_last_upd_time 是虚构的函数,返回时间戳(我猜你可以使用 bash 命令来获取这些时间戳)。然后你可以比较它们并将最后修改时间戳存储到缓存中。

    但是,这个解决方案对我来说看起来很难看,因为我知道如果你正确定义了目标和它们之间的依赖关系,CMake 本身会负责重建 only 修改过的文件,不是吗?你能告诉我目标定义吗?

    编辑

    您可以使用以下 CMakeLists.txt(我不确定,它基于我的项目):

    # 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)
    

    祝你好运

    【讨论】:

    • 是的,CMake 本身只重建修改过的文件......但是这个一般规则如何应用于 bash 脚本生成的文件?
    • 只要 bash 生成的文件 (page.cpp) 没有改变,make 将不会构建目标。同样,page.cpp 不会被重建,除非对 page.tmpl 进行了修改,而 page.cpp 依赖于该修改。
    【解决方案2】:

    看看这个CMake file of Wikipp第66-72行

    你基本上需要这样的东西:

    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) 
    

    编辑:另外,如果你想提高编译速度,你可以编译 将视图放入共享对象并动态加载。

    如果您只更改视图,这也将允许您不重新启动应用程序, 重新编译后的共享对象会自动重新加载。

    有关详细信息,请参阅:http://art-blog.no-ip.info/wikipp/en/page/cppcms_1x_config#views

    【讨论】:

    • 我检查了 wikipp 源,但我只检查了主干并没有看到分支,这就是为什么我最初无法在那里看到你的 cmake 文件的原因。我在 wiki 中添加了一条注释:art-blog.no-ip.info/wikipp/en/page/….
    • 感谢添加注释:共享对象。我以后会记住的。我仍处于早期阶段,目前代码更改比模板更频繁;)
    猜你喜欢
    • 2014-10-30
    • 1970-01-01
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    相关资源
    最近更新 更多