1. CMake 소개
CMake는 소프트웨어 개발에서 프로젝트를 빌드하고 의존성을 관리하는 데 도움을 주는 툴이다. 크로스 플랫폼 지원과 자동 의존성 관리를 통해 복잡한 프로젝트에서도 일관된 빌드 환경을 유지할 수 있다. 프로젝트 빌드 규칙은 CMakeLists.txt 파일에 정의되며, 플랫폼에 맞는 빌드 시스템(Ninja, Make, Visual Studio 등)으로 변환된다.
- 주요 장점
- 여러 플랫폼에서 동일한 빌드 스크립트를 사용 가능, 자동 의존성 관리
- 주요 사용 사례
- 대규모 프로젝트의 멀티 플랫폼 빌드, 라이브러리 의존성 관리
2. CMake 설치 및 환경 설정
CMake는 Windows, Linux, Docker 등 다양한 플랫폼에서 설치할 수 있으며, 설치 후 PATH 설정을 통해 명령어를 사용할 수 있게 한다.
설치 방법
- Windows
- CMake 공식 웹사이트에서 설치 파일을 다운로드하여 설치한다. 설치 중 Add CMake to the system PATH 옵션을 체크하는 것이 편리하다.
- Linux
- sudo apt install cmake 명령어로 설치할 수 있으며, Red Hat이나 CentOS에서는 yum을 통해 설치 가능하다. 예를 들어, 최신 버전을 설치하려면 공식 사이트에서 소스 파일을 다운로드하여 빌드할 수 있다.
-
# ./bootstrap && make && sudo make install
- Docker
- Docker 이미지를 사용해 격리된 환경에서 CMake를 실행할 수 있다.
-
docker pull kitware/cmake docker run --rm -it kitware/cmake cmake --version
설치 확인
설치가 완료되면 cmake --version을 통해 설치가 정상적으로 완료되었는지 확인한다.
3. CMakeLists.txt 기본 구조와 주요 명령어
CMake의 모든 프로젝트는 CMakeLists.txt 파일을 통해 빌드 설정을 정의한다. 주요 명령어는 아래와 같다.
- cmake_minimum_required(VERSION 3.10)
- 프로젝트에 필요한 최소 CMake 버전을 지정한다.
- project(MyProject)
- 프로젝트의 이름과 사용 언어를 지정한다.
- add_executable(MyApp main.cpp)
- main.cpp 파일로부터 실행 파일 MyApp을 생성한다.
- target_link_libraries(MyApp MyLibrary)
- 생성된 타겟 MyApp에 MyLibrary를 연결한다.
기본 예제
cmake_minimum_required(VERSION 3.10)
project(MyProject)
# 실행 파일 생성
add_executable(MyApp main.cpp)
# 라이브러리 연결
target_link_libraries(MyApp MyLibrary)
추가 명령어
- add_library
- 정적 또는 동적 라이브러리를 생성한다.
- include_directories
- 특정 디렉토리를 포함 디렉토리로 추가한다.
- set
변수를 설정하여 전역이나 로컬 스코프에서 사용할 수 있게 한다.
4. 외부 라이브러리 연결 및 의존성 관리
CMake는 외부 라이브러리를 자동으로 검색하고 추가할 수 있는 find_package, include_directories, target_link_libraries와 같은 명령어를 제공한다. 이를 통해 프로젝트의 의존성을 간편하게 설정하고 관리할 수 있다.
- find_package(MyLibrary REQUIRED)
- MyLibrary 라이브러리를 프로젝트에 추가한다.
- include_directories(${MyLibrary_INCLUDE_DIRS})
- MyLibrary의 헤더 파일 경로를 추가한다.
- target_link_libraries(MyApp ${MyLibrary_LIBRARIES})
- MyLibrary를 MyApp 타겟에 연결한다.
예제
find_package(MyLibrary REQUIRED)
include_directories(${MyLibrary_INCLUDE_DIRS})
target_link_libraries(MyApp ${MyLibrary_LIBRARIES})
5. 빌드 시스템 설정 및 하위 프로젝트 관리
대규모 프로젝트에서는 여러 모듈을 하위 디렉토리로 나누어 관리하는 것이 유용하다. add_subdirectory와 aux_source_directory 같은 명령어를 활용해 프로젝트 내 여러 디렉토리를 포함시키고, 빌드 시 자동으로 관리할 수 있다.
- add_subdirectory(src): src 디렉토리를 하위 디렉토리로 추가하고 해당 디렉토리의 CMakeLists.txt 파일을 빌드에 포함시킨다.
- aux_source_directory(<dir> <variable>): 지정된 디렉토리의 모든 소스 파일을 변수에 저장한다.
예제
add_subdirectory(src)
add_subdirectory(lib)
# src와 lib 디렉토리 각각에 있는 CMakeLists.txt 파일을 통해 빌드를 수행
6. 고급 기능: 정적 분석, 단위 테스트, 패키지 관리
CMake는 빌드 시스템뿐 아니라 코드 품질 관리, 패키지 관리까지 통합하여 지원한다.
정적 분석
target_compile_options를 사용하여 코드의 정적 분석 옵션을 추가할 수 있다. 예를 들어, 컴파일러 경고를 강화하거나 특정 정적 분석 옵션을 추가하여 코드 품질을 높일 수 있다.
target_compile_options(MyApp PRIVATE -Wall -Wextra -Werror)
단위 테스트
CMake는 Google Test와 같은 단위 테스트 프레임워크와 함께 사용할 수 있다. 테스트 타겟을 정의하고 add_test 명령으로 자동 테스트를 설정할 수 있다.
add_executable(MyTests test.cpp)
target_link_libraries(MyTests gtest gtest_main)
add_test(NAME RunTests COMMAND MyTests)
패키지 관리
패키지 관리에 유용한 find_package와 install 명령어를 사용해 의존성 패키지를 자동으로 설치하고, 컴파일 환경을 구성할 수 있다.
install(TARGETS MyApp DESTINATION bin)
install(FILES config.h DESTINATION include)
7. CMake 활용 예제
CMake 예제를 통해 실전에서 사용법을 익힐 수 있다. 예제는 간단한 C/C++ 프로젝트 설정부터 시작해 Docker와 같은 컨테이너 환경에서 빌드 환경을 테스트하거나, 여러 라이브러리와 실행 파일을 관리하는 대규모 프로젝트를 설정하는 방법까지 포함한다.
기본 프로젝트 설정 예제
- 프로젝트 초기화
- CMakeLists.txt 파일을 생성하고 프로젝트를 정의한다.
- 라이브러리 연결
- 외부 라이브러리를 찾고 빌드에 포함시킨다.
- 빌드 및 실행
- cmake 명령어를 사용해 빌드를 수행하고, 실행 파일을 실행한다.
Docker를 이용한 CMake 빌드 예제
Docker에서 CMake 환경을 설정하면 빌드를 격리하여 실행할 수 있다. Dockerfile을 사용하여 빌드 환경을 설정하고, CMake를 이용해 프로젝트를 빌드하는 예제는 다음과 같다.
FROM ubuntu:latest
RUN apt-get update && apt-get install -y cmake g++
COPY . /project
WORKDIR /project
RUN cmake . && make
참조URL
https://sonseungha.tistory.com/372?category=710904
https://www.tuwlab.com/index.php?mid=ece&page=2&document_srl=27193
https://gitlab.kitware.com/cmake/community/-/wikis/doc/tutorials/How-To-Find-Libraries
https://gist.github.com/luncliff/6e2d4eb7ca29a0afd5b592f72b80cb5c#cmake-%ED%8A%9C%ED%86%A0%EB%A6%AC%EC%96%BC-lv1
https://github.com/ttroy50/cmake-examples
'기술 노트' 카테고리의 다른 글
애자일 선언과 소프트웨어 장인 정신: 더 나은 개발을 위한 나의 다짐 (0) | 2022.02.10 |
---|---|
형상 관리 도구의 선택: Git, SVN, 그리고 DevOps 환경에서의 최적화 (3) | 2022.02.09 |
개발과 운영의 경계를 허물다: 데브옵스와 실무 경험기 (1) | 2022.02.08 |
GitLab Runner 설치 및 설정 가이드 (0) | 2022.01.21 |
레거시 코드와의 씨름: C에서 C++로의 마이그레이션 여정 (0) | 2021.07.05 |