1

I need to call the findstr Windows command (grep on Linux) from my CMakeList.txt.
If I do this, it is working :

execute_process(
    COMMAND findstr "NABO_VERSION " nabo\\nabo.h
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    RESULT_VARIABLE FINDSTR_RESULT
    ERROR_VARIABLE FINDSTR_ERROR
    OUTPUT_VARIABLE FINDSTR_OUT
    OUTPUT_STRIP_TRAILING_WHITESPACE
)

I get the output:

FINDSTR_ERROR =
FINDSTR_OUT =   
  #define NABO_VERSION "1.0.7"
  #define NABO_VERSION_INT 10007
FINDSTR_RESULT = 0

However, the space at the end of "NABO_VERSION " is not taken into account. I have to add /c: before my string.

So I get this following code :

execute_process(
    COMMAND findstr /c:"NABO_VERSION " nabo\\nabo.h
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    RESULT_VARIABLE FINDSTR_RESULT
    ERROR_VARIABLE FINDSTR_ERROR
    OUTPUT_VARIABLE FINDSTR_OUT
    OUTPUT_STRIP_TRAILING_WHITESPACE
)

But now it doesn't work and I get this:

FINDSTR_ERROR =
FINDSTR_OUT =
FINDSTR_RESULT = 1

The command works well in PowerShell or CMD, but not from CMake. I think that CMake modify the command, but in what way ?

  • Possibly related: https://stackoverflow.com/questions/34905194/cmake-how-to-call-execute-process-with-a-double-quote-in-the-argument-a-k-a-u. Passing literal double quotes via `execute_process` to some Windows commands could be difficult (or even impossible). It could be simpler to write a separate shell script and run that script via `execute_process`. – Tsyvarev Jan 26 '22 at 15:18

1 Answers1

1

So I created a test file called nabo\nabo.h with the following contents:

#define NABO_VERSION "1.0.7"
#define NABO_VERSION_INT 10007

Then at cmd, I wrote:

> findstr "NABO_VERSION " nabo\nabo.h
#define NABO_VERSION "1.0.7"
#define NABO_VERSION_INT 10007

and got both lines back. Adding /c: is necessary:

> findstr /c:"NABO_VERSION " nabo\nabo.h
#define NABO_VERSION "1.0.7"

Now to write this in CMake:

# test.cmake

cmake_minimum_required(VERSION 3.21)
# Script mode, no project() call

execute_process(
    COMMAND findstr "/c:NABO_VERSION " [[nabo\nabo.h]]
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    RESULT_VARIABLE FINDSTR_RESULT
    ERROR_VARIABLE FINDSTR_ERROR
    OUTPUT_VARIABLE FINDSTR_OUT
    OUTPUT_STRIP_TRAILING_WHITESPACE
)

message(STATUS "FINDSTR_ERROR  = ${FINDSTR_ERROR}")
message(STATUS "FINDSTR_OUT    = ${FINDSTR_OUT}")
message(STATUS "FINDSTR_RESULT = ${FINDSTR_RESULT}")

Running this script returns the expected result:

>cmake -P test.cmake
-- FINDSTR_ERROR  =
-- FINDSTR_OUT    = #define NABO_VERSION "1.0.7"
-- FINDSTR_RESULT = 0

This works because, as the findstr /? output says:

Use spaces to separate multiple search strings unless the argument is prefixed with /C.

So then you just need the quotes in CMake to ensure the space is included in the whole argument.

Alex Reinking
  • 16,724
  • 5
  • 52
  • 86