【问题标题】:Cause CMake to force recompile a file, but only if project is otherwise recompiled?导致 CMake 强制重新编译文件,但前提是重新编译项目?
【发布时间】:2022-07-08 19:03:58
【问题描述】:

我的问题与Can CMake always force the compilation/build of a specific file?中的问题大致相同

我有一个使用 __DATE__ 的 C++ 文件来显示我的应用程序的构建日期。但是如果不修改这个文件,就不会重建,也不会更新日期。

CMake 能否始终重建该特定文件?

...除了我想要一些稍微不同的东西:

在我拥有的 CMake 项目中(对于 C,转译为我使用的 Makefile),有时当我运行 make 时,代码没有实际更改,这可以很好地检测到,因为没有重新编译(或重新链接)程序。

显然,在这种情况下,我确实想要更新时间戳,并最终得到一个新的可执行文件,除了构建日期之外,它与前一个相同。 p>

我在引用的帖子中看到,只需确保文件上的时间戳已更改,即可强制重新编译。所以,假设我的__DATE__ 使用在use_date.c 中,我想要的是use_date.c 的时间戳被更新(强制重新编译),只有在项目中的任何其他文件(例如,main.c)已更改,因此它会强制重新编译和链接项目(显然,如果我只是手动更改 use_date.c 而没有其他文件,这也应该有效)。

所以,假设我的项目只生成一个可执行文件(没有库):

add_executable(my_project use_date.c other_file.c main.c)

...是否可以添加一个 CMake 步骤,更新 use_date.c 的时间戳(从而导致其重新编译),除非项目正在重新编译和重新链接?

【问题讨论】:

  • 如果没有构建目标,不确定是否会执行 PRE_BUILD event。它也仅限于某些生成器...

标签: cmake


【解决方案1】:

好的,找到了一种方法:这似乎是一种很糟糕的解决方案——希望在 CMake 方面更博学的人最终会发布一个合适的解决方案。但与此同时:

我发现add_custom_commandPOST_BUILD 运行自定义命令如果生成新的二进制文件(.elf 对我来说),否则 em> 运行自定义命令。

所以,基本上,我们可以在自定义命令中有一个小的 bash 脚本:

  • 如果调用了这个 bash 脚本,我们可以假设 POST_BUILD 已经调用了它,这意味着已经构建了一个新的 .elf(无论其他原因)
  • 所以我们可以touchuse_date.c,而在bash 脚​​本中,进入构建目录,并再次显式运行make - 这应该只重新编译use_date.c,然后链接上一个版本的其余部分。

这基本上是有效的 - 除了它会导致无限循环。

这可以通过创建一个临时文件来解决:

  • 如果调用了这个 bash 脚本,我们可以假设 POST_BUILD 已经调用了它,这意味着已经构建了一个新的 .elf(无论出于何种原因)
  • 检查临时文件:
    • 如果它不存在,就创建它——然后我们可以touchuse_date.c,同时在bash脚本中,进入构建目录,并再次显式运行make——这应该...
    • 如果它确实存在,那么我们已经从第二个 .elf. 构建中被调用(对于被触摸的 use_date.c),所以我们想要删除临时文件,然后退出 - 停止无限循环

这似乎工作正常:

add_custom_command(TARGET ${PROJECT_NAME}
                   POST_BUILD
                   DEPENDS ALL
                   #COMMAND bash ARGS -c "touch ${CMAKE_CURRENT_SOURCE_DIR}/use_date.c && cd build && make" ## infinite loop!
                   COMMAND bash ARGS -c "if [ ! -f .refresh ]; then echo '.refresh' | tee .refresh && touch ${CMAKE_CURRENT_SOURCE_DIR}/use_date.c && cd build && make; else rm -v .refresh; fi" # OK!
                   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                   COMMENT "remake with refreshed __DATE__ in use_date.c (${CMAKE_CURRENT_SOURCE_DIR})"
                   VERBATIM
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2012-10-14
    • 2020-08-16
    • 2015-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多