CMake:如何在参数中用双引号调用 execute_process? a.k.a。使用 CMake 中的查找来计算匹配字符串的行数
CMake: How to call execute_process with a double quote in the argument? a.k.a. Using find from CMake to count lines matching a string
我想调用命令find
from within a 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
, which doesn't need the double quotes; however it doesn't provide a counting feature. I could use find
by calling find /v /c ""
,但同样,我需要双引号!
我想在cmake之外计算输出行数,并将结果直接存储在MY_COUNT
变量中。
注意:我正在使用 CMake 3.4.1
要重现该问题,您可以使用以下代码,其中 cmake -E echo
用于将字符串提供给 findstr
和 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
选项,问题仍然存在。
这个:
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.
According to CMake developers,
由于 CreateProcess API 和non-standard 方式 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
只用于 count matching lines.
find
前面的@
是为了防止脚本中的命令调用在输出变量中结束。
我想调用命令find
from within a 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
, which doesn't need the double quotes; however it doesn't provide a counting feature. I could use find
by calling find /v /c ""
,但同样,我需要双引号!
我想在cmake之外计算输出行数,并将结果直接存储在MY_COUNT
变量中。
注意:我正在使用 CMake 3.4.1
要重现该问题,您可以使用以下代码,其中 cmake -E echo
用于将字符串提供给 findstr
和 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
选项,问题仍然存在。
这个:
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.
According to CMake developers,
由于 CreateProcess API 和non-standard 方式 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
只用于 count matching lines.
find
前面的@
是为了防止脚本中的命令调用在输出变量中结束。