프로그래밍/리눅스 프로그래밍

[cmake] cmake 기초 부터 활용 까지

jinkwon.kim 2021. 6. 17. 16:52
728x90
반응형

cmake란?

쉽게 말하면?

    - source의 코드의 빌드를 쉽게 해주는 tool

어렵게 말하면?

    - Meta-Make기반의 빌드 프로세스를 관리하고 작성는 툴

    - 빌드에 필요한 설정, 의존성, 패키징을 위한 파일을 생성 및 관리 함

    - 직접 빌드를 수행하는 빌드 시스템이 아님, build는 컴파일러가 한다.

 

 

핵심 기본 구조

    - 프로젝트의 기본 구조 

        - 출처 : https://medium.com/swlh/c-project-structure-for-cmake-67d60135f6f5

Simple project structure

The main idea about project structure is that you have at least 2 folders include and src. Folders purpose is:

  • include - PUBLIC header files (.h files).
  • src - PRIVATE source files (.h and .m files).
  • test - tests files if you write tests (indefinitely you should).
  • libs - third party or your own libraries you depend on.

Headers files in include should be under folder named after your library domain. Reason behind this is that when you expose public header files you expose only include directory and when you #include files from library you do this #inlcude <HMM/Algorithm.h> instead of #include "Algorithm.h"

 

프로젝트 구조 

├── CMakeLists.txt
├── include
│       └── main.hpp
├── libs
│       └── hello
│                  ├── include
│                  │       └── hello.hpp
│                  └── src
│                            └── hello.cpp
├── src
│       └── main.cpp
└── test

 

기본 실행 파일 생성

#cmake 최소 버전
cmake_minimum_required(VERSION 3.18.2)
 
#프로젝트 이름
project(hello)
 
#CMake 옵션 처리
set(CMAKE_VERBOSE_MAKEFILE ON)
 
#컴파일 옵션 추가
add_compile_options(-std=c++11 -ggdb3 -O3 -Wall -Werror)
 
#define 추가
add_definitions(-DFMT_HEADER_ONLY -D_REENTRANT)
 
#header include 경로
include_directories(
    ./include
)
 
#라이브러리 링크 디렉토리 경로
link_directories()
 
#전체 적용될 라이브러리 링크
link_libraries(
    pthread
)

#staic 실행 파일 생성 옵션
set(CMAKE_EXE_LINKER_FLAGS "-static")

#targeting 하여 옵션을 처리합니다.
TARGET_COMPILE_OPTIONS ( <Target_이름> PUBLIC <옵션> <옵션> ... )
TARGET_INCLUDE_DIRECTORIES ( <Target_이름> PUBLIC <디렉토리> <디렉토리> ... )
TARGET_LINK_LIBRARIES ( <Target_이름> <라이브러리> <라이브러리> ... )

#cmake 변수 처리
file(GLOB all_srcs "./src/*.cpp")
 
#실행 파일 생성
add_executable(main ${all_srcs})

 

라이브러리 생성

     - add_executable 을 add_library로 만변경하면 됩니다.

#cmake 최소 버전
cmake_minimum_required(VERSION 3.18.2)
 
#프로젝트 이름
project(hello)
 
#CMake 옵션 처리
set(CMAKE_VERBOSE_MAKEFILE ON)
 
#컴파일 옵션 추가
add_compile_options(-std=c++11 -ggdb3 -O3 -Wall -Werror)
 
#define 추가
add_definitions(-DFMT_HEADER_ONLY -D_REENTRANT)
 
#header include 경로
include_directories(
    ./include
)
 
#라이브러리 링크 디렉토리 경로
link_directories()


#전체 적용될 라이브러리 링크
link_libraries(
    pthread
)
 
#cmake 변수 처리
file(GLOB all_srcs "./src/*.cpp")
 
#라이브러리 생성
set(OUTPUT_STATIC_LIB "hello")
add_library(${OUTPUT_STATIC_LIB} STATIC ${all_srcs})

 

 

라이브러리 링크를 통한 실행 파일 생성

#cmake 최소 버전
cmake_minimum_required(VERSION 3.18.2)
 
#프로젝트 이름
project(hello)
 
#CMake 옵션 처리
set(CMAKE_VERBOSE_MAKEFILE ON)
 
#컴파일 옵션 추가
add_compile_options(-std=c++11 -ggdb3 -O3 -Wall -Werror)
 
#define 추가
add_definitions(-DFMT_HEADER_ONLY -D_REENTRANT)
 
#header include 경로
include_directories(
    ./include
)
 
#라이브러리 링크 디렉토리 경로
link_directories()
 
#전체 적용될 라이브러리 링크
link_libraries(
    pthread
)
 
#cmake 변수 처리
file(GLOB all_srcs "./src/*.cpp")
 
#라이브러리 생성
set(OUTPUT_STATIC_LIB "hello")
add_library(${OUTPUT_STATIC_LIB} STATIC ${all_srcs})

#실행 파일 생성
add_executable(main ${all_srcs})

#특정 실행 파일에 적용될 라이브러리 링크추가
target_link_libraries(main ${OUTPUT_STATIC_LIB})

설치

https://runebook.dev/ko/docs/cmake/command/install

 

유용한 Cmake문법

1. 파일 존재 확인

    if (EXIST file.txt) # 파일의 존재여부 확인

        ...

    endif()

2. 없는 파일 확인

    if (NOT EXIST file.txt) # 파일의 존재여부 확인

        ...

    endif()

 

3. bash 명령어 실행

    - pwd 명령을 실행한 후 결과 극 CUR_PATH에 저장한다. 

    execute_process (

        COMMAND bash -c "pwd"

        OUTPUT_VARIABLE CUR_PATH

    )

 

 

참조 

https://stackoverflow.com/questions/46809303/how-to-static-linking-to-glibc-in-cmake

 

How to static linking to glibc in cmake

I'm trying to build a package from Fedora that can run on a RedHat 6 machine. So I need to build and static linking with some library that does not exist in RedHat machine. I found that I can you -...

stackoverflow.com

https://goodgodgd.github.io/ian-flow/archivers/build-system

 

[C++] CMake Build System « IanFlow

1. Linux Build System C언어를 처음 배울 때 보통 Visual Studio에서 시작하는 경우가 많다. Visual Studio(이하 VS)는 통합개발환경(IDE)라서 VS에서 코딩도하고 컴파일 빌드 디버깅 실행 모두가 가능하다. 하지

goodgodgd.github.io

 

https://gist.github.com/dongbum/d1d49e38a20f9cf52ea39f9ce2702160

 

CMake 할때 쪼오오금 도움이 되는 문서

CMake 할때 쪼오오금 도움이 되는 문서. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

 https://cmake.org/cmake/help/latest/command/execute_process.html 

 

execute_process — CMake 3.24.2 Documentation

execute_process Execute one or more child processes. execute_process(COMMAND [ ] [COMMAND [ ]]... [WORKING_DIRECTORY ] [TIMEOUT ] [RESULT_VARIABLE ] [RESULTS_VARIABLE ] [OUTPUT_VARIABLE ] [ERROR_VARIABLE ] [INPUT_FILE ] [OUTPUT_FILE ] [ERROR_FILE ] [OUTPUT

cmake.org

 

cpack 사용법

https://m.blog.naver.com/PostView.nhn?isHttpsRedirect=true&blogId=likeafree&logNo=221475154955&proxyReferer=

https://gitlab.kitware.com/cmake/community/-/wikis/doc/cpack/Component-Install-With-CPack

https://runebook.dev/ko/docs/cmake/module/cpack 

728x90
반응형