Cmake命令之execute_process

2023-08-21  本文已影响0人  Domibaba

本文所使用的相关软件版本:

软件名称 软件版本
Linux操作系统 Ubuntu 22.04 LTS
cmake 3.22.1

一、基本介绍

如其名字,该命令通过运行指定的命令来执行一个或多个子进程。命令的签名如下:

execute_process(COMMAND <cmd1> [<arguments>]
 [COMMAND <cmd2> [<arguments>]]...
 [WORKING_DIRECTORY <directory>]
 [TIMEOUT <seconds>]
 [RESULT_VARIABLE <variable>]
 [RESULTS_VARIABLE <variable>]
 [OUTPUT_VARIABLE <variable>]
 [ERROR_VARIABLE <variable>]
 [INPUT_FILE <file>]
 [OUTPUT_FILE <file>]
 [ERROR_FILE <file>]
 [OUTPUT_QUIET]
 [ERROR_QUIET]
 [COMMAND_ECHO <where>]
 [OUTPUT_STRIP_TRAILING_WHITESPACE]
 [ERROR_STRIP_TRAILING_WHITESPACE]
 [ENCODING <name>]
 [ECHO_OUTPUT_VARIABLE]
 [ECHO_ERROR_VARIABLE]
 [COMMAND_ERROR_IS_FATAL <ANY|LAST>])

execute_process可以指定多个命令,并且多个命令是通过管道方式执行,上一个命令的标准输出通过管道传递,作为下一个命令的标准输入。所有的命令都共享单个标准错误管道。

来看几个简单的例子:

  1. 执行单个命令,本例子以执行uname -o获取操作系统名称为例。
# CMakeLists.txt
# 输出操作系统名称
EXECUTE_PROCESS(COMMAND uname -o)

运行结果:

GNU/Linux

  1. 执行多个命令,前一个命令的输出会作为后一个命令的输入(相当于Unix/Linux中管道的概念),本例以ls -algrep "cmake"awk '{print $9}',请注意,实际相当于在命令行中执行ls -al | grep "cmake" | awk "{print $9}",即过滤出带匹配cmake字符串的行后,取该行以空格分割的第9项(对于ls -al命令就是过滤出文件名称)。
# CMakeLists.txt
# 列出当前文件目录内容项,通过"cmake"和"awk"过滤出文件名"cmake_install.cmake"
# 相当于执行命令: ls -al | grep "cmake" | awk "{print $9}"
EXECUTE_PROCESS(COMMAND ls -al
 COMMAND grep "cmake"
 COMMAND awk "{print $9}")

运行结果 cmake_install.cmake

二、参数选项详解

# 指定命令的工作目录,在指定目录下执行pwd命令
EXECUTE_PROCESS(COMMAND pwd
 WORKING_DIRECTORY "/home")

运行结果: /home

# 设置子命令的超时时间
# 注意,是针对每个子命令而言的超时时间,而不是命令总的执行时间
EXECUTE_PROCESS(COMMAND sleep 5
 COMMAND sleep 5
 TIMEOUT 4
 RESULT_VARIABLE msg)
 MESSAGE("Commands execute result: ${msg}")

运行结果: Commands execute result: Process terminated due to timeout

# 最后一个子命令是删除一个不存在的文件,即使前面的命令执行成功,它也只是包含最后一个子命令的执行结果
EXECUTE_PROCESS(COMMAND rm "notexistfile.ext"
 RESULT_VARIABLE msg)
MESSAGE("Command execute result: ${msg}")

运行结果: rm: 无法删除 'notexistfile.ext': 没有那个文件或目录 Command execute result: 1

# 存储所有子命令的运行结果
EXECUTE_PROCESS(COMMAND ls -al
 COMMAND rm "notexistfile.ext"
 RESULTS_VARIABLE msg_all)
MESSAGE("ALL commands execute result: ${msg_all}")

运行结果: rm: 无法删除 'notexistfile.ext': 没有那个文件或目录 ALL commands execute result: 0;1

EXECUTE_PROCESS(COMMAND echo "start"
 COMMAND rm "notexistfile.ext"
 COMMAND pwd
 COMMAND rm "notexistfile2.ext"
 COMMAND pwd
 WORKING_DIRECTORY "/home"
 RESULTS_VARIABLE msg_result
 OUTPUT_VARIABLE msg_out
 ERROR_VARIABLE msg_err)
MESSAGE("Commands execute results: ${msg_result}")
MESSAGE("Commands output: ${msg_out}")
MESSAGE("Commands error: ${msg_err}")

运行结果:值得注意的是,由于命令是按照管道方式执行,OUTPUT_VARIABLE只会存储最后一个命令的运行结果,而ERROR_VARIABLE则是存储所有错误 Commands execute results: 0;1;0;1;0 Commands output: /home

Commands error: rm: 无法删除 'notexistfile.ext': 没有那个文件或目录 rm: 无法删除 'notexistfile2.ext': 没有那个文件或目录

EXECUTE_PROCESS(COMMAND read
 COMMAND rm "noexistfile.ext"
 COMMAND rm "noexistfile2.ext"
 COMMAND echo "write message to output"
 INPUT_FILE input
 OUTPUT_FILE output
 ERROR_FILE error)

output文件内容: write message to output error文件内容: rm: noexistfile.ext: No such file or directory rm: noexistfile2.ext: No such file or directory

EXECUTE_PROCESS(
 COMMAND echo "execute commad"
 COMMAND ls "CMakeLists.txt"
 COMMAND_ECHO STDERR
 )

执行:cmake . 2> file_stderr的命令行输出为(最后一个命令ls的输出仍然在命令行展示): CMakeLists.txt

查看文件file_stderrcat file_stderr 'echo' 'execute commad' 'ls' 'CMakeLists.txt'

NONE:默认值,使用CMake内部默认的编码方式(也就是UTF-8)对命令输出进行解码。 AUTO:使用当前的控制台编码方式,如果未找到合法的编码方式,则使用ANSIANSI:使用ANSI方式解码命令输出。 OEM:使用OEM方式解码命令输出。 UTF8UTF-8:使用UTF-8方式解码命令输出(3.11版本引入)。

EXECUTE_PROCESS(
 COMMAND echo "hello world"
 OUTPUT_VARIABLE var_output
 ECHO_OUTPUT_VARIABLE # 如果没有指定这个选项,那么命令行终端不会有"hello world"的打印
 )
MESSAGE("output var: ${var_output}")

运行结果: hello world output var: hello world

ANY:任一子命令执行错误,execute_process会停止执行并抛出错误 LAST:最后一个子命令执行错误,execute_process会停止执行抛出错误

EXECUTE_PROCESS(COMMAND pwd
 COMMAND rm "noexistfile.ext"
 COMMAND echo "hello world"
 COMMAND_ERROR_IS_FATAL LAST)

运行结果(最后一个子命令执行成功,LAST选项不会导致CMake抛出错误): rm: noexistfile.ext: No such file or directory hello world

EXECUTE_PROCESS(COMMAND pwd
 COMMAND rm "noexistfile.ext"
 COMMAND echo "hello world"
 COMMAND_ERROR_IS_FATAL ANY)

运行结果(第二个子命令执行失败,ANY选项会导致CMake抛出错误): rm: noexistfile.ext: No such file or directory hello world CMake Error at CMakeLists.txt:21 (execute_process): execute_process failed command indexes:

2: "Child return code: 1"


附录:参考文档

  1. https://cmake.org/cmake/help/latest/command/execute_process.html
上一篇 下一篇

猜你喜欢

热点阅读