답변:
CMake 스크립트를 작성할 때 구문과 CMake에서 변수를 사용하는 방법에 대해 알아야 할 것이 많습니다.
다음을 사용하는 문자열 set()
:
set(MyString "Some Text")
set(MyStringWithVar "Some other Text: ${MyString}")
set(MyStringWithQuot "Some quote: \"${MyStringWithVar}\"")
또는과 string()
:
string(APPEND MyStringWithContent " ${MyString}")
를 사용하여 나열 set()
:
set(MyList "a" "b" "c")
set(MyList ${MyList} "d")
또는 더 나은 list()
:
list(APPEND MyList "a" "b" "c")
list(APPEND MyList "d")
파일 이름 목록 :
set(MySourcesList "File.name" "File with Space.name")
list(APPEND MySourcesList "File.name" "File with Space.name")
add_excutable(MyExeTarget ${MySourcesList})
set()
명령string()
명령list()
명령먼저 "정상 변수"와 그 범위에 대해 알아야 할 사항이 있습니다.
CMakeLists.txt
그들이라는 설정 및 모든 있습니다에서가 ( add_subdirectory()
, include()
, macro()
및 function()
).add_subdirectory()
과 function()
그들이 오픈까지 있기 때문에 자신의 범위를 명령은 특별하다.
set(...)
거기에만 표시되며 호출 된 범위 수준의 모든 일반 변수 (부모 범위)의 복사본을 만듭니다.set(... PARENT_SCOPE)
function(xyz _resultVar)
설정입니다set(${_resultVar} 1 PARENT_SCOPE)
include()
또는 macro()
스크립트는 변수가 호출되는 범위에서 변수를 직접 수정합니다.두 번째로 "전역 변수 캐시"가 있습니다. 캐시에 대해 알아야 할 사항 :
CMakeCache.txt
이진 출력 디렉토리 의 파일에 저장됩니다 .캐시의 값 은 생성되기 전에 CMake의 GUI 응용 프로그램 에서 수정할 수 있습니다 . 따라서 정규 변수와 비교하여 a type
와 a가 docstring
있습니다. 나는 일반적으로 GUI를 사용하지 않으므로 set(... CACHE INTERNAL "")
전역 및 지속 값을 설정 하는 데 사용 합니다.
있습니다 INTERNAL
캐시 변수 유형을 의미 않는다FORCE
CMake 스크립트에서는 set(... CACHE ... FORCE)
구문 을 사용하는 경우 기존 캐시 항목 만 변경할 수 있습니다 . 이 동작은 일반적으로 캐시 항목 자체를 강제하지 않으므로 다른 값으로 미리 정의 할 수 있기 때문에 CMake 자체에 의해 사용됩니다.
cmake -D var:type=value
만으로 cmake -D var=value
또는 항목으로 항목을 설정할 수 있습니다 cmake -C CMakeInitialCache.cmake
.unset(... CACHE)
.캐시는 전역 적이며 CMake 스크립트의 거의 모든 위치에 설정할 수 있습니다. 그러나 캐시 변수를 사용할 위치에 대해 두 번 생각하는 것이 좋습니다 (전역적이고 지속 가능합니다). 나는 일반적으로 비 구속 글로벌 변수를 정의하기 위해 set_property(GLOBAL PROPERTY ...)
and set_property(GLOBAL APPEND PROPERTY ...)
구문을 선호합니다 .
함정을 피하려면 변수에 대해 다음을 알아야합니다.
find_...
성공하면 - - 명령 캐시 변수로 결과를 기록 할 "그래서 전화가 다시 검색되지 것"set(MyVar a b c)
이다 "a;b;c"
와 set(MyVar "a b c")
이다"a b c"
list()
목록 처리 명령을 선호 합니다functions()
보다는 대신 사용 하는 것이 좋습니다 macros()
.project()
및 enable_language()
호출 로 설정됩니다 . 따라서 해당 명령을 사용하기 전에 일부 변수를 설정하는 것이 중요 할 수 있습니다.때로는 디버깅 변수 만 도움이됩니다. 다음이 도움이 될 수 있습니다.
printf
을 사용하여 이전 디버깅 스타일을 사용하십시오 message()
. CMake 자체와 함께 제공되는 모듈을 사용할 준비가되었습니다 : CMakePrintHelpers.cmake , CMakePrintSystemInformation.cmakeCMakeCache.txt
바이너리 출력 디렉토리에서 파일을 찾으십시오 . 이 파일은 실제 make 환경 생성에 실패한 경우에도 생성됩니다.cmake --trace ...
CMake의 전체 구문 분석 프로세스를 보려면 전화 하십시오. 그것은 많은 양의 출력을 생성하기 때문에 일종의 마지막 예약입니다.$ENV{...}
쓸 수 있습니다set(ENV{...} ...)
$<...>
은 CMake 생성기가 작성 환경을 작성할 때만 평가됩니다 (구문 분석기로 "제자리에서"대체되는 일반 변수와 비교)${${...}}
변수에 변수 이름을 부여하고 그 내용을 참조 할 수 있습니다.if()
명령 참조 )
if(MyVariable)
당신이 직접 참 / 거짓에 대한 변수 (둘러싸는 여기를 필요 없음을 확인하실 수 있습니다 ${...}
)1
, ON
, YES
, TRUE
, Y
, 또는 비 제로의 수입니다.0
, OFF
, NO
, FALSE
, N
, IGNORE
, NOTFOUND
, 빈 문자열, 또는 접미사의 끝 -NOTFOUND
.if(MSVC)
되지만이 구문 단축키를 모르는 사람에게는 혼동 될 수 있습니다.set(CMAKE_${lang}_COMPILER ...)
if()
명령. 다음은 CMAKE_CXX_COMPILER_ID
is "MSVC"
와 is의 예 MSVC
입니다 "1"
.
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
그것은 평가하기 때문에 사실이다 if("1" STREQUAL "1")
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
그것이 평가되기 때문에 거짓이다 if("MSVC" STREQUAL "1")
if(MSVC)
cmake_policy(SET CMP0054 NEW)
만 if()
변수 또는 키워드로 해석하도록 설정 하는 것이 좋습니다 .option()
명령
ON
또는 캐시 될 수 있고 의존성OFF
과 같은 특별한 처리를 허용 하는 캐시 된 문자열option
와 set
명령. 주어진 값 option
은 실제로는 "초기 값"(첫 번째 구성 단계에서 캐시로 한 번 전송 됨) 일 뿐이며 이후 CMake의 GUI를 통해 사용자가 변경하도록되어 있습니다 .${MyString}
하면 "주어진 경우 ..." 근처의 CMake 오류 와 같은 "인수 주어진 경우 ..."에 대한 많은 오류가 발생합니다 .
if (MyString ...)
코드를 경고하는 것입니다.
다음은 빠르고 더러운 시작을위한 몇 가지 기본 예입니다.
변수 설정 :
SET(INSTALL_ETC_DIR "etc")
변수 사용 :
SET(INSTALL_ETC_CROND_DIR "${INSTALL_ETC_DIR}/cron.d")
변수 설정 :
SET(PROGRAM_SRCS
program.c
program_utils.c
a_lib.c
b_lib.c
config.c
)
변수 사용 :
add_executable(program "${PROGRAM_SRCS}")
if ("${MyString}" ...)
경고가 표시Policy CMP0054 is not set: Only interpret if() arguments as variables or keywords when unquoted
됩니다.. 예를 들어 빌드 367 을 참조하십시오 . 어떤 아이디어?