I usually have a policy in my project, to never create lines in text files that exceed a line length of 80, so they are easily editable in all kinds of editors (you know the deal). But with CMake I get the problem that I do not know how to split a simple string into multiple lines to avoid one huge line. Consider this basic code:
set(MYPROJ_VERSION_MAJOR "1")
set(MYPROJ_VERSION_MINOR "0")
set(MYPROJ_VERSION_PATCH "0")
set(MYPROJ_VERSION_EXTRA "rc1")
set(MYPROJ_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_EXTRA}")
It already exeeds the 80 line limit. So how do I break a line in CMake into multiple lines without getting to verbose (multiple list(APPEND ...)
or the like)?
Update for CMake 3.0 and newer :
line continuation is possible with \
. see cmake-3.0-doc
message("\
This is the first line of a quoted argument. \
In fact it is the only line but since it is long \
the source code uses line continuation.\
")
Availability of CMake versions:
Debian Wheezy (2013): 2.8.9
Debian Wheezy-backports: 2.8.11
Debian Jessy (2015): 3.0.2
Ubuntu 14.04 (LTS): 2.8.12
Ubuntu 15.04 : 3.0.2
Mac OSX : cmake-3 available through Homebrew, Macports and Fink
Windows: cmake-3 available through Chocolatey
CMake 3.0 and newer
Use the string(CONCAT)
command:
set(MYPROJ_VERSION_MAJOR "1")
set(MYPROJ_VERSION_MINOR "0")
set(MYPROJ_VERSION_PATCH "0")
set(MYPROJ_VERSION_EXTRA "rc1")
string(CONCAT MYPROJ_VERSION "${MYPROJ_VERSION_MAJOR}"
".${MYPROJ_VERSION_MINOR}"
".${MYPROJ_VERSION_PATCH}"
"-${MYPROJ_VERSION_EXTRA}")
Although CMake 3.0 and newer support line continuation of quoted arguments, you cannot indent the second or subsequent lines without getting the indentation whitespace included in your string.
CMake 2.8 and older
You can use a list. Each element of the list can be put on a new line:
set(MYPROJ_VERSION_MAJOR "1")
set(MYPROJ_VERSION_MINOR "0")
set(MYPROJ_VERSION_PATCH "0")
set(MYPROJ_VERSION_EXTRA "rc1")
set(MYPROJ_VERSION_LIST "${MYPROJ_VERSION_MAJOR}"
".${MYPROJ_VERSION_MINOR}"
".${MYPROJ_VERSION_PATCH}"
"-${MYPROJ_VERSION_EXTRA}")
A list used without quotes is concatenated without white-space:
message(STATUS "Version: " ${MYPROJ_VERSION_LIST})
-- Version: 1.0.0-rc1
If you really need a string, you can convert the list to a string first:
string(REPLACE ";" "" MYPROJ_VERSION "${MYPROJ_VERSION_LIST}")
message(STATUS "Version: ${MYPROJ_VERSION}")
-- Version: 1.0.0-rc1
Any semicolons in your original strings will be seen as list element separators, and removed. They must be escaped:
set(MY_LIST "Hello World "
"with a \;semicolon")
It's still a little verbose, but if the 80 char limit really bugs you then you could repeatedly append to the same variable:
set(MYPROJ_VERSION_MAJOR "1")
set(MYPROJ_VERSION_MINOR "0")
set(MYPROJ_VERSION_PATCH "0")
set(MYPROJ_VERSION_EXTRA "rc1")
set(MYPROJ_VERSION "${MYPROJ_VERSION_MAJOR}.")
set(MYPROJ_VERSION "${MYPROJ_VERSION}${MYPROJ_VERSION_MINOR}.")
set(MYPROJ_VERSION "${MYPROJ_VERSION}${MYPROJ_VERSION_PATCH}-")
set(MYPROJ_VERSION "${MYPROJ_VERSION}${MYPROJ_VERSION_EXTRA}")
message(STATUS "version: ${MYPROJ_VERSION}")
Gives output:
$ cmake ~/project/tmp
-- version: 1.0.0-rc1
-- Configuring done
-- Generating done
-- Build files have been written to: /home/rsanderson/build/temp
There is no way to split a string literal across multiple lines in CMakeLists.txt files or in CMake scripts. If you include a newline within a string, there will be a literal newline in the string itself.
# Don't do this, it won't work, MYPROJ_VERSION will contain newline characters:
set(MYPROJ_VERSION "${VERSION_MAJOR}.
${VERSION_MINOR}.${VERSION_PATCH}-
${VERSION_EXTRA}")
However, CMake uses whitespace to separate arguments, so you can change a space that's an argument separator into a newline anywhere you like, without changing the behavior.
You could re-phrase this longer line:
set(MYPROJ_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_EXTRA}")
as these two shorter lines:
set(MYPROJ_VERSION
"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_EXTRA}")
They are entirely equivalent.