【CMake 语法】(10) CMake 文件操作

文件操作命令。

这个命令专用于需要访问文件系统的文件操作 和 简单的路径转换操作。

概要

Reading
  file(READ <filename> <out-var> [...])
  file(STRINGS <filename> <out-var> [...])
  file(<HASH> <filename> <out-var>)
  file(TIMESTAMP <filename> <out-var> [...])
  file(GET_RUNTIME_DEPENDENCIES [...])

Writing
  file({WRITE | APPEND} <filename> <content>...)
  file({TOUCH | TOUCH_NOCREATE} [<file>...])
  file(GENERATE OUTPUT <output-file> [...])
  file(CONFIGURE OUTPUT <output-file> CONTENT <content> [...])

Filesystem
  file({GLOB | GLOB_RECURSE} <out-var> [...] [<globbing-expr>...])
  file(RENAME <oldname> <newname>)
  file({REMOVE | REMOVE_RECURSE } [<files>...])
  file(MAKE_DIRECTORY [<dir>...])
  file({COPY | INSTALL} <file>... DESTINATION <dir> [...])
  file(SIZE <filename> <out-var>)
  file(READ_SYMLINK <linkname> <out-var>)
  file(CREATE_LINK <original> <linkname> [...])
  file(CHMOD <files>... <directories>... PERMISSIONS <permissions>... [...])
  file(CHMOD_RECURSE <files>... <directories>... PERMISSIONS <permissions>... [...])

Path Conversion
  file(REAL_PATH <path> <out-var> [BASE_DIRECTORY <dir>])
  file(RELATIVE_PATH <out-var> <directory> <file>)
  file({TO_CMAKE_PATH | TO_NATIVE_PATH} <path> <out-var>)

Transfer
  file(DOWNLOAD <url> [<file>] [...])
  file(UPLOAD <file> <url> [...])

Locking
  file(LOCK <path> [...])

Archiving
  file(ARCHIVE_CREATE OUTPUT <archive> PATHS <paths>... [...])
  file(ARCHIVE_EXTRACT INPUT <archive> [...])

读文件(Reading)

读取文本文件和二进制文件

file(READ <filename> <variable> [OFFSET <offset>] [LIMIT <max-in>] [HEX])

<filename> 文件中读取内容,并将其存储在 <variable> 变量中。<offset> 表示从该文件的偏移位置开始,<max-in> 表示最多读取的字节数。HEX 将文件内容作为十六进制读取,输出字母 af 为小写。

读取文件作为 ASCII 字符串列表

file(STRINGS <filename> <variable> [<options>...])

<filename> 文件解析 ASCII 字符串列表,并将其存储在 <variable> 中。忽略文件中的二进制数据,忽略回车符(\r, CR)。每行字符串为列表中一个元素。

<options> 选项包括:

  • LENGTH_MAXIMUM <max-len>: 只考虑不超过给定长度的字符串。
  • LENGTH_MINIMUM <min-len>: 只考虑不少于给定长度的字符串。
  • LIMIT_COUNT <max-num>: 限制要提取的不同字符串的数量。
  • LIMIT_INPUT <max-in>: 限制从文件中读取的输入字节数。
  • LIMIT_OUTPUT <max-out>: 限制 <variable> 中存储的总字节数。
  • NEWLINE_CONSUME: 将换行符(\n, LF)作为字符串内容的一部分,而不是终止于它们。
  • NO_HEX_CONVERSION: 除非给出此选项,否则读取时 Intel HexMotorola S-record 文件会自动转换为二进制文件。
  • REGEX <regex>: 只考虑匹配给定正则表达式的字符串,如 string(REGEX) 所述。如果匹配成功,包括该行。
  • ENCODING <encoding-type>: 考虑给定编码的字符串。目前支持的编码有:UTF-8UTF-16LEUTF-16BEUTF-32LEUTF-32BE。如果没有提供编码选项,并且文件具有字节顺序标记,则默认情况下,编码选项将遵循字节顺序标记。

例如,

file(STRINGS "data.txt" VAR)

从文件 “data.txt” 文件解析为字符串列表,其中每一个元素为文件的一行。

例如,

file(STRINGS "data.txt" VAR REGEX "Pride")

如果文件行包含 “Pride” 字符串,则保留该行。

计算文件的哈希值

file(<HASH> <filename> <variable>)

计算 <filename> 文件的内容为哈希值,并将其存储在 <variable> 变量中。支持的 <HASH> 算法名称由 string(<HASH>) 命令列出。
https://cmake.org/cmake/help/v3.19/command/string.html#supported-hash-algorithms

注意,文件名 <filename> 需要是绝对路径。

例如,

get_filename_component(FILE_NAME file.dat ABSOLUTE)
message("FILE_NAME: ${FILE_NAME}")
file(SHA256 ${FILE_NAME} CHECKSUM_VARIABLE)
message("CHECKSUM_VARIABLE: ${CHECKSUM_VARIABLE}")

先将文件路径,转换为绝对路径,然后计算文件的哈希值。

获取文件的修改时间

file(TIMESTAMP <filename> <variable> [<format>] [UTC])

计算文件 <filename> 修改时间的字符串表示,并将其存储在变量 <variable> 中。 如果该命令无法获得时间戳变量将被设置为空字符串("")。例,file(TIMESTAMP ${FILE_NAME} TIME_DATE)

注意: 文件名 <filename> 需要为绝对路径。

有关 <format>UTC 选项的文档,请参阅 string(TIMESTAMP) 命令。

依赖项查找

file(GET_RUNTIME_DEPENDENCIES
  [RESOLVED_DEPENDENCIES_VAR <deps_var>]
  [UNRESOLVED_DEPENDENCIES_VAR <unresolved_deps_var>]
  [CONFLICTING_DEPENDENCIES_PREFIX <conflicting_deps_prefix>]
  [EXECUTABLES [<executable_files>...]]
  [LIBRARIES [<library_files>...]]
  [MODULES [<module_files>...]]
  [DIRECTORIES [<directories>...]]
  [BUNDLE_EXECUTABLE <bundle_executable_file>]
  [PRE_INCLUDE_REGEXES [<regexes>...]]
  [PRE_EXCLUDE_REGEXES [<regexes>...]]
  [POST_INCLUDE_REGEXES [<regexes>...]]
  [POST_EXCLUDE_REGEXES [<regexes>...]]
  )

递归获取给定文件依赖的库列表。

请注意,此子命令不适用于项目模式。相反,在 install(CODE)install(SCRIPT) 块中使用它。 例如:

install(CODE [[
  file(GET_RUNTIME_DEPENDENCIES
    # ...
    )
  ]])

file(GET_RUNTIME_DEPENDENCIES) 参数,说明如下:

  • RESOLVED_DEPENDENCIES_VAR <deps_var>: 存储已解析依赖项列表的变量的名称。
  • UNRESOLVED_DEPENDENCIES_VAR <unresolved_deps_var>: 用于存储未解析依赖项列表的变量的名称。如果未指定此变量,并且存在任何未解析的依赖项,则会发出错误。
  • CONFLICTING_DEPENDENCIES_PREFIX <conflicting_deps_prefix>: 存储冲突依赖信息的变量前缀。如果在两个不同目录中找到两个同名文件,则依赖项会发生冲突。冲突的文件名列表存储在 <conflicting_deps_prefix>_FILENAMES 中。对于每个文件名,为该文件名找到的路径列表存储在 <conflicting_deps_prefix>_<filename> 中。
  • EXECUTABLES <executable_files>: 要读取依赖项的可执行文件列表。这些是通常使用 add_executable() 创建的可执行文件,但它们不必由 CMake 创建。在 Apple 平台上,这些文件的路径决定了递归解析库时 @executable_path 的值。在此处指定任何类型的库(STATICMODULESHARED)都将导致未定义的行为。
  • LIBRARIES <library_files>: 要读取依赖项的库文件列表。这些是通常使用 add_library(SHARED) 创建的库,但它们不必由 CMake 创建。在此处指定 STATIC 库、MODULE 库或可执行文件将导致未定义的行为。
  • MODULES <module_files>: 要读取依赖项的可加载模块文件列表。这些是通常使用 add_library(MODULE) 创建的模块,但它们不必由 CMake 创建。它们通常通过在运行时调用 dlopen() 来使用,而不是在链接时使用 ld -l 链接。在此处指定 STATIC 库、SHARED 库或可执行文件将导致未定义的行为。
  • DIRECTORIES <directories>: 用于搜索依赖项的其他目录列表。在 Linux 平台上,如果在任何其他常用路径中找不到依赖项,则会搜索这些目录。如果在这样的目录中找到它,则会发出警告,因为这意味着该文件不完整(它没有列出包含其依赖项的所有目录)。在 Windows 平台上,如果在任何其他搜索路径中找不到依赖项,则会搜索这些目录,但不会发出警告,因为搜索其他路径是 Windows 依赖项解析的正常部分。在 Apple 平台上,此参数无效。
  • BUNDLE_EXECUTABLE <bundle_executable_file>: 解析库时,可执行文件被视为 “捆绑可执行文件”。在 Apple 平台上,此参数在递归解析 LIBRARIESMODULES 文件的库时确定 @executable_path 的值。它对 EXECUTABLES 文件没有影响。在其他平台上,它没有影响。这通常(但不总是)是 EXECUTABLES 参数中的可执行文件之一,它指定包的 “主要” 可执行文件。

这些参数,用正则表达式要包含或排除的过滤器,在解析依赖项时,排除不需要的系统库,或包含特定的库。如下说明:

  • PRE_INCLUDE_REGEXES [<regexes>...]: 预包含。
  • PRE_EXCLUDE_REGEXES [<regexes>...]: 预排除。
  • POST_INCLUDE_REGEXES [<regexes>...]: 后包含。
  • POST_EXCLUDE_REGEXES [<regexes>...]: 后排除。

例,因为 Windows DLL 名称不区分大小写,我们想实现这种不区分大小写动态库文件查找,查找 “mylibrary.dll” 或 “MYLIBRARY.DLL”:

file(GET_RUNTIME_DEPENDENCIES
  # ...
  PRE_INCLUDE_REGEXES "^[Mm][Yy][Ll][Ii][Bb][Rr][Aa][Rr][Yy]\\.[Dd][Ll][Ll]$"
)

DLL 名称转换为小写允许正则表达式只匹配小写名称,从而简化了正则表达式。 例如:

file(GET_RUNTIME_DEPENDENCIES
  # ...
  PRE_INCLUDE_REGEXES "^mylibrary\\.dll$"
)

此函数接受多个变量,以确定用于依赖项解析的工具:

  • CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM: 确定文件为哪种操作系统和可执行文件格式。选择值为: linux+elf, windows+pe, macos+macho
  • CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL: 确定用于解析依赖库的工具,根据 CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM 变量值来确定。
    • linux+elf 对应 objdump
    • windows+pe 对应 dumpbin
    • windows+pe 对应 objdump
    • macos+macho 对应 otool
  • CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND: 确定用于依赖项解析的工具的路径。这是 objdump, dumpbinotool 的实际路径。

写文件(Writing)

写入文件内容

file(WRITE <filename> <content>...)
file(APPEND <filename> <content>...)

将内容 <content> 写入 <filename> 文件中。 如果文件不存在,它将被创建。如果文件已经存在,WRITE 模式将覆盖它,APPEND 模式将附加到末尾。例,file(WRITE "data.txt" "Hello World")

<filename> 文件名中的路径不存在,那么会创建这些不存在的目录。

如果文件是构建输入,则使用 configure_file() 命令仅在其内容更改时更新文件。

创建空文件

file(TOUCH [<files>...])
file(TOUCH_NOCREATE [<files>...])

创建一个空文件,若文件已存在,不会修改现有文件的内容,仅更新访问和修改时间。

使用 TOUCH_NOCREATE 并不创建文件,仅用来更新访问和修改时间。

在构建目标时,生成输出文件

file(GENERATE OUTPUT output-file
     <INPUT input-file|CONTENT content>
     [CONDITION expression] [TARGET target])

在构建目标时,生成输出文件。

为当前 CMake 生成器支持的每个构建配置生成一个输出文件。从输入内容评估生成器表达式以生成输出内容。选项是:

  • CONDITION <condition>: 仅当条件为真时才为特定配置生成输出文件。计算生成器表达式后,条件必须为 01
  • CONTENT <content>: 使用明确给出的内容作为输入。
  • INPUT <input-file>: 使用给定文件中的内容作为输入。相对路径根据 CMAKE_CURRENT_SOURCE_DIR 的值进行处理。请参阅政策 CMP0070
  • OUTPUT <output-file>: 指定要生成的输出文件名。使用诸如 $<CONFIG> 之类的生成器表达式来指定特定于配置的输出文件名。只有生成的内容相同,多个配置才能生成相同的输出文件。否则, <output-file> 必须评估为每个配置的唯一名称。相对路径(在评估生成器表达式之后)根据 CMAKE_CURRENT_BINARY_DIR 的值进行处理。请参阅政策 CMP0070
  • TARGET <target>: 指定在评估需要评估目标的生成器表达式时使用哪个目标(例如 $<COMPILE_FEATURES:...>, $<TARGET_PROPERTY:prop>)。

必须只给出一个 CONTENTINPUT 选项。 一个特定的 OUTPUT 文件最多可以通过调用一次 file(GENERATE) 来命名。 生成的文件会被修改,并且只有当它们的内容发生更改时,它们的时间戳才会在后续 cmake 运行时更新。

还要注意 file(GENERATE) 直到生成阶段才创建输出文件。 当 file(GENERATE) 命令返回时,输出文件尚未写入,只有在处理完项目的所有 CMakeLists.txt 文件后才会写入。

例,在执行 CMakeLists.txt 时,构建 hello 目录时,将内容 “Hello World” 输出到文件 “out.txt”

add_executable(hello main.cpp)
file(GENERATE OUTPUT "out.txt" CONTENT "Hello World" TARGET hello)

输出配置文件

file(CONFIGURE OUTPUT output-file
     CONTENT content
     [ESCAPE_QUOTES] [@ONLY]
     [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])

configure_file() 命令替换规则相同,CONTENT 文件内容 类似于 xxx.in 文件,替换其中包含的引用为 @VAR@${VAR} 的变量值,输出文件名为 OUTPUT

参数说明:

  • ESCAPE_QUOTES: 使用反斜杠 C 样式 转义任何替换的引号。
  • @ONLY: 将变量替换限制为 @VAR@ 形式的引用。这对于配置使用 ${VAR} 语法的脚本很有用。
  • NEWLINE_STYLE <style>: 指定输出文件的换行样式。 指定 UNIX/LF\n 换行符,或 指定 DOS/WIN32/CRLF\r\n 换行符。

文件系统(Filesystem)

搜索文件

file(GLOB <variable>
     [LIST_DIRECTORIES true|false] [RELATIVE <path>] [CONFIGURE_DEPENDS]
     [<globbing-expressions>...])
file(GLOB_RECURSE <variable> [FOLLOW_SYMLINKS]
     [LIST_DIRECTORIES true|false] [RELATIVE <path>] [CONFIGURE_DEPENDS]
     [<globbing-expressions>...])

GLOB 模式仅搜索当前目录,而 GLOB_RECURSE 模式会递归搜索目录或所有子目录。只有在给定 FOLLOW_SYMLINKS 或策略 CMP0009 未设置为 NEW 时,才会遍历作为符号链接的子目录。

搜索文件,根据 <globbing-expressions> glob 表达式 匹配文件名,并将文件列表存储在变量 <variable>

如果指定 RELATIVE 标志,结果作为该路径的相对路径返回。

如果指定了 CONFIGURE_DEPENDS 标志,CMake 将向主构建系统检查目标添加逻辑,以在构建时重新运行标记的 GLOB 命令。 如果任何输出发生变化,CMake 将重新生成构建系统。

默认情况下会列出目录,如果指定 LIST_DIRECTORIES 设置为 false,则搜索的结果并不输出。

请注意,不建议使用 GLOB 收集源文件列表。如果添加或删除源文件时,并没有在 CMakeLists.txt 文件更改,则生成的构建系统无法直到何时要求 CMake 重新生成。CONFIGURE_DEPENDS 标志可能无法在所有生成器上可靠地工作,或者如果将来添加了不能支持它的新生成器,使用它的项目将被卡住。 即使 CONFIGURE_DEPENDS 工作可靠,在每次重建时执行检查仍然存在成本。

<globbing-expressions> glob 表达式,包括:

*.cxx      - match all files with extension cxx
*.vt?      - match all files with extension vta,...,vtz
f[3-5].txt - match files f3.txt, f4.txt, f5.txt
The GLOB_RECURSE mode will traverse all the subdirectories of the matched directory and match the files. Subdirectories that are symlinks are only traversed if FOLLOW_SYMLINKS is given or policy CMP0009 is not set to NEW.

例,按当前目录中所有的 .cpp 文件,获取绝对路径的文件列表:

file(GLOB FILE_LISTS *.cpp)
file(GLOB INCLUDE_FILE_LISTS include/*.h)
file(GLOB_RECURSE SRC_FILE_LISTS src/*.cpp)

文件重命名

file(RENAME <oldname> <newname>)

重命名文件或目录。

例,将当前目录下 main.cpp 重命名为 hello.cp

file(RENAME main.cpp hello.cpp)

文件删除

file(REMOVE [<files>...])
file(REMOVE_RECURSE [<files>...])

REMOVE 模式仅删除文件,REMOVE_RECURSE 模式删除文件和目录(空目录和非空目录)。如果不存在,则不会发出错误。

例,删除当前目录下 main.cpp 文件, src 目录, include 目录

file(REMOVE hello.cpp)
file(REMOVE_RECURSE src)
file(REMOVE_RECURSE include)

创建目录

file(MAKE_DIRECTORY [<directories>...])

根据需要创建给定的目录及其父目录。

例,创建目录 core 和 父目录 src

file(MAKE_DIRECTORY src/core)

文件复制与安装

file(<COPY|INSTALL> <files>... DESTINATION <dir>
     [FILE_PERMISSIONS <permissions>...]
     [DIRECTORY_PERMISSIONS <permissions>...]
     [NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS]
     [FOLLOW_SYMLINK_CHAIN]
     [FILES_MATCHING]
     [[PATTERN <pattern> | REGEX <regex>]
      [EXCLUDE] [PERMISSIONS <permissions>...]] [...])

COPY 签名,将文件、目录和符号链接复制到 DESTINATION 目标文件夹。<files> 文件路径为当前目录,<dir> 输出目录为 CMAKE_BINARY_DIR 变量路径。

输出文件时间戳 和 权限都与输入文件相同。权限选项默认为 USE_SOURCE_PERMISSIONS 与源相同,NO_SOURCE_PERMISSIONS 不使用源的权限。FILE_PERMISSIONSDIRECTORY_PERMISSIONS

如果指定 FOLLOW_SYMLINK_CHAIN 选项,当遇到符号链接时,会找到真正的文件,并在目标中为遇到的每个符号链接安装相应的符号链接。

例,将所有符号链接和 libfoo.so.1.2.3 本身安装到 lib 目录中。

目录结构为

  • /opt/foo/lib/libfoo.so.1.2 -> libfoo.so.1.2.3
  • /opt/foo/lib/libfoo.so.1 -> libfoo.so.1.2
  • /opt/foo/lib/libfoo.so -> libfoo.so.1

然后做

file(COPY /opt/foo/lib/libfoo.so DESTINATION lib FOLLOW_SYMLINK_CHAIN)

关于 PERMISSIONSFILES_MATCHINGPATTERNREGEXEXCLUDE 选项的文档,请参阅 install(DIRECTORY) 命令。 即使使用选项来选择文件的子集,复制目录也会保留其内容的结构。

INSTALL 签名COPY 签名 略有不同:它打印状态消息(取决于 CMAKE_INSTALL_MESSAGE 变量),并且 NO_SOURCE_PERMISSIONS 是默认值。install() 命令,生成的安装脚本使用此签名(带有一些未公开的供内部使用的选项)。

文件大小

file(SIZE <filename> <variable>)

Determine the file size of the and put the result in variable. Requires that is a valid path pointing to a file and is readable.

确定 <filename> 的文件大小,将结果放入 <variable> 变量中。

注意,路径为绝对路径

例,

file(SIZE ${CMAKE_SOURCE_DIR}/main.cpp FILE_SIZE)

查询文件符号链接

file(READ_SYMLINK <linkname> <variable>)

将符号链接 <linkname> 的真实路径存储在 <variable> 中。

例,确保获得绝对路径

set(linkname "/path/to/foo.sym")
file(READ_SYMLINK "${linkname}" result)
if(NOT IS_ABSOLUTE "${result}")
  get_filename_component(dir "${linkname}" DIRECTORY)
  set(result "${dir}/${result}")
endif()

创建文件符号链接

file(CREATE_LINK <original> <linkname> [RESULT <result>] [COPY_ON_ERROR] [SYMBOLIC])

创建 <original> 文件的链接 <linkname>。若成功创建将 <result> 设置为 0,否则操作失败。

默认情况下,创建的是硬链接,使用 SYMBOLIC 选项,是创建符号链接。硬链接要求 <original> 文件,为 文件,而不是 目录。

COPY_ON_ERROR 选项启用,如果链接创建失败,将复制文件作为后被操作。

注意,路径为绝对路径

例,创建文件 main.cpp 的硬链接,目录 src 的软链接,结果输出到 CMAKE_BINARY_DIR 变量路径

file(CREATE_LINK ${CMAKE_SOURCE_DIR}/main.cpp main.1.cpp)
file(CREATE_LINK ${CMAKE_SOURCE_DIR}/src src.1 SYMBOLIC)

文件权限

file(CHMOD <files>... <directories>...
    [PERMISSIONS <permissions>...]
    [FILE_PERMISSIONS <permissions>...]
    [DIRECTORY_PERMISSIONS <permissions>...])
file(CHMOD_RECURSE <files>... <directories>...
    [PERMISSIONS <permissions>...]
    [FILE_PERMISSIONS <permissions>...]
    [DIRECTORY_PERMISSIONS <permissions>...])

更改 <files>...<directories>... 权限。有效权限为 OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, WORLD_READ, WORLD_WRITE, WORLD_EXECUTE

选项有效的组合是:

  • PERMISSIONS: 更改所有项。
  • FILE_PERMISSIONS: 仅更改文件。
  • DIRECTORY_PERMISSIONS: 仅更改目录。
  • PERMISSIONS and FILE_PERMISSIONS: 文件中的权限 FILE_PERMISSIONS 覆盖 PERMISSIONS
  • PERMISSIONS and DIRECTORY_PERMISSIONS: 目录中的权限 DIRECTORY_PERMISSIONS 覆盖 PERMISSIONS
  • FILE_PERMISSIONS and DIRECTORY_PERMISSIONS: 对文件使用 FILE_PERMISSIONS,对目录使用 DIRECTORY_PERMISSIONS

CHMOD_RECURSECHMOD 相同,但以递归方式更改 <directories>... 中存在的文件和目录权限。

路径转换(Path Conversion)

转换为绝对路径

file(REAL_PATH <path> <out-var> [BASE_DIRECTORY <dir>])

将相对路径 <path> 转换为 绝对路径,并存储在变量 <out-var> 中。绝对路径是基于 <dir> 进行计算,默认情况下为 CMAKE_CURRENT_SOURCE_DIR

若路径 <path> 为绝对路径,那么返回就是该绝对路径。

请注意,<path> 仅用来计算路径,与文件是否存在,是否为链接文件无关。

例,

file(REAL_PATH main.cpp REAL_PATH_VAR)
file(REAL_PATH C:\\CMake\\example\\main.cpp REAL_PATH_VAR)

转换为相对路径

file(RELATIVE_PATH <out-var> <directory> <file>)

计算从目录 <directory> 到 文件 <file> 的相对路径,并存储在变量 <out-var> 中。

例,

file(RELATIVE_PATH RELATIVE_PATH_VAR C:\\CMake\\example C:\\CMake\\example\\main.cpp)

CMake 路径 与 本机 路径 风格之间的转换

file(TO_CMAKE_PATH <path> <out-var>)
file(TO_NATIVE_PATH <path> <out-var>)

CMake 风格的路径Linux 风格路径是一样的用正斜杠 '/',而 Windows 风格路径是用反斜杠 '\'

我们有些见需要将各种平台的路径统一风格,那么使用 TO_CMAKE_PATH 模式,将路径 <path> 转换为 CMake 风格的路径

也可以使用 TO_NATIVE_PATH 模式,将路径 <path> 根部不同的操作系统,转换为特定平台的本机路径。

例,演示 CMake 风格的路径Windows 风格的路径

set(FILE_PATH C:\\CMake\\example\\main.cpp)
message(${FILE_PATH})
file(TO_CMAKE_PATH ${FILE_PATH} CMAKE_FILE_PATH)
message("CMake Style: ${CMAKE_FILE_PATH}")
file(TO_NATIVE_PATH "${FILE_PATH}" NATIVE_FILE_PATH)
message("Native Style: ${NATIVE_FILE_PATH}")

上传和下载(Transfer)

file(DOWNLOAD <url> [<file>] [<options>...])
file(UPLOAD   <file> <url> [<options>...])

DOWNLOAD 子命令将 <url> 下载到本地 <file>。如果未指定保存文件 <file>,则不保存文件,用于检查文件是否可下载,这很有用。将文件下载到 CMAKE_CURRENT_BINARY_DIR 目录。
UPLOAD 子命令将本地 <file> 文件上传到 <url>

DOWNLOADUPLOAD 的选项 <options> 为:

  • INACTIVITY_TIMEOUT <seconds>: 在一段时间不活动后终止操作。
  • LOG <variable>: 将操作存储在日志中。
  • SHOW_PROGRESS: 打印进度信息。
  • STATUS <variable>: 将操作的结果状态存储在变量中。
  • TIMEOUT <seconds>: 超时后终止操作。
  • USERPWD <username>:<password>: 设置用户和密码。
  • HTTPHEADER <HTTP-header>: 用于操作的 HTTP 头。子选项可以重复多次。
  • NETRC <level>: 指定是否使用 .netrc 文件进行操作。如果未指定此选项,则将使用 CMAKE_NETRC 变量的值。有效级别为:
    • IGNORED: .netrc 文件被忽略。 这是默认设置。
    • OPTIONAL: .netrc 文件是可选的,URL 中的信息是首选。 将扫描文件以查找 URL 中未指定的信息。
    • REQUIRED: .netrc 文件是必需的,URL 中的信息将被忽略。
  • NETRC_FILE <file>: 如果 NETRC 级别为 OPTIONALREQUIRED,则指定替代 .netrc 文件到您的主目录中的文件。 如果未指定此选项,则将使用 CMAKE_NETRC_FILE 变量的值。如果没有给出 NETRC 选项,CMake 将分别检查变量 CMAKE_NETRCCMAKE_NETRC_FILE
  • TLS_VERIFY <ON|OFF>: 指定是否验证 https://URLs 的服务器证书。 默认是不验证。
  • TLS_CAINFO <file>: 为 https://URLs 指定自定义证书颁发机构文件。

对于 https://URLsCMake 必须使用 OpenSSL 支持构建。 默认情况下不检查 TLS/SSL 证书。将 TLS_VERIFY 设置为 ON 以检查证书。如果没有给出 TLS 选项,CMake 将分别检查变量 CMAKE_TLS_VERIFYCMAKE_TLS_CAINFO

DOWNLOAD 其他选项:

  • EXPECTED_HASH ALGO=<value>: 验证下载的内容哈希是否与预期值匹配,其中 ALGOfile(<HASH>) 支持的算法之一。如果不匹配,操作将失败并显示错误。如果没有给 DOWNLOAD 一个 <file>,那么指定这个是错误的。
  • EXPECTED_MD5 <value>: 是 EXPECTED_HASH MD5=<value> 的简写。 如果没有给 DOWNLOAD 一个 <file>,那么指定这个是错误的。

文件锁(Locking)

file(LOCK <path> [DIRECTORY] [RELEASE]
     [GUARD <FUNCTION|FILE|PROCESS>]
     [RESULT_VARIABLE <variable>]
     [TIMEOUT <seconds>])

可以锁定文件或目录。锁定由 <path> 指定的文件,若指定 DIRECTORY 选项,锁定 <path>/cmake.lock 文件。
文件锁定范围由 GUARD 选项定义,默认值为 PROCESS
RELEASE 选项可用于显式解锁文件。
若想设置等锁定的超时时间,指定 TIMEOUT 选项。如果 TIMEOUT 设置为 0 锁定将尝试一次并立即报告结果。如果 TIMEOUT 不是 0CMake 将尝试在 <seconds> 值指定的时间段内锁定文件。若未指定 TIMEOUT 选项,CMake 将等待锁定成功或发生致命错误。
若想保存返回结果,指定 RESULT_VARIABLE 选项,将结果将存储在 <variable> 变量中,成功时为 0,失败时为错误消息。若未指定 RESULT_VARIABLE 选项,任何错误都将被解释为致命错误。

请注意,锁是建议性的。不能保证其他进程会尊重这个锁,即锁同步两个或多个共享一些可修改资源的 CMake 实例。应用于 DIRECTORY 选项的类似逻辑,锁定父目录不会阻止其他 LOCK 命令锁定任何子目录或文件。

不允许尝试锁定文件两次。如果它们不存在,任何中间目录和文件本身将被创建。在 RELEASE 操作中忽略 GUARDTIMEOUT 选项。

归档(Archiving)

创建归档

file(ARCHIVE_CREATE OUTPUT <archive>
  PATHS <paths>...
  [FORMAT <format>]
  [COMPRESSION <compression> [COMPRESSION_LEVEL <compression-level>]]
  [MTIME <mtime>]
  [VERBOSE])

根据 <paths> 中的文件或目录 创建归档文件 <archive>FORMAT 指定归档格式,支持的值为 7zipgnutarpaxpaxrrawzip,默认格式为 paxr

例,将 目录 include, 目录 src, 文件 main.cpp 归档为 out.zip

file(ARCHIVE_CREATE OUTPUT out.zip
	PATHS ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
	FORMAT zip
)

请注意,<paths> 需要是绝对路径。

某些存档格式允许指定压缩类型。7zipzip 允许压缩类型,可以使用 COMPRESSION 选项指示这样做。<compression> 的有效值为 NoneBZip2GZipXZZstd。使用 COMPRESSION_LEVEL 选项指定压缩级别。<compression-level> 应该在 0-9 之间,默认值为 0。当给出 COMPRESSION_LEVEL 时必须存在 COMPRESSION 选项。

VERBOSE 选项为归档操作启用详细输出。

要指定记录在 tarball 条目中的修改时间,请使用 MTIME 选项。

提取归档

file(ARCHIVE_EXTRACT INPUT <archive>
  [DESTINATION <dir>]
  [PATTERNS <patterns>...]
  [LIST_ONLY]
  [VERBOSE])

提取归档文件 <archive>,并输出到 DESTINATION 目录中,如果目录不存在,它将被创建,默认情况下输出目录为 CMAKE_CURRENT_BINARY_DIR

例,提取归档文件 out.zip

file(ARCHIVE_EXTRACT INPUT out.zip)

请注意,<archive> 默认所在目录在 CMAKE_CURRENT_BINARY_DIR

如果需要,您可以使用指定的 <patterns> 选择要列出或从存档中提取的文件和目录。支持通配符。 如果未给出 PATTERNS 选项,则将列出或提取整个存档。

LIST_ONLY 将列出存档中的文件而不是提取它们。

使用 VERBOSE,该命令将产生详细输出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>