답변:
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_IDis "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 을 참조하십시오 . 어떤 아이디어?