CMake - 캐시 변수

mohadang·2022년 8월 7일
0

CMake

목록 보기
6/24
post-thumbnail

캐시 변수

  • 캐시 변수는 글로벌 변수다.
  • 캐시 변수는 사용자가 설정할 수 있는 변수다.
  • 캐시 변수와 일반 변수가 있을때 일반 변수가 우선적으로 사용된다.
  • 캐시 변수는 CMakeCache.txt에 저장 된다.

캐시 변수 용도

  • 캐시 변수는 사용자가 프로젝트 설정을 커스마이즈 할 수 있도록 옵션 역할을 한다.
cmake_minimum_required(VERSION 2.8)
project(foo NONE)

# 캐시 변수
set(FOO_A "Default value for A" CACHE STRING "")

# 일반 변수
set(FOO_B "Default value for B")

message("FOO_A: ${FOO_A}")
message("FOO_B: ${FOO_B}")
[usage-of-variables]> cmake -H project-customization -B _builds
FOO_A: Default value for A    # FOO_A 변수 기본값, 캐시
FOO_B: Default value for B    # FOO_B 변수 기본값, 일반 변수
-- Configuring done
-- Generating done
-- Build files have been written to: /.../usage-of-variables/_builds
# 사용자가 캐시 변수 FOO_A 설정
# 캐시 변수를 설정할 때는 -D 옵션과 같이 사용

[usage-of-variables]> cmake -DFOO_A=User -H project-customization -B _builds
FOO_A: User                  # 캐시 변수 : 사용자가 정의한 값이 설정됨
FOO_B: Default value for B   # 일반 변수
-- Configuring done
-- Generating done
-- Build files have been written to: /.../usage-of-variables/_builds
# 사용자가 일반 변수 FOO_B 설정

[usage-of-variables]> rm -rf _builds
[usage-of-variables]> cmake -DFOO_B=User -H project-customization -B _builds
FOO_A: User   # 캐시 변수 : 사용자가 설정한 값이 그대로 유지
FOO_B: Default value for B    # 일반 변수 : 사용자가 정의한 값이 있음에도 코드상에 기본값 사용
-- Configuring done
-- Generating done
-- Build files have been written to: /.../usage-of-variables/_builds
  • 캐시 변수는 cmake 실행시 파라미터 역할을 수행 하는것으로 보면 된다.

CMakeCache.txt

  • 캐시 변수는 cmake를 여러번 실행하여도 CMakeCache.txt에 남아서 값이 유지된다.
cmake_minimum_required(VERSION 2.8)
project(foo NONE)

message("Regular variable (before): ${abc}")
message("Cache variable (before): ${xyz}")

set(abc "123") # 일반 변수 선언
set(xyz "321" CACHE STRING "") # 캐시 변수 선언

message("Regular variable (after): ${abc}")
message("Cache variable (after): ${xyz}")
# 첫번째 실행

[usage-of-variables]> cmake -H cache-vs-regular -B _builds
Regular variable (before):
Cache variable (before):
Regular variable (after): 123       # 일반 변수
Cache variable (after): 321         # 캐쉬 변수
-- Configuring done
-- Generating done
-- Build files have been written to: /.../usage-of-variables/_builds

# 두번째 실행

[usage-of-variables]> cmake -H cache-vs-regular -B _builds
Regular variable (before):          # 일반 변수는 두번째 실행에서 비어있지만
Cache variable (before): 321        # 캐쉬 변수는 두번째 실행에도 값이 유지되어 있음
Regular variable (after): 123
Cache variable (after): 321
-- Configuring done
-- Generating done
-- Build files have been written to: /.../usage-of-variables/_builds  

캐시값 설정

  • CMakeLists.txt에서 값을 바꾸더라도 캐시가 CMakeCache.txt에 존재하면 CMakeCache.txt에 존재하는 캐시값을 사용한다.
cmake_minimum_required(VERSION 2.8)
project(foo NONE)
set(abc "123" CACHE STRING "") # 첫번째 실행에서 abc 캐시값 없으면 123 저장
message("Variable from cache: ${abc}") # 123
# CMakeLists.txt의 코드를 다음과 같이 수정

...
# set(abc "123" CACHE STRING "")
set(abc "789" CACHE STRING "")
...
# CMakeLists.txt의 캐시값 설정 부분을 수정 후 실행

[usage-of-variables]> cmake -H double-set -B _builds
Variable from cache: 123   # 123 출력, 캐시의 값
-- Configuring done
-- Generating done
-- Build files have been written to: /.../usage-of-variables/_builds

캐시값이 캐시 파일에 이미 있으면 값이 바뀌어도 캐시 파일에 있는 값 사용, 
캐시가 있음으로 여전히 123 출력

[usage-of-variables]> grep abc _builds/CMakeCache.txt
abc:STRING=123    <-- 첫번째 실행에서 설정된 캐시값

-D 옵션을 사용하여 실행시 캐시값 설정

  • cmake 실행시 -D로 캐시값을 사용자가 설정할 수 있다.
    • 흔히 사용하는 패턴
  • -D를 사용한 캐시값 설정이 set(... CACHE ...) 명령어보다 우선순위가 높아서 cmake 실행시 -D로 설정된 캐시값을 사용하게 된다.
  • CMakeCache.txt에 캐시값이 있어도 -D로 설정된 캐시값을 사용하며 CMakeCache.txt에 존재하는 캐시값을 덮어쓴다.
# -D 를 사용하여 abc 캐시 변수에 444 값을 설정

red@DESKTOP-G15ND3V:~/cgold$ cmake -Dabc=444 -B build
Variable from cache: 444    # -D에서 설정된 444 출력
-- Configuring done
-- Generating done
-- Build files have been written to: /home/red/cgold/build
# CMakeCache.txt 내용도 444로 덮어써진다.

red@DESKTOP-G15ND3V:~/cgold$ grep abc build/CMakeCache.txt
abc:STRING=444

캐시 초기화

  • -D를 이용하여 많은 캐시값을 하나씩 초기화 하는것은 불편하다.
  • 캐시 초기화 기능을 사용하면 한번에 초기화 가능
# CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(foo NONE)

message("A: ${A}")
message("B: ${B}")
message("C: ${C}")
# cache.cmake : 캐시 초기화 파일

set(A "123" CACHE STRING "")
set(B "456" CACHE STRING "")
set(C "789" CACHE STRING "")
# -C 옵션과 캐시 초기화 파일(cache.cmake)을 이용하여 캐시값 초기화

[usage-of-variables]> cmake -C initial-cache/cache.cmake -H initial-cache -B _builds
loading initial cache file initial-cache/cache.cmake
A: 123
B: 456
C: 789
-- Configuring done
-- Generating done
-- Build files have been written to: /.../usage-of-variables/_builds  

캐시값 강제로 덮어쓰기

  • FORCE 키워드를 사용하면 캐시값을 덮어 쓰기가 가능하다
    • 그러나 안티 패턴이다, 권고하지 않는다.
    • 캐시 변수 본래 사용 의도가 아니다.
cmake_minimum_required(VERSION 2.8)
project(foo NONE)

set(A "123" CACHE STRING "" FORCE)  # 캐시값을 강제로 123 설정
message("A: ${A}")
# 사용자가 A 캐시 변수에 456 값을 할당

[usage-of-variables]> cmake -D A=456 -H force -B _builds
A: 123    # 그러나 무시하고 123 설정
-- Configuring done
-- Generating done
-- Build files have been written to: /.../usage-of-variables/_builds  
cmake_minimum_required(VERSION 2.8)
project(foo NONE)

set(A "123")

# 첫번째 실행 : A 라는 캐시 변수 없음, 일반 변수 A 제거, A를 캐시 변수 456으로 설정
# 두번째 실행 : A 라는 캐시 변수가 이미 있음, 기존 A 변수 제거하지 않음
set(A "456" CACHE STRING "")    

# 첫번째 실행 : 캐시 변수 456 출력, 일반 변수는 제거 되었기에
# 두번째 실행 : 일반 변수 123 출력
message("A: ${A}") 
cmake_minimum_required(VERSION 2.8)
project(foo NONE)

set(A "123")
set(A "456" CACHE STRING "" FORCE)

# 첫번째 실행 : 캐시 변수 456 출력
# 두번째 실행 : 캐시 변수 456 출력
message("A: ${A}")

캐시 타입

  • 캐시 변수 역시 변수이기에 무조건 문자열이지만 hint를 통해서 CMake-GUI에 어떤 타입인지 표시 가능
  • hint로 어떤 타입인지 명시 할 수 있지만 그래도 실제 캐시 타입은 문자열이다.
cmake_minimum_required(VERSION 2.8)
project(foo NONE)

set(FOO_A "YES" CACHE BOOL "Variable A")
set(FOO_B "boo/info.txt" CACHE FILEPATH "Variable B")
set(FOO_C "boo/" CACHE PATH "Variable C")
set(FOO_D "abc" CACHE STRING "Variable D")

message("FOO_A (bool): ${FOO_A}")
message("FOO_B (file path): ${FOO_B}")
message("FOO_C (dir path): ${FOO_C}")
message("FOO_D (string): ${FOO_D}")
  • CMake-GUI에서 열거로 표시
cmake_minimum_required(VERSION 2.8)
project(foo NONE)

# 캐시 변수를 하나 선언
set(FOO_CRYPTO "OpenSSL" CACHE STRING "Backend for cryptography")

# 캐시 변수 속성을 열거로 표시함
# 이 캐시 변수는 CMake-GUI에서 콤보 박스로로 3 항목을 표시하게 된다
set_property(CACHE FOO_CRYPTO PROPERTY STRINGS "OpenSSL;Libgcrypt;WinCNG")
  • INTERNAL : INTERNAL로 설정된 변수는 CMake-GUI에서 출력되지 않는다.
cmake_minimum_required(VERSION 2.8)
project(foo NONE)

set(FOO_A "123" CACHE STRING "")
set(FOO_B "456" CACHE INTERNAL "")    # CMake-GUI에서 표시되지 않음
set(FOO_C "789" CACHE STRING "")
  • INTERNAL은 FORCE 처럼 동작한다
cmake_minimum_required(VERSION 2.8)
project(foo NONE)

set(FOO_A "123" CACHE INTERNAL "")
set(FOO_A "456" CACHE INTERNAL "")    # FORCE 옵션 효과와 비슷해서 456으로 설정
set(FOO_A "789" CACHE INTERNAL "")    # 다시 한번 789로 설정

set(FOO_B "123" CACHE STRING "")    # FORCE를 설정하지 않은 123 설정, 캐시에 저장됨
set(FOO_B "456" CACHE STRING "")    # 캐시에 이미 있어서 무시
set(FOO_B "789" CACHE STRING "")    # 캐시에 이미 있어서 무시

message("FOO_A (internal): ${FOO_A}")   # 789
message("FOO_B (string): ${FOO_B}")     # 123
  • Advanced : Advanced 변수로 설정하면 CMake-GUI에서 Advanced 옵션 체크를 해야만 볼 수 있다.
cmake_minimum_required(VERSION 2.8)
project(foo NONE)

set(FOO_A "123" CACHE STRING "")
set(FOO_B "456" CACHE STRING "")
set(FOO_C "789" CACHE STRING "")

# CMake-GUI에서 Advanced 옵션 체크하면 이 캐시 변수를 볼 수 있음
mark_as_advanced(FOO_B)

option

  • option은 bool 값을 담는 캐시값이다
cmake_minimum_required(VERSION 2.8)
project(foo NONE)

option(FOO_A "Option A" OFF)
option(FOO_B "Option A" ON)

message("FOO_A: ${FOO_A}")
message("FOO_B: ${FOO_B}")  
[usage-of-variables]> cmake -H option -B _builds
FOO_A: OFF
FOO_B: ON
-- Configuring done
-- Generating done
-- Build files have been written to: /.../usage-of-variables/_builds

# 캐시 파일에 옵션으로 설정된 값 저장됨

[usage-of-variables]> grep FOO_ _builds/CMakeCache.txt
FOO_A:BOOL=OFF
FOO_B:BOOL=ON

권고

  • 캐시 변수는 글로벌한 접근이 가능하기 떄문에 prefix를 붙여서 이름 중복을 회피하여 사용하는것을 추천
# 최상위 CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(zoo)
add_subdirectory(boo)
add_subdirectory(foo)
# foo/CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(foo)
option(FOO_FEATURE_1 "Enable feature 1" OFF)  # FOO 캐시들
option(FOO_FEATURE_2 "Enable feature 2" OFF)
# boo/CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(boo)
option(BOO_FEATURE_1 "Enable feature 1" ON)   # BOO 캐시들
option(BOO_FEATURE_2 "Enable feature 2" ON)  
# CMakeCache.txt : CMakeCache.txt 에서 구분할 수 있음, 충돌 방지

red@DESKTOP-G15ND3V:~/cgold$ grep "FOO_" build/CMakeCache.txt
FOO_FEATURE_1:BOOL=OFF
FOO_FEATURE_2:BOOL=OFF
red@DESKTOP-G15ND3V:~/cgold$ grep "BOO_" build/CMakeCache.txt
BOO_FEATURE_1:BOOL=ON
BOO_FEATURE_2:BOOL=ON
profile
mohadang

0개의 댓글