Как разделить строки на несколько строк в CMake?
Обычно у меня есть политика в моем проекте, чтобы никогда не создавать строки в текстовых файлах, которые превышают длину строки 80, поэтому они легко редактируются во всех видах редакторов (вы знаете сделку). Но с CMake у меня возникает проблема, что я не знаю, как разбить простую строку на несколько строк, чтобы избежать одной огромной линии. Рассмотрим этот базовый код:
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}")
Он уже превышает 80 лимитов. Итак, как мне разбить строку в CMake на несколько строк, не доводя до подробностей (несколько list(APPEND ...)
или тому подобное)?
Ответы
Ответ 1
Обновление для CMake 3.0 и более новых:
продолжение строки возможно с помощью \
. см. 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.\
")
Доступность версий CMake:
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 доступен через Homebrew, Macports и Fink
Windows: cmake-3 доступен через Chocolatey
Ответ 2
CMake 3.0 и новее
Используйте команду string(CONCAT)
:
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}")
Хотя CMake 3.0 и более новые версии поддерживают строку продолжения аргументов в кавычках, вы не можете сделать отступ для второй или последующих строк, не вставив пробел в отступе в вашей строке.
CMake 2.8 и старше
Вы можете использовать список. Каждый элемент списка можно поместить в новую строку:
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}")
Список, используемый без кавычек, объединяется без пробелов:
message(STATUS "Version: " ${MYPROJ_VERSION_LIST})
-- Version: 1.0.0-rc1
Если вам действительно нужна строка, сначала вы можете преобразовать список в строку:
string(REPLACE ";" "" MYPROJ_VERSION "${MYPROJ_VERSION_LIST}")
message(STATUS "Version: ${MYPROJ_VERSION}")
-- Version: 1.0.0-rc1
Любые точки с запятой в исходных строках будут рассматриваться как разделители элементов списка и удаляться. Им нужно сбежать:
set(MY_LIST "Hello World "
"with a \;semicolon")
Ответ 3
Это все еще немного подробный, но если ограничение 80 char действительно вызывает ошибки, вы можете многократно добавлять к одной и той же переменной:
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}")
Выдает вывод:
$ cmake ~/project/tmp
-- version: 1.0.0-rc1
-- Configuring done
-- Generating done
-- Build files have been written to: /home/rsanderson/build/temp
Ответ 4
Невозможно разбить строковый литерал на несколько строк в файлах CMakeLists.txt или в сценариях CMake. Если вы включите новую строку в строку, в самой строке будет буквальная строка новой строки.
# 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}")
Однако CMake использует пробелы для разделения аргументов, поэтому вы можете изменить пространство, разделяющее разделитель аргументов, на новую строку в любом месте, не изменяя поведение.
Вы можете перефразировать эту более длинную строку:
set(MYPROJ_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_EXTRA}")
как эти две более короткие строки:
set(MYPROJ_VERSION
"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_EXTRA}")
Они полностью эквивалентны.
Ответ 5
Пример в оригинальном вопросе касается только относительно короткой строки. Для более длинных строк (включая примеры, приведенные в других ответах) аргумент в скобках может быть лучше. Из документации:
Открывающая скобка написана [
, за которой следует ноль или более =
, а затем [
. Соответствующая закрывающая скобка написана ]
, за которой следует то же число =
, за которым следует ]
. Скобы не гнездятся. Всегда можно выбрать уникальную длину для открывающих и закрывающих скобок, чтобы они содержали закрывающие скобки другой длины.
[...]
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.
]=])'''