CMake检查本地文件是否存在


73

在我的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中是否存在文件的正确方法是什么?

Answers:


155

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

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


6
不幸的是,EXISTS它并没有声称要做什么。如果无法读取或写入已检查的文件,则尽管文件可见,但它返回false。这是一个令人伤心的错误,因为有时这会很有用,例如某个设备文件的存在。
Philippos '18

1
奇怪的是,这个简单命令不适用于我创建的任何文件:/
Jimmy Pettersson

您能否提供一个无效的示例?尝试使用EXISTS测试后不久,是否可能在某种竞争条件下创建文件?
DLRdave

1
对于最新的cmake(至少3.14+),这是不完整的答案。您还必须在目录路径之外进行测试:if (EXISTS "..." AND NOT IS_DIRECTORY "...")只要EXISTS在目录上也返回true!
安德里(Andry)

9

您应该能够使用

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

文档

if(<constant>)

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

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

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

6

我相信 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()

编辑:添加ERROR_QUIETexecute_process否则文件不存在时,您将从ls收到错误消息。


2

从条件语法文档

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

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.