CMake:如何在参数中使用双引号调用execute_process?又名:使用 CMake 中的 find 来计算与字符串匹配的行数

2023-11-25

我想调用命令find从一个内execute_process.

的格式find命令是:

find [/v] [/c] [/n] [/i] [/off[line]] "<String>" [[<Drive>:][<Path>]<FileName>[...]]

因此,该字符串必须用双引号引起来。但是,如果在 cmake 中我这样做:

execute_process(COMMAND <firstCommandPipingSomethingToFind> 
                COMMAND find "<myString>" /c
                OUTPUT_VARIABLE MY_COUNT
                OUTPUT_STRIP_TRAILING_WHITESPACE)

我收到一个错误FIND: Parameter format not correct.
如果我用转义双引号\,我收到一个错误Access denied - \.
还使用双重转义\\或双双引号""没有帮助。

所以我的问题是:
有没有办法在调用时转义双引号execute_process以便find正确接收其论点?

我可以用findstr,不需要双引号;但它不提供计数功能。我可以用find通过致电find /v /c "",但同样,我需要双引号! 我想计算 cmake 之外的输出行数,并将结果直接存储在MY_COUNT多变的。

注意:我正在使用CMake 3.4.1


要重现该问题,您可以使用以下代码,其中cmake -E echo用于将字符串提供给findstr and find:

#This works
execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND findstr ell OUTPUT_VARIABLE DUMMY)
message (STATUS "0) DUMMY=${DUMMY}")

#All of the following don't work
set(MyCommand "find \"ell\" /c")
execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND "${MyCommand}" OUTPUT_VARIABLE DUMMY)
message (STATUS MyCommand=${MyCommand})
message (STATUS "1) DUMMY=${DUMMY}")

execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND ${MyCommand} OUTPUT_VARIABLE DUMMY)
message (STATUS "2) DUMMY=${DUMMY}")

execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND MyCommand OUTPUT_VARIABLE DUMMY)
message (STATUS "3) DUMMY=${DUMMY}")

execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND "find \"ell\" /c" OUTPUT_VARIABLE DUMMY)
message (STATUS "4) DUMMY=${DUMMY}")

哪个输出:

0) DUMMY=hello

MyCommand=find "ell" /c
1) DUMMY=
2) DUMMY=
3) DUMMY=
4) DUMMY=

我也尝试过

set(MyArgument "\"ell\" /c")
message (STATUS MyArgument=${MyArgument})
execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND find "${MyArgument}" OUTPUT_VARIABLE DUMMY)
message (STATUS "1) DUMMY=${DUMMY}")

execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND find ${MyArgument} OUTPUT_VARIABLE DUMMY)
message (STATUS "2) DUMMY=${DUMMY}")

set(MyArgument "\"ell\"")
message (STATUS MyArgument=${MyArgument})
execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND find "${MyArgument}" /c OUTPUT_VARIABLE DUMMY)
message (STATUS "1) DUMMY=${DUMMY}")

execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND find ${MyArgument} /c OUTPUT_VARIABLE DUMMY)
message (STATUS "2) DUMMY=${DUMMY}")

哪个输出:

MyArgument="ell" /c
File not found - \ELL\

1) DUMMY=
File not found - \ELL\

2) DUMMY=
MyArgument="ell"
Access denied - \

1) DUMMY=
Access denied - \

2) DUMMY=
CMake Error at CMakeRules.cmake:404 (execute_process):
  execute_process given COMMAND argument with no value.
Call Stack (most recent call first):
  CMakeLists.txt:24 (include)

如果删除该问题仍然存在/c选项。


This:
execute_process(COMMAND ${CMAKE_COMMAND} -E echo hello COMMAND find \"ell\" OUTPUT_VARIABLE DUMMY)
message (STATUS "DUMMY=${DUMMY}")

输出这个:

Access denied - \

DUMMY=

按照 Tsyvarev 建议检索有效传递到命令行的字符串,如下:

execute_process(COMMAND cmd /c echo \"ell\")
execute_process(COMMAND cmd /c echo "ell")
execute_process(COMMAND cmd /c echo ""ell"")

输出这个:

\"ell\"

ell

"" ell\"\"

第三条命令有警告:

Argument not separated from preceding token by whitespace.
This warning is for project developers.  Use -Wno-dev to suppress it.

根据 CMake 开发人员的说法,
视窗find不能被调用directly通过 cmake 从内部execute_process,由于 CreateProcess API 和非标准方式的限制find解析参数。

它可以被称为间接地不过,通过创建临时批处理脚本。

我在 Windows 中计算程序输出中字符串出现次数的问题是通过以下方式解决的:

file(WRITE ${CMAKE_BINARY_DIR}/countLines.bat [[@find /v /c "" %1]])
execute_process(COMMAND <firstCommandPipingSomethingToFind> COMMAND findstr <regular expression> COMMAND countLines.bat WORKING_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_VARIABLE N_MATCHES OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "N_MATCHES=${N_MATCHES}")
file(REMOVE ${CMAKE_BINARY_DIR}/countLines.bat)

优点findstr介于两者之间的是它支持正则表达式。find只是用来计算匹配行数.

The @在...前面find是为了防止脚本内的命令调用最终出现在输出变量中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMake:如何在参数中使用双引号调用execute_process?又名:使用 CMake 中的 find 来计算与字符串匹配的行数 的相关文章

随机推荐