[모던 CMake] 외부 라이브러리와 패키지 관리

모던 CMake를 활용하여 효율적인 C++ 프로젝트 빌드 시스템을 구축하는 방법을 계속해서 알아보겠습니다. 이번 글에서는 외부 라이브러리를 포함하는 방법과 패키지 관리 시스템을 활용하여 프로젝트의 의존성을 관리하는 방법에 대해 다루겠습니다.

etc-image-0

외부 라이브러리 포함하기

프로젝트에서 외부 라이브러리를 사용할 때, CMake의 find_package() 명령어를 활용하여 해당 라이브러리를 찾고 연결할 수 있습니다.

find_package() 사용법

find_package(LibraryName REQUIRED)
  • LibraryName: 찾고자 하는 라이브러리의 이름입니다.
  • REQUIRED: 라이브러리를 찾지 못하면 빌드를 중단합니다.

예제: Boost 라이브러리 포함

find_package(Boost 1.71.0 REQUIRED COMPONENTS filesystem)

add_executable(MyApp src/main.cpp)

target_link_libraries(MyApp PRIVATE Boost::filesystem)
  • Boost::filesystem 타겟을 MyApp에 링크하여 Boost Filesystem 라이브러리를 사용할 수 있습니다.

패키지 관리 시스템과 CMake

외부 라이브러리를 보다 쉽게 관리하기 위해 패키지 관리 시스템을 사용할 수 있습니다. 대표적으로 vcpkgConda가 있습니다.

vcpkg를 사용한 라이브러리 관리

vcpkg는 Microsoft에서 제공하는 C++ 패키지 관리자입니다.

vcpkg 설정

  1. vcpkg 설치
  2. git clone https://github.com/Microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.sh
  3. 필요한 라이브러리 설치
  4. ./vcpkg install boost-filesystem
  5. CMake에서 vcpkg 사용 설정
  6. cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake

CMakeLists.txt 수정

vcpkg를 사용하면 find_package()를 통해 라이브러리를 쉽게 찾을 수 있습니다.

find_package(Boost REQUIRED COMPONENTS filesystem)

add_executable(MyApp src/main.cpp)

target_link_libraries(MyApp PRIVATE Boost::filesystem)

Conda를 사용한 라이브러리 관리

Conda는 다양한 프로그래밍 언어와 플랫폼에서 패키지와 환경을 관리할 수 있는 패키지 관리자입니다. 주로 Python 환경에서 사용되지만, C++ 라이브러리도 관리할 수 있습니다.

Conda 설정

  1. Conda 설치
  2. 새로운 Conda 환경 생성
  3. conda create -n my_project_env
  4. 환경 활성화
  5. conda activate my_project_env
  6. 필요한 라이브러리 설치
    conda install -c conda-forge boost
    
  7. Conda Forge 채널을 통해 C++ 라이브러리를 설치할 수 있습니다.

CMakeLists.txt 수정

Conda 환경에서 라이브러리를 설치하면, 해당 환경의 경로에 라이브러리가 설치됩니다. CMake에서 이 경로를 인식하도록 설정해야 합니다.

# Conda 환경 변수 설정
if(DEFINED ENV{CONDA_PREFIX})
    set(CONDA_PREFIX $ENV{CONDA_PREFIX})
else()
    message(FATAL_ERROR "Conda 환경이 활성화되지 않았습니다.")
endif()

# 라이브러리와 인클루드 디렉토리 설정
set(CMAKE_INCLUDE_PATH "${CONDA_PREFIX}/include" ${CMAKE_INCLUDE_PATH})
set(CMAKE_LIBRARY_PATH "${CONDA_PREFIX}/lib" ${CMAKE_LIBRARY_PATH})

find_package(Boost REQUIRED COMPONENTS filesystem)

add_executable(MyApp src/main.cpp)

target_link_libraries(MyApp PRIVATE Boost::filesystem)
  • ENV{CONDA_PREFIX}를 통해 현재 활성화된 Conda 환경의 경로를 가져옵니다.
  • CMAKE_INCLUDE_PATH와 CMAKE_LIBRARY_PATH에 Conda 경로를 추가하여 CMake가 해당 디렉토리에서 라이브러리를 찾을 수 있게 합니다.
  • 이제 find_package()를 통해 Conda 환경에 설치된 Boost 라이브러리를 찾을 수 있습니다.

Conda 환경에서 빌드

Conda 환경이 활성화된 상태에서 CMake를 실행하고 빌드를 진행합니다.

conda activate my_project_env
cmake -B build -S .
cmake --build build

FetchContent를 통한 라이브러리 포함

CMake의 FetchContent 모듈을 사용하여 외부 프로젝트를 직접 가져올 수 있습니다.

예제: GoogleTest 포함

include(FetchContent)

FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/release-1.11.0.zip
)

FetchContent_MakeAvailable(googletest)

enable_testing()

add_executable(MyTests tests/test.cpp)

target_link_libraries(MyTests PRIVATE gtest_main)

add_test(NAME MyTest COMMAND MyTests)
  • FetchContent_Declare()로 외부 프로젝트를 선언하고, FetchContent_MakeAvailable()로 다운로드하여 사용합니다.

패키지 설정 파일 생성

라이브러리를 다른 프로젝트에서 쉽게 사용할 수 있도록 패키지 설정 파일을 생성할 수 있습니다.

install()과 export()

add_library(MyLib src/mylib.cpp)

target_include_directories(MyLib PUBLIC include)

install(TARGETS MyLib EXPORT MyLibConfig
        DESTINATION lib)

install(EXPORT MyLibConfig
        DESTINATION lib/cmake/MyLib)

install(DIRECTORY include/
        DESTINATION include)
  • install() 명령어로 타겟과 설정을 설치하여 다른 프로젝트에서 find_package(MyLib CONFIG REQUIRED)로 사용할 수 있습니다.

예제 프로젝트 적용

디렉토리 구조

my_project/
├── CMakeLists.txt
├── include/
│   └── mylib.h
├── src/
│   └── mylib.cpp
└── tests/
    └── test.cpp

CMakeLists.txt 내용

cmake_minimum_required(VERSION 3.15)
project(MyProject)

add_subdirectory(src)
add_subdirectory(tests)

src/CMakeLists.txt

add_library(MyLib mylib.cpp)

target_include_directories(MyLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../include)

install(TARGETS MyLib EXPORT MyLibConfig
        ARCHIVE DESTINATION lib)

install(EXPORT MyLibConfig
        DESTINATION lib/cmake/MyLib)

install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../include/
        DESTINATION include)

tests/CMakeLists.txt

enable_testing()

add_executable(MyTests test.cpp)

target_link_libraries(MyTests PRIVATE MyLib gtest_main)

add_test(NAME MyTest COMMAND MyTests)

빌드 및 설치

cmake -B build -S .
cmake --build build
cmake --install build --prefix /usr/local

결론

이번 글에서는 외부 라이브러리를 프로젝트에 포함하는 다양한 방법과 패키지 관리 시스템을 활용한 의존성 관리에 대해 알아보았습니다. 특히, Conda를 사용하여 C++ 라이브러리를 관리하고 CMake 프로젝트와 연동하는 방법을 살펴보았습니다. 다음 글에서는 CMake를 활용한 테스트 설정과 CI/CD 파이프라인 연동에 대해 살펴보겠습니다.

반응형