1. project 초기 설정

CMAKE_MINIMUM_REQUIRED

[용법]

cmake_minimum_required(VERSION major.minor[.patch[.tweak]][FATAL_ERROR])

만약 어떤 오픈소스 라이브러리가 cmake 3.0 버전 이상으로 작성 되었고, 현재 나의 빌드환경은 cmake 2.8버전 미만이라면 빌드 시, 다음의 에러가 출력된다 ->
CMake 3.0 or higher is required. You are running version 2.8.12.2
이 커맨드는 반드시 CMakeListst.txt 작성시 맨 처음에 선언 해 놓아야 정상적인 버전 호환 에러를 출력할 수 있다.

# Bad example
project(foo)
cmake_minimum_required(VERSION 3.0)
message("Using CMake version ${CMAKE_VERSION}")

PROJECT

[용법]

project(<PROJECT-NAME> [LANGUAGES] [<language-name>...])
project(<PROJECT-NAME>
        [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
        [LANGUAGES <language-name>...])

이름 및 버전, 언어등 전체 프로젝트에 대한 정의를 한다.
아래와 같이 1.0 버전의 c/c++로 작성된 foo라는 프로젝트를 명시할 수 있다. Visual Studio로 예를 들자면 솔루션 탐색기의 최상단에 위치하는 프로젝트의 이름이 된다.

project(foo C CXX VERSION 1.0)

SET

[용법]

# Normal Variable
set(<variable> <value>... [PARENT_SCOPE])
# Cache Entry
set(<variable> <value>... CACHE <type> <docstring> [FORCE])

각종 변수를 정의하는데 사용되는 명령어이다.
set( var1 10 )일때 var1은 10의 값을 가지고 현재 디렉토리내에서만 유효하다. 하지만 만약 마지막에 PARENT_SCOPE 옵션을 사용한다면 var1의 scope는 부모 디렉터리까지 유효하게 된다. 또한, ENV옵션을 사용해 다음처럼 환경변수를 정의할 수도 있다.

set(ENV{LOG_LEVEL} TRACE)

INCLUDE

[용법]

include(<file|module> [OPTIONAL] [RESULT_VARIABLE <VAR>]
                      [NO_POLICY_SCOPE])

.cmake 로 작성된 파일들을 사용할수 있도록 프로젝트에 포함시킨다. CMAKE_MODULE_PATH라는 예약변수에 의해 경로가 설정되며, 해당 경로를 통해 .cmake 파일을 탐색한다.

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # cmake폴더 path 추가
include(options) # options.cmake 파일 Load

INCLUDE_DIRECTORIES

[용법]

include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])

컴파일러에게 각 소스파일에 있는 #include로 포함된 헤더파일들을 포함시킬 수 있도록 하는 명령이다. 아래 예시를 들면 include폴더에 있는 모든 헤더파일을 찾을 수 있도록 한다.

# EXAMPLE
# 현재 CMakeLists.txt가 실행되는 파일 위치의 경로에서 include라는 폴더를 포함함
include_directories( ${CMAKE_CURRENT_LIST_DIR}/include )

ADD_SUBDIRECTORY

[용법]

add_subdirectory(source_dir [binary_dir]
                 [EXCLUDE_FROM_ALL])

cmake 빌드에 필요한 디렉토리를 추가하는 명령이다. 만약 모듈별, 폴더별로 CMakeLists.txt가 나누어져 있다고 하면, 이 명령어를 통해서 CMakeListst.txt가 있는 폴더의 위치를 명시해줌으로써, 하위 모듈의 CMakeLists.txt파일들을 source_dir에 추가시킬 수 있도록 한다.

# EXAMPLE
# src 폴더내의 CMakeLists.txt를 포함해 실행될수 있도록 함
add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/src )



2. compile 설정 관련

ADD_COMPILE_OPTIONS

[용법]

add_compile_options(<option> ...)

소스를 컴파일해 오브젝트 파일(.obj)을 만들때, 컴파일러에게 옵션(flag)를 지정해주는 명령어.
add_compile_options(-Wall)gcc -Wall과 대치된다.


ADD_DEFINITIONS

[용법]

add_definitions(-DFOO -DBAR ...)

preprocesor에서 처리할 변수를 선언한다. gcc flag중 -D option에 대치된다.
add_definitions( -D__linux__ )#define __linux와 같다.


CMAKE_BUILD_TYPE

project의 build type을 결정한다.

  • Debug : 디버깅 정보를 포함하는 빌드
  • Relase : 릴리즈 전용 빌드
  • RelWithDebInfo : 디버깅 정보를 포함하는 릴리즈 빌드
  • MinSizeRel : 최소크기를 가지는 릴리즈 빌드
# EXAMPLE
# 릴리즈로 빌드
set(CMAKE_BUILD_TYPE Release)

CMAKE_VERBOSE_MAKEFILE

Makefile output의 verbose정보를 포함여부를 설정하는 변수이다. 초기설정값은 FALSE로 설정돼있다.

# EXAMPLE
set(CMAKE_VERBOSE_MAKEFILE true)

true로 설정시, 빌드 중 Makefile의 빌드 과정을 출력한다.


CMAKE_VERBOSE_MAKEFILE

Makefile output의 verbose정보를 포함여부를 설정하는 변수이다. 초기설정값은 FALSE로 설정돼있다.

set(CMAKE_VERBOSE_MAKEFILE true)

true로 설정시, 빌드 중 Makefile의 빌드 과정을 출력한다.




3. build 설정 관련

ADD_EXECUTABLE

[용법]

add_executable(<name> [WIN32] [MACOSX_BUNDLE]
               [EXCLUDE_FROM_ALL]
               source1 [source2 ...])

<name>으로 설정된 project 타겟에 대하여 source list로부터 실행가능한 executable 파일을 생성한다. 기본적으로 생성된 파일의 위치는 명령어가 발생한 곳의 위치에 생성되며, RUNTIME_OUTPUT_DIRECTORY 변수를 통해 위치를 변경할 수 있다.

# EXAMPLE
set(src main.cpp foo.cpp boo.cpp)
# test.out의 실행파일을 생성
add_executable(test.out ${src})

[용법]

link_libraries([item1 [item2 [...]]]
               [[debug|optimized|general] <item>] ...)

모든 타겟에 대해 사용될 라이브러리를 링크하는 명령. gcc 옵션중 -l에 대치되는 명령이며 링크옵션 또한 사용가능하다.

# EXAMPLE
 # libbluetooth 라이브러리를 링크
link_libraries(bluetooth)

INSTALL

[용법]

install(TARGETS targets... [EXPORT <export-name>]
        [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE|
          PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
         [DESTINATION <dir>]
         [PERMISSIONS permissions...]
         [CONFIGURATIONS [Debug|Release|...]]
         [COMPONENT <component>]
         [OPTIONAL] [EXCLUDE_FROM_ALL]
         [NAMELINK_ONLY|NAMELINK_SKIP]
        ] [...]
        [INCLUDES DESTINATION [<dir> ...]]
        )

make install 명령어 입력시 진행되는 과정을 정의하는 명령. 주로 cmake 빌드 과정을 통해 나오는 결과물 ( 실행파일, 라이브러리, 리소스) 등을 특정한 위치로 복사하는 동작을 한다.

# EXAMPLE
# output.out 바이너리 파일을 /usr/local/bin의 위치로 설치함
install(TARGETS output.out DESTINATION usr/local/bin)



4. 기타

FIND_FILE

[용법]

find_file (
          <VAR>
          name | NAMES name1 [name2 ...]
          [HINTS path1 [path2 ... ENV var]]
          [PATHS path1 [path2 ... ENV var]]
          [PATH_SUFFIXES suffix1 [suffix2 ...]]
          [DOC "cache documentation string"]
          [NO_DEFAULT_PATH]
          [NO_CMAKE_ENVIRONMENT_PATH]
          [NO_CMAKE_PATH]
          [NO_SYSTEM_ENVIRONMENT_PATH]
          [NO_CMAKE_SYSTEM_PATH]
          [CMAKE_FIND_ROOT_PATH_BOTH |
           ONLY_CMAKE_FIND_ROOT_PATH |
           NO_CMAKE_FIND_ROOT_PATH]
         )

찾을 파일의 이름의 전체경로를 찾아주는 명령. <VAR>변수에 결과가 저장되도록 한다. 만약 경로를 찾지 못하였을경우 <VAR>-NOTFOUND로 최종적으로 저장이된다.

# EXAMPLE
# test.cpp 파일의 전체 경로를 ${CPP_FILE_PATH}변수에 저장
find_file(CPP_FILE_PATH test.cpp PATHS /home/test)

FIND_PACKAGE

[용법]

find_package(<package> [version] [EXACT] [QUIET] [MODULE]
             [REQUIRED] [[COMPONENTS] [components...]]
             [OPTIONAL_COMPONENTS components...]
             [NO_POLICY_SCOPE])

시스템에 설치된 Package들을 찾는 명령. Package를 찾았을 경우 <package>_FOUND 변수에 결과가 저장된다.

  • version : package의 버전을 요청
  • EXACT : 버전이 정확히 일치하도록 요청
  • QUIET : package를 찾을 수 없는경우 메시지 비활성화
  • MODULE : 모듈모드로 package 찾음

    결론적으로, target link libraries 명령을 사용할 때 사용되는 정보들을 받아 linking하는데 관련된 정보를 사용할 수 있도록 하는 명령어이다. 기타 세부설명은 다음 링크에서 확인한다. [click] (https://cmake.org/cmake/help/v3.10/command/find_package.html)
# EXAMPLE
find_package(pak 1.0)
if(pak_FOUND)
        # ...
endif()
# pak 이라는 패키지를 찾았으면 if실행

------------------------------------------

find_package(pak 1.0 REQUIRED)
# pak 이라는 패키지를 찾지 못할경우 오류 메시지 출력 ('REQUIRED'에 의해)
 

FIND_LIBRARY

[용법]

find_library (
          <VAR>
          name | NAMES name1 [name2 ...] [NAMES_PER_DIR]
          [HINTS path1 [path2 ... ENV var]]
          [PATHS path1 [path2 ... ENV var]]
          [PATH_SUFFIXES suffix1 [suffix2 ...]]
          [DOC "cache documentation string"]
          [NO_DEFAULT_PATH]
          [NO_PACKAGE_ROOT_PATH]
          [NO_CMAKE_PATH]
          [NO_CMAKE_ENVIRONMENT_PATH]
          [NO_SYSTEM_ENVIRONMENT_PATH]
          [NO_CMAKE_SYSTEM_PATH]
          [CMAKE_FIND_ROOT_PATH_BOTH |
           ONLY_CMAKE_FIND_ROOT_PATH |
           NO_CMAKE_FIND_ROOT_PATH]
         )

shared library(.so) , static library(.a) 파일등을 찾는 cmake 명령어이다. 찾고자하는 파일을 발견하면, <VAR>변수에 결과가 저장되며, 라이브러리 파일을 찾지 못하였을 경우 <VAR>-NOTFOUND를 저장한다.

# EXAMPLE
find_library (
  FOO_LIBS
  NAMES foo
  PATHS /usr/lib
  )
# /usr/lib의 경로에서 libfoo.so 라이브러리를 찾았으면 if실행
if( FOO_LIBS )
  set(FOO_LIBS_FOUND true)
  include_directories(...)
  message(STATUS "success to find library")
else()
  message(STATUS "failed to find libarary")
endif()