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?
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.
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?
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: