簡體   English   中英

CMake:如果重建目標,則重新生成源文件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM