微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

add_custom_command

如何解决add_custom_command

如果我在 DEPENDSadd_custom_command 部分包含不存在的文件,它会失败。有没有办法指定依赖项可能不存在,但如果它被创建,命令应该重新运行?

具体来说,我使用的是 Coco/R,它要求 Parser.frameScanner.frame 文件与语法文件或由命令行参数指定的目录存在于同一目录中,并且 {{1 }} 可以存在与否。所以我这样做:

copyright.frame

如果我在 foreach(FRAME_DIR IN ITEMS ${GRAMMAR_DIR} ${ARG_FRAME_DIR}) foreach(FRAME_FILE_NAME IN ITEMS copyright Scanner Parser) set(FULL_FRAME_FILE ${FRAME_DIR}/${FRAME_FILE_NAME}.frame) if(EXISTS ${FULL_FRAME_FILE}) list(APPEND FRAME_FILES ${FULL_FRAME_FILE}) endif() endforeach() endforeach() ... set(GEN_SOURCES ${ARG_OUTPUT_DIR}/Scanner.h ${ARG_OUTPUT_DIR}/Parser.h ${ARG_OUTPUT_DIR}/Scanner.cpp ${ARG_OUTPUT_DIR}/Parser.cpp) add_custom_command(OUTPUT ${GEN_SOURCES} COMMAND ${COCOCPP} ${COCOCPP_ARGS} MAIN_DEPENDENCY ${ARG_GRAMMAR} DEPENDS ${FRAME_FILES} VERBATIM) add_library(${ARG_TARGET} ${GEN_SOURCES}) 中注释掉 if,我得到

foreach

在构建时。有了这个 ninja: error: '../verification/debug/config/copyright.frame',needed by 'verification/gen/config/Parser.h',missing and no kNown rule to make it 文件生成了,但如果我稍后创建 if,构建程序当然不会知道它。

解决方法

对于常见的生成器,您可以使用 DEPFILE 生成 Make-ish 依赖项,就像 gcc -MT -MD 对包含文件所做的一样。您必须编写一个包装器来检测文件是否存在,然后生成文件。

depfile 大致如下所示:

output: source1 source2

而且 output 必须与 CMAKE_BINARY_DIR 相关(我花了很长时间才发现),source1 是绝对的。而且您还必须转义名称中的空格、制表符、换行符和 # (!)。一般:

# CMakeLists.txt
# Example for one file
set(output ${ARG_OUTPUT_DIR}/Scanner.h)
# Relative to BINARY_DIR!
file(RELATIVE_PATH outputbinrela "${CMAKE_BINARY_DIR}" "${output}")
set(depfile "${CMAKE_CURRENT_BINARY_DIR}/Scanner.h.d" ABSOLUTE)
add_custom_command(
   OUTPUT ${someoutput}
   DEPFILE ${depfile}
   # TODO: write it in cmake,to be portable
   COMMAND sh ./thescript.sh
        "${outputbinrela}" "${depfile}" "${input}"
        ${FRAME_DIR}/Copyright.frame
   DEPENDS ${input}
   WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
   VERBATIM
)

# ./thescript.sh
outputbinrela="$1"
depfile="$2"
input="$3"
copyright="$4"

# Check if the file exists - if it does,add it to depfile
if [[ -e "$copyright" ]]; then
    copyright=$(readlink -f "$copyright") # absolute!
    echo "$outputbinrela: $copyright" > "$depfile"
else
    echo "$outputbinrela:" > "$depfile"
fi

# Run the command to generate output.
yourcommand "$copyright" > "$input"

我曾经为m4预处理器编写过这样的系统,您可以查看运行m4预处理器并抓取m4包含文件并生成depfile的this script,以及调用{{1}的this script }.

不过,如果你添加 add_custom_command( ${CMAKE_COMMAND} -Pthe_other_script.cmake DEPFILE ...) 文件,cmake 不会在第一次运行时把它捡起来,但是如果你修改了别的东西,那么 depfile 将重新生成并且 depdency 将是采摘。或者,您可以例如在每次构建时重新生成 depfile。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?