Skip to content

CMake:Modules

CMake스크립트로 작성된 모듈에 대하여 정리한다.

Category

CMakeParseArguments

CMake 스타일의 인자를 분석할 수 있도록 도와준다.

FindProtobuf

Example:

include(FindProtobuf)
find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIR})
# ...
target_link_libraries(complex
    ${Boost_FILESYSTEM_LIBRARY}
    ${Boost_SYSTEM_LIBRARY}
    ${PROTOBUF_LIBRARY}
)

FindwxWidgets

Not found wxWidgets in MinGW

MinGW에서 정상적으로 찾을 수 없는 경우 파일 경로를 확인해야 한다. 아래의 코드를 참조하자.

if(WX_ROOT_DIR)
    # Select one default tree inside the already determined wx tree.
    # Prefer static/shared order usually consistent with build
    # settings.
    set(_WX_TOOL "")
    set(_WX_TOOLVER "")
    set(_WX_ARCH "")

    if(MINGW)
        set(_WX_TOOL gcc)
    elseif(MSVC)
        set(_WX_TOOL vc)
        if(MSVC14)
            set(_WX_TOOLVER 140)
        elseif(MSVC12)
            set(_WX_TOOLVER 120)
        elseif(MSVC11)
            set(_WX_TOOLVER 110)
        elseif(MSVC10)
            set(_WX_TOOLVER 100)
        elseif(MSVC90)
            set(_WX_TOOLVER 90)
        endif()
        if(CMAKE_SIZEOF_VOID_P EQUAL 8)
            set(_WX_ARCH _x64)
        endif()
    endif()

    ## ...

    find_path(wxWidgets_LIB_DIR
        NAMES
        msw/wx/setup.h
        mswd/wx/setup.h
        mswu/wx/setup.h
        mswud/wx/setup.h
        mswuniv/wx/setup.h
        mswunivd/wx/setup.h
        mswunivu/wx/setup.h
        mswunivud/wx/setup.h
        PATHS
        ${WX_ROOT_DIR}/lib/${_WX_TOOL}${_WX_TOOLVER}${_WX_ARCH}_dll   # prefer shared
        ${WX_ROOT_DIR}/lib/${_WX_TOOL}${_WX_ARCH}_dll                 # prefer shared
        ${WX_ROOT_DIR}/lib/${_WX_TOOL}${_WX_TOOLVER}${_WX_ARCH}_lib
        ${WX_ROOT_DIR}/lib/${_WX_TOOL}${_WX_ARCH}_lib
        DOC "Path to wxWidgets libraries"
        NO_DEFAULT_PATH)

    ## ...
endif ()

결국, wx-base 라이브러리의 위치가 C:\wxWidgets-3.1.0\lib\gcc_dll\libwxbase31u.a와 같은 경로에 위치해야 한다.

또한 MinGW의 경우 Components 순서가 중요하다.

# Note that for MinGW users the order of libs is important!
find_package(wxWidgets COMPONENTS net gl core base)

ExternalProject

외부 프로젝트를 적용한다. 일괄적인 빌드 순서에 따라 적용된다.

Example

아래는 zlib을 다운받아 설치하는 예제이다.

include (ExternalProject)

set (DEP_PREFIX_DIR  "${CMAKE_BINARY_DIR}/dep/source")
set (DEP_INSTALL_DIR "${CMAKE_BINARY_DIR}/dep/local")

ExternalProject_Add (zlib
    PREFIX "${DEP_PREFIX_DIR}"
    #--Download step--------------
    URL "http://www.zlib.net/zlib-1.2.11.tar.gz"
    URL_MD5 "1c9f62f0778697a09d36121ead88e08e"
    #--Configure step-------------
    CMAKE_ARGS "-DCMAKE_MACOSX_RPATH=TRUE"
               "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
               "-DCMAKE_INSTALL_PREFIX=${DEP_INSTALL_DIR}"
    #--Output logging-------------
    LOG_DOWNLOAD 1
    )

ProcessorCount

아래와 같이 프로세스 개수를 확인할 수 있다.

include (ProcessorCount)
ProcessorCount (_process_count)
message ("process: ${_process_count}")

CMakeParseArguments

As an example here a my_install() macro, which takes similar arguments as the real install() command:

function(MY_INSTALL)
  set(options OPTIONAL FAST)
  set(oneValueArgs DESTINATION RENAME)
  set(multiValueArgs TARGETS CONFIGURATIONS)
  cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
  ...

Assume my_install() has been called like this:

my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)

After the cmake_parse_arguments() call the macro will have set the following variables:

MY_INSTALL_OPTIONAL = TRUE
MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
MY_INSTALL_DESTINATION = "bin"
MY_INSTALL_RENAME = "" (was not used)
MY_INSTALL_TARGETS = "foo;bar"
MY_INSTALL_CONFIGURATIONS = "" (was not used)
MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"

You can then continue and process these variables.

GenerateExportHeader

Windows Symbol export

To try this out on an existing project, run

$ cmake -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=TRUE -DBUILD_SHARED_LIBS=TRUE

on a CMake project. This should turn all add_library calls that do not explicitly specify build type into shared builds. If there are no global data variables in the project, all libraries will be built as DLLs with no errors. If you run into undefined symbols, check for global data like static data members of classes. The easiest way to handle the global data is to use the CMake GenerateExportHeader module like this:

add_library(mylibrary ${mylibrary_SOURCES})
# add these lines
include(GenerateExportHeader)
generate_export_header(mylibrary)

FindwxWidgets

Find a wxWidgets (a.k.a., wxWindows) installation.

Could NOT find wxWidgets in Windows

만약, Windows에서 wxWidgets를 MSYS를 사용하여 설치했을 때, 아래와 같이 적용해 보자.

set (wxWidgets_ROOT_DIR "C:\\wxWIdgets")
set (CMAKE_CROSSCOMPILING  YES) # Force setting: wxWidgets_FIND_STYLE = unix

FetchContent

Examples

How to create a module

파일을 검색할 경우 아래와 같은 명령을 사용하면 된다.

  • find_file
  • find_library
  • find_package
  • find_path
  • find_program

그리고 mark_as_advanced명령으로 캐시를 만든다.