developer tip

CMake에서 문자열을 여러 줄로 분할하는 방법은 무엇입니까?

optionbox 2020. 9. 25. 07:46
반응형

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 ...)무엇입니까?


CMake 3.0 이상 업데이트 :

줄 연속은 \. 참조 cmake-3.0-문서를

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 백 포트 : 2.8.11
Debian Jessy (2015) : 3.0.2
Ubuntu 14.04 (LTS) : 2.8.12
Ubuntu 15.04 : 3.0.2
Mac OSX : Homebrew를 통해 cmake-3 사용 가능 , MacportsFink
Windows : Chocolatey를 통해 cmake-3 사용 가능


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

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.


The example in the original question is only about a relatively short string. For longer strings (including the examples given in other answers), a bracket argument could be better. From the documentation:

An opening bracket is written [ followed by zero or more = followed by [. The corresponding closing bracket is written ] followed by the same number of = followed by ]. Brackets do not nest. A unique length may always be chosen for the opening and closing brackets to contain closing brackets of other lengths.

[...]

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.
]=])```

참고URL : https://stackoverflow.com/questions/7637539/how-to-split-strings-across-multiple-lines-in-cmake

반응형