I have a template cpp file that will contain several placeholders. Excerpt:
// WARNING! this file is autogenerated, do not edit manually
QString appName()
{
return "APP_NAME_VALUE";
}
Cmake will read this file in, fill in the placeholders and write it back out to the shadow build directory for compilation
set(APP_NAME "real application name")
file(READ ${CMAKE_SOURCE_DIR}/templates/app-info.cpp APP_INFO)
string(REPLACE "APP_NAME_VALUE" ${APP_NAME} APP_INFO ${APP_INFO})
# other tag replacements
file(WRITE "${CMAKE_BINARY_DIR}/src/app-info.cpp" ${APP_INFO})
But every time I run cmake, it seems to strip the semi-colon from the file contents.
// WARNING! this file is autogenerated, do not edit manually
QString appName()
{
return "real application name"
}
Is this expected behaviour? What can I do to counter this?
CodePudding user response:
From https://discourse.cmake.org/t/what-is-the-best-way-to-search-and-replace-strings-in-a-file/1879
In my CMake script, I need to modify other source files by searching and replacing specified strings. In my case, the configure_file 2 command is not a solution because I have no control over the input file. Previously I used the file and string commands in the following way -
file(READ header.h FILE_CONTENTS)
string(REPLACE "old text" "new text" FILE_CONTENTS ${FILE_CONTENTS})
file(WRITE header.h ${FILE_CONTENTS})
However this technique appears to strip out semi-colons from the input file.
Answer: put quotes around ${FILE_CONTENTS} in both commands
Explanation:
It comes from a CMake’s list syntax, which is ;-separated, the fact that arguments passed to CMake commands are basically mashed together into a list, and that those commands take unbounded number of inputs. So you end up with one longer list.
Quoting prevents the semicolons in the expansion from being treated as list-element-separators.
Consider:
WRITE;header.h;x;y;z
vs
WRITE;header.h;"x;y;z"
So in your case, it will appear as such:
set(APP_NAME "real application name")
file(READ ${CMAKE_SOURCE_DIR}/templates/app-info.cpp APP_INFO)
string(REPLACE "APP_NAME_VALUE" ${APP_NAME} APP_INFO "${APP_INFO}")
# other tag replacements
file(WRITE "${CMAKE_BINARY_DIR}/src/app-info.cpp" "${APP_INFO}")