cmake 提供了 file()命令可对文件进行一系列操作,譬如读写文件、删除文件、文件重命名、拷贝文件、创建目录等等,本文我们一起来学习这个功能强大的 file()命令。
1、写文件:写、追加内容
使用 file()命令写文件,使用方式如下所示:
file(WRITE <filename> <content>...)
file(APPEND <filename> <content>...)
将写入名为的文件中。如果文件不存在,它将被创建;如果文件已经存在,WRITE 模式将覆盖它,APPEND 模式将内容追加到文件末尾。
测试代码如下:
# file()写文件测试
file(WRITE wtest.txt "Hello World!") #给定内容生成 wtest.txt 文件
file(APPEND wtest.txt " China") #给定内容追加到 wtest.txt 文件末尾
注意文件可以使用绝对路径或相对路径指定,相对路径被解释为相对于当前源码路径。
执行 CMakeLists.txt 代码之后,会在当前源码目录下生成一个名为 wtest.txt 的文件,如下:
接着查看 wtest.txt 文件中内容,如下所示:
2、写文件:由内容生成文件
由内容生成文件的命令为:
file(GENERATE OUTPUT output-file
<INPUT input-file|CONTENT content>
[CONDITION expression])
output-file:指定输出文件名,可以带路径(绝对路径或相对路径);
INPUT input-file:指定输入文件,通过输入文件的内容来生成输出文件;
CONTENT content:指定内容,直接指定内容来生成输出文件;
CONDITION expression:如果表达式expression 条件判断为真,则生成文件、否则不生成。
同样,指定文件既可以使用相对路径、也可使用绝对路径,不过在这里,相对路径被解释为相对于当前源码的 BINARY_DIR 路径,而不是当前源码路径。
测试代码如下:
# 由前面生成的 wtest.txt 中的内容去生成 out1.txt 文件
file(GENERATE OUTPUT out1.txt INPUT "${PROJECT_SOURCE_DIR}/wtest.txt")
# 由指定的内容生成 out2.txt
file(GENERATE OUTPUT out2.txt CONTENT "This is the out2.txt file")
# 由指定的内容生成 out3.txt,加上条件控制,用户可根据实际情况
# 用表达式判断是否需要生成文件,这里只是演示,直接是 1
file(GENERATE OUTPUT out3.txt CONTENT "This is the out3.txt file" CONDITION 1)
进入到 build 目录下执行 cmake:
执行完 cmake 之后会在 build 目录(也就是顶层源码的 BINARY_DIR)下生成了 out1.txt、out2.txt 和 out3.txt 三个文件,内容如下:
3、读文件:字节读取
file()读文件命令格式如下:
file(READ <filename> <variable>
[OFFSET <offset>] [LIMIT <max-in>] [HEX])
从名为的文件中读取内容并将其存储在<variable>中。
可选择从给定的<offset>开始,最多读取<max-in>字节。HEX 选项使数据转换为十六进制表示(对二进制数据有用)。
同样,指定文件既可以使用相对路径、也可使用绝对路径,相对路径被解释为相对于当前源码路径。 测试代码如下:
# file()读文件测试
file(READ "${PROJECT_SOURCE_DIR}/wtest.txt" out_var) #读取前面生成的 wtest.txt
message(${out_var}) # 打印输出
# 读取 wtest.txt 文件:限定起始字节和大小
file(READ "${PROJECT_SOURCE_DIR}/wtest.txt" out_var OFFSET 0 LIMIT 10)
message(${out_var})
# 读取 wtest.txt 文件:以二进制形式读取,限定起始字节和大小,
file(READ "${PROJECT_SOURCE_DIR}/wtest.txt" out_var OFFSET 0 LIMIT 5 HEX)
message(${out_var})
打印信息如下所示:
4、以字符串形式读取
命令格式如下所示:
file(STRINGS <filename> <variable> [<options>...])
file(STRINGS [...]) 从文件中解析 ASCII 字符串列表并将其存储在中。这个命令专用于读取字符串, 会将文件中的二进制数据将被忽略,回车符(\r, CR)字符被忽略。
filename:指定需要读取的文件,可使用绝对路径、也可使用相对路径,相对路径被解释为相对于当前源码路径。
variable:存放字符串的变量。
options:可选的参数,可选择 0 个、1 个或多个选项,这些选项包括:
➢ LENGTH_MAXIMUM :读取的字符串的最大长度;
➢ LENGTH_MINIMUM :读取的字符串的最小长度;
➢ LIMIT_COUNT :读取的行数;
➢ LIMIT_INPUT :读取的字节数;
➢ LIMIT_OUTPUT :存储到变量的限制字节数;
➢ NEWLINE_CONSUME:把换行符也考虑进去;
➢ NO_HEX_CONVERSION:除非提供此选项,否则 Intel Hex 和 Motorola S-record 文件在读取时会 自动转换为二进制文件。
➢ REGEX :只读取符合正则表达式的行;
➢ ENCODING :指定输入文件的编码格式,目前支持的编码有:UTF-8、UTF-16LE、 UTF-16BE、UTF-32LE、UTF-32BE。如果未提供 ENCODING 选项并且文件具有字节顺序标记, 则 ENCODING 选项将默认为尊重字节顺序标记。
测试代码如下:
# 从 input.txt 文件读取字符串
file(STRINGS "${PROJECT_SOURCE_DIR}/input.txt" out_var)
message("${out_var}")
# 限定读取字符串的最大长度
file(STRINGS "${PROJECT_SOURCE_DIR}/input.txt" out_var LENGTH_MAXIMUM 5)
message("${out_var}")
# 限定读取字符串的最小长度
file(STRINGS "${PROJECT_SOURCE_DIR}/input.txt" out_var LENGTH_MINIMUM 4)
message("${out_var}")
# 限定读取行数
file(STRINGS "${PROJECT_SOURCE_DIR}/input.txt" out_var LIMIT_COUNT 3)
message("${out_var}")
从 input.txt 文件读取字符串,input.txt 文件的内容如下所示:
上述代码执行的结果如下所示:
5、计算文件的 hash 值
file()命令可以计算指定文件内容的加密散列(hash 值)并将其存储在变量中。如下所示:
file(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512> <filename> <variable>)
MD5|SHA1|SHA224|SHA256|SHA384|SHA512 表示不同的计算 hash 的算法,必须要指定其中之一, filename 指定文件(可使用绝对路径、也可使用相对路径,相对路径被解释为相对于当前源码的 BINARY_DIR),将计算结果存储在 variable 变量中。
测试代码如下:
# 计算文件的 hash 值
file(SHA256 "${PROJECT_SOURCE_DIR}/input.txt" out_var)
message("${out_var}")
这里我们还是用上面创建的 input.txt 文件,使用 SHA256 算法进行计算,结果如下:
6、 文件重命名
使用 file()命令可以对文件进行重命名操作,命令格式如下:
file(RENAME <oldname> <newname>)
oldname 指的是原文件,newname 指的是重命名后的新文件,文件既可以使用绝对路径指定,也可以使用相对路径指定,相对路径被解释为相对于当前源码路径。
测试代码:
# 文件重命名
file(RENAME "${PROJECT_SOURCE_DIR}/input.txt" "${PROJECT_SOURCE_DIR}/output.txt")
测试结果如下:
7、删除文件
使用 file()命令可以删除文件,命令格式如下:
file(REMOVE [<files>...])
file(REMOVE_RECURSE [<files>...])
REMOVE 选项将删除给定的文件,但不可以删除目录;而 REMOVE_RECURSE 选项将删除给定的文件或目录、以及非空目录。指定文件或目录既可以使用绝对路径、也可以使用相对路径,相对路径被解释为相对于当前源码路径。 测试代码:
# file 删除文件或目录测试
file(REMOVE "${PROJECT_SOURCE_DIR}/out1.txt")
file(REMOVE_RECURSE "${PROJECT_SOURCE_DIR}/out2.txt" "${PROJECT_SOURCE_DIR}/empty-dir"
"${PROJECT_SOURCE_DIR}/Non_empty-dir")
out1.txt 和 out2.txt 是普通文件,empty-dir 是一个空目录,而 Non_empty-dir 是一个非空目录,如下所示:
进入到 build 目录下,执行 cmake:
执行完 cmake 命令之后,这些文件以及文件夹都被删除了。
关于 file()命令就给大家介绍这么多了,其实 file()命令的功能很强大,除了以上给大家介绍的基本功能外,还支持文件下载、文件锁等功能。