Skip to content

CMakeLists.txt

CMake의 빌드 스크립트인 CMakeList.txt 파일에 대하여 정리한다.

Category

Commands

FIND_PACKAGE

Load settings for an external project.

How package finding works

The find_package() command will look in the module path for Find<name>.cmake, which is the typical way for finding libraries. First CMake checks all directories in ${CMAKE_MODULE_PATH}, then it looks in its own module directory <CMAKE_ROOT>/share/cmake-x.y/Modules/.

If no such file is found, it looks for <Name>Config.cmake or <lower-case-name>-config.cmake, which are supposed to be installed by libraries (but there are currently not yet many libraries which install them) and that don't do detection, but rather just contain hardcoded values for the installed library.

The former is called module mode and the latter is called config mode. Creation of config mode files is documented here. You may also need the documentation for importing and exporting targets.

For the module system there seems to be no documentation elsewhere, so this article concentrates on it.

No matter which mode is used, if the package has been found, a set of variables will be defined:

  • <NAME>_FOUND
  • <NAME>_INCLUDE_DIRS or <NAME>_INCLUDES
  • <NAME>_LIBRARIES or <NAME>_LIBRARIES or <NAME>_LIBS
  • <NAME>_DEFINITIONS

All this takes place in the Find<name>.cmake file.

Now, in the CMakeLists.txt file in the top level directory of your code (the client code that is actually going to make use of the library <name>, we check for the variable <NAME>_FOUND to see whether the package has been found or not. For most packages the resulting variables use the name of the package all uppercased, e.g. LIBFOO_FOUND, for some packages the exact case of the package is used, e.g. LibFoo_FOUND. If this variable is found, then, we pass the<NAME>_INCLUDE_DIRS to the include_directories() command and <NAME>_LIBRARIES to the target_link_libraries() command of CMake.

These conventions are documented in the file readme.txt in the CMake module directory.

The "REQUIRED" and other optional find_package arguments are forwarded to the module by find_package and the module should affect its operation based on them.

STRING

문자열을 조작할 수 있는 명령어. 정규표현식(REGEX), TIMESTAMP, RANDOM 등을 사용할 수 있다.

Windows path caution

string(REPLACE "\\" "/" outputVar ${_inputVar})

MESSAGE

다음과 같이 디버깅용 매크로를 만들 수 있다.

macro(DBG_MSG _MSG)
  message(STATUS
    "${CMAKE_CURRENT_LIST_FILE}(${CMAKE_CURRENT_LIST_LINE}): ${_MSG}")
endmacro()

MATH

수식 계산은 아래와 같이 사용할 수 있다.

set (value 2)
math (EXPR result "${value} * 2")

INSTALL

# Install ${CMAKE_INSTALL_PREFIX} settings.
install (TARGETS ${MAIN_NAME}
         RUNTIME DESTINATION bin
         LIBRARY DESTINATION lib
         ARCHIVE DESTINATION lib)
install (DIRECTORY ${MAIN_NAME}/
         DESTINATION include/${MAIN_NAME}
         FILES_MATCHING PATTERN "*.h")

TARGET~

TARGET 계열 명령 목록은 아래와 같다.

  • target_compile_definitions
  • target_compile_options
  • target_include_directories
  • target_link_libraries

get_property

get_source_file_property

set_property

The set_*_properties() functions are shorthands for basic usage. For "advanced" cases, it's better to use the full power of set_property():

set_property(
     SOURCE a.cpp
     APPEND
     PROPERTY COMPILE_DEFINITIONS
     DIR1="/home/xxx/b.i" DIR2="/home/xxx/c.i" DIR3="/home/xxx/d.i"
)

set_source_files_properties

set_source_files_properties(${SOURCES}
       PROPERTIES
       COMPILE_FLAGS  "-std=c++0x")

#set_property으로 대체할 수 있다. 참고로 Getter 명령은 #get_source_file_property 또는 #get_property 가 있다.

Properties

속성 목록은 다음과 같다:

  • ABSTRACT
  • AUTOUIC_OPTIONS
  • AUTORCC_OPTIONS
  • COMPILE_DEFINITIONS
  • COMPILE_FLAGS
  • EXTERNAL_OBJECT
  • Fortran_FORMAT
  • GENERATED
  • HEADER_FILE_ONLY
  • KEEP_EXTENSION
  • LABELS
  • LANGUAGE
  • LOCATION
  • MACOSX_PACKAGE_LOCATION
  • OBJECT_DEPENDS
  • OBJECT_OUTPUTS
  • SYMBOLIC
  • VS_DEPLOYMENT_CONTENT
  • VS_DEPLOYMENT_LOCATION
  • VS_SHADER_ENTRYPOINT
  • VS_SHADER_FLAGS
  • VS_SHADER_MODEL
  • VS_SHADER_TYPE
  • VS_XAML_TYPE
  • WRAP_EXCLUDE
  • XCODE_EXPLICIT_FILE_TYPE
  • XCODE_LAST_KNOWN_FILE_TYPE

set_target_properties

Targets can have properties that affect how they are built.

SET_TARGET_PROPERTIES(hello PROPERTIES SUFFIX .so)

mark_as_advanced

GUI의 고급(advanced) 옵션에 추가한다.

Object Library

CMake 2.8.8 부터 add_library명령에 OBJECT 타입이 추가되었다.

우선, OBJECT를 만든다.

# A/CMakeLists.txt
add_library(A OBJECT ${A_srcs})
# B/CMakeLists.txt
add_library(B OBJECT ${B_srcs})

OBJECT를 프로젝트 타겟에 적용하는 방법은 아래와 같다.

# CMakeLists.txt
add_subdirectory(A)
add_subdirectory(B)
add_library(big STATIC ${other_srcs} $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)

Favorite site