Helio Setup


Setup

📦 환경

  • OS: CentOS 9
  • g++ --version -> g++ (GCC) 11.5.0     20240719 (Red Hat 11.5.0-2)

📦 helio 프로젝트 다운 받기

  • helio 프로젝트 다운 받기.
    $ git clone https://github.com/romange/helio.git -> helio 디렉토리가 만들어지고 그 안에 다운 받아짐.
  • redis user에 sudo 권한 추가하기 (sudo 권한이 없으면)
  • 필요한 소프트웨어를 설치합니다.
    "Development Tools" -> 83 Packages 설치 완료.

📦 install-dependencies.sh

필요한 소프트웨어들과 Boost C++ 라이브러리를 설치합니다.
필요한 소프트웨어들을 apt(Advanced Package Tool)로 설치하는데, apt는 Debian/Ubuntu 계열에서 사용하므로 여기 CentOS 9에서는 dnf(Dandified Yum)를 사용합니다.
apt install은 아래와 같이 주석 처리했고, dnf로 설치했습니다.
# apt install -y cmake libunwind-dev zip bison ninja-build autoconf-archive libtool
# apt install -y curl

◼️ dnf로 설치

$ sudo dnf install -y cmake libunwind-devel zip bison ninja-build autoconf-archive libtool
$ sudo dnf install -y curl

◼️ 설치 확인

                                Name -> Architecture Version-Release
$ dnf list installed cmake -> x86_64 3.26.5-2.el9
$ dnf list installed libunwind-devel -> x86_64 1.6.2-1.el9
$ dnf list installed zip -> x86_64 3.0-35.el9
$ dnf list installed bison -> x86_64 3.7.4-5.el9
$ dnf list installed autoconf-archive -> noarch 2019.01.06-9.el9
$ dnf list installed libtool -> x86_64 2.4.6-45.el9
$ dnf list installed curl -> x86_64 7.76.1-29.el9

◼️ ninja-build

ninja-build는 dnf로 설치되지 않습니다.
$ sudo dnf update epel-release
$ sudo dnf install ninja-build -> No match for argument: ninja-build
참고로 Debian/Ubuntu 계열에서는 apt로 설치할 수 있는것으로 보입니다.

"CentOS 9" / "Rocky 9.5"에서는 다운받아 직업 설치(컴파일)했습니다.

  • $ git clone https://github.com/ninja-build/ninja.git -> ninja 디렉토리가 만들어지고 그 안에 다운 받아짐.
  • $ cd ninja
  • $ cmake -Bbuild-cmake
    이 명령어는 CMake 빌드 디렉토리를 설정하고, 그 안에 필요한 빌드 파일들을 생성합니다.
    • '-B' 옵션은 빌드 파일을 저장할 디렉토리를 지정하는 데 사용됩니다. 여기서는 'build-cmake'라는 이름의 디렉토리가 빌드 파일을 저장할 위치로 지정되었습니다.
    • 이 명령을 실행하면 CMake가 프로젝트의 'CMakeLists.txt' 파일을 읽고, 'build-cmake' 디렉토리에 Makefile 또는 Visual Studio 솔루션 파일 등의 빌드 파일을 생성하게 됩니다.
  • $ cmake --build build-cmake
    이 명령어는 앞서 생성된 빌드 파일을 이용해 실제로 프로젝트를 빌드합니다.
    • '--build' 옵션 다음에 빌드 디렉토리를 지정함으로써, 지정된 디렉토리에 있는 빌드 파일을 사용하여 컴파일 및 링크 작업을 수행합니다.
    • 결과적으로, 프로젝트의 실행 파일이나 라이브러리가 생성됩니다.
  • $ sudo cp build-cmake/ninja /usr/local/bin/ -> 어디서나 실행할 수 있도록 ninja 파일을 복사
  • $ ninja --version -> 1.13.0.git -> 버전 확인

◼️ 소스 설명 (install-dependencies.sh)

  • 1. 의존성 패키지 설치
    • set -e 명령어는 Bash 스크립트에서 에러 처리를 보다 엄격하게 하기 위해 사용됩니다.
      set -e를 사용하면 스크립트 내에서 실행된 명령어가 비정상적으로 종료되었을 때(즉, 반환 값이 0이 아닌 경우) 스크립트 실행을 즉시 중단합니다.
      이는 스크립트의 중간에서 오류가 발생했을 때 계속 진행되지 않도록 하여, 오류를 일찍 감지하고 적절히 대응할 수 있게 합니다.
    • apt install: 여러 패키지를 설치합니다.
      - cmake: 프로젝트를 구성하는 데 필요한 빌드 시스템 생성 도구입니다.
      - libunwind-dev: 비동기식 스택 언와인딩을 지원하는 라이브러리로 디버깅에 유용합니다.
      - zip: 압축 파일을 다룰 때 사용됩니다.
      - bison: 파서 생성기입니다.
      - ninja-build: 빠르고 효율적인 빌드 시스템입니다.
      - autoconf-archive, libtool: 프로젝트 빌드와 라이브러리 관리에 필요한 툴들입니다.
      - curl: Boost 파일을 다운로드하는 데 필요합니다. 정작 소스에서는 wget을 사용한다.
    • 'g++ --version'은 설치된 g++의 버전을 출력하여, 설치가 제대로 되었는지 확인합니다.
  • 2. Boost 버전 설정 및 환경 변수 설정
    • 'BVER=1.76.0': Boost 버전 1.76.0을 지정합니다.
    • 'BOOST=boost_${BVER//./_}': 'BVER'에서 점을 밑줄로 변경하여 'boost_1_76_0' 형식으로 변환합니다.
    • 'export CXX=g++': Boost 설치에서 사용할 C++ 컴파일러로 'g++'을 지정합니다.
  • 3. Boost 설치 함수 ('install_boost')
    이 함수는 Boost 라이브러리를 '/opt/boost_1_76_0' 경로에 설치합니다.
  • 3-1. Boost 다운로드 및 압축 해제
    • 'wget' 명령으로 'Boost' 다운로드 링크(url)에서 'boost_1_76_0.tar.bz2' 파일을 다운로드합니다.
    • 압축을 해제한 후 소유권을 변경합니다('chown' 명령).
  • 3-2. Boost 빌드와 설치
    • Boost 빌드를 위한 설정 파일을 생성하는 'bootstrap.sh'를 실행하며, '--without-libraries' 옵션으로 특정 라이브러리는 제외하여 빌드 시간을 단축합니다.
    • Boost의 빌드 도구인 'b2'로 라이브러리를 컴파일합니다.
    • 컴파일 플래그로 '-std=c++14 -Wno-deprecated-declarations'를 사용하여 C++14 표준을 따르며,
      '-Wno-deprecated-declarations' 옵션을 통해 경고를 숨깁니다.
  • 3-3. 권한 변경 및 원래 디렉토리 이동
    • '/opt/${BOOST}' 아래 모든 파일의 소유권을 'SUDO_USER'로 변경하여 권한을 사용자에게 넘깁니다.
    • popd: 원래 디렉토리로 돌아옵니다.
  • 4. Boost 설치 여부 확인 및 링크 생성
    • '/opt/${BOOST}/lib'에 Boost 라이브러리가 없으면 'install_boost' 함수를 호출하여 설치를 진행합니다.
    • '/opt/boost' 심볼릭 링크가 없으면, '/opt/boost'에서 '/opt/${BOOST}'로 연결되는 심볼릭 링크를 만듭니다.

    이 스크립트는 의존성과 Boost 라이브러리 설치를 자동으로 수행하며, 필요한 파일을 다운로드 및 컴파일하는 복잡한 설정을 자동화하여 'helio' 프로젝트 환경을 구성하는 데 중요한 역할을 합니다.
  • 설명 (chatgpt)

◼️ 실행

여기서는 Boost 버전을 1.86.0 (2024년 8월 14일)로 수정해서 실행했습니다.
실행 로그를 그대로 기재했습니다.
실행 후 '/tmp/boost'와 '/opt' 디렉토리 내용은 아래와 같습니다.

  • '/tmp/boost' 디렉토리: size 1.4GB
    drwxr-xr-x. 10 redis redis 4096 Nov 14 01:03 boost_1_86_0
    -rw-r--r--. 1 redis redis 126220652 Aug 14 23:19 boost_1_86_0.tar.bz2 -> size 121MB
  • '/opt' 디렉토리: size 299MB
    lrwxrwxrwx. 1 root root 17 Nov 14 01:26 boost -> /opt/boost_1_86_0
    drwxr-xr-x. 4 root root 32 Nov 14 01:09 boost_1_86_0

Boost 버전을 1.89.0 (2025년 11월 03일)로 수정해서 실행했습니다.
실행 로그를 그대로 기재했습니다.
실행 후 '/tmp/boost'와 '/opt' 디렉토리 내용은 아래와 같습니다.

  • '/tmp/boost' 디렉토리: size 1.7GB
    drwxr-xr-x 10 redis redis 4096 Nov 3 15:34 boost_1_89_0
    -rw-r--r-- 1 redis redis 154699732 Aug 14 10:26 boost_1_89_0.tar.bz2 -> size 148MB
  • '/opt' 디렉토리: size 311MB
    lrwxrwxrwx 1 root root 17 Nov 3 15:36 boost -> /opt/boost_1_89_0
    drwxr-xr-x 5 root root 45 Nov 3 15:36 boost_1_89_0

📦 blaze.sh

이 'blaze.sh' 스크립트는 CMake 빌드 환경을 설정하고 빌드 도구, 컴파일러, 빌드 타입 등을 설정하는데 사용됩니다.
$ blaze.sh -release -> Release 모드로 컴파일: build-opt 디렉토리 생성
$ blaze.sh <No option> -> Debug 모드로 컴파일: build-dbg 디렉토리 생성

examples 디렉토리에 있는 echo_server, raw_echo_server, ping_iouring_server를 컴파일하려면 build-opt 또는 build-dbg 디렉토리로 가서
$ ninja -j1 echo_server
이렇게 컴파일하면 됩니다.

◼️ ccache 설치

blaze.sh 안에서 사용되는 'ccache'에 대한 설명과 'hiredis'가 같이 설치되는 이유

'ccache'는 Linux에서 C/C++ 소스 코드를 컴파일할 때 캐시를 활용하여 컴파일 속도를 향상시키는 도구입니다. 일반적으로 코드 변경 없이 반복해서 컴파일하는 경우에도 컴파일러는 매번 코드를 컴파일해야 하는데, 'ccache'는 이전 컴파일 결과를 저장해두고 같은 소스 코드를 다시 컴파일할 때 저장된 결과를 재사용합니다. 이를 통해 불필요한 컴파일 시간을 줄이고, 빌드 속도를 크게 향상시킬 수 있습니다.

  • 'ccache'의 동작 방식
    1. 캐시 확인: 컴파일 명령어가 실행되면, 'ccache'는 해당 명령어, 소스 파일 내용, 컴파일러 옵션 등을 조합한 해시 값을 생성하여 이전 결과가 있는지 캐시에서 확인합니다.
    2. 캐시 재사용 또는 컴파일: 캐시에 동일한 결과가 있으면 그 결과를 즉시 반환하고, 없다면 컴파일러를 호출해 새로 컴파일한 후 결과를 캐시에 저장합니다.
    3. 결과 반환: 컴파일이 완료되면 결과가 저장되거나 캐시된 출력 파일을 반환하여 빌드가 완료됩니다.
    'ccache'는 주로 C/C++ 프로젝트에 많이 사용되지만, 다른 컴파일러나 링커에도 사용이 가능하며, Jenkins와 같은 CI/CD 파이프라인에서 빌드 시간을 절약하는 데 유용합니다.
  • 'ccache'와 'hiredis'의 관계
    'hiredis'는 Redis 데이터베이스와 통신하기 위한 C 라이브러리입니다.
    기본적으로 'ccache'는 'hiredis'에 의존하지 않지만, 'ccache'를 Redis를 백엔드 캐시 스토리지로 사용할 수 있도록 설정할 수 있습니다.
    이 경우 캐시 데이터를 로컬 디스크에 저장하는 대신 Redis 서버에 저장하고 불러오게 됩니다.

    Redis 캐시 백엔드를 사용하면 여러 빌드 서버나 개발 환경에서 공유 캐시를 사용할 수 있어 빌드 효율성을 극대화할 수 있기 때문에, 'hiredis'가 'ccache'의 선택적 종속성(dependency)으로 추가될 수 있습니다.
    Redis를 사용하려는 설정이 아닌 경우에는 반드시 'hiredis'가 설치될 필요는 없습니다.
  • 'ccache' 설치 로그

⚛ 설명 (chatgpt)

◼️ patch 설치

리눅스에서 'patch'는 파일의 변경 사항을 적용하는 명령어로, 주로 텍스트 파일(예: 소스 코드 파일)의 수정 사항을 배포하고 적용할 때 사용됩니다.
'patch' 명령어는 일반적으로 'diff' 명령어로 생성된 차이 파일(패치 파일)을 입력으로 받아 파일에 변경 사항을 적용합니다.

  • 주요 사용 방법
    1. diff 명령어로 패치 파일 생성하기
    • 두 파일의 차이점을 비교하여 'patch' 명령어에 사용할 수 있는 패치 파일을 만듭니다.
      $ diff -u original_file modified_file > changes.patch
    • 'changes.patch' 파일에는 'original_file'과 'modified_file' 사이의 차이점이 저장됩니다.
    2. patch 명령어로 수정 사항 적용하기
    • 패치 파일을 원본 파일에 적용하여 변경 사항을 반영합니다.
      $ patch < changes.patch
    • 이 명령어는 현재 디렉토리의 파일을 자동으로 수정합니다.
      수정할 파일을 명시하고 싶다면 '-i' 옵션을 사용하여 패치 파일을 지정할 수도 있습니다.
    3. 디렉토리 단위로 패치 적용하기
    • 전체 디렉토리에서 파일 여러 개의 변경 사항을 패치 파일로 생성하고 적용할 수 있습니다.
      $ diff -ruN original_directory/ modified_directory/ > directory_changes.patch
      $ patch -p1 < directory_changes.patch
    • '-p' 옵션은 파일 경로의 상위 디렉토리 수준을 제어합니다. 보통 '-p1' 또는 '-p0'을 많이 사용합니다.
  • 옵션 요약
    • '-pN' : 파일 경로의 상위 디렉토리 수준을 제거하여 적용할 위치를 지정합니다.
    • '-R' : 패치 파일을 거꾸로 적용(변경 사항을 되돌림)합니다.
    • '--dry-run' : 실제 적용 없이 테스트로 패치가 성공적으로 적용될지 확인합니다.
  • 설치: $ sudo dnf install patch -> patch.x86_64 2.7.6-16.el9

'patch' 명령어는 소스 코드 관리, 특히 커널 코드 수정이나 오픈 소스 프로젝트에서 변경 사항을 공유하고 적용하는 데 매우 유용합니다.
⚛ 설명 (chatgpt)

◼️ blaze.sh 소스와 설명

blaze.sh 소스

소스 설명 ⚛ 설명 (chatgpt)

실행 로그

📦 kernel io_uring 설정

'echo_server'를 실행하면 다음과 같은 에러 메시지가 나옵니다.
"Error initializing io_uring: (1) Operation not permitted"
확인 결과 이 메시지는 util/fibers/uring_proactor.cc: UringProactor::Init()에서 io_uring_queue_init_params() 함수 실행 결과가 0보다 작으면 발생시킵니다.
이유는 io_uring이 비활성(disabled)이기 때문입니다.

해결 방법
"kernel.io_uring_disabled=0" '활성(enable)'으로 설정합니다.

설명: 이 파라미터는 io_uring 기능의 활성화 여부를 제어합니다.
    0: io_uring이 활성화되어 있습니다.
    1: io_uring이 비활성화되어 있습니다.
    2: io_uring이 기본적으로 비활성화되어 있으며, 특정 사용자 그룹에만 허용됩니다.


보충 설명

📦 CMake

CMake는 오픈 소스 빌드 시스템으로, 소프트웨어의 컴파일, 링크, 설치를 자동화하는 도구입니다.
여러 플랫폼에서 사용될 수 있으며, 복잡한 빌드 프로세스를 관리하는데 유용합니다.

  1. CMake의 개요
    • 목적: CMake는 소프트웨어 빌드 과정에서 반복적이고 복잡한 작업을 자동화하여, 사용자가 코드 작성에 더 집중할 수 있게 해줍니다.
    • 크로스 플랫폼: CMake는 Windows, macOS, Linux 등 다양한 운영체제에서 사용 가능합니다.
    • 언어 지원: 주로 C, C++ 프로젝트에서 많이 사용되지만, Python, Fortran 등 다른 언어의 프로젝트에서도 사용할 수 있습니다.
  2. CMake의 주요 기능
    • 빌드 설정: 다양한 빌드 옵션과 설정을 통해 프로젝트의 빌드 과정을 세밀하게 조정할 수 있습니다.
    • 다양한 빌드 시스템 지원: Makefiles, Ninja, Visual Studio 프로젝트 파일 등을 생성할 수 있습니다.
    • 모듈 시스템: 외부 라이브러리나 패키지를 쉽게 찾고 설정할 수 있는 모듈 시스템을 제공합니다.
    • 테스트 시스템: CTest를 통해 자동화된 테스트를 설정하고 실행할 수 있습니다.
  3. CMake의 주요 구성 요소
    • CMakeLists.txt: CMake의 설정 파일로, 프로젝트의 빌드 설정, 소스 파일 목록, 타겟, 라이브러리 등 빌드에 필요한 모든 정보를 정의합니다.
    • cmake 명령어: CMakeLists.txt 파일을 읽고, 실제 빌드 파일을 생성하는 명령어입니다. 주로 'cmake .' 또는 'cmake ' 형태로 사용됩니다.
    • ccmake: CMake의 curses 인터페이스로, 터미널에서 CMake 설정을 시각적으로 편집할 수 있습니다.
    • cmake-gui: CMake의 그래픽 인터페이스로, GUI 환경에서 CMake 설정을 편집할 수 있습니다.
  4. CMake 사용 예제
    간단한 CMakeLists.txt 파일을 통해 CMake 사용법을 설명하겠습니다.
    • 예제 프로젝트 구조
    • CMakeLists.txt 파일 예제
    • main.cpp 파일 예제
    • src/example.h 파일 예제
    • src/example.cpp 파일 예제
    • CMake 빌드 명령어
      프로젝트의 루트 디렉토리에서 다음 명령어를 실행합니다: 이렇게 하면 'build' 디렉토리에 빌드 파일이 생성되고, 'make' 명령어를 통해 프로젝트가 컴파일됩니다.
  5. 추가 기능과 고급 주제
    • 외부 라이브러리 사용: 'find_package' 명령어를 사용하여 외부 라이브러리를 찾아서 사용할 수 있습니다.
    • 설치 설정: 'install' 명령어를 사용하여 컴파일된 바이너리, 라이브러리, 헤더 파일 등을 지정한 디렉토리에 설치할 수 있습니다.
    • 테스트 설정: 'add_test' 명령어와 CTest를 사용하여 자동화된 테스트를 설정할 수 있습니다.
    • 조건부 빌드: 'if', 'else', 'endif' 등 조건부 명령어를 사용하여 특정 조건에 따라 빌드 설정을 변경할 수 있습니다.
    CMake는 강력하고 유연한 도구이므로, 프로젝트의 요구 사항에 맞춰 다양한 방식으로 설정하고 사용할 수 있습니다.

◼️ 'cmake ..' 명령은

  • 'cmake ..' 명령어에서 '..'은 CMake가 프로젝트의 루트 디렉토리를 지정하는 경로입니다.
    이를 통해 CMake는 해당 디렉토리에서 'CMakeLists.txt' 파일을 찾고, 그 파일을 기반으로 빌드 시스템을 설정하게 됩니다.
    • '..'은 현재 디렉토리의 부모 디렉토리를 나타내는 상대 경로입니다.
    • 이 명령어는 일반적으로 프로젝트의 루트 디렉토리 바깥에 빌드 디렉토리를 생성한 후 사용됩니다. 이렇게 하면 빌드 파일과 소스 파일이 분리되어, 소스 디렉토리가 깔끔하게 유지됩니다.
    • 이 명령어는 'my_project' 디렉토리에서 'CMakeLists.txt' 파일을 찾아서 읽고, 현재 디렉토리('build')에 빌드 파일을 생성합니다.
  • 왜 이렇게 하는가?
    • 빌드 파일 분리: 소스 디렉토리에 빌드 파일이 섞이지 않아서, 소스 코드가 깔끔하게 유지됩니다.
    • 재빌드 용이성: 빌드 디렉토리를 삭제하고 새로 만들기만 하면 쉽게 클린 빌드를 할 수 있습니다.
    • 다중 빌드 디렉토리 지원: 동일한 소스 디렉토리에 대해 여러 개의 빌드 디렉토리를 사용할 수 있습니다. 예를 들어, 하나의 빌드 디렉토리는 Debug 빌드, 다른 하나는 Release 빌드에 사용할 수 있습니다.
  • 명령어 변형
    • 절대 경로 사용: 'cmake /path/to/project'
    • - 다른 상대 경로 사용: 'cmake ../source'
    이러한 유연성을 통해 CMake는 다양한 프로젝트 구조와 빌드 환경을 지원할 수 있습니다.

⚛ 설명 (chatgpt)

◼️ CMakeLists.txt -> include()

include(), include_directories(), add_subdirectory() 각각을 설명하고 차이점을 설명합니다.

  • include()
    • 목적: 'include()' 명령어는 다른 CMake 스크립트 파일을 현재 CMakeLists.txt 파일로 가져와 실행합니다. 이를 통해 코드 재사용이 가능하며, 공통 설정을 여러 파일에 걸쳐 공유할 수 있습니다.
    • 사용 예시:
      # common.cmake 파일에 정의된 내용을 포함
      include(common.cmake)
    • 사용 사례:
      - 공통 설정, 함수, 매크로를 여러 CMakeLists.txt 파일에서 재사용할 때
      - 프로젝트 설정을 분리하여 유지보수성을 높일 때
  • include_directories()
    • 목적: 'include_directories()' 명령어는 컴파일러가 헤더 파일을 찾을 수 있는 경로를 지정합니다. 지정된 디렉토리는 해당 디렉토리 안에 있는 모든 파일에 대해 컴파일러의 검색 경로에 추가됩니다.
    • 사용 예시:
      include_directories(${PROJECT_SOURCE_DIR}/include)
    • 사용 사례:
      - 프로젝트 내 공통 헤더 파일 경로를 설정할 때
      - 외부 라이브러리의 헤더 파일 경로를 추가할 때
  • add_subdirectory()
    • 목적: 'add_subdirectory()' 명령어는 하위 디렉토리에 있는 CMakeLists.txt 파일을 현재 빌드에 포함시킵니다. 이를 통해 프로젝트를 여러 서브 디렉토리로 나누어 구성할 수 있으며, 각 서브 디렉토리의 CMakeLists.txt 파일을 독립적으로 관리할 수 있습니다.
    • 사용 예시:
      add_subdirectory(base)
    • 사용 사례:
      - 프로젝트를 모듈화하여 관리할 때
      - 하위 프로젝트를 포함시켜 빌드할 때
  • 각 명령어의 차이점
    • 'include()'는 다른 CMake 스크립트를 현재 스크립트로 포함시키는 용도입니다. 이는 단순히 코드의 재사용과 공통 설정의 분리를 위해 사용됩니다.
    • 'include_directories()'는 컴파일러가 헤더 파일을 찾을 수 있는 디렉토리를 추가하는 용도로, 컴파일 과정에서 헤더 파일의 위치를 지정하기 위해 사용됩니다.
    • 'add_subdirectory()'는 특정 디렉토리 내의 CMakeLists.txt 파일을 포함시켜, 해당 디렉토리의 설정과 빌드 목표를 현재 빌드 시스템에 추가합니다. 이는 주로 프로젝트를 모듈화하여 관리하거나, 하위 프로젝트를 포함시킬 때 사용됩니다.
  • 요약
    • include(): 다른 CMake 스크립트를 포함하여 코드 재사용 및 공통 설정 분리
    • include_directories(): 컴파일러가 헤더 파일을 찾을 수 있는 디렉토리 경로 추가
    • add_subdirectory(): 하위 디렉토리의 CMakeLists.txt 파일을 포함하여 프로젝트 모듈화 및 하위 프로젝트 관리
    • 이 세 가지 명령어를 적절히 활용하면 CMake를 통해 프로젝트의 빌드 시스템을 더욱 효율적으로 관리할 수 있습니다.

◼️ CMake, Make 비교

CMake와 Make는 소프트웨어 빌드 프로세스에서 서로 다른 역할을 수행하는 도구로, 함께 사용될 때 강력한 빌드 시스템을 제공합니다. 아래에 이 두 도구의 관계와 각각의 역할에 대해 설명합니다.

  • CMake
    • 역할: CMake는 프로젝트의 빌드 설정을 관리하고, 플랫폼 독립적인 방식으로 빌드 시스템을 생성하는 도구입니다.
    • 기능: CMake는 여러 플랫폼과 빌드 도구를 지원하며, 이를 통해 다양한 형태의 빌드 스크립트를 생성할 수 있습니다.
    • 출력: CMake는 Makefile, Visual Studio 프로젝트 파일, Xcode 프로젝트 파일 등 다양한 형태의 빌드 스크립트를 생성할 수 있습니다.
  • Make
    • 역할: Make는 주로 유닉스 계열 시스템에서 사용되는 빌드 도구로, Makefile을 읽어 들여 소프트웨어를 컴파일하고 빌드하는 역할을 합니다.
    • 기능: Make는 파일 간의 의존 관계를 관리하고, 필요한 경우에만 파일을 다시 컴파일하여 빌드 효율성을 높입니다.
    • 입력: Make는 Makefile을 입력으로 사용하여, 그 안에 정의된 빌드 규칙에 따라 작업을 수행합니다.
  • CMake와 Make의 관계
    1. CMake가 Makefile을 생성:
      CMake는 프로젝트 설정을 기반으로 플랫폼에 맞는 빌드 스크립트를 생성합니다. 유닉스 계열 시스템에서는 주로 Makefile을 생성합니다.
      CMakeLists.txt 파일에 정의된 내용을 바탕으로, 소스 파일, 헤더 파일, 라이브러리 등의 빌드 규칙을 포함한 Makefile을 만듭니다.
    2. Make가 Makefile을 사용하여 빌드 수행:
      CMake에 의해 생성된 Makefile을 사용하여, Make는 실제로 소스 파일을 컴파일하고 링크하여 실행 파일이나 라이브러리를 생성합니다.
      Make는 Makefile에 정의된 규칙과 의존성을 기반으로, 필요한 파일만을 다시 컴파일하여 빌드 시간을 단축합니다.
  • 요약
    • CMake는 빌드 설정을 관리하고, 플랫폼에 맞는 빌드 스크립트를 생성하는 도구입니다.
    • Make는 Makefile을 읽어 들여, 실제로 소스 파일을 컴파일하고 빌드하는 도구입니다.
    • 관계: CMake는 Makefile을 생성하고, Make는 그 Makefile을 사용하여 빌드 작업을 수행합니다. CMake는 여러 빌드 시스템을 지원하지만, Make는 그 중 하나일 뿐입니다.

📦 Ninja

Ninja는 고성능 빌드 시스템으로, 주로 대규모 프로젝트에서 빌드 시간을 최소화하기 위해 설계되었습니다.
Google의 직원인 Evan Martin이 개발했으며, 주로 C, C++ 프로젝트에서 사용되지만 다른 언어의 빌드에도 사용할 수 있습니다.
Ninja는 주로 Google의 Chrome 및 Android 프로젝트에서 사용됩니다.

Ninja의 주요 특징 및 설계 철학은 다음과 같습니다:

  • 1. 속도
    • 고속성: Ninja의 주된 목표는 빌드 속도를 최대한 빠르게 하는 것입니다. 이를 위해 Ninja는 복잡한 기능보다는 간단하고 효율적인 기능을 제공합니다.
    • 최소화된 오버헤드: Ninja는 빌드 프로세스 중에 발생하는 오버헤드를 최소화하기 위해 최적화되어 있습니다.
  • 2. 단순성
    • 구성 파일의 단순성: Ninja는 간단한 규칙과 빌드 명령을 사용하여 빌드 파일을 구성합니다. 이는 사람이 직접 작성하기보다는 다른 빌드 시스템이나 도구가 자동으로 생성하는 것을 염두에 둔 설계입니다.
  • 3. 반복 가능성과 결정성
    • 결정적 빌드: Ninja는 같은 입력이 주어졌을 때 항상 같은 출력을 생성하는 결정적 빌드를 지향합니다. 이는 빌드의 신뢰성을 높이는 데 중요한 요소입니다.
    • 반복 가능성: 같은 소스 코드에 대해 반복해서 빌드를 실행할 때, Ninja는 항상 일관된 결과를 제공합니다.
  • 4. 고급 기능
    • 병렬 빌드: Ninja는 다중 코어를 활용하여 병렬로 빌드를 수행할 수 있습니다. 이는 빌드 속도를 크게 향상시킵니다.
    • 파일 시스템 이벤트 사용: Ninja는 빌드할 파일의 변경 사항을 감지하기 위해 파일 시스템 이벤트를 사용할 수 있습니다.
    • 인크리멘탈 빌드: Ninja는 소스 파일이 변경된 경우에만 해당 부분을 다시 빌드하여 전체 빌드 시간을 단축합니다.
  • 5. 다른 빌드 시스템과의 통합
    • CMake와의 통합: Ninja는 CMake와 잘 통합되어, CMake를 사용하여 프로젝트의 빌드 구성을 관리하고, Ninja를 실제 빌드 도구로 사용할 수 있습니다.
    • GN (Generate Ninja): Google은 GN이라는 도구를 만들어, Chrome 프로젝트와 같이 매우 큰 프로젝트에서 빌드 구성을 관리하고 Ninja 파일을 생성하는 데 사용합니다.
  • 예시
    Ninja 빌드 파일('build.ninja')의 간단한 예시는 다음과 같습니다:
    # 빌드 규칙 정의 # 빌드 지시 사항 위의 예제는 'foo.c'와 'bar.c'를 각각 컴파일하여 'foo.o'와 'bar.o' 오브젝트 파일을 만들고, 이들을 링크하여 'myapp' 실행 파일을 생성하는 간단한 빌드 스크립트입니다.
  • 결론
    Ninja는 대규모 프로젝트에서 빌드 시간을 최소화하고 효율성을 극대화하기 위해 설계된 강력한 빌드 시스템입니다. 단순하면서도 빠르고, 반복 가능한 빌드를 제공하여 개발자들이 코드 변경 사항을 빠르게 테스트하고 배포할 수 있도록 돕습니다. CMake나 GN과 같은 도구와 통합하여 사용하는 것이 일반적이며, 특히 성능이 중요한 프로젝트에서 널리 사용됩니다.

⚛ 설명 (chatgpt)

◼️ Ninja와 make 비교

Ninja와 Make는 모두 빌드 시스템으로, 소스 코드를 컴파일하고 프로그램을 링크하는 등의 작업을 자동화합니다.   두 시스템은 목적은 같지만, 설계 철학, 사용 방식, 성능 측면에서 차이가 있습니다.
다음은 Ninja와 Make를 여러 측면에서 비교한 내용입니다:

  • 1. 설계 철학
    ◎ Make:
    - 1976년에 개발된 전통적인 빌드 시스템입니다.
    - 유연하고 강력한 기능을 제공하지만, 복잡한 프로젝트에서는 비효율적일 수 있습니다.
    - Makefile을 직접 작성하며, 프로젝트 규모가 커질수록 관리가 어려워질 수 있습니다.
    ◎ Ninja:
    - 속도와 효율성을 극대화하기 위해 설계된 현대적인 빌드 시스템입니다.
    - Make와 비교하여 더 간단한 빌드 파일 형식을 사용합니다.
    - 주로 자동 생성된 빌드 파일을 사용하며, 사람이 직접 작성하는 경우는 드뭅니다.
    - 다른 빌드 시스템(CMake, GN 등)을 통해 빌드 파일을 생성하는 방식으로 사용됩니다.
  • 2. 빌드 파일 형식 및 작성
    ◎ Make:
    - Makefile을 사용하여 빌드 규칙과 종속성을 정의합니다.
    - Makefile은 사람이 직접 작성하거나 관리하며, 복잡한 구문과 변수 사용이 가능합니다.
    - 예시:
    ◎ Ninja:
    - 'build.ninja' 파일을 사용하여 빌드 규칙을 정의합니다.
    - 간단하고 명확한 구문을 사용하여 성능을 최적화합니다.
    - 주로 CMake, GN 등 다른 도구에 의해 자동 생성됩니다.
    - 예시:
  • 3. 성능
    ◎ Make:
    - 큰 프로젝트에서 병렬 빌드를 지원하지만, 병렬화가 최적화되어 있지 않을 수 있습니다.
    - 빌드 파일의 복잡성이 증가할수록 성능이 저하될 수 있습니다.
    ◎ Ninja:
    - 매우 빠른 빌드 속도를 제공하며, 빌드 오버헤드를 최소화하도록 설계되었습니다.
    - 높은 병렬 빌드 성능을 제공하여 다중 코어를 효율적으로 활용합니다.
    - 파일 시스템 이벤트를 활용하여 변경된 파일만 빌드합니다.
  • 4. 사용 사례
    ◎ Make:
    - 소규모에서 중규모 프로젝트에 널리 사용됩니다.
    - 전통적인 Unix/Linux 환경에서 표준으로 많이 사용됩니다.
    - 다양한 언어 및 툴체인을 지원합니다.
    ◎ Ninja:
    - 대규모 프로젝트, 특히 빌드 속도가 중요한 프로젝트에 적합합니다.
    - Google의 Chrome, Android 등의 대규모 프로젝트에서 사용됩니다.
    - CMake, GN 등의 도구와 통합하여 사용됩니다.
  • 5. 장단점
    ◎ Make:
        • 장점:
            - 유연하고 강력한 기능
            - 폭넓은 지원과 문서
            - 전통적인 도구로 널리 사용됨
        • 단점:
            - 복잡한 프로젝트에서 성능 저하
            - Makefile 작성 및 유지보수의 어려움
    ◎ Ninja:
        • 장점:
            - 매우 빠른 빌드 속도
            - 간단하고 명확한 빌드 파일 형식
            - 대규모 프로젝트에서의 효율성
        • 단점:
            - 사람이 직접 작성하기에는 부적합
            - 자동 생성된 빌드 파일에 대한 의존성
  • 결론
    Ninja와 Make는 각각의 장단점이 있으며, 사용 환경과 요구사항에 따라 적합한 빌드 시스템을 선택하는 것이 중요합니다.   Make는 유연성과 전통적인 접근 방식이 필요한 프로젝트에 적합하며, Ninja는 성능과 효율성이 중요한 대규모 프로젝트에 적합합니다.   많은 경우, CMake와 같은 도구를 통해 프로젝트 설정을 관리하고, 실제 빌드에는 Ninja를 사용하는 방식으로 두 시스템의 장점을 조합하여 사용합니다.


Email 답글이 올라오면 이메일로 알려드리겠습니다.