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
[용법]
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()