이번 포스트에서는 C/C++ 프로젝트를 빌드하는 툴인 CMAKE에 대하여 알아보자.

학교에서 C나 C++ 프로그래밍을 배운 경우 대부분의 수업에서는 Visual Studio 라는 MS의 툴을 사용하게 된다. 이경우 이 IDE에서 빌드까지 자동적으로 해주기 때문에 빌드에 대한 고민은 별로 할 필요가 없다.
C++ 전용 Visual Studio IDE는 mac에서는 지원을 하지 않기 때문에 mac유저들은 기본으로 내장되어 있는 Xcode나 CLION 이라는 jetbrain사의 IDE를 사용하여 C++을 빌드한다.
Xcode 인 경우는 Visual Studio처럼 클릭 한번에 알아서 빌드를 해주기 때문에 빌드 과정에 대해서 별로 신경 쓸 필요가 없다. 하지만 CLION 이라는 IDE는 오픈 플랫폼이며 이러한 오픈플랫폼이라는 성질을 유지하기 위해 CMAKE라는 빌드 툴을 이용하여 빌드 기능을 지원한다.
(오픈 플랫폼이란 어느 운영체제든지 상관없이 동일하게 작동하는 것을 말한다.)

만약 이러한 IDE (개발 환경 도구)들을 사용하지 않고 리눅스 환경에서 vim으로 작업을 할경우에도 CMAKE라는 빌드 툴을 사용해야만 한다.

여기서 이런 질문이 나올 수 있다.

굳이 CMAKE를 배워야 하나?
당신이 만약 그저 학교 과제용 프로젝트를 하거나 간단한 프로토 타입 프로젝트를 할 경우 빌드 시스템에 대해서 깊게 고민할 필요는 없지만, 만약 규모가 큰 오픈소스를 참여하고자 한다면 CMAKE의 사용법을 알면 도움이 된다.
(대부분의 C++ 오픈소스 프로젝트는 CMAKE 빌드시스템을 지원하므로…)

자 이제 CMAKE를 사용하여 간단한 프로젝트를 돌려보기로 하자.

cmake_logo

이번 튜토리얼의 목차는 다음과 같다.

  • CMAKE 설치
  • Google Test 설치
  • CMAKE로 오픈소스를 빌드하는 방법
  • 자체 코드를 CMAKE로 Build 및 실행

CMAKE 설치

CMAKE 빌드시스템은 주로 linux 환경에서 사용이 되므로, linux 환경에서 튜토리얼을 진행하도록 하겠다.

Cmake download URL
위에 링크로 접속하여 가장 최신의 Unix/Linux Source를 다운로드를 받는다.

sudo apt-get install g++ # g++ 컴파일러 설치
sudo apt-get install make # make 프로그램 설치
sudo apt purge --auto-remove cmake # 기존에 cmake 프로그램이 있다면 삭제
cd /opt
wget https://github.com/Kitware/CMake/releases/download/v3.15.0-rc1/cmake-3.15.0-rc1.tar.gz   # 2019년 6월 19일자 기준 가장 최신

tar -xvf cmake-3.15.0-rc1.tar.gz # 파일의 이름은 버전마다 다를 수 있음
mv cmake-3.15.0-rc1.tar.gz cmake 
cd cmake
sudo ./bootstrap   # 제공되는 설치용 script파일을 사용하자.
make -j4 # make 프로그램을 통해 빌드
sudo make install # 빌드한 프로그램을 기존의 컴퓨터에 설치
cmake --version  # 설치한 cmake 프로그램 버전 확인

만약 cmake 설치 이후에도 cmake 커맨드를 인식하지 못한다면 (cmake –version 커맨드시 오류날 경우)

    vi ~/.bashrc # 실행경로 추가를 위해
    # .bashrc 마지막줄에 추가 -> PATH=$PATH:/opt/cmake/bin
    source ./bashrc  # bashrc 업데이트

Google test 설치 (우분투 패키지 이용)

이제 Google test를 설치해보자.

google test URL

Google test는 C++ 프로그램을 테스트하기 위한 라이브러리로써, 오픈소스 프로그램이다.

많은 오픈소스 프로젝트들이 사용하고 있는 라이브러리이기 때문에 이 튜토리얼에서도 역시 한번 적용해 보도록 하자.

설치 방법에는 두가지 방법이 있다.

  • ubuntu package를 사용한 다운로드 방법 (apt-get)
    sudo apt-get install libgtest-dev # google test설치

CMAKE로 오픈소스를 빌드하는 방법

  • source 에서 다운로드 하는 방법 (github)
    git clone https://github.com/google/googletest.git # google test git clone
    cd googletest
    mkdir build && cd build
    cmake ..
    make -j4
    sudo make install
    cmake --help-module-list # cmake 모듈 list에 google test가 있는지 확인

소스에서 직접 빌드하여 다운을 받을 경우 CMAKE를 사용하게 되는데 잠시 간단히 설치 과정 커맨드들을 살펴보자

    mkdir build && cd build
    cmake ..

git clone 하여 받은 프로젝트에서는 이미 CMakeList.txt라는 파일이 존재하고, 그 안에는 빌드 과정을 쉘 스크립트 처럼 작성해 두었다.

build 라는 폴더를 만들어서 빌드한 결과물을 폴더안에 넣어서 따로 분리하기 위해, mkdir build 커맨드를 치고, cmake .. 라는 커맨드로 build 폴더 밖에 있는 CMakeLists.txt 를 cmake로 실행 시킨다.

cmake 커맨드를 치고 나면, cmake가 Makefile을 생성하며 이 make 파일을 실행

    make -j4

이전에 설치하였던 make 커맨드로 cmake가 생성한 makefile을 실행시켜서 build 작업을 시작한다.
(-j4 옵션은 4개의 스레드로 빌드작업을 진행한다는 의미)

    sudo make install

빌드한 google test 프로그램을 컴퓨터에 설치한다.
(여기서 컴퓨터에 설치한다는 뜻은, /usr/local/bin 에 저장한다는 의미)

오픈소스를 빌드하고 그냥 사용만 하려면, 지금까지 언급한 내용으로도 불편함 없이 사용할 수 있다. 하지만 새로운 기능을 추가하고 커밋을 해야할 경우 CMakeLists.txt 파일을 수정해야할 때가 있다.

프로젝트 구성도

이제 직접 오픈소스를 만들어서 CMake로 빌드를 할수 있도록 해보자.

udemy 강의에서 제공해주는 오픈소스를 활용해 보자.

    git clone https://github.com/apolol92/udemy_cmake_tutorial_01.git

프로젝트는 크게 두가지 폴더로 이루어져 있다.

  • cmake_project2
  • command line calculator

일단 command line calculator 프로젝트를 통하여 공부를 해보자.

    cd udemy_cmake_tutorial_02-master
    프로젝트의 구성도
    +-- cmake_project2
    |   +- CMakeLists.txt
    |   +- hello.cc
    +-- command_line_calculator
    |   +- src
    |       +- app
    |           +- CMakeLists.txt
    |           +- src
    |               +- main.cc
    |       +- calculator
    |           +- CMakeLists.txt
    |           +- include
    |               +- calculator.h
    |           +- src
    |               +- calculator.cc
    |           +- test
    |               +- test_calculator.cc
    |       +- CMakeLists.txt

위의 프로젝트 구성도를 보면 크게 두개의 프로젝트가 있다.

먼저 command_line_calculator 프로젝트를 보면, app과 calculator 로 크게 나뉜다. calculator는 라이브러리를 만드는 부분이고, app은 그 라이브러리를 사용하는 어플리케이션 파트이다.
추후에 command_line_calculator 어플리케이션을 라이브러리화 시킨 뒤 cmake_project2 프로젝트에서 생성한 라이브러리를 사용할 계획이다.

이제 전체적인 구조를 봤으니, CMakeLists.txt 파일들의 위치를 살펴보자.
command_line_calculator 프로젝트의 src 디렉토리에 CMakeLists.txt 파일이 있으며, 이 파일은 다른 세부 디렉토리들을(app, calculator) 연결하여 하나의 프로젝트로 설정하는 역할을 한다. (자세한 내용은 뒷부분에…)
src 디렉토리에 있는 각각의 app, calculator 디렉토리도 역시 CMakeLists.txt 파일을 가지고 있으며, 각각의 파일은 자신의 디렉토리에 있는 src 파일들을 빌드하는 명령어를 가지고 있다.

따라서 command_line_calculator 프로젝트를 전체적으로 본다면, 각각 app 디렉토리와, calculator 디렉토리를 빌드하고 마지막으로 command_line_calculator 프로젝트를 빌드한다.

cmake_project2 프로젝트는 빌드된 command_line_calculator를 라이브러리를 사용하는 프로젝트로, 단 하나의 CMakeLists.txt로 빌드를 한다.

자 이제 각각의 CMakeLists.txt 내용을 살펴보자.

자체 코드를 CMAKE로 Build 및 실행

  • /command_line_calculator/src/CMakeLists.txt
    cmake_minimum_required(VERSION 3.10...3.14 FATAL_ERROR)
    project(command_line_calculator CXX)
    enable_testing()
    add_subdirectory(calculator)
    adD_subdirectory(app)

cmake_minimum_required –> cmake의 버전은 3.10에서부터 3.14사이로 두고, 에러가 날경우 FATAL_ERROR를 낸다.
project –> 프로젝트 명과 언어 설정을 한다 (C or CXX)
enable_testing –> google test를 작동시킨다.
add_subdirectory –> 프로젝트 내에 있는 소규모 디렉토리(각각 따로 빌드할)을 정한다.

  • /command_line_calculator/src/app/CMakeLists.txt
    add_executable(app src/main.cc)
    set_target_properties(app PROPERTIES CXX_STANDARD 17 CMAKE_CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO)
    target_link_libraries(app calculator)
    install(TARGETS app RUNTIME DESTINATION /home/kakao)

add_executable –> 소스코드를 실행 가능파일로 변경 (상위 디렉토리에서 빌드할때 사용)
set_target_properties –> C++ 버전을 17로 설정, standard, extension 적용 여부 설정
target_link_libraries –> calculator 라는 빌드된 라이브러리를 사용한다. (다음부분에서 정의, 빌드함)
install –> app을 빌드한 뒤에 컴퓨터에 설치 (경로 /home/kakao)

  • /command_line_calculator/src/calculator/CMakeLists.txt
    find_package(GTest REQUIRED)
    
    add_library(calculator STATIC src/calculator.cc)
    set_target_properties(calculator PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO)
    target_include_directories(calculator PUBLIC include)

    add_executable(runTestCalculator test/test_calculator.cc)
    set_target_properties(runTestCalculator PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO)
    target_include_directories(runTestCalculator PRIVATE ${GTEST_INCLUDE_DIRS} include)
    target_link_libraries(runTestCalculator ${GTEST_LIBRARIES} pthread calculator)

    add_test(testCalculator runTestCalculator)

    export(TARGETS calculator NAMESPACE ${PROJECT_NAME}:: FILE calculatorConfig.cmake)
    export(PACKAGE calculator)

find_package –> google test 모듈을 가져온다 (이미 컴퓨터에 설치되어 있어야 한다.)
add_library –> 소스코드를 라이브러리 파일로 변경 (app에서 이 라이브러리를 사용함)
set_target_properties –> 특성값 설정
target_include_directories –> calculator 라이브러리를 만드는데 쓰이는 include 디렉토리 추가
add_test –> 실행파일로 만든 테스트 파일을 최종 테스트 실행파일로 만듬.
export –> 빌드된 라이브러리의 namespace를 설정 및 라이브러리로 빌드.

이처럼 서브 디렉토리에 있는 각각의 CMakeLists.txt들이 빌드를 수행하고, 최종적으로 마지막 root 디렉토리에 있는 CMakeLists.txt 파일이 빌드할 수 있도록 한다. 이렇게 하여 command_line_calculator 프로젝트와 테스트프로그램을 빌드하였다.

/home/kakao 경로로 가보면 새로운 실행 파일이 생긴것을 확인할 수 있다.

마지막으로 이렇게 생성한 프로젝트 (라이브러리)를 cmake_project2에서 사용해 보자.

  • cmake_project2/CMakeLists.txt
    cmake_minimum_required(VERSION 3.10)
    project(another_project)
    find_package(calculator) # 위에서 만든 프로그램이 컴퓨터에 설치되어 있으므로 가능

    add_executable(my_program hello.cc능
    set_target_properties(my_program PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO)
    target_link_libraries(my_program command_line_calculator::calculator) # 이미 만든 라이브러리를 link 한다.

내용이 많았다…. 정리해 보자.

  • CMAKE는 오픈소스 C++ 프로젝트를 빌드할때 자주 사용된다 -> 왜? -> 오픈 플랫폼이라서.
  • 단지 오픈소스를 빌드하고 사용만 하고 싶다면, build 폴더를 생성하고 cmake 커맨드를 입력하면 빌드가 된다.
  • 만약 내가 기능을 추가하거나 새로운 오픈소스를 만들고 싶다면 디렉토리별로 CMakeLists.txt를 작성해야 하며, 차례대로 빌드되도록 해야한다.

references

CMAKE UDEMY 강의

⤧  Previous post Intrusion detection System