CMake - include, function, if, find_package, git submodule, execute_process

markyang92·2025년 12월 10일

cmake

목록 보기
4/4


function

나중에 명령으로 호출하기 위해 함수 기록을 시작합니다.

    function(<name> [<arg1> ...]) <commands> endfunction()
    function(foo) <commands> endfunction()
  • 예:
function(add_git_submodule relative_dir)
//       ^^^함수이름^^^     ^^^argument^^
// 함수
endfunction(add_git_submodule)


- 외부 호출
add_git_submodule(external/json)
//add_git_submodule 함수 호출
//argument는 external/json


include


find_package

패키지(일반적으로 프로젝트 외부에서 제공)를 찾고 패키지별 세부 정보를 로드합니다. 이 명령에 대한 호출은 종속성 공급자가 가로챌 수도 있습니다.

    find_package(<PackageName> [<version>] [REQUIRED] [COMPONENTS <components>...])
    find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE] [REQUIRED] [[COMPONENTS] [components...]] [OPTIONAL_COMPONENTS components...] [REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)] [GLOBAL] [NO_POLICY_SCOPE] [BYPASS_PROVIDER])
    find_package(<PackageName> [version] [EXACT] [QUIET] [REQUIRED] [[COMPONENTS] [components...]] [OPTIONAL_COMPONENTS components...] [CONFIG|NO_MODULE] [GLOBAL] [NO_POLICY_SCOPE] [BYPASS_PROVIDER] [NAMES name1 [name2 ...]] [CONFIGS config1 [config2 ...]] [HINTS path1 [path2 ... ]] [PATHS path1 [path2 ... ]] [REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)] [PATH_SUFFIXES suffix1 [suffix2 ...]] [NO_DEFAULT_PATH] [NO_PACKAGE_ROOT_PATH] [NO_CMAKE_PATH] [NO_CMAKE_ENVIRONMENT_PATH] [NO_SYSTEM_ENVIRONMENT_PATH] [NO_CMAKE_PACKAGE_REGISTRY] [NO_CMAKE_BUILDS_PATH] [NO_CMAKE_SYSTEM_PATH] [NO_CMAKE_INSTALL_PREFIX] [NO_CMAKE_SYSTEM_PACKAGE_REGISTRY] [CMAKE_FIND_ROOT_PATH_BOTH | ONLY_CMAKE_FIND_ROOT_PATH | NO_CMAKE_FIND_ROOT_PATH])
  • find_package는 CMake에서 외부 라이브러리/패키지를 찾아 프로젝트에 연결한다.
옵션설명
REQUIRED패키지를 못 찾으면 빌드 실패
QUIET메시지 출력 억제
COMPONENTS특정 컴포넌트만 검색
CONFIGconfig 모드 강제
  • <PackageName>Config.cmake 또는 <lowercase>-config.cmake검색
  • 패키지 설치시 함께 제공됨
MODULEmodule 모드 강제
  • Find<PackageName>.cmake 파일 검색
  • CMake 내장 또는 CMAKE_MODULE_PATH에서 찾음

기본 검색 경로

  1. CMAKE_PREFIX_PATH: 환경변수/CMake변수
  2. <PackageName>_DIR: 특정 패키지 경로 힌트
  3. PATH환경 변수
  4. 시스템 기본 경로

message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}") 같은걸로 디버깅 가능


결과변수

<PackageName>_FOUND: TRUE/FALSE
<PackageName>_INCLUDE_DIRS: 헤더 경로
<PackageName>_LIBRARIES: 라이브러리 경로
<PackageName>_VERSION: 버전 정보
<PackageName>_EXECUTABLE: 바이너리 위치


예:

# OpenSSL 찾기 (필수)
find_package(OpenSSL REQUIRED)
target_link_libraries(myapp PRIVATE OpenSSL::SSL OpenSSL::Crypto)

# Boost 특정 컴포넌트 찾기
find_package(Boost 1.70 REQUIRED COMPONENTS filesystem system)
target_link_libraries(myapp PRIVATE Boost::filesystem Boost::system)

# 선택적 패키지
find_package(ZLIB)
if(ZLIB_FOUND)
    target_link_libraries(myapp PRIVATE ZLIB::ZLIB)
endif()


# 구식 방식
find_package(OpenSSL REQUIRED)
include_directories(${OPENSSL_INCLUDE_DIR})
target_link_libraries(myapp ${OPENSSL_LIBRARIES})

# 현대적 방식 (권장)
find_package(OpenSSL REQUIRED)
target_link_libraries(myapp PRIVATE OpenSSL::SSL)
Imported Target(OpenSSL::SSL)은 include 경로, 컴파일 옵션 등을 자동으로 전파합니다.

if

if(<condition>)
...
elseif(<condition>)
...
else()
...
endif()

기본 참/거짓

  • 참(TRUE) 로 평가되는 값
if(1)
if(ON)
if(YES)
if(TRUE)
if(Y)
if("non-empty-string") # 빈 문자열이 아니면 참

  • 거짓(FALSE)로 평가되는 값
if(0)
if(OFF)
if(NO)
if(FALSE)
if(N)
if(IGNORE)
if(NOTFOUND)
if("") # 빈 문자열
if(VAR-NOTFOUND) # *-NOTFOUND 패턴

변수 검사

  • 변수가 정의되어 있고 참인지
if(MY_VAR)
  • 변수가 정의되어 있는지 (값과 무관)
if(DEFINED MY_VAR)
if(DEFINED ENV{PATH}) # 환경 변수
  • 변수가 비어있는지
if(NOT MY_VAR)
if("${MY_VER}" STREQUAL "")

비교 연산자

  • 숫자 비교
if(NUM EQUAL 10)
if(NUM LESS 10)
if(NUM GREATER 10)
if(NUM LESS_EQUAL 10)
if(NUM GREATER_EQUAL 10)
  • 문자열 비교
if(STR STREQUAL "hello")
if(STR STRLESS "b")
if(STR STRGREATER "a")
  • 버전 비교
if(VER VERSION_EQUAL "1.2.3")
if(VER VERSION_LESS "2.0")
if(VER VERSION_GREATER_EQUAL "1.0")

논리 연산자

if(NOT condition)
if(cond1 AND cond2)
if(cond1 OR cond2)

파일/디렉토리 검사

if(EXISTS "/path/to/file")
if(IS_DIRECTORY "/path/to/dir")
if(IS_SYMLINK "/path/to/link")
if(IS_ABSOLUTE "/path")
if(file1 IS_NEWER_THAN file2) # 파일 수정 시간 비교

리스트/문자열 검사

if("item" IN_LIST MY_LIST) # 리스트에 포함되어 있는지

if(STR MATCHES "^[0-9]+$") # 정규표현식 매칭
if(STR MATCHES "error|warning")

타겟/명령어 존재 검사

if(TARGET my_target)	# 타겟이 정의 되어 있는지
if(COMMAND my_function)	# 함수/매크로가 정의되어 있는지
if(POLICY CMP0048)		# 정책이 존재하는지
if(TEST my_test)		# 테스트가 정의되어 있는지

예시

플랫폼분기

if(WIN32)
	set(PLATFORM_LIBS ws2_32)
elseif(APPLE)
	set(PLATFORM_LIBS "-framework CoreFoundation")
elseif(UNIX)
	set(PLATFORM_LIBS pthread dl)
endif()

옵션에 따른 분기

option(ENABLE_TESTS "Enable testing" ON)
if(ENABLE_TESTS)
	enable_testing()
    add_subdirectory(tests)
endif()

패키지 존재여부

find_package(OpenSSL)
if(OpenSSL_FOUND)
	target_link_libraries(myapp PRIVATE OpenSSL::SSL)
else()
	message(WARNING "OpenSSL not found, using fallback")
endif()

빌드 타입 확인

if(CMAKE_BUILD_TYPE STREQUAL "Debug"
	add_compile_definition(DEBUG_MODE)
endif()

컴파일러 확인

if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
	add_compile_options(-Wall -Wextra)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
	add_compile_options(-Weverything)
endif()

execute_process

하나 이상의 자식 프로세스를 실행합니다.

execute_process(
    COMMAND <cmd1> [args1...]
    [WORKING_DIRECTORY <directory>]
    [TIMEOUT <seconds>]
    [RESULT_VARIABLE <variable>]
    [OUTPUT_VARIABLE <variable>]
    [ERROR_VARIABLE <variable>]
    [OUTPUT_STRIP_TRAILING_WHITESPACE]
    [ERROR_STRIP_TRAILING_WHITESPACE]
)
  • CMake 구성(configure) 시점에 외부 명령어를 실행하는 명령이다.
  • execute_processadd_custom_command차이
구분execute_processadd_custom_command
실행 시점구성 시점(cmake 실행 시)빌드 시점 (make/ninja 실행시)
용도버전 확인, 환경 설정코드 생성, 파일 복사

  • 주요 옵션
옵션설명
COMMAND실행할 명령어와 인자들
WORKING_DIRECTORY명령어 실행 디렉토리
RESULT_VARIABLE반환 코드 저장 (0=성공)
OUTPUT_VARIABLE표준 출력 저장
ERROR_VARIABLE표준 에러 저장
TIMEOUT타임아웃(초)

예시

execute_process(COMMAND ${GIT_EXECUTABLE}
            submodule update --init --recursive -- ${relative_dir}
            WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
  • git submodule update --init --recursive -- ${relative_dir} 명령 실행
  • 명령을 ${PROJECT_SOURCE_DIR}에서 실행
profile
pllpokko@alumni.kaist.ac.kr

0개의 댓글