问题描述
我正在使用 CMake 构建一个 C++ 项目(在 Linux 上)。该项目由许多子项目组成,每个子项目都可以调用一个函数来创建一个有用的 link_date.c
源文件,其中包含链接发生时的时间戳。我使用这种方式将构建时间可靠地嵌入到二进制文件中,而不管自上次构建以来发生了哪些源更改。
这个函数是这样声明的:
function(add_link_date TARGET)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/link_date.c.in "
const char *link_date() { return(\"@LINK_DATE@\"); }
")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/link_date.cmake "
EXECUTE_PROCESS(
COMMAND date
OUTPUT_VARIABLE LINK_DATE
OUTPUT_STRIP_TRAILING_WHITESPACE
)
CONfigURE_FILE(\${SRC} \${DST} @ONLY)
")
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/link_date.c
COMMAND ${CMAKE_COMMAND} -DSRC=link_date.c.in -DDST=link_date.c
-P link_date.cmake
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/link_date.c.in)
add_library(link_date-${TARGET} STATIC EXCLUDE_FROM_ALL link_date.c)
target_link_libraries(${TARGET} link_date-${TARGET})
add_custom_command(
TARGET ${TARGET}
PRE_LINK
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/link_date.c.in
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR} --target link_date-${TARGET})
endfunction()
这个函数,对于每个调用它的目标,创建一个 link_date.c.in
模板,然后使用这个模板创建 link_date.c
,只为那个目标。然后将其添加到特定于目标的库中,然后与目标可执行文件链接。最后的 add_custom_command
用于确保每次 CMake 即将链接目标可执行文件时都会重新构建 link_date 库。我从 here 获得了原始代码。
关键是它总是将构建时间戳注入可执行文件,无论是谁构建它 - 开发人员、CI 管道等。它与 Makefiles 生成器配合得很好,我已经使用它超过 12 个月了,没有任何问题。
最近我一直在考虑更新我们的构建以使用 Ninja,因为它在我的大多数管道中明显更快,但是在这个项目中它遇到了问题,特别是最后一个 COMMAND
add_custom_command
(PRE_LINK) 语句,运行子构建。这具有 cd
进入调用 add_link_date
的子项目的 build 子目录的效果,但是因为 CMake 只在 build 目录的顶部生成一个 Ninja build.ninja
文件,子cmake --build
失败,因为这个子项目目录中没有build.ninja
。
有没有办法修改这个过程以与 Ninja 一起工作?
我知道并非每个 CMake 项目都可以从 Makefile 迁移到 Ninja,但是这是我在这个特定项目中遇到的唯一真正障碍,因此很高兴找到解决方法。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)