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

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

외부 라이브러리 포함하기

프로젝트에서 외부 라이브러리를 사용할 때, 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 파이프라인 연동에 대해 살펴보겠습니다.

반응형