Preventing the contents of a string being substituted

I want to run awk with a script as argument. This is what I have done

set(AWK_SCRIPT [=[$1 == "TOTAL" && $4 == "100%" { exit 0; }; END { print "Line coverage is not 100%. Please see the HTML coverage report."; exit 1; }]=])

message(STATUS ${AWK_SCRIPT})

add_custom_target(coverage_check
                  DEPENDS ${PROJECT_BINARY_DIR}/summary.txt
                  COMMAND awk ${AWK_SCRIPT} ${PROJECT_BINARY_DIR}/summary.txt
                  COMMENT "Check whether line coverage is 100%.")

I create the script as a raw string. This works. When I print the string, everything is shown correctly ($ is preserved, spaces…). But when running this, I get

... && /bin/sh -c awk\ \ ==\ "TOTAL"\ &&\ \ ==\ "100%"\ {\ exit\ 0;\ };\ END\ {\ print\ "Line\ coverage\ is\ not\ 100%.\ Please\ see\ the\ HTML\ coverage\ report.";\ exit\ 1;\ }\ /home/hannes/devel/tools-build/coverage/summary.txt
awk: line 1: syntax error at or near ==
/bin/sh: 1:  }: not found
/bin/sh: 1:  END { print Line\ coverage\ is\ not\ 100%.\ Please\ see\ the\ HTML\ coverage\ report.: not found
/bin/sh: 1:  exit 1: not found
/bin/sh: 1:  } /home/hannes/devel/tools-build/coverage/summary.txt: not found
ninja: build stopped: subcommand failed.

Why is the string variable split into multiple arguments to the command? What’s up with all the escaping? How can I pass the variable “as-is” to the command as a single argument?

Thank you

Try adding VERBATIM to the arguments for add_custom_target(). Not using VERBATIM is effectively never the right choice, and it’ recommended to make it a habit to use it always. I cannot guarantee that it will fix your issue, but it’s quite likely that it will.

Thanks. This generates a different error:

FAILED: CMakeFiles/coverage_check /home/hannes/devel/tools-build/coverage/CMakeFiles/coverage_check 
cd /home/hannes/devel/tools-build/coverage && awk "\$1 == \"TOTAL\" && \$4 == \"100%\" { exit 0" " }" " END { print \"Line coverage is not 100%. Please see the HTML coverage report.\"" " exit 1" " }" /home/hannes/devel/tools-build/coverage/summary.txt
awk: line 2: missing } near end of file

This looks a little better (maybe?), but obviously some funky things are still happening. Look at the quotes after exit.

Also, the semi-colons are all gone. But now that I double-checked, I see that they are also gone from the variable (at least not visible when printing it).

I really just want to pass a string “as-is” without any logic happening. Surely, it can’t be so difficult?

Ok, if I additionally escape the semicolons in the raw string, it works. Not sure why the raw string isn’t raw, but oh well.

It is, but semi-colon is also a CMake argument separator, and that is what is “eating” them. It should be fixed by adding quotes around the string’s expansion:

    COMMAND awk ${AWK_SCRIPT} ${PROJECT_BINARY_DIR}/summary.txt