외부 라이브러리 추가 방법

CMake에서 외부 라이브러리를 추가하는 방법은 크게 세 가지로 나눌 수 있다. 첫째는 find_package() 함수를 사용하는 방법, 둘째는 add_subdirectory()를 사용하는 방법, 셋째는 ExternalProject_Add()를 사용하는 방법이다. 이 방법들은 각각의 상황에 맞게 사용할 수 있으며, 외부 라이브러리의 소스 코드 위치와 빌드 방법에 따라 적절한 방법을 선택해야 한다.

find_package() 함수 사용

find_package() 함수는 시스템에 설치된 패키지나 라이브러리를 검색하고, 그 정보를 CMake에 제공하는 방법이다. CMake는 다양한 패키지 구성 파일(CMake configuration files, Config.cmake 또는 Find<Package>.cmake 파일)을 통해 라이브러리의 위치, 헤더 파일 경로, 라이브러리 파일 등을 찾아낸다. 이 방법은 보통 외부 라이브러리가 이미 시스템에 설치되어 있을 때 사용된다.

예를 들어, Eigen3 라이브러리를 사용하는 경우, 다음과 같이 find_package() 함수를 사용할 수 있다:

find_package(Eigen3 REQUIRED)
target_link_libraries(MyTarget PRIVATE Eigen3::Eigen)

이 코드에서 REQUIRED는 해당 패키지가 필수임을 의미하며, 찾지 못할 경우 CMake가 오류를 발생시킨다. target_link_libraries() 함수는 대상(MyTarget)에 라이브러리를 연결하는 역할을 한다.

add_subdirectory() 함수 사용

add_subdirectory() 함수는 외부 라이브러리의 소스 코드를 직접 프로젝트에 포함시키는 방법이다. 이 방법은 외부 라이브러리가 CMake를 사용하여 빌드되는 경우에 유용하다. 라이브러리 소스 코드를 프로젝트 디렉토리에 포함시키고, CMakeLists.txt 파일에서 해당 디렉토리를 추가하면 된다.

예를 들어, 프로젝트에 MyLibrary라는 외부 라이브러리를 포함시키려면 다음과 같이 설정할 수 있다:

add_subdirectory(external/MyLibrary)
target_link_libraries(MyTarget PRIVATE MyLibrary)

이렇게 하면 MyLibrary는 프로젝트의 일부로 빌드되며, MyTarget에 링크된다. 이 방법은 라이브러리를 소스 코드 레벨에서 제어할 수 있다는 장점이 있지만, 프로젝트의 크기와 빌드 시간을 증가시킬 수 있다.

ExternalProject_Add() 함수 사용

ExternalProject_Add() 함수는 외부 라이브러리를 별도의 빌드 단계에서 가져오고 빌드하는 방법이다. 이 방법은 외부 라이브러리가 독립적으로 빌드될 필요가 있거나, 다양한 빌드 시스템을 사용할 때 유용하다. 이 함수는 외부 라이브러리를 다운로드, 구성, 빌드, 설치하는 작업을 CMake 스크립트 내에서 자동으로 수행한다.

예를 들어, 외부 프로젝트로 MyExternalProject를 추가하려면 다음과 같이 할 수 있다:

include(ExternalProject)
ExternalProject_Add(
    MyExternalProject
    GIT_REPOSITORY https://github.com/user/MyExternalProject.git
    CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
)

이 코드는 Git 리포지토리에서 소스를 가져와서 별도의 빌드 디렉토리에서 빌드하고, 설치하는 과정까지 포함한다. CMAKE_ARGS 옵션을 통해 외부 프로젝트에 전달할 CMake 인자를 설정할 수 있다.

타겟 종속성 관리

CMake에서는 target_link_libraries() 함수를 통해 타겟의 종속성을 관리한다. 이 함수는 대상 타겟에 필요한 라이브러리를 연결하며, 타겟 간의 종속성을 명확하게 정의하는 데 사용된다. 종속성은 PUBLIC, PRIVATE, INTERFACE의 세 가지 범위로 나눌 수 있다.

PUBLIC, PRIVATE, INTERFACE

예를 들어, 다음 코드는 MyTargetMyLibraryPRIVATE으로 링크하고, MyInterfaceLibINTERFACE로 링크하는 경우이다:

target_link_libraries(MyTarget PRIVATE MyLibrary INTERFACE MyInterfaceLib)

이 설정에서 MyLibraryMyTarget에만 종속성이 적용되며, MyInterfaceLibMyTarget을 사용하는 타겟에 종속성이 전달된다.

라이브러리 경로 및 헤더 경로 설정

CMake에서 외부 라이브러리의 경로를 설정할 때는 include_directories()link_directories() 함수를 사용할 수 있다. 그러나 현대적인 CMake에서는 target_include_directories()target_link_directories()를 사용하는 것이 권장된다.

target_include_directories()

target_include_directories() 함수는 특정 타겟에 대해 헤더 파일 경로를 설정한다. 이 함수도 PUBLIC, PRIVATE, INTERFACE의 범위를 가지며, 각 범위는 헤더 파일 경로가 어떻게 전달될지 결정한다.

예를 들어, 다음 코드는 MyTarget에 대해 MyLibrary의 헤더 파일 경로를 PUBLIC으로 설정하는 방법이다:

target_include_directories(MyTarget PUBLIC ${MYLIBRARY_INCLUDE_DIR})

이 설정은 MyTarget과 그 타겟을 사용하는 모든 타겟에 MYLIBRARY_INCLUDE_DIR 경로를 포함시킨다.

target_link_directories() 함수는 특정 타겟에 대해 라이브러리 파일의 경로를 설정한다. 하지만, 이 함수는 보통 잘 사용되지 않으며, 대신 target_link_libraries() 함수에서 라이브러리의 절대 경로를 직접 지정하는 것이 일반적이다.

패키지 구성 파일 생성

프로젝트가 설치될 때 다른 프로젝트에서 사용할 수 있도록 CMake 패키지 구성 파일(Config.cmake 파일)을 생성할 수 있다. 이를 통해 사용자는 find_package()를 사용하여 해당 라이브러리를 쉽게 사용할 수 있다.

install() 함수와 export() 함수

패키지 구성 파일을 생성하려면, install() 함수와 export() 함수를 사용한다. 이 함수들은 타겟과 관련된 파일들을 설치하고, 타겟을 내보내는 역할을 한다.

예를 들어, 다음과 같이 설정할 수 있다:

install(TARGETS MyLibrary
    EXPORT MyLibraryTargets
    ARCHIVE DESTINATION lib
    LIBRARY DESTINATION lib
    RUNTIME DESTINATION bin
    INCLUDES DESTINATION include
)

install(EXPORT MyLibraryTargets
    FILE MyLibraryConfig.cmake
    DESTINATION lib/cmake/MyLibrary
)

이 설정은 MyLibrary 타겟을 설치하고, MyLibraryConfig.cmake 파일을 생성하여 lib/cmake/MyLibrary 경로에 설치한다. 이렇게 하면 다른 프로젝트에서 find_package(MyLibrary CONFIG REQUIRED)를 사용하여 쉽게 MyLibrary를 가져올 수 있다.


관련 자료: