[英]CMake: Regenerate source file if target gets rebuilt
我正在嘗試將構建日期嵌入到源文件中,以便每次構建特定目標時都會刷新嵌入日期,而不會在每次構建整個項目時重新生成。
即我有一個 header 文件builddate.h
由具有一組#define
的命令生成。 然后從其他源文件中包含此 header 文件。
我的第一次嘗試是這樣的:
add_custom_target(builddate COMMAND <command that generates header file>)
add_library(mylibrary ...)
add_dependencies(mylibrary builddate)
這會正確生成 header 文件,但是無論是否需要重建mylibrary
目標,每次都會生成 header 文件。
嘗試使用自定義命令,即
add_custom_command(OUTPUT builddate.h COMMAND <command that generates header file>)
add_library(mylibrary ... builddate.h)
正確生成一次 header,但如果重建mylibrary
目標,則不會重新生成 header,因為builddate.h
已經是最新的。
這感覺應該是相當普遍的事情,但我無法弄清楚自定義命令和目標的什么咒語會給我想要的效果。 我想要的是每次構建mylibrary
目標時調用該命令,如果沒有任何更改或構建不相關的目標(例如使用mylibrary
的可執行文件),則不會進行虛假重建。
使用PRE_BUILD
自定義命令聽起來是個好主意,但文檔 state 會在 Visual Studio 以外的生成器的PRE_LINK
命令之前調用它,即在編譯源代碼之后。 這似乎使它不適合此目的,因為在編譯源代碼時需要 header。
在https://cmake.org/pipermail/cmake/2010-October/040247.html找到一個舊線程,建議將 CMake 的--build
作為PRE_LINK
命令調用為目標:
# This is the library that I want to build
add_library(mylibrary ...)
# Set up a library that contains the code depending on the build date
# Use an OBJECT library because we don't need it to be a full static lib
# we just want to build some source that would "normally" have been part of mylibrary
add_library(builddate OBJECT EXCLUDE_FROM_ALL codethatusesbuilddate.cpp)
# Add a PRE_LINK command for mylibrary so that prior to linking we
# 1. Generate the builddate.h header
# 2. Call CMake to build the builddate library we just set up
add_custom_command(
TARGET mylibrary PRE_LINK
COMMAND <command that generates builddate.h>
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target builddate
)
# We also need to link with the library
# NOTE: uses the generator expression to link with the output files rather than the target
# to avoid CMake setting up a dependency from builddate to mylibrary which I think
# would cause builddate to be built prior to building mylibrary, but at that point we
# haven't generated the header yet. Which we could fix, but then we'd just build it twice
target_link_libraries(mylibrary PRIVATE $<TARGET_OBJECTS:builddate>)
這感覺有點尷尬,但它似乎工作。
Footnote: Generating the header is easily done using CMake, ie first configure_file
or similar to create a CMake script that does the generation, then invoke ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/generated_cmake_file.cmake
as the command to generate the header.
前段時間寫了一個cmake makro。 它添加了自定義命令,通過執行 Cversion.cmake 在當前構建目錄中生成 version.cpp。 只有在依賴關系發生變化時才會執行文件的生成。 使用 cmake-generator-expressions 依賴項設置為目標的依賴項減去它自己的(文件)。
可以通過添加庫依賴項來生成新的版本文件來改進它。
macro(add_versioning T)
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/version.cpp"
COMMAND ${CMAKE_COMMAND} "-DCMAKE_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}"
-P "${PROJECT_SOURCE_DIR}/Version/CVersion.cmake"
MAIN_DEPENDENCY "${PROJECT_SOURCE_DIR}/Version/version.cpp.in"
DEPENDS "$<FILTER:$<TARGET_OBJECTS:${T}>,EXCLUDE,version.cpp.+$>")
target_include_directories(${T} PUBLIC "${PROJECT_SOURCE_DIR}/Version")
target_sources(${T} PUBLIC "${PROJECT_SOURCE_DIR}/Version/version.h" PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/version.cpp")
endmacro()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.