728x90
반응형
728x90
반응형
728x90
반응형

CPM.cmake (CMake Package Manager) : 설정이 필요 없는 크로스 플랫폼, 재현 가능한 종속성 관리를 위한 CMake용 패키지 관리자


1. 개요

  • CPM.cmake(CMake Package Manager)는 CMakeFetchContent 모듈을 확장하여, 프로젝트 외부의 라이브러리를 간편하게 가져오고 캐싱할 수 있도록 돕는 경량 의존성 관리 도구 입니다.

  • 일반적으로 GitHub 저장소에서 패키지를 받아오는 용도로 사용되지만, 사설 Git 서버(예: 내부 IP 기반 서버)에서도 충분히 활용 가능합니다.

  • 이 문서에서는 사설 Git 서버를 구축하고, CPM.cmake를 이용해 해당 서버에서 라이브러리를 자동으로 다운로드하여 사용하는 방법 을 자세히 소개합니다.



2. CPM.cmake 사용법

2.1. CPM.cmake 가져오기

  • CPM.cmake는 프로젝트 내에 직접 포함하는 것이 일반적입니다:

  • bash

      mkdir -p cmake
      wget -O cmake/CPM.cmake https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/get_cpm.cmake
    

2.2. CMakeLists.txt 구성 예시 (GitHub 저장소)

  • 아래는 fmt, nlohmann/json, Catch2CPM(CMake Package Manager)을 통해 GitHub에서 받아 사용하는 예시입니다:

  • cmake

      cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
      
      # create project
      project(MyProject)
      
      # add executable
      add_executable(main main.cpp)
      
      # add dependencies
      include(cmake/CPM.cmake)
      
      CPMAddPackage("gh:fmtlib/fmt#7.1.3")
      CPMAddPackage("gh:nlohmann/json@3.10.5")
      CPMAddPackage("gh:catchorg/Catch2@3.4.0")
      
      # link dependencies
      target_link_libraries(main
          fmt::fmt
          nlohmann_json::nlohmann_json
          Catch2::Catch2WithMain
      )
    

  • #버전Git 태그/브랜치/커밋을 직접 지정하는 방식이며,
    @버전CPM 내부 버전 추적용 이름을 포함하는 방식입니다.
    일반적으로 @버전이 캐시 충돌을 줄이고 관리에 더 유리합니다.



2.3. CMakeLists.txt 구성 예시 (사설 저장소)

  • 다음은 사설 Git 저장소에서 라이브러리를 받아와 사용하는 예시입니다:

  • cmake

      cmake_minimum_required(VERSION 3.14)
      
      project(MyProject)
      
      include(cmake/CPM.cmake)
      
      CPMAddPackage(
        NAME MyLib
        GIT_REPOSITORY git@192.168.0.10:mylib.git
        GIT_TAG main   # 또는 특정 커밋 해시, 태그
      )
      
      add_executable(main main.cpp)
      target_link_libraries(main MyLib)
    
  • GIT_TAG는 반드시 명시해야 하며, 브랜치명, 태그명, 또는 커밋 해시를 사용할 수 있습니다.



2.4. URL에서 아카이브 직접 다운로드 예시

  • CPM(CMake Package Manager)은 Git 저장소뿐만 아니라 압축 파일(.zip 등) 형식의 패키지URL을 통해 직접 가져올 수 있습니다.

  • cmake

      # 버전은 자동 추정 (예: 파일명에서 추출)
      CPMAddPackage("https://example.com/my-package-1.2.3.zip")
      
      # MD5 해시값을 명시하여 무결성 검증
      CPMAddPackage("https://example.com/my-package-1.2.3.zip#MD5=68e20f674a48be38d60e129f600faf7d")
      
      # 명시적으로 버전 지정
      CPMAddPackage("https://example.com/my-package.zip@1.2.3")
    
  • 이 방식은 Git을 사용하지 않는 사내 배포 시스템이나, 외부 공개 라이브러리를 간단히 가져오고자 할 때 유용합니다.



3. 캐싱 및 오프라인 빌드

  • CPM.cmake는 다운로드된 의존성을 자동으로 캐싱합니다. 기본 캐시 위치는 다음과 같습니다:

    • $HOME/.cache/CPM
    • ${CMAKE_BINARY_DIR}/_deps (빌드 디렉토리 내)
  • 이 디렉토리를 보존하거나 다른 머신에 복사하면 오프라인에서도 동일하게 사용할 수 있습니다.



4. Gitea 또는 GitLab 등 도구를 활용한 구성 방안

  • 단순한 Git 베어 저장소 외에도, 다음과 같은 웹 기반 Git 서버를 설치하여 사용자 인터페이스와 프로젝트 관리 기능을 강화할 수 있습니다:

    • Gitea : 경량 오픈소스 Git 서비스
    • GitLab CE : 보다 강력한 CI/CD, 권한 관리 등 제공
  • 이런 도구들은 SSH/HTTPS 모두를 지원하며, 여러 개발자와 협업 시 매우 유용합니다.



5. 사설 Git 저장소 준비

5.1 Git 설치 및 저장소 생성

  • 사설 서버(IP: 192.168.0.10 등)에 Git을 설치합니다:

    • bash

        sudo apt update
        sudo apt install git
      
  • 베어 저장소를 생성합니다:

    • bash

        mkdir -p /srv/git/mylib.git
        cd /srv/git/mylib.git
        git init --bare
      

5.2 SSH 접근 설정

  • 클라이언트에서 해당 서버로 접속할 수 있도록 SSH 인증을 설정합니다:

    • (1) 서버에 git 사용자 생성 (또는 기존 사용자 사용)
    • (2) 클라이언트의 공개키를 서버의 ~/.ssh/authorized_keys에 등록
    • (3) 클라이언트에서 SSH 접속 확인:
      • bash

        ssh git@192.168.0.10
        
  • CPM 사용을 위하여 비밀번호 없이 접근되도록 설정하는 것이 중요합니다.


5.3 HTTPS 저장소 사용 시 참고사항

  • 사설 Git 서버가 HTTPS로 동작하고 있고, 자체 서명된 SSL 인증서를 사용하는 경우 다음 설정으로 인증서 검증을 건너뛸 수 있습니다:

  • bash

    git config --global http.sslVerify false
    
  • ⚠️ 단, 이 설정은 보안상 위험하므로, 내부 개발 환경 에서만 사용하는 것이 좋습니다.



6. 정리

  • 사설 Git 서버와 CPM.cmake를 조합하면, 외부 네트워크에 의존하지 않고도 안정적으로 CMake 의존성을 관리할 수 있습니다.
  • 특히, 보안이 중요한 기업 내 네트워크나, 오프라인 환경에서도 CMake 프로젝트를 유연하게 운영할 수 있는 강력한 방법입니다.



  • 도움이 되셨으면 하단의 ❤️ 공감 버튼 부탁 드립니다. 감사합니다! 😄

728x90
반응형
728x90
반응형

cmrc : CMake 프로젝트에서 리소스를 바이너리에 포함

  • CMake를 사용한 프로젝트에서 이미지, 텍스트 파일, JSON 등의 리소스를 관리하는 방법은 여러 가지가 있습니다.
  • 일반적으로 실행 파일과 함께 별도로 배포하거나, Windows.rc 리소스 파일을 이용하는 방법이 있습니다.
  • 하지만 이런 방법은 배포 및 관리가 번거롭고 플랫폼 의존성이 발생할 수 있습니다.

  • 이를 해결하기 위해 cmrc를 사용하면 리소스를 실행 파일 내부에 직접 포함할 수 있습니다.
  • 실행 파일 하나만 배포하면 되므로 편리하고, 코드에서 리소스를 파일처럼 읽을 수 있습니다.

  • 이번 글에서는 cmrc를 사용하여 CMake 프로젝트에서 리소스를 쉽게 포함하는 방법을 설명합니다.


1. cmrc 설치

1.1 FetchContent 사용

  • CMakeFetchContent를 이용하여 cmrc를 프로젝트에 추가할 수 있습니다.

  • cmake

      include(FetchContent)
      FetchContent_Declare(
          cmrc
          GIT_REPOSITORY https://github.com/vector-of-bool/cmrc.git
          GIT_TAG        master
      )
      FetchContent_MakeAvailable(cmrc)
    


2. cmrc 사용 방법

2.1 리소스를 CMake에서 등록

  • CMake에서 리소스를 바이너리에 포함하려면 cmrc_add_resource_library를 사용해야 합니다.

  • cmake

      cmake_minimum_required(VERSION 3.10)
      project(MyProject)
      
      include(FetchContent)
      FetchContent_Declare(
          cmrc
          GIT_REPOSITORY https://github.com/vector-of-bool/cmrc.git
          GIT_TAG        master
      )
      FetchContent_MakeAvailable(cmrc)
      
      # 실행 파일 생성
      add_executable(MyProject src/main.cpp)
      
      # 리소스 라이브러리 생성
      cmrc_add_resource_library(resources STATIC
          resources/image.png
          resources/config.json
      )
      
      # cmrc를 사용하려면 cmrc::resources를 링크해야 함
      target_link_libraries(MyProject PRIVATE resources cmrc::resources)
      
      # cmrc를 사용하려면 이 설정이 필요함
      cmrc_add_library(resources)
    


2.2 코드에서 리소스 사용

  • 리소스를 바이너리에 포함하면 cmrc::open()을 이용해 파일처럼 접근할 수 있습니다.

2.2.1 cmrc 헤더 포함

  • 먼저, #include <cmrc/cmrc.hpp>를 추가하고 CMRC_DECLARE()를 사용하여 리소스를 등록합니다.

  • cpp

      #include <iostream>
      #include <string>
      #include <cmrc/cmrc.hpp> // 헤더 추가
      
      CMRC_DECLARE(resources);
      
      int main() {
          // 리소스 파일 시스템 가져오기
          auto fs = cmrc::resources::get_filesystem();
      
          // 이미지 파일 읽기
          if (fs.exists("resources/image.png")) {
              auto file = fs.open("resources/image.png");
              std::cout << "이미지 파일 크기: " << file.size() << " 바이트" << std::endl;
          } else {
              std::cout << "리소스가 존재하지 않습니다!" << std::endl;
          }
      
          return 0;
      }
    


3. cmrc의 장점과 단점

✅ 장점

  • 실행 파일 하나에 리소스를 포함 → 배포가 편리
  • 리소스를 메모리에서 직접 접근 가능 → 빠른 로딩 속도
  • 운영 체제에 관계없이 CMake에서 일관된 방식으로 적용 가능

❌ 단점

  • 바이너리 크기가 커질 수 있음
  • 리소스 파일을 변경하려면 다시 컴파일 이 필요함


4. 실전 예제 (CMakeLists.txt)

  • 전체적인 예제를 정리하면 다음과 같습니다.

  • cmake

      cmake_minimum_required(VERSION 3.10)
      project(MyProject)
      
      # cmrc 가져오기
      include(FetchContent)
      FetchContent_Declare(
          cmrc
          GIT_REPOSITORY https://github.com/vector-of-bool/cmrc.git
          GIT_TAG        master
      )
      FetchContent_MakeAvailable(cmrc)
      
      # 실행 파일
      add_executable(MyProject src/main.cpp)
      
      # 리소스 라이브러리 생성
      cmrc_add_resource_library(resources STATIC resources/image.png)
      
      # cmrc 리소스 사용 설정
      target_link_libraries(MyProject PRIVATE resources cmrc::resources)
    


5. 정리

  • cmrc를 사용하면 CMake 프로젝트에서 리소스를 실행 파일에 포함 할 수 있음.

  • CMake에서 cmrc_add_resource_library를 사용 하여 리소스를 바이너리에 추가.

  • 코드에서 파일처럼 cmrc::open()으로 리소스 접근 가능.

  • 실행 파일을 단일 배포 파일 로 만들기에 적합.


  • 실행 파일 하나만 배포하는 방식이 필요한 경우, cmrc는 매우 유용한 솔루션이 될 수 있습니다. 🚀
728x90
반응형
728x90
반응형

CMakeFetchContent 모듈 : 의존성 빌드

  • FetchContentCMake에서 외부 의존성을 쉽게 가져오고 빌드할 수 있도록 도와주는 모듈입니다.
  • ExternalProject와 유사하지만, 더 직관적이고 CMake 내부에서 자연스럽게 통합할 수 있도록 설계되었습니다.


1. FetchContent 기본 사용법

1.1. 모듈 포함

  • cmake

      include(FetchContent)
    

1.2. 패키지 가져오기

  • cmake

      FetchContent_Declare(
          googletest
          GIT_REPOSITORY https://github.com/google/googletest.git
          GIT_TAG        release-1.12.1
      )
    
      FetchContent_MakeAvailable(googletest)
    

  • 위 코드는 googletestGit에서 받아와 현재 프로젝트에서 사용 가능하도록 설정합니다.
  • git의 최신 코드를 받으려면 GIT_TAG master로 설정하면 됩니다.


2. FetchContent 주요 함수

2.1. FetchContent_Declare()

  • cmake

      FetchContent_Declare(
      <이름>
      GIT_REPOSITORY <URL>
      GIT_TAG <브랜치/태그>
      SOURCE_DIR <경로>
      BINARY_DIR <경로>
      )
    

  • 외부 프로젝트를 정의합니다.
  • Git, HTTP, Local Path 등 다양한 방법으로 소스를 가져올 수 있습니다.

2.2. FetchContent_MakeAvailable()

  • cmake

      FetchContent_MakeAvailable(<이름>)
    

  • FetchContent_Declare()로 정의한 프로젝트를 다운로드하고 빌드 시스템에 포함합니다.
  • add_subdirectory()와 유사하게 동작하며, 별도의 add_subdirectory() 호출 없이 자동으로 처리됩니다.


2.3. 예제: fmt 라이브러리 가져오기

  • cmake

      cmake_minimum_required(VERSION 3.14)
      project(MyProject)
      
      include(FetchContent)
      
      FetchContent_Declare(
          fmt
          GIT_REPOSITORY https://github.com/fmtlib/fmt.git
          GIT_TAG        9.1.0
      )
      
      FetchContent_MakeAvailable(fmt)
      
      add_executable(main main.cpp)
      target_link_libraries(main PRIVATE fmt)
    

  • fmt 라이브러리를 가져와 프로젝트에 통합하고, main 실행 파일에서 사용합니다.


2.4. FetchContent vs ExternalProject

  • 기능 FetchContent ExternalProject
    빌드 시점 Configure 단계에서 처리 Build 단계에서 처리
    통합 방식 add_subdirectory()와 유사 독립적인 외부 프로젝트로 관리
    사용 용도 내부에서 직접 라이브러리 활용 별도 빌드가 필요한 프로젝트
  • FetchContent는 프로젝트와 동일한 CMake 빌드 시스템을 공유하는 경우에 적합합니다.

  • ExternalProject는 별도로 빌드해야 하는 외부 바이너리를 가져올 때 적합합니다.



2.5. FetchContent 내부 캐싱

  • CMakeFetchContent를 통해 다운로드한 패키지를 CMakeCache.txt에 저장하며, 이미 다운로드된 경우 다시 가져오지 않습니다.

  • 필요하면 CMakeCache.txt를 삭제하거나 다음과 같이 강제로 업데이트할 수 있습니다.

  • cmake

      FetchContent_Populate(<이름> QUIET)
    


6. FetchContent + CMake 옵션 사용

  • cmake

      FetchContent_Declare(
          spdlog
          GIT_REPOSITORY https://github.com/gabime/spdlog.git
          GIT_TAG        v1.10.0
      )
      
      set(SPDLOG_FMT_EXTERNAL ON CACHE BOOL "" FORCE) # fmt 사용 설정
      FetchContent_MakeAvailable(spdlog)
    

  • 특정 라이브러리의 옵션을 설정하여 원하는 형태로 빌드할 수도 있습니다.


정리

  • FetchContentCMake에서 외부 의존성을 쉽게 관리하는 강력한 도구입니다.
  • 기존 ExternalProject보다 더 직관적이며, 프로젝트 내부에 자연스럽게 통합할 수 있습니다.
  • Git 리포지토리, 로컬 디렉토리 등을 활용해 다양한 방식으로 패키지를 불러올 수 있습니다.

  • 📌 CMake에서 외부 라이브러리를 관리할 때 FetchContent를 적극 활용하면 빌드 과정이 훨씬 간결해집니다.
728x90
반응형
728x90
반응형
#-----------------------------------------------------------------------
# Objective-C Makefile (Executable file)
#
# gnustep + msys(mingw) makefile (Executable file)
#-----------------------------------------------------------------------
EXE = hello
FLAGS += -I ./src
SRC += src/HelloWorld.m src/main.m
#-----------------------------------------------------------------------
OBJ = $(SRC:.m=.o)
CC = gcc
OBJ_C += `gnustep-config --objc-flags`
FLAGS += -I /GNUstep/System/Library/Headers
FLAGS += -L /GNUstep/System/Library/Libraries
LDFLAGS += -lobjc
LDFLAGS += -lgnustep-base
EFLAGS += -enable-auto-import
EFLAGS += -fconstant-string-class=NSConstantString
%.o: %.m
$(CC) $(OBJ_C) $(FLAGS) $(LDFLAGS) $(EFLAGS) -o $@ -c $<
$(EXE): $(OBJ)
$(CC) -o $@ $(OBJ) $(FLAGS) $(LDFLAGS) $(EFLAGS)
all: $(EXE)
clean:
rm -f src/*.o
rm -f src/*.d
rm -f $(EXE)
rm -f $(EXE).exe
728x90
반응형

+ Recent posts