How to split lines into multiple lines in CMake?

Usually I have a policy in my project to never create lines in text files that exceed a line length of 80, so they are easily edited in all kinds of editors (you know the deal). But with CMake, I have a problem that I don’t know how to split a simple line into several lines in order 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 exceeds 80 limits. So, how do I split a line in CMake into multiple lines without getting into the details (multiple list(APPEND ...) or the like)?

+82
cmake
03 Oct 2018-11-11T00:
source share
5 answers

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

+73
Jan 16 '15 at 11:42
source share

CMake 3.0 and later

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 versions support quotation marks for continuing arguments , you cannot indent the second or subsequent lines without inserting a space in the indent in your line.

CMake 2.8 and older

You can use a list. Each list item can be placed 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 spaces:

 message(STATUS "Version: " ${MYPROJ_VERSION_LIST}) -- Version: 1.0.0-rc1 

If you really need a string, you can first convert the list to a string:

 string(REPLACE ";" "" MYPROJ_VERSION "${MYPROJ_VERSION_LIST}") message(STATUS "Version: ${MYPROJ_VERSION}") -- Version: 1.0.0-rc1 

Any semicolons in the source lines will be considered as separators of the list items and deleted. They need to escape:

 set(MY_LIST "Hello World " "with a \;semicolon") 
+48
May 22 '13 at 23:27
source share

This is still a bit verbose, but if the 80 char constraint really causes errors, you can add multiple times 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 
+8
Oct 03 2018-11-11T00:
source share

It is not possible to split a string literal into multiple lines in CMakeLists.txt files or in CMake scripts. If you include a new line in a line, the line itself will contain the literal line of the new line.

 # 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 spaces to separate arguments, so you can change the space that separates the argument separator to a new line anywhere without changing the behavior.

You can rephrase this longer line:

 set(MYPROJ_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_EXTRA}") 

like these two shorter lines:

 set(MYPROJ_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_EXTRA}") 

They are completely equivalent.

+7
04 Oct 2018-11-21T00:
source share

The example in the original question concerns only a relatively short line. For longer lines (including examples given in other answers), an argument in parentheses might be better. From the documentation:

The opening bracket is written [ , followed by zero or more = , and then [ . The corresponding closing bracket is written ] , followed by the same number = , followed by ] . Staples do not nest. You can always choose a unique length for opening and closing brackets so that they contain closing brackets of a different length.

[...]

For example:

 message([=[ This is the first line in a bracket argument with bracket length 1. No \-escape sequences or ${variable} references are evaluated. This is always one argument even though it contains a ; character. The text does not end on a closing bracket of length 0 like ]]. It does end in a closing bracket of length 1. ]=])''' 
0
Aug 07 '19 at 16:48
source share



All Articles