【问题标题】:CMake check that a local file existsCMake 检查本地文件是否存在
【发布时间】:2012-10-15 13:35:53
【问题描述】:

在我的 CMake 脚本中,我想查看我的系统上是否有文件,如果有,请使用它执行某些操作,否则使用默认文件执行某些操作。代码如下:

find_file(
          ${project_name}_${customer}_config 
          ${ROOT}/configuration/${customer}/configuration.${project_name}.xml
)

if(NOT ${${project_name}_${customer}_config} STREQUAL
   ${project_name}_${customer}_config-NOTFOUND )
        configure_file(${ROOT}/configuration/${customer}/configuration.${project_name}.xml
                       ${CMAKE_CURRENT_BINARY_DIR}/conf/configuration.xml)
else()
    configure_file(${FAPP_ROOT}/configuration/Default/configuration.${project_name}.xml
                   ${CMAKE_CURRENT_BINARY_DIR}/conf/configuration.xml)
endif()

但似乎,这行不通。

在 CMake 中检查文件是否存在的正确方法是什么?

【问题讨论】:

    标签: file cmake file-exists


    【解决方案1】:

    来自条件语法docs:

    if(EXISTS path-to-file-or-directory)

    如果指定的文件或目录存在,则为真。 行为仅针对完整路径进行了明确定义。解析符号链接,即如果命名文件或目录是符号链接,如果符号链接的目标存在,则返回 true。

    如果您要查找的文件位于当前的 cmakelist 文件中,那么一种解决方案可能是:

    if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${FILE_WORKING_ON}) ...

    【讨论】:

      【解决方案2】:

      我相信if (EXISTS <path>) 是一个很好的解决方案。我想分享一个我最近遇到的场景,尽管在大多数情况下你可能不会关心这个场景。

      请注意,如果有效用户无法访问该文件,此解决方案将不会返回 true。该文件确实存在,但它只是不可读。

      如果您确实关心文件是否真的存在,解决此方案的方法是调用execute_process(COMMAND ls /dev/fb0 RESULT_VARIABLE result OUTPUT_QUIET ERROR_QUIET),然后像这样检查result

      if (result)
          message("/dev/fb0 doesn't exist.")
      endif()
      

      编辑:在execute_process 中添加ERROR_QUIET,否则当文件不存在时,您会从ls 收到错误消息。

      【讨论】:

      • 谢谢!在我的情况下,此处提供的解决方法是唯一可行的解​​决方案。
      【解决方案3】:

      如果您已经知道文件的完整路径名,那么检查文件是否存在的正确方法是:

      if(EXISTS "${ROOT}/configuration/${customer}/configuration.${project_name}.xml")
         ...
      else()
         ...
      endif()
      

      【讨论】:

      • 不幸的是,EXISTS 并没有像它声称的那样做。如果检查的文件无法读取或写入,则返回 false,尽管该文件是可见的。这是一个可悲的错误,因为这有时很有用,比如某个设备文件的存在。
      • 奇怪的是,这个简单的命令不适用于我创建的任何文件:/
      • 你能提供一个不起作用的例子吗?在您尝试使用 EXISTS 测试后不久可能会创建文件,是否存在某种竞争条件?
      • 对于最新的 cmake(至少 3.14+),这是不完整的答案。您必须另外测试不是目录路径:if (EXISTS "..." AND NOT IS_DIRECTORY "..."),只要EXISTS 在目录上也返回 true!
      【解决方案4】:

      你应该可以使用

      if(NOT ${project_name}_${customer}_config)
      

      来自docs

      if(<constant>)

      如果常量为 1、ON、YES、TRUE、Y 或非零数字,则为真。如果常量为 0、OFF、NO、FALSE、N、IGNORE、“”或以后缀“-NOTFOUND”结尾,则为 False。

      但是,如果使用find_file 找到文件,则该值将被缓存,随后的 CMake 运行将不会尝试再次找到它。要在每次运行时强制重新检查,请在调用 find_file 之前执行以下操作:

      unset(${project_name}_${customer}_config CACHE)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-05
        • 2023-03-04
        • 1970-01-01
        • 2011-12-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多