cmake之file:文件处理指令
概要
文件操作命令,该命令专用于操作文件系统中的文件。
对于只处理语法方面的路径操作,查看cmake_path()命令。
按照其功能可共分为以下几类:
读:
命令结构:
file(READ <filename> <out-var> [...])
file(STRINGS <filename> <out-var> [...])
file(<HASH> <filename> <out-var>)
file(TIMESTAMP <filename> <out-var> [...])
file(GET_RUNTIME_DEPENDENCIES [...])
写:
命令结构:
file({WRITE | APPEND} <filename> <content>...)
file({TOUCH | TOUCH_NOCREATE} [<file>...])
file(GENERATE OUTPUT <output-file> [...])
file(CONFIGURE OUTPUT <output-file> CONTENT <content> [...])
文件系统:
命令结构:
file({GLOB | GLOB_RECURSE} <out-var> [...] [<globbing-expr>...])
file(MAKE_DIRECTORY [<dir>...])
file({REMOVE | REMOVE_RECURSE } [<files>...])
file(RENAME <oldname> <newname> [...])
file(COPY_FILE <oldname> <newname> [...])
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>... [...])
路径转换:
命令结构:
file(REAL_PATH <path> <out-var> [BASE_DIRECTORY <dir>] [EXPAND_TILDE])
file(RELATIVE_PATH <out-var> <directory> <file>)
file({TO_CMAKE_PATH | TO_NATIVE_PATH} <path> <out-var>)
传输:
命令结构:
file(DOWNLOAD <url> [<file>] [...]) file(UPLOAD <file> <url> [...])
锁定:
命令结构:
file(LOCK <path> [...])
归档:
命令结构:
file(ARCHIVE_CREATE OUTPUT <archive> PATHS <paths>... [...])
file(ARCHIVE_EXTRACT INPUT <archive> [...])
下面详细分析个功能下的file指令即用法,为了方便理解,每个file都有详细的代码做解释:
1. 读(Reading)
1.1. READ
file(READ <filename> <variable> [OFFSET <offset>] [LIMIT <max-in>] [HEX])
描述:
读取文件(filename)的内容保存到变量(variable)中;
参数:
[]内的参数代表可选,从offset作为开始位置,最多读取max-in个字节的数据;
HEX:将数据转为十六进制标识(对二进制数据很有用);如果指定了HEX选项,输出的字母(a到f)都是小写。
假如有config.cmake文件,内容如下:
set(TEST, "this is test")
则file的READ用法:
file(READ config.cmake contents)
string(REGEX REPLACE "set\\(([A-Za-z_0-9]+)\\) \"([^\"]*)\"" "\\1 \\2" contents "${contents}")
message("TEST: ${TEST}")
1.2. STRINGS
file(STRINGS <filename> <variable> [<options>...])
描述:
解析<filename>中的ASCII字符串列表,并将其存储在中。忽略文件中的二进制数据。忽略回车(\r, CR)字符;
参数:
filename:文件名
variable:变量名
options:可选选项,选项如下:
LENGTH_MAXIMUM <max-len>:
只考虑长度不超过给定值(max-len)的字符串
LENGTH_MINIMUM <min-len>:
只考虑不少于给定长度的字符串
LIMIT_COUNT <max-num>:
限制要提取的不同字符串的数量
LIMIT_INPUT <max-in>:
限制从文件中读取的输入字节数
LIMIT_OUTPUT <max-out>:
限制(变量)中存储的总字节数。
NEWLINE_CONSUME:
将换行符(\n, LF)视为字符串内容的一部分,而不是以换行符结束。
NO_HEX_CONVERSION:
除非提供此选项,否则英特尔十六进制和摩托罗拉S-record文件在读取时将自动转换为二进制。
REGEX <regex>:
只考虑匹配给定正则表达式的字符串
ENCODING <encoding-type>:
3.1版本新功能,考虑给定编码的字符串。目前支持的编码有:UTF-8、UTF-16LE、UTF-16BE、UTF-32LE、UTF-32BE。如果没有提供编码选项,并且文件有字节顺序标记,则编码选项将默认遵守字节顺序标记。在3.2版本添加了UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE编码支持
示例代码
#文件名test.txt,内容
q wst qwert asdfghjkl
test
#CMakeLists.txt内容
cmake_minimum_required(VERSION 1.0)
project(TEST)
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/test.txt" str LENGTH_MAXIMUM 5)
foreach(mystr ${str})
message("string : ${mystr}")
endforeach()
#执行cmake之后的打印
string : q wst
string : qwer
string : t asd
string : fghjk
string : l
string : test
#可以看到,对于file命令,一行中空格相当于字符,可以被读进字符串;直到遇到换行符才重新开始读行。
1.3 HASH
file(<HASH> <filename> <variable>)
描述:
计算<文件名>内容的加密散列,并将其存储在<变量>中,保证文件内容的正确性。
参数:
filename:文件名
variable:变量名
file的HASH指令只是计算文件的hash值,用于确保文件内容的正确性。
1.4 TIMESTAMP
file(TIMESTAMP <filename> <variable> [<format>] [UTC])
描述:
获取文件的时间戳,并将其存储在中。如果命令无法获取时间戳变量将被设置为空字符串("")。
参数:
<filename>:指定要获取时间戳的文件路径。
<variable>:指定存储时间戳的变量名。
<format>(可选):指定时间戳的格式,默认为%Y-%m-%d %H:%M:%S。
UTC(可选):指定使用UTC时间作为时间戳。
时间戳在构建的时候可以由TIMESTAMP命令设置,关于TIMESTAMP命令参考我的博客:cmake之string命令
1.5 GET_RUNTIME_DEPENDENCIES
file(GET_RUNTIME_DEPENDENCIES [...])
描述:
3.16版本新增的功能,递归地获取给定文件依赖的库的列表。
参数:
[...]选项如下:
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>...]]
[POST_INCLUDE_FILES [<files>...]]
[POST_EXCLUDE_FILES [<files>...]]
)
请注意,此子命令不打算在项目模式下使用。它是在安装时使用的,可以从install(RUNTIME_DEPENDENCY_SET)命令生成的代码中使用,也可以从项目通过install(code)或install(SCRIPT)提供的代码中使用。例如:
install(CODE [[ file(GET_RUNTIME_DEPENDENCIES # ... ) ]])
参数如下:
RESOLVED_DEPENDENCIES_VAR <deps_var>:
用于存储已解决依赖项列表的变量名。
UNRESOLVED_DEPENDENCIES_VAR <unresolved_deps_var>:
用于存储未解决依赖项列表的变量名。如果未指定此变量,并且存在任何未解决的依赖项,则会引发错误。
CONFLICTING_DEPENDENCIES_PREFIX <conflicting_deps_prefix>:
变量前缀,用于存储冲突的依赖信息。如果在两个不同的目录中发现同名的两个文件,则依赖关系是冲突的。冲突文件名的列表存储在_FILENAMES中。对于每个文件名,为该文件名找到的路径列表保存在_中。
EXECUTABLES <executable_files>:
要读取依赖项的可执行文件列表。这些可执行文件通常是用add_executable()创建的,但它们不一定要由CMake创建。
LIBRARIES <library_files>:
要读取依赖项的库文件列表。这些库通常是用add_library(SHARED)创建的,但它们不一定要由CMake创建。不能指定静态库、模块库或可执行文件,否则将导致未定义错误(在这里指定静态库、模块库或可执行文件将导致未定义的行为。)。
MODULES <module_files>:
要读取依赖的可加载模块文件列表。这些模块通常是用add_library(MODULE)创建的,但它们不一定要由CMake创建。它们通常通过在运行时调用dlopen()来使用,而不是在链接时使用ld -l进行链接。不能指定静态库、模块库或可执行文件,否则将导致未定义错误(在这里指定静态库、模块库或可执行文件将导致未定义的行为。)。
DIRECTORIES <directories>:
要搜索依赖项的附加目录列表。在Linux平台上,如果在任何其他常用路径中都没有找到依赖项,则搜索这些目录。如果在这样的目录中找到它,则会发出警告,因为这意味着文件不完整(它没有列出包含其依赖项的所有目录)。
BUNDLE_EXECUTABLE <bundle_executable_file>:
可执行文件在解析库时被视为“bundle Executable”。
下列参数指定包含或排除要解析的库的过滤器。参数描述如下:
PRE_INCLUDE_REGEXES <regexes>:
预包含正则表达式的列表,通过它过滤尚未解析的依赖项的名称。
PRE_EXCLUDE_REGEXES <regexes>:
预排除正则表达式列表,通过它过滤尚未解析的依赖项的名称。
POST_INCLUDE_REGEXES <regexes>:
post-include正则表达式列表,用于过滤解析依赖项的名称。
POST_EXCLUDE_REGEXES <regexes>:
后排除正则表达式列表,用于过滤解析依赖项的名称。
POST_INCLUDE_FILES <files>
3.21版本新增的功能,post-include文件名列表,用于过滤解析依赖项的名称。当试图匹配这些文件名时,符号链接将被解析。
POST_EXCLUDE_FILES <files>:
3.21版本新增的功能,用于过滤解析依赖项名称的后排除文件名列表。当试图匹配这些文件名时,符号链接将被解析。
这些参数可用于在解析依赖关系时排除不需要的系统库,或从特定目录包含库。过滤的工作原理如下:
- 如果尚未解决的依赖项匹配任何PRE_INCLUDE_REGEXES,则跳过步骤2和3,并继续解析依赖项到步骤4。
- 如果尚未解析的依赖项与PRE_EXCLUDE_REGEXES中的任何一个匹配,则对该依赖项的解析将停止。
- 否则,解析依赖关系。
- file(GET_RUNTIME_DEPENDENCIES)根据平台的链接规则搜索依赖项
- 如果找到了依赖项,并且它的完整路径与POST_INCLUDE_REGEXES或POST_INCLUDE_FILES中的一个匹配,那么完整路径会添加到解析的依赖项中,file(GET_RUNTIME_DEPENDENCIES)递归地解析库自身的依赖项。否则,执行步骤6。
- 如果找到了依赖项,但它的完整路径与PRE_EXCLUDE_REGEXES或POST_EXCLUDE_FILES中的一个匹配,则不会将其添加到已解析的依赖项中,并停止对该依赖项的解析。
- 如果找到依赖项,并且它的完整路径与POST_INCLUDE_REGEXES、POST_INCLUDE_FILES、post_exclude_regex或POST_EXCLUDE_FILES不匹配,那么完整路径会被添加到解析的依赖项中,file(GET_RUNTIME_DEPENDENCIES)递归地解析库自身的依赖项。
未完待续。。。
2. 写(Writing)
2.1 WRITE和APPEND
file(WRITE <filename> <content>...)
file(APPEND <filename> <content>...)
将指定的内容(content)写入文件(filename),如果文件不存在则创建文件,如果文件存在,WRITE模式将覆盖文件,APPEND模式将在末尾追加内容,如果filename所在的路径中的任何一个路径不存在该目录将被创建。
如果文件是构建输入,则仅在其内容更改时使用configure_file()命令更新该文件。关于configure_file命令参考我的博文:cmake之configure_file命令。
代码演示:
#原本没有test.txt
#CMakeLists.txt内容
file(WRITE test.txt "this is test")
#执行之后,CMakeLists.txt所在的目录下生成test.txt文件,并且文件内容为this is test
2.2 TOUCH和TOUCH_NOCREATE
file(TOUCH [<files>...])
file(TOUCH_NOCREATE [<files>...])
3.12版本新增功能,如果文件不存在则创建新的空文件,如果文件存在,则文件的访问或修改时间会更新为执行该命令的时间。文件存在两者作用一样,但是文件不存在两者有着区别。
文件不存在两者的区别是:如果文件不存在,TOUCH模式会创建文件,而TOUCH_NOCREATE不会创建文件。
代码演示:
#当前目录下存在test.txt,访问日期如下
-rw-r--r-- 1 root root 12 7月 18 08:56 test.txt
#CMakeLists.txt
file(TOUCH/TOUCH_NOCREATE test.txt)
#执行cmake之后,test.txt的访问日期改为最新日期,并且文件内容不会改变
-rw-r--r-- 1 root root 12 7月 18 09:09 ../test.txt
2.3 GENERATE
file(GENERATE [...])
它可以用于根据某些条件生成文件,或者根据需要动态生成文件内容。
可选参数如下:
file(GENERATE OUTPUT <output-file>
<INPUT <input-file>|CONTENT <content>>
[CONDITION <expression>] [TARGET <target>]
[NO_SOURCE_PERMISSIONS | USE_SOURCE_PERMISSIONS |
FILE_PERMISSIONS <permissions>...]
[NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
参数分析:
CONDITION <expression>:
仅当expression为真时,生成特定配置的输出文件。计算生成器表达式后的条件必须是0或1。
参数:
<expression>:指定一个表达式,用于判断是否生成文件。
代码演示:
set(MY_VARIABLE "Hello, world!")
# 生成文件
file(GENERATE OUTPUT "output.txt"
CONDITION ${MY_VARIABLE} STREQUAL "Hello, world!"
)
#${MY_VARIABLE} STREQUAL "Hello, world!"就是<expression>
CONTENT <content>:
指定输入文件的内容
INPUT <input-file>:
创建输入文件,3.10版本后根据CMAKE_CURRENT_SOURCE_DIR来确定文件的路径。
OUTPUT <output-file>:
使用生成器表达式生成特定配置的输出文件。3.10版本后根据CMAKE_CURRENT_SOURCE_DIR来确定文件的路径。
之后的选项都是3.20版本新增的,暂时没用过,不做解释,后面用到再做补充。
2.4 CONFIGURE
file(CONFIGURE OUTPUT <output-file> CONTENT <content> [ESCAPE_QUOTES] [@ONLY]
[NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
3.18版本新增,暂时没用过,只做简单分析:使用CONTENT给出的输入生成一个输出文件,并替换其中包含的@VAR@或${VAR}引用的变量值。不支持生成器表达式。
OUTPUT <output-file>:
指定要生成的输出文件名。相对路径是根据CMAKE_CURRENT_BINARY_DIR的值来处理的。不支持生成器表达式。
CONTENT <content>:
指定文件的内容。不支持生成器表达式。
ESCAPE_QUOTES:
用反斜杠(c风格)转义替换的引号。
@ONLY
将变量替换限制为对形式@VAR@.的引用这对于配置使用${VAR}语法的脚本很有用。
NEWLINE_STYLE <style>
指定输出文件的换行样式。\n换行符指定为UNIX或LF, \r\n换行符指定为DOS、WIN32或CRLF。
3. 文件系统(Filesystem)
3.1 GLOB和GLOB_RECURSE
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>...])
生成一个与<通配表达式>匹配的文件列表,并将其存储到<变量>中。通配表达式类似于正则表达式.
<variable>:
一个变量名,用于存储匹配的文件路径。
LIST_DIRECTORIES true|false(可选参数):
指定是否列出匹配的文件所在的目录。默认值为 false,即不列出目录。如果设置为 true,则会在返回的文件路径中保留目录信息。
RELATIVE <path>(可选参数):
指定相对于哪个路径进行文件搜索。如果没有指定 ,则默认搜索当前 CMakeLists.txt 所在的目录。
CONFIGURE_DEPENDS(可选参数):
在生成的 Makefile 中添加规则,以便在重新配置时重新执行 file(GLOB) 命令以更新匹配的文件列表。这可以确保在文件发生变化时重新构建相关的目标。
<globbing-expressions>(可选参数):
一个或多个用于定制文件搜索的 globbing 表达式。这些表达式可以包含通配符(如 *、? 等)以及其他特定的匹配规则。如果没有指定 globbing 表达式,则默认查找所有文件。
一般情况下我们会利用GLOB指定源码的路径,代码演示:
file(GLOB SRCS ${CMAKE_CURRENT_SOURCE_DIR}/api/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/impl/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/model/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/impl/userManager/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/impl/userManager/config/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp )
add_executable(${PROJECT_NAME} ${SRCS})
将所有需要编译的cpp源码文件路径资源保存在SRCS中,然后直接调用add_executable进行编译,相对于AUX_SOURCE_DIRECTOR命令一个目录一个目录的添加方便很多。
GLOB模式和GLOB_RECURSE模式的区别在于:
GLOB模式只会在指定的目录搜索文件,不会递归搜索子目录,而GLOB_RECURSE不仅会搜索指定目录,连指定目录下的子目录也会递归搜索。
这个模式就不做举例,已经很清楚了。
3.2 MAKE_DIRECTORY
file(MAKE_DIRECTORY [<directories>...])
描述:
根据需要创建给定的目录及其父目录。
参数:
要创建的目录路径列表。可以指定多个目录路径,以逗号分隔。
代码示例:
file(MAKE_DIRECTORY my_directory)
该命令在构建时执行,如果指定的目录不存在,则会自动创建它们。在 CMake 构建过程中,可以使用该命令来确保所需的目录已经存在,以便后续的操作可以在这些目录中进行。
3.3 REMOVE 和REMOVE_RECURSE
file(REMOVE [<files>...]) file(REMOVE_RECURSE [<files>...])
删除给定的文件。REMOVE_RECURSE模式将删除给定的文件和目录,包括非空目录。如果给定的文件不存在,则不会报错。
在3.15版更改:空的输入路径会被忽略并产生警告。之前版本的CMake将空字符串解释为相对于当前目录的相对路径,并删除其内容。接受一个或多个目录路径作为参数,可以指定多个目录路径,以逗号分隔。
REMOVE_RECURSE和REMOVE模式的区别:
REMOVE模式只能删除文件,不能删除目录;REMOVE_RECURSE模式不仅能删除文件,也能删除目录,并且递归删除给定的目录。
3.4 RENAME
file(RENAME <oldname> <newname> [RESULT <result>] [NO_REPLACE])
描述:
重命名一个文件或者目录。如果没有添加NO_REPLACE选项,如果路径已经存在,则覆盖。
参数:
RESULT <result>:
3.21版本新增的功能,如果成功,将变量设置为0,否则将显示错误消息。如果未指定RESULT且操作失败,则会触发错误。
NO_REPLACE:
3.21版本新增的功能,如果路径已经存在,不需要替换。如果使用RESULT < result >,则result变量将设置为NO_REPLACE。否则,就会触发错误。
3.5 COPY_FILE
file(COPY_FILE <oldname> <newname> [RESULT <result>] [ONLY_IF_DIFFERENT] [INPUT_MAY_BE_RECENT])
描述:
3.21版本新增功能,复制一个文件从到。不支持目录。
参数:
RESULT <result>:
如果成功,将<result>变量设置为0,否则将显示错误消息。如果未指定RESULT且操作失败,则会触发错误。
ONLY_IF_DIFFERENT:
如果<newname>路径已经存在,如果文件的内容已经与<oldname>相同,则不要替换它(这可以避免更新<newname>的时间戳)。
INPUT_MAY_BE_RECENT:
3.26版本新增功能,告诉CMake输入文件可能是最近创建的。这只在Windows上有意义,因为在Windows上,文件创建后可能短时间内无法访问。有了这个选项,如果权限被拒绝,CMake将重试几次输入。
3.6 COPY和INSTALL
file(COPY [...]) file(INSTALL [...])
描述:
将文件、目录和符号链接复制到目标文件夹。复制可以保留输入文件的时间戳,并优化目标文件中具有相同时间戳的文件。除非明确的权限或NO_SOURCE_PERMISSIONS(默认值为USE_SOURCE_PERMISSIONS),否则复制将保留输入权限。
该模式下的可用选项:
file(<COPY|INSTALL> <files>... DESTINATION <dir>
[NO_SOURCE_PERMISSIONS | USE_SOURCE_PERMISSIONS]
[FILE_PERMISSIONS <permissions>...]
[DIRECTORY_PERMISSIONS <permissions>...]
[FOLLOW_SYMLINK_CHAIN]
[FILES_MATCHING]
[[PATTERN <pattern> | REGEX <regex>]
[EXCLUDE] [PERMISSIONS <permissions>...]] [...])
<COPY|INSTALL>:
指定要执行的操作,可以是 COPY 或 INSTALL。
<files>:
是要复制的文件或目录列表。可以指定多个文件和目录,用逗号分隔。
<dir>:
是目标位置的路径,可以是绝对路径或相对路径。
NO_SOURCE_PERMISSIONS 和 USE_SOURCE_PERMISSIONS:
用于指定是否使用源文件的权限。默认情况下,源文件的权限将被保留。
FILE_PERMISSIONS 和 DIRECTORY_PERMISSIONS:
用于指定文件和目录的权限。可以指定多个权限,用逗号分隔。例如:OWNER_READ,OWNER_WRITE。
FOLLOW_SYMLINK_CHAIN:
表示在复制过程中,将符号链接解析为实际文件和目录。
FILES_MATCHING:
表示使用模式匹配来选择要复制的文件和目录。可以指定 PATTERN 或 REGEX 来指定匹配的模式或正则表达式。
EXCLUDE:
表示排除符合模式的文件和目录,不进行复制。
PERMISSIONS:
用于指定复制后的文件或目录的权限。可以指定多个权限,用逗号分隔。
代码示例:
#假如有以下目录结构:
#[[
/opt/foo/lib/libfoo.so.1.2.3
/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
]]
#CMakeLists.txt 运行内容
file(COPY /opt/foo/lib/libfoo.so DESTINATION lib FOLLOW_SYMLINK_CHAIN)
#这将把所有的符号链接以及libfoo.so.1.2.3本身安装到lib中。
3.22版本更新后:环境变量CMAKE_INSTALL_MODE可以覆盖file(INSTALL)的默认复制行为。
3.7 SIZE
file(SIZE <filename> <variable>)
3.14版本新增加的功能;确定filename的大小,并且将结果存放到variable中。
3.8 READ_SYMLINK
file(READ_SYMLINK <linkname> <variable>)
3.14版本新增的功能;查询符号链接<linkname>,并将其指向的路径存储在 中;它会获取符号链接的最终目标路径,而不是符号链接本身。如果<linkname>不存在或不是符号链接,CMake将发出致命错误。
READ_SYMLINK模式返回的路径是可能是相对路径,也可能是绝对路径,具体看下面解析:
返回相对路径:
如果linkname链接指向的文件在软链接linktest目录下的目录即返回相对路径:
#当前目录有以下几个文件
CMakeLists.txt build(编译目录) linktest(软链接)
#linktest为指向某个文件的软链接,如果linktest指向build目录下的某个文件,则返回的就是相对目录:build/xxx(被指的文件名)
返回绝对路径:
如果linkname链接指向的文件在软链接linktest目录外的目录即返回绝对路径:
#当前目录有以下几个文件
CMakeLists.txt build(编译目录) linktest(软链接)
#linktest为指向某个文件的软链接,如果linktest指向CMakeLists.txt所在目录以外的目录,假如为/lib/下的某个文件,则返回的为句对路径:/lib/xxx(被指的文件名)
所以可以使用如下程序进行路径是否为绝对路径的判断,如果不是绝对路径就改为绝对路径:
set(linkname "/path/to/foo.sym")
file(READ_SYMLINK "${linkname}" result)
if(NOT IS_ABSOLUTE "${result}")#判断result是否为绝对路径,IS_ABSOLUTE 是一个函数,用于判断一个路径是否是绝对路径。
get_filename_component(dir "${linkname}" DIRECTORY)#获取linkname的目录部分
set(result "${dir}/${result}")#进目录部分与相对路径合并,即为绝对路径
endif()
3.9 CREATE_LINK
file(CREATE_LINK <original> <linkname> [RESULT <result>] [COPY_ON_ERROR] [SYMBOLIC])
3.14版本新增功能;创建一个链接<linkname>指向<original>。默认情况下,它将是一个硬链接,但提供SYMBOLIC选项将创建为符号链接。硬链接要求original存在并且是文件,而不是目录。如果<linkname>已经存在,它将被覆盖。
参数:
RESULT <result>:
如果指定了变量,则接收操作的状态。成功时将其设置为0,否则将显示错误消息。如果未指定RESULT且操作失败,则会触发致命错误。
COPY_ON_ERROR:
会在创建链接失败时将文件作为回退复制。它对于处理以下情况很有用:例如和在不同的驱动器或挂载点上,这使得它们无法支持硬链接。
3.10 CHMOD
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>...])
3.19版本新增的功能;设置指定的files和directories权限,有效权限为:OWNER_READ、OWNER_WRITE、OWNER_EXECUTE、GROUP_READ、GROUP_WRITE、GROUP_EXECUTE、WORLD_READ、WORLD_WRITE、WORLD_EXECUTE、SETUID、SETGID。
参数:
PERMISSIONS:
改变所有项的权限,files和directories。
FILE_PERMISSIONS:
只改变文件项权限;
DIRECTORY_PERMISSIONS:
只改变目录项权限;
当这三个参数同时存在时有一定的优先级关系:对目录操作DIRECTORY_PERMISSIONS覆盖PERMISSIONS,对文件操作FILE_PERMISSIONS覆盖PERMISSIONS,DIRECTORY_PERMISSIONS和FILE_PERMISSIONS同时存在类似于PERMISSIONS;
CHMOD_RECURSE模式与CHMOD类似,只不过CHMOD_RECURSE会递归改变子文件权限。
4. 路径转换(Path Conversion)
4.1 REAL_PATH
file(REAL_PATH <path> <out-var> [BASE_DIRECTORY <dir>] [EXPAND_TILDE])
描述:
计算已解析符号链接的现有文件或目录的绝对路径。
BASE_DIRECTORY :
如果提供的<path>是一个相对路径,它会相对于给定的基本目录<dir>进行计算。如果没有提供基本目录,默认的基本目录将是CMAKE_CURRENT_SOURCE_DIR。
EXPAND_TILDE:
3.21版本新增的功能;如果<路径>是~或以~/开头,~将被用户的主目录替换。home目录的路径从环境变量中获取。
4.2 RELATIVE_PATH
file(RELATIVE_PATH <variable> <directory> <file>)
描述:
用于确定文件相对于目录的相对路径,并将其存储在变量中。
参数:
<variable>:一个变量名,用于存储相对路径。
<directory>:一个目录路径,作为参考路径。
<file>:一个文件路径,相对于参考目录的相对路径将被计算并存储在变量中。
示例代码:
set(CMAKE_DIR "/home/project")
set(SOURCE_DIR "/home/project/resources")
file(RELATIVE_PATH relative_path ${CMAKE_DIR} ${SOURCE_DIR}/file.txt)
message("myfile.txt relative path: ${relative_path}")
#打印
file.txt relative path: resources/file.txt
4.3 TO_CMAKE_PATH 和TO_NATIVE_PATH
file(TO_CMAKE_PATH "<path>" <variable>)
file(TO_NATIVE_PATH "<path>" <variable>)
描述:
CMake 中的两个函数,用于将文件路径从一种表示法转换为另一种表示法。
参数:
<path>:要转换的文件路径。
<variable>:一个变量名,用于存储转换后的 CMake 路径表示法。
TO_CMAKE_PATH:
用途是将文件路径从其他表示法转换为 CMake 的路径表示法。CMake 的路径表示法使用 / 作为路径分隔符,可以在不同操作系统上使用,而不受操作系统特定的路径分隔符的限制。
代码示例:
set(MY_FILE_PATH "C:\\Users\\user\\file.txt")
file(TO_CMAKE_PATH "${MY_FILE_PATH}" cmake_path)
message("file.txt (CMake format): ${cmake_path}")
#运行结果
file.txt (CMake format): C;/Users/user/file.txt
TO_NATIVE_PATH:
将文件路径从 CMake 的路径表示法转换为特定操作系统的本地路径表示法。
代码示例:
set(MY_CMAKE_PATH "/cygdrive/c/Users/file.txt")
file(TO_NATIVE_PATH "${MY_CMAKE_PATH}" native_path)
message("file.txt (Windows format): ${native_path}")
5. 传输(Transfer)
5.1 DOWNLOAD和UPLOAD
file(DOWNLOAD <url> [<file>] [<options>...])
file(UPLOAD <file> <url> [<options>...])
描述:
CMake 中的两个函数,用于在本地计算机和远程计算机之间进行文件下载和上传操作。DOWNLOAD用于从指定的 URL 下载文件到本地计算机;UPLOAD用于将指定的文件上传到远程计算机;
参数:
<url>:是要下载的文件的 URL,
<file>:是要保存的文件路径(如果未指定,则由 CMake 自动生成一个临时文件路径),
<options>:是可选的参数,用于指定下载过程中的一些行为,例如是否在下载之前删除已存在的文件、是否显示下载进度等。选项如下:
不做过多解释,很少使用;以下是官网资料:
INACTIVITY_TIMEOUT<seconds> :在一段时间的不活动后终止操作。
LOG <variable>:将操作的信息记录到一个变量中,以便进行人可读的日志记录。
SHOW_PROGRESS:打印操作进度信息作为状态消息,直到操作完成。
STATUS<variable> :将操作的结果状态存储在一个变量中。状态是一个长度为2的分号分隔的列表。第一个元素是操作返回的数值,第二个元素是错误的字符串值。0的数字错误表示操作中没有错误。
TIMEOUT <seconds>:在给定的总时间过去后终止操作。
USERPWD<username> :<password>:自版本3.7起。为操作设置用户名和密码。
HTTPHEADER<HTTP-header> :自版本3.7起。为 DOWNLOAD 和 UPLOAD 操作设置 HTTP 头。HTTPHEADER 可以重复多次以提供多个选项:
file(DOWNLOAD <url> HTTPHEADER "Authorization: Bearer <auth-token>" HTTPHEADER "UserAgent: Mozilla/5.0")
NETRC <level>:自版本3.11起。指定是否使用 .netrc 文件进行操作。如果未指定此选项,则使用 CMAKE_NETRC 变量的值。
有效级别包括:
IGNORED:忽略 .netrc 文件。这是默认的。
OPTIONAL:可选的 .netrc 文件,URL中的信息更优。文件将被扫描以找到其中不包含在URL中的信息。
REQUIRED:必需的 .netrc 文件,忽略 URL中的信息。
NETRC_FILE <file>:自版本3.11起。如果NETRC级别为OPTIONAL或REQUIRED,指定一个替代的 .netrc 文件,而不是位于用户目录中的文件。如果未指定此选项,则使用 CMAKE_NETRC_FILE 变量的值。
TLS_VERIFY <ON|OFF>:指定是否验证 https:// URL 的服务器证书。默认情况下是不验证。如果未指定此选项,则使用 CMAKE_TLS_VERIFY 变量的值。
TLS_CAINFO<file>用于指定一个自定义的证书授权文件,用于处理https://URLs。如果未指定此选项,则会使用CMAKE_TLS_CAINFO变量的值。在版本3.18中添加了对file(UPLOAD)的支持。
对于https://URLs,CMake必须与OpenSSL支持一起构建。默认情况下,TLS/SSL证书不受检查。将TLS_VERIFY设置为ON以检查证书。
额外的DOWNLOAD选项包括:
EXPECTED_HASH<algorithm>=<value>用于验证下载的内容哈希是否与预期值匹配,其中是支持的算法之一。如果文件已存在并且与哈希匹配,则跳过下载。如果文件已存在但不匹配哈希,则再次下载文件。如果下载后文件不匹配哈希,则操作将失败并出现错误。如果在DOWNLOAD未给出的情况下指定此选项是错误的。
EXPECTED_MD5<value>是历史悠久的EXPECTED_HASH MD5=<value>的简写方法。如果在DOWNLOAD未给出的情况下指定此选项是错误的。
RANGE_START<value>是自版本3.24起添加的新选项。它指定了文件中范围的起始偏移量(以字节为单位)。可以省略以从指定的RANGE_END下载所有内容。
RANGE_END<value>是自版本3.24起添加的新选项。它指定了文件中范围的结束偏移量(以字节为单位)。可以省略以从指定的RANGE_START下载所有内容。
6. 锁(Locking)
file(LOCK <path> [DIRECTORY] [RELEASE] [GUARD <FUNCTION|FILE|PROCESS>] [RESULT_VARIABLE <variable>] [TIMEOUT <seconds>])
3.18新增的功能;这个函数用于在文件系统上获取一个文件的锁。它接受一系列参数来指定锁的类型、行为和选项。下面是每个参数的说明:
LOCK<path> :
指定要锁定的文件的路径。
DIRECTORY:
如果指定了该参数,则文件锁将应用于目录而不是文件。这个选项用于在目录上设置读锁或写锁,以控制对该目录的访问。
RELEASE:
如果指定了该参数,则在函数执行完毕后自动释放文件锁。这个选项用于在需要手动控制锁的释放时使用。
GUARD<FUNCTION|FILE|PROCESS> :
如果指定了该参数,则文件锁将作为保护措施,在指定的函数、文件或进程范围内一直保持有效。这个选项用于确保在特定的代码块或进程中只有一个实例可以访问受保护的资源。
RESULT_VARIABLE<variable> :
如果指定了该参数,则将函数的结果存储在指定的变量中。这个选项用于获取文件锁操作的结果状态。
TIMEOUT <seconds>:
如果指定了该参数,则设置文件锁的超时时间。如果文件锁在指定的时间内无法获取,则函数将返回失败。
这个函数在获取文件锁时可能会阻塞程序的执行,直到获得锁为止。超时参数可以用来限制等待时间,以避免长时间阻塞程序。
7. 归档(Archiving)
7.1 ARCHIVE_CREATE
file(ARCHIVE_CREATE OUTPUT <archive> PATHS <paths>...
[FORMAT <format>] [COMPRESSION <compression>
[COMPRESSION_LEVEL <compression-level>]] [MTIME <mtime>] [VERBOSE])
3.18新增的功能;用于创建归档文件的 CMake 命令。它通过将多个文件和目录组合在一起,创建一个归档文件,以便于存储、传输和备份,就是所谓的打包,压缩。下面是该命令的参数说明:
OUTPUT <archive>:
指定要创建的归档文件的名称或路径。
PATHS <paths>...:
指定要打包的文件或文件路径列表。可以包含多个路径,以逗号分隔。
FORMAT <format>:
可选参数,指定归档文件的格式。例如,常见的格式包括 ZIP、GZIP、BZIP2 等。
COMPRESSION <compression>:
可选参数,指定压缩算法。可以和上面的 FORMAT 参数一起使用,以指定特定的归档格式和压缩算法。例如,COMPRESSION ZIP 表示使用 ZIP 格式进行压缩。
COMPRESSION_LEVEL <compression-level>:
可选参数,指定压缩级别。如果使用了压缩算法,可以通过这个参数来指定压缩的程度。常见的压缩级别包括高速(fastest)和最大(best),以及一些介于两者之间的级别。
MTIME <mtime>:
可选参数,指定归档文件的修改时间。可以使用一个时间戳或一个日期来指定。
VERBOSE:
可选参数,如果启用,将显示详细的命令输出信息。
示例程序:
file(ARCHIVE_CREATE OUTPUT test.tar.gz PATHS build FORMAT GZIP)#将build文件夹以gzip格式进行压缩,压缩包名为test.tar.gz
7.2 ARCHIVE_EXTRACT
file(ARCHIVE_EXTRACT INPUT <archive> [DESTINATION <dir>] [PATTERNS <patterns>...] [LIST_ONLY] [VERBOSE] [TOUCH])
用于从归档文件中提取文件或文件路径,就是所谓的解压。以下是参数说明:
INPUT <archive>:
指定要提取的归档文件的名称或路径。
DESTINATION <dir>:
可选参数,指定提取的文件或文件路径的输出目录。如果未指定,则输出到当前工作目录。
PATTERNS <patterns> ...:
可选参数,指定要提取的文件或文件路径的模式列表。可以使用多个模式,以逗号分隔。模式可以是通配符,例如 */*.txt 表示提取所有子目录中的所有 .txt 文件。
LIST_ONLY:
可选参数,如果指定了该参数,则只列出要提取的文件或文件路径,而不实际提取它们。
VERBOSE:
可选参数,如果指定了该参数,则显示详细的命令输出信息。
TOUCH:
可选参数,如果指定了该参数,则仅更新提取的文件的修改时间,而不实际提取它们。
file(ARCHIVE_EXTRACT INPUT test.tar.gz ./)#将test.tar.gz 解压到当前目录
- 点赞
- 收藏
- 关注作者
评论(0)