외부 라이브러리 추가 방법
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
- PUBLIC: 라이브러리를 사용하는 타겟과 그 타겟을 사용하는 다른 타겟 모두에 종속성을 전달한다.
- PRIVATE: 라이브러리를 사용하는 타겟에만 종속성을 전달한다.
- INTERFACE: 라이브러리를 사용하는 타겟에는 종속성을 전달하지 않고, 그 타겟을 사용하는 다른 타겟에만 전달한다.
예를 들어, 다음 코드는 MyTarget
이 MyLibrary
를 PRIVATE
으로 링크하고, MyInterfaceLib
를 INTERFACE
로 링크하는 경우이다:
target_link_libraries(MyTarget PRIVATE MyLibrary INTERFACE MyInterfaceLib)
이 설정에서 MyLibrary
는 MyTarget
에만 종속성이 적용되며, MyInterfaceLib
는 MyTarget
을 사용하는 타겟에 종속성이 전달된다.
라이브러리 경로 및 헤더 경로 설정
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_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
를 가져올 수 있다.
관련 자료:
- CMake 공식 문서: https://cmake.org/documentation/
- Kitware CMake Tutorial: https://cmake.org/cmake/help/latest/guide/tutorial/index.html