CMake์™€ C++๋Š” ์˜์›ํžˆ ํ˜•์ œ์ž…๋‹ˆ๋‹ค

CMake์™€ C++๋Š” ์˜์›ํžˆ ํ˜•์ œ์ž…๋‹ˆ๋‹ค

๊ฐœ๋ฐœ ์ค‘์—๋Š” ์ปดํŒŒ์ผ๋Ÿฌ, ๋นŒ๋“œ ๋ชจ๋“œ, ์ข…์†์„ฑ ๋ฒ„์ „ ๋ณ€๊ฒฝ, ์ •์  ๋ถ„์„ ์ˆ˜ํ–‰, ์„ฑ๋Šฅ ์ธก์ •, ์ ์šฉ ๋ฒ”์œ„ ์ˆ˜์ง‘, ๋ฌธ์„œ ์ƒ์„ฑ ๋“ฑ์„ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ €๋Š” ์ œ๊ฐ€ ์›ํ•˜๋Š” ๋ชจ๋“  ๊ฒƒ์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” CMake๋ฅผ ์ •๋ง ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค.

๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด CMake๋ฅผ ๋น„ํŒํ•˜๊ณ , ๋‹น์—ฐํžˆ ๊ทธ๋Ÿด ๋•Œ๋„ ์žˆ์ง€๋งŒ, ์‚ดํŽด๋ณด๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ๊ทธ๋ ‡๊ฒŒ ๋‚˜์˜์ง€๋Š” ์•Š์œผ๋ฉฐ ์ตœ๊ทผ์—๋Š” ๋‚˜์˜์ง€ ์•Š์•„, ๊ฐœ๋ฐœ ๋ฐฉํ–ฅ์€ ์ƒ๋‹นํžˆ ๊ธ์ •์ ์ž…๋‹ˆ๋‹ค.

์ด ๋…ธํŠธ์—์„œ๋Š” CMake ์‹œ์Šคํ…œ์—์„œ C++๋กœ ํ—ค๋” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐ„๋‹จํžˆ ๊ตฌ์„ฑํ•˜์—ฌ ๋‹ค์Œ ๊ธฐ๋Šฅ์„ ์–ป๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค ๋“œ๋ฆฌ๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

  1. ์ง‘ํšŒ;
  2. ์ž๋™ ์‹คํ–‰ ํ…Œ์ŠคํŠธ;
  3. ์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€ ์ธก์ •;
  4. ์„ค์น˜;
  5. ์ž๋™ ๋ฌธ์„œํ™”;
  6. ์˜จ๋ผ์ธ ์ƒŒ๋“œ๋ฐ•์Šค ์ƒ์„ฑ;
  7. ์ •์  ๋ถ„์„.

์ด๋ฏธ ์žฅ์ ๊ณผ C-make๋ฅผ ์ดํ•ดํ•˜๊ณ  ์žˆ๋Š” ์‚ฌ๋žŒ์ด๋ผ๋ฉด ๋ˆ„๊ตฌ๋‚˜ ๊ฐ„๋‹จํžˆ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ ํ…œํ”Œ๋ฆฟ ๋‹ค์šด๋กœ๋“œ ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.


๋‚ด์šฉ

  1. ๋‚ด๋ถ€์—์„œ ํ”„๋กœ์ ํŠธํ•˜๊ธฐ
    1. ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ
    2. ๊ธฐ๋ณธ CMake ํŒŒ์ผ(./CMakeLists.txt)
      1. ํ”„๋กœ์ ํŠธ ์ •๋ณด
      2. ํ”„๋กœ์ ํŠธ ์˜ต์…˜
      3. ์ปดํŒŒ์ผ ์˜ต์…˜
      4. ์ฃผ์š” ๋ชฉํ‘œ
      5. ์„ค์น˜
      6. ํ…Œ์ŠคํŠธ
      7. ะ”ะพะบัƒะผะตะฝั‚ะฐั†ะธั
      8. ์˜จ๋ผ์ธ ์ƒŒ๋“œ๋ฐ•์Šค
    3. ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ(test/CMakeLists.txt)
      1. ํ…Œ์ŠคํŠธ
      2. ์ ์šฉ ๋ฒ”์œ„
    4. ๋ฌธ์„œ์šฉ ์Šคํฌ๋ฆฝํŠธ(doc/CMakeLists.txt)
    5. ์˜จ๋ผ์ธ ์ƒŒ๋“œ๋ฐ•์Šค์šฉ ์Šคํฌ๋ฆฝํŠธ(online/CMakeLists.txt)
  2. ์™ธ๋ถ€ ํ”„๋กœ์ ํŠธ
    1. ์กฐ๋ฆฝ
      1. ์„ธ๋Œ€
      2. ์กฐ๋ฆฝ
    2. ์˜ต์…˜
      1. MYLIB_COVERAGE
      2. MYLIB_ํ…Œ์ŠคํŠธ ์ค‘
      3. MYLIB_DOXYGEN_LANGUAGE
    3. ์กฐ๋ฆฝ๋Œ€์ƒ
      1. ๊ธฐ๋ณธ์ ์œผ๋กœ
      2. mylib ๋‹จ์œ„ ํ…Œ์ŠคํŠธ
      3. ๊ฒ€์‚ฌ
      4. ์ ์šฉ ๋ฒ”์œ„
      5. ์˜์‚ฌ
      6. ์ง€ํŒก์ด ์ƒ์ž
    4. ์˜ˆ
  3. ๋„๊ตฌ
  4. ์ •์  ๋ถ„์„
  5. ์‚ฌํ›„

๋‚ด๋ถ€์—์„œ ํ”„๋กœ์ ํŠธํ•˜๊ธฐ

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

.
โ”œโ”€โ”€ CMakeLists.txt
โ”œโ”€โ”€ README.en.md
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ doc
โ”‚   โ”œโ”€โ”€ CMakeLists.txt
โ”‚   โ””โ”€โ”€ Doxyfile.in
โ”œโ”€โ”€ include
โ”‚   โ””โ”€โ”€ mylib
โ”‚       โ””โ”€โ”€ myfeature.hpp
โ”œโ”€โ”€ online
โ”‚   โ”œโ”€โ”€ CMakeLists.txt
โ”‚   โ”œโ”€โ”€ mylib-example.cpp
โ”‚   โ””โ”€โ”€ wandbox.py
โ””โ”€โ”€ test
    โ”œโ”€โ”€ CMakeLists.txt
    โ”œโ”€โ”€ mylib
    โ”‚   โ””โ”€โ”€ myfeature.cpp
    โ””โ”€โ”€ test_main.cpp

CMake ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฃผ๋กœ ๋‹ค๋ฃจ๋ฏ€๋กœ ์ž์„ธํžˆ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ๋‚˜ ๋‚˜๋จธ์ง€ ํŒŒ์ผ์„ ์ง์ ‘ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ…œํ”Œ๋ฆฟ ํ”„๋กœ์ ํŠธ ํŽ˜์ด์ง€์—์„œ.

๊ธฐ๋ณธ CMake ํŒŒ์ผ(./CMakeLists.txt)

ํ”„๋กœ์ ํŠธ ์ •๋ณด

์šฐ์„ , ํ•„์š”ํ•œ CMake ์‹œ์Šคํ…œ ๋ฒ„์ „์„ ์š”์ฒญํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. CMake๋Š” ๋ฐœ์ „ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋‹ค์–‘ํ•œ ์กฐ๊ฑด์—์„œ์˜ ๋ช…๋ น ์„œ๋ช…๊ณผ ๋™์ž‘์ด ๋ณ€ํ™”ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. CMake๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ์ฆ‰์‹œ ์ดํ•ดํ•˜๋ ค๋ฉด ์ด์— ๋Œ€ํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์„ ์ฆ‰์‹œ ๊ธฐ๋กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

cmake_minimum_required(VERSION 3.13)

๊ทธ๋Ÿฐ ๋‹ค์Œ ํ”„๋กœ์ ํŠธ, ์ด๋ฆ„, ๋ฒ„์ „, ์‚ฌ์šฉ๋œ ์–ธ์–ด ๋“ฑ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ะบะพะผะฐะฝะดัƒ project).

์ด ๊ฒฝ์šฐ ์–ธ์–ด๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. CXX (์ด๊ฒƒ์€ C++๋ฅผ ์˜๋ฏธํ•จ) CMake๊ฐ€ C ์–ธ์–ด ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ๋ฌด๋ฆฌํ•˜๊ฒŒ ๊ฒ€์ƒ‰ํ•˜์ง€ ์•Š๋„๋ก ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค(๊ธฐ๋ณธ์ ์œผ๋กœ CMake์—๋Š” C์™€ C++๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ์–ธ์–ด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค).

project(Mylib VERSION 1.0 LANGUAGES CXX)

์—ฌ๊ธฐ์—์„œ ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์— ํ•˜์œ„ ํ”„๋กœ์ ํŠธ๋กœ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ์ฆ‰์‹œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์•ž์œผ๋กœ ๋งŽ์€ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

get_directory_property(IS_SUBPROJECT PARENT_DIRECTORY)

ํ”„๋กœ์ ํŠธ ์˜ต์…˜

์šฐ๋ฆฌ๋Š” ๋‘ ๊ฐ€์ง€ ์˜ต์…˜์„ ์ œ๊ณตํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ฒซ ๋ฒˆ์งธ ์˜ต์…˜์€ MYLIB_TESTING โ€” ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์ด ํ…Œ์ŠคํŠธ์— ์ ํ•ฉํ•˜๋‹ค๊ณ  ํ™•์‹ ํ•˜์ง€๋งŒ ์˜ˆ๋ฅผ ๋“ค์–ด ํ”„๋กœ์ ํŠธ๋ฅผ ์„ค์น˜ํ•˜๊ฑฐ๋‚˜ ํŒจํ‚ค์ง€ํ•˜๊ธฐ๋งŒ ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์ด๋Š” ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ํ”„๋กœ์ ํŠธ๊ฐ€ ํ•˜์œ„ ํ”„๋กœ์ ํŠธ๋กœ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ํ”„๋กœ์ ํŠธ ์‚ฌ์šฉ์ž๋Š” ํ…Œ์ŠคํŠธ ์‹คํ–‰์— ๊ด€์‹ฌ์ด ์—†์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉํ•˜๋Š” ์ข…์†์„ฑ์„ ํ…Œ์ŠคํŠธํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

option(MYLIB_TESTING "ะ’ะบะปัŽั‡ะธั‚ัŒ ะผะพะดัƒะปัŒะฝะพะต ั‚ะตัั‚ะธั€ะพะฒะฐะฝะธะต" ON)

์ถ”๊ฐ€์ ์œผ๋กœ ๋ณ„๋„์˜ ์˜ต์…˜์„ ๋งŒ๋“ค์–ด ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. MYLIB_COVERAGE ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ ์ ์šฉ ๋ฒ”์œ„๋ฅผ ์ธก์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ถ”๊ฐ€ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•˜๋ฏ€๋กœ ๋ช…์‹œ์ ์œผ๋กœ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

option(MYLIB_COVERAGE "ะ’ะบะปัŽั‡ะธั‚ัŒ ะธะทะผะตั€ะตะฝะธะต ะฟะพะบั€ั‹ั‚ะธั ะบะพะดะฐ ั‚ะตัั‚ะฐะผะธ" OFF)

์ปดํŒŒ์ผ ์˜ต์…˜

๋ฌผ๋ก  ์šฐ๋ฆฌ๋Š” ๋ฉ‹์ง„ ํ”„๋กœ๊ทธ๋ž˜๋จธ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ปดํŒŒ์ผ๋Ÿฌ๋กœ๋ถ€ํ„ฐ ์ตœ๋Œ€ ์ˆ˜์ค€์˜ ์ปดํŒŒ์ผ ํƒ€์ž„ ์ง„๋‹จ์„ ์›ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์šฐ์Šค ํ•œ ๋งˆ๋ฆฌ๋„ ๋น ์ ธ๋‚˜์˜ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

add_compile_options(
    -Werror

    -Wall
    -Wextra
    -Wpedantic

    -Wcast-align
    -Wcast-qual
    -Wconversion
    -Wctor-dtor-privacy
    -Wenum-compare
    -Wfloat-equal
    -Wnon-virtual-dtor
    -Wold-style-cast
    -Woverloaded-virtual
    -Wredundant-decls
    -Wsign-conversion
    -Wsign-promo
)

๋˜ํ•œ C++ ์–ธ์–ด ํ‘œ์ค€์„ ์™„์ „ํžˆ ์ค€์ˆ˜ํ•˜๊ธฐ ์œ„ํ•ด ํ™•์žฅ ๊ธฐ๋Šฅ์„ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. CMake์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

if(NOT CMAKE_CXX_EXTENSIONS)
    set(CMAKE_CXX_EXTENSIONS OFF)
endif()

์ฃผ์š” ๋ชฉํ‘œ

์šฐ๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ํ—ค๋” ํŒŒ์ผ๋กœ๋งŒ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ •์  ๋˜๋Š” ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜•ํƒœ์˜ ๋ฐฐ๊ธฐ ํŒŒ์ผ์ด ์—†์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด, ์šฐ๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•˜๊ณ  ์‹œ์Šคํ…œ์—์„œ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๋ฉฐ ํ”„๋กœ์ ํŠธ์— ์—ฐ๊ฒฐ๋˜์–ด์•ผ ํ•˜๋ฉฐ ๋™์‹œ์— ๋™์ผํ•œ ํ—ค๋”์™€ ์ถ”๊ฐ€ ํ—ค๋”๋„ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์†์„ฑ์— ์ฒจ๋ถ€๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด ์ธํ„ฐํŽ˜์ด์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

add_library(mylib INTERFACE)

ํ—ค๋”๋ฅผ ์ธํ„ฐํŽ˜์ด์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋ฐ”์ธ๋”ฉํ•ฉ๋‹ˆ๋‹ค.

CMake์˜ ํ˜„๋Œ€์ ์ด๊ณ  ํŒจ์…”๋„ˆ๋ธ”ํ•œ ์ฒญ์†Œ๋…„ ์‚ฌ์šฉ์€ ํ—ค๋”, ์†์„ฑ ๋“ฑ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ๋‹จ์ผ ๋Œ€์ƒ์„ ํ†ตํ•ด ์ „์†ก๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ๋งํ•ด๋„ ์ถฉ๋ถ„ํ•ด target_link_libraries(target PRIVATE dependency)๋ฐ ๋Œ€์ƒ๊ณผ ๊ด€๋ จ๋œ ๋ชจ๋“  ํ—ค๋” dependency, ๋Œ€์ƒ์— ์†ํ•œ ์†Œ์Šค์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. target. ๊ทธ๋ฆฌ๊ณ  ๋‹น์‹ ์€ ์•„๋ฌด๊ฒƒ๋„ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค [target_]include_directories. ์ด๋Š” ์•„๋ž˜ ๋ถ„์„์—์„œ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ CMake ์Šคํฌ๋ฆฝํŠธ.

์†Œ์œ„์—๋„ ์ฃผ๋ชฉํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ะฒั‹ั€ะฐะถะตะฝะธั-ะณะตะฝะตั€ะฐั‚ะพั€ั‹: $<...>.

์ด ๋ช…๋ น์€ ํ•„์š”ํ•œ ํ—ค๋”๋ฅผ ์ธํ„ฐํŽ˜์ด์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ์—ฐ๊ฒฐํ•˜๋ฉฐ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋™์ผํ•œ CMake ๊ณ„์ธต ๋‚ด์˜ ๋Œ€์ƒ์— ์—ฐ๊ฒฐ๋œ ๊ฒฝ์šฐ ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ํ—ค๋”๊ฐ€ ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ${CMAKE_CURRENT_SOURCE_DIR}/include, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์‹œ์Šคํ…œ์— ์„ค์น˜๋˜์–ด ์žˆ๊ณ  ๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์— ์—ฐ๊ฒฐ๋œ ๊ฒฝ์šฐ find_package, ๊ทธ๋Ÿฌ๋ฉด ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ํ—ค๋”๊ฐ€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. include ์„ค์น˜ ๋””๋ ‰ํ† ๋ฆฌ์— ์ƒ๋Œ€์ ์ž…๋‹ˆ๋‹ค.

target_include_directories(mylib INTERFACE
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

์–ธ์–ด ํ‘œ์ค€์„ ์„ค์ •ํ•ด ๋ด…์‹œ๋‹ค. ๋ฌผ๋ก , ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ ๊ฒƒ. ๋™์‹œ์— ์šฐ๋ฆฌ๋Š” ํ‘œ์ค€์„ ํฌํ•จํ•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์šฐ๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋„ ์ด๋ฅผ ํ™•์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์„ค์ •๋œ ์†์„ฑ์— ์นดํ…Œ๊ณ ๋ฆฌ๊ฐ€ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค๋กœ ์ธํ•ด ๋‹ฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. INTERFACE (์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. target_compile_features ๋ช…๋ น).

target_compile_features(mylib INTERFACE cxx_std_17)

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋ณ„์นญ์„ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์•„๋ฆ„๋‹ค์›€์„ ์œ„ํ•ด ํŠน๋ณ„ํ•œ "๋„ค์ž„์ŠคํŽ˜์ด์Šค"์— ์œ„์น˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋‹ค๋ฅธ ๋ชจ๋“ˆ์ด ๋‚˜ํƒ€๋‚  ๋•Œ ์œ ์šฉํ•˜๋ฉฐ, ์„œ๋กœ ๋…๋ฆฝ์ ์œผ๋กœ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Busta์—์„œ์ฒ˜๋Ÿผ.

add_library(Mylib::mylib ALIAS mylib)

์„ค์น˜

ํ—ค๋”๋ฅผ ์‹œ์Šคํ…œ์— ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ๋Š” ๋ชจ๋“  ๊ฒƒ์ด ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  ํ—ค๋”๊ฐ€ ์žˆ๋Š” ํด๋”๊ฐ€ ๋””๋ ‰ํ† ๋ฆฌ์— ๋“ค์–ด๊ฐ€์•ผ ํ•œ๋‹ค๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค. include ์„ค์น˜ ์œ„์น˜์— ๋น„ํ•ด

install(DIRECTORY include/mylib DESTINATION include)

๋‹ค์Œ์œผ๋กœ, ํƒ€์‚ฌ ํ”„๋กœ์ ํŠธ์—์„œ ๋ช…๋ น์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•œ๋‹ค๊ณ  ๋นŒ๋“œ ์‹œ์Šคํ…œ์— ์•Œ๋ฆฝ๋‹ˆ๋‹ค. find_package(Mylib) ๊ทธ๋ฆฌ๊ณ  ๋ชฉํ‘œ๋ฅผ ๋‹ฌ์„ฑ Mylib::mylib.

install(TARGETS mylib EXPORT MylibConfig)
install(EXPORT MylibConfig NAMESPACE Mylib:: DESTINATION share/Mylib/cmake)

๋‹ค์Œ ์ฃผ๋ฌธ์€ ์ด๋ ‡๊ฒŒ ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํƒ€์‚ฌ ํ”„๋กœ์ ํŠธ์—์„œ ๋‹ค์Œ ๋ช…๋ น์„ ํ˜ธ์ถœํ•  ๋•Œ find_package(Mylib 1.2.3 REQUIRED), ์„ค์น˜๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‹ค์ œ ๋ฒ„์ „์€ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. 1.2.3CMake๋Š” ์ž๋™์œผ๋กœ ์˜ค๋ฅ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๋ฒ„์ „์„ ์ˆ˜๋™์œผ๋กœ ์ถ”์ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

include(CMakePackageConfigHelpers)
write_basic_package_version_file("${PROJECT_BINARY_DIR}/MylibConfigVersion.cmake"
    VERSION
        ${PROJECT_VERSION}
    COMPATIBILITY
        AnyNewerVersion
)
install(FILES "${PROJECT_BINARY_DIR}/MylibConfigVersion.cmake" DESTINATION share/Mylib/cmake)

ํ…Œ์ŠคํŠธ

๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™”๋œ ๊ฒฝ์šฐ ํ•ด๋‹น ์˜ต์…˜ ๋˜๋Š” ์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ๊ฐ€ ํ•˜์œ„ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ CMake ํ”„๋กœ์ ํŠธ์— ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. add_subdirectory, ์šฐ๋ฆฌ๋Š” ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ผ ๋” ์ด์ƒ ์ด๋™ํ•˜์ง€ ์•Š์œผ๋ฉฐ ํ…Œ์ŠคํŠธ ์ƒ์„ฑ ๋ฐ ์‹คํ–‰ ๋ช…๋ น์„ ์„ค๋ช…ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹จ์ˆœํžˆ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

if(NOT MYLIB_TESTING)
    message(STATUS "ะขะตัั‚ะธั€ะพะฒะฐะฝะธะต ะฟั€ะพะตะบั‚ะฐ Mylib ะฒั‹ะบะปัŽั‡ะตะฝะพ")
elseif(IS_SUBPROJECT)
    message(STATUS "Mylib ะฝะต ั‚ะตัั‚ะธั€ัƒะตั‚ัั ะฒ ั€ะตะถะธะผะต ะฟะพะดะผะพะดัƒะปั")
else()
    add_subdirectory(test)
endif()

ะ”ะพะบัƒะผะตะฝั‚ะฐั†ะธั

ํ•˜์œ„ ํ”„๋กœ์ ํŠธ์˜ ๊ฒฝ์šฐ์—๋„ ๋ฌธ์„œ๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

if(NOT IS_SUBPROJECT)
    add_subdirectory(doc)
endif()

์˜จ๋ผ์ธ ์ƒŒ๋“œ๋ฐ•์Šค

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ•˜์œ„ ํ”„๋กœ์ ํŠธ์—๋„ ์˜จ๋ผ์ธ ์ƒŒ๋“œ๋ฐ•์Šค๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

if(NOT IS_SUBPROJECT)
    add_subdirectory(online)
endif()

ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ(test/CMakeLists.txt)

ํ…Œ์ŠคํŠธ

์šฐ์„ , ํ•„์š”ํ•œ ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ํฌํ•จ๋œ ํŒจํ‚ค์ง€๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค(์›ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ๊ต์ฒด).

find_package(doctest 2.3.3 REQUIRED)

ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ์‹คํ–‰ ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋‚˜๋Š” ํ•จ์ˆ˜๋ฅผ ํฌํ•จํ•  ํŒŒ์ผ๋งŒ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๋ฐ”์ด๋„ˆ๋ฆฌ์— ์ง์ ‘ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. main.

add_executable(mylib-unit-tests test_main.cpp)

๊ทธ๋ฆฌ๊ณ  ๋‚˜์ค‘์— ํ…Œ์ŠคํŠธ ์ž์ฒด๋ฅผ ์„ค๋ช…ํ•˜๋Š” ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋ ‡๊ฒŒ ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.

target_sources(mylib-unit-tests PRIVATE mylib/myfeature.cpp)

์šฐ๋ฆฌ๋Š” ์˜์กด์„ฑ์„ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ํ•„์š”ํ•œ CMake ๋Œ€์ƒ๋งŒ ๋ฐ”์ด๋„ˆ๋ฆฌ์— ์—ฐ๊ฒฐํ–ˆ๊ณ  ๋ช…๋ น์„ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. target_include_directories. ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ์šฐ๋ฆฌ ํ”„๋ ˆ์ž„์›Œํฌ์˜ ์ œ๋ชฉ Mylib::mylib, ๋นŒ๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜(์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ C++ ์–ธ์–ด ํ‘œ์ค€)๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ด๋Ÿฌํ•œ ๋ชฉํ‘œ๋ฅผ ๋‹ฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

target_link_libraries(mylib-unit-tests
    PRIVATE
        Mylib::mylib
        doctest::doctest
)

๋งˆ์ง€๋ง‰์œผ๋กœ, "๋นŒ๋“œ"๊ฐ€ ํ…Œ์ŠคํŠธ ์‹คํ–‰๊ณผ ๋™์ผํ•œ ๋”๋ฏธ ๋Œ€์ƒ์„ ์ƒ์„ฑํ•˜๊ณ  ์ด ๋Œ€์ƒ์„ ๊ธฐ๋ณธ ๋นŒ๋“œ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค(์†์„ฑ์€ ์ด ์ž‘์—…์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค). ALL). ์ฆ‰, ๊ธฐ๋ณธ ๋นŒ๋“œ๊ฐ€ ํ…Œ์ŠคํŠธ ์‹คํ–‰์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๋ฏ€๋กœ ํ…Œ์ŠคํŠธ ์‹คํ–‰์„ ์žŠ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

add_custom_target(check ALL COMMAND mylib-unit-tests)

์ ์šฉ ๋ฒ”์œ„

๋‹ค์Œ์œผ๋กœ, ์ ์ ˆํ•œ ์˜ต์…˜์ด ์ง€์ •๋œ ๊ฒฝ์šฐ ์ฝ”๋“œ ์ ์šฉ ๋ฒ”์œ„ ์ธก์ •์„ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. CMake๋ณด๋‹ค๋Š” ์ปค๋ฒ„๋ฆฌ์ง€ ์ธก์ • ๋„๊ตฌ์™€ ๋” ๊ด€๋ จ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž์„ธํžˆ ์„ค๋ช…ํ•˜์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ ๋ชฉํ‘œ๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค๋Š” ์ ๋งŒ ์•Œ์•„๋‘๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. coverage, ์ปค๋ฒ„๋ฆฌ์ง€ ์ธก์ •์„ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์ด ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

find_program(GCOVR_EXECUTABLE gcovr)
if(MYLIB_COVERAGE AND GCOVR_EXECUTABLE)
    message(STATUS "ะ˜ะทะผะตั€ะตะฝะธะต ะฟะพะบั€ั‹ั‚ะธั ะบะพะดะฐ ั‚ะตัั‚ะฐะผะธ ะฒะบะปัŽั‡ะตะฝะพ")

    target_compile_options(mylib-unit-tests PRIVATE --coverage)
    target_link_libraries(mylib-unit-tests PRIVATE gcov)

    add_custom_target(coverage
        COMMAND
            ${GCOVR_EXECUTABLE}
                --root=${PROJECT_SOURCE_DIR}/include/
                --object-directory=${CMAKE_CURRENT_BINARY_DIR}
        DEPENDS
            check
    )
elseif(MYLIB_COVERAGE AND NOT GCOVR_EXECUTABLE)
    set(MYLIB_COVERAGE OFF)
    message(WARNING "ะ”ะปั ะทะฐะผะตั€ะพะฒ ะฟะพะบั€ั‹ั‚ะธั ะบะพะดะฐ ั‚ะตัั‚ะฐะผะธ ั‚ั€ะตะฑัƒะตั‚ัั ะฟั€ะพะณั€ะฐะผะผะฐ gcovr")
endif()

๋ฌธ์„œ์šฉ ์Šคํฌ๋ฆฝํŠธ(doc/CMakeLists.txt)

Doxygen์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค.

find_package(Doxygen)

๋‹ค์Œ์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์–ธ์–ด ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ–ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ๋งŒ์ง€์ง€ ์•Š๊ณ , ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ๋Ÿฌ์‹œ์•„์–ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ Doxygen ์‹œ์Šคํ…œ ํŒŒ์ผ์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์–ธ์–ด๋ฅผ ํฌํ•จํ•˜์—ฌ ํ•„์š”ํ•œ ๋ชจ๋“  ๋ณ€์ˆ˜๋Š” ๊ตฌ์„ฑ ํ”„๋กœ์„ธ์Šค ์ค‘์— ํ•ด๋‹น ์œ„์น˜๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค(์ฐธ์กฐ: ะบะพะผะฐะฝะดัƒ configure_file).

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋ชฉํ‘œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. doc, ๋ฌธ์„œ ์ƒ์„ฑ์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ๋ฌธ์„œ ์ƒ์„ฑ์€ ๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค์—์„œ ๊ฐ€์žฅ ํฐ ์š”๊ตฌ ์‚ฌํ•ญ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€์ƒ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”๋˜์ง€ ์•Š์œผ๋ฉฐ ๋ช…์‹œ์ ์œผ๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

if (Doxygen_FOUND)
    if (NOT MYLIB_DOXYGEN_LANGUAGE)
        set(MYLIB_DOXYGEN_LANGUAGE Russian)
    endif()
    message(STATUS "Doxygen documentation will be generated in ${MYLIB_DOXYGEN_LANGUAGE}")
    configure_file(Doxyfile.in Doxyfile)
    add_custom_target(doc COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
endif ()

์˜จ๋ผ์ธ ์ƒŒ๋“œ๋ฐ•์Šค์šฉ ์Šคํฌ๋ฆฝํŠธ(online/CMakeLists.txt)

์—ฌ๊ธฐ์„œ๋Š” ์„ธ ๋ฒˆ์งธ Python์„ ์ฐพ์•„ ํƒ€๊ฒŸ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. wandbox, ์„œ๋น„์Šค API์— ํ•ด๋‹นํ•˜๋Š” ์š”์ฒญ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์™„๋“œ๋ฐ•์Šค, ๊ทธ๋ฆฌ๊ณ  ๊ทธ๋ฅผ ๋ฉ€๋ฆฌ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์‘๋‹ต์—๋Š” ์™„์„ฑ๋œ ์ƒŒ๋“œ๋ฐ•์Šค์— ๋Œ€ํ•œ ๋งํฌ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

find_program(PYTHON3_EXECUTABLE python3)
if(PYTHON3_EXECUTABLE)
    set(WANDBOX_URL "https://wandbox.org/api/compile.json")

    add_custom_target(wandbox
        COMMAND
            ${PYTHON3_EXECUTABLE} wandbox.py mylib-example.cpp "${PROJECT_SOURCE_DIR}" include |
            curl -H "Content-type: application/json" -d @- ${WANDBOX_URL}
        WORKING_DIRECTORY
            ${CMAKE_CURRENT_SOURCE_DIR}
        DEPENDS
            mylib-unit-tests
    )
else()
    message(WARNING "ะ”ะปั ัะพะทะดะฐะฝะธั ะพะฝะปะฐะนะฝ-ะฟะตัะพั‡ะฝะธั†ั‹ ั‚ั€ะตะฑัƒะตั‚ัั ะธะฝั‚ะตั€ะฟั€ะตั‚ะฐั‚ะพั€ ะฏะŸ python 3-ะน ะฒะตั€ัะธะธ")
endif()

์™ธ๋ถ€ ํ”„๋กœ์ ํŠธ

์ด์ œ ์ด ๋ชจ๋“  ๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์กฐ๋ฆฝ

CMake ๋นŒ๋“œ ์‹œ์Šคํ…œ์˜ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ด ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ๋Š” ๋‘ ๋‹จ๊ณ„๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.

์„ธ๋Œ€

cmake -S ะฟัƒั‚ัŒ/ะบ/ะธัั…ะพะดะฝะธะบะฐะผ -B ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ [ะพะฟั†ะธะธ ...]

์ด์ „ ๋ฒ„์ „์˜ CMake๋กœ ์ธํ•ด ์œ„ ๋ช…๋ น์ด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์ƒ๋žตํ•ด ๋ณด์„ธ์š”. -S:

cmake ะฟัƒั‚ัŒ/ะบ/ะธัั…ะพะดะฝะธะบะฐะผ -B ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ [ะพะฟั†ะธะธ ...]

์˜ต์…˜์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ธฐ.

ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ

cmake --build ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ [--target target]

์กฐ๋ฆฝ ๋ชฉํ‘œ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด.

์˜ต์…˜

MYLIB_COVERAGE

cmake -S ... -B ... -DMYLIB_COVERAGE=ON [ะฟั€ะพั‡ะธะต ะพะฟั†ะธะธ ...]

๋Œ€์ƒ ํฌํ•จ coverage, ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ ์ ์šฉ ๋ฒ”์œ„ ์ธก์ •์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

MYLIB_ํ…Œ์ŠคํŠธ ์ค‘

cmake -S ... -B ... -DMYLIB_TESTING=OFF [ะฟั€ะพั‡ะธะต ะพะฟั†ะธะธ ...]

๋‹จ์œ„ ํ…Œ์ŠคํŠธ ๋นŒ๋“œ ๋ฐ ๋Œ€์ƒ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. check. ๊ฒฐ๊ณผ์ ์œผ๋กœ ํ…Œ์ŠคํŠธ์— ์˜ํ•œ ์ฝ”๋“œ ์ ์šฉ ๋ฒ”์œ„ ์ธก์ •์ด ๊บผ์ง‘๋‹ˆ๋‹ค(์ฐธ์กฐ: MYLIB_COVERAGE).

ํ”„๋กœ์ ํŠธ๊ฐ€ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•˜์œ„ ํ”„๋กœ์ ํŠธ๋กœ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์— ์—ฐ๊ฒฐ๋œ ๊ฒฝ์šฐ์—๋„ ํ…Œ์ŠคํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ๋น„ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. add_subdirectory.

MYLIB_DOXYGEN_LANGUAGE

cmake -S ... -B ... -DMYLIB_DOXYGEN_LANGUAGE=English [ะฟั€ะพั‡ะธะต ะพะฟั†ะธะธ ...]

ํƒ€๊ฒŸ์ด ์ƒ์„ฑํ•˜๋Š” ๋ฌธ์„œ์˜ ์–ธ์–ด๋ฅผ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค. doc ์ฃผ์–ด์ง„ ๊ฒƒ์—๊ฒŒ. ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์–ธ์–ด ๋ชฉ๋ก์€ ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์„ธ์š”. Doxygen ์‹œ์Šคํ…œ ์›น์‚ฌ์ดํŠธ.

๋Ÿฌ์‹œ์•„์–ด๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์กฐ๋ฆฝ๋Œ€์ƒ

๊ธฐ๋ณธ์ ์œผ๋กœ

cmake --build path/to/build/directory
cmake --build path/to/build/directory --target all

๋Œ€์ƒ์ด ์ง€์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ(๋Œ€์ƒ๊ณผ ๋™์ผํ•จ) all), ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ฒƒ์„ ์ˆ˜์ง‘ํ•˜๊ณ  ๋Œ€์ƒ์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. check.

mylib ๋‹จ์œ„ ํ…Œ์ŠคํŠธ

cmake --build path/to/build/directory --target mylib-unit-tests

๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒ€์‚ฌ

cmake --build ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ --target check

์ˆ˜์ง‘๋œ(์•„์ง ์ˆ˜์ง‘๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ˆ˜์ง‘๋œ) ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

ะกะผ. ั‚ะฐะบะถะต mylib-unit-tests.

์ ์šฉ ๋ฒ”์œ„

cmake --build ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ --target coverage

ํ”„๋กœ๊ทธ๋žจ์„ ์‚ฌ์šฉํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ ์ ์šฉ ๋ฒ”์œ„์— ๋Œ€ํ•œ ์‹คํ–‰ ์ค‘์ธ(์•„์ง ์‹คํ–‰๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ) ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค. gcovr.

์ฝ”ํŒ… ๋ฐฐ๊ธฐ ์žฅ์น˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

------------------------------------------------------------------------------
                           GCC Code Coverage Report
Directory: /path/to/cmakecpptemplate/include/
------------------------------------------------------------------------------
File                                       Lines    Exec  Cover   Missing
------------------------------------------------------------------------------
mylib/myfeature.hpp                            2       2   100%   
------------------------------------------------------------------------------
TOTAL                                          2       2   100%
------------------------------------------------------------------------------

์˜ต์…˜์ด ํ™œ์„ฑํ™”๋œ ๊ฒฝ์šฐ์—๋งŒ ๋Œ€์ƒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. MYLIB_COVERAGE.

ะกะผ. ั‚ะฐะบะถะต check.

์˜์‚ฌ

cmake --build ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ --target doc

์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ ๋ฌธ์„œ ์ƒ์„ฑ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋…์†Œ.

์ง€ํŒก์ด ์ƒ์ž

cmake --build ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ --target wandbox

์„œ๋น„์Šค์˜ ์‘๋‹ต์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

{
    "permlink" :    "QElvxuMzHgL9fqci",
    "status" :  "0",
    "url" : "https://wandbox.org/permlink/QElvxuMzHgL9fqci"
}

์„œ๋น„์Šค๋Š” ์ด๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์™„๋“œ๋ฐ•์Šค. ์„œ๋ฒ„๊ฐ€ ์–ผ๋งˆ๋‚˜ ์œ ์—ฐํ•œ์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ, ์ด ๊ธฐํšŒ๋ฅผ ๋‚จ์šฉํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ

์ปค๋ฒ„๋ฆฌ์ง€ ์ธก์ •์„ ํ†ตํ•ด ๋””๋ฒ„๊ทธ ๋ชจ๋“œ์—์„œ ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ

cmake -S ะฟัƒั‚ัŒ/ะบ/ะธัั…ะพะดะฝะธะบะฐะผ -B ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ -DCMAKE_BUILD_TYPE=Debug -DMYLIB_COVERAGE=ON
cmake --build ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ --target coverage --parallel 16

์˜ˆ๋น„ ์กฐ๋ฆฝ ๋ฐ ํ…Œ์ŠคํŠธ ์—†์ด ํ”„๋กœ์ ํŠธ ์„ค์น˜

cmake -S ะฟัƒั‚ัŒ/ะบ/ะธัั…ะพะดะฝะธะบะฐะผ -B ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ -DMYLIB_TESTING=OFF -DCMAKE_INSTALL_PREFIX=ะฟัƒั‚ัŒ/ะบ/ัƒัั‚ะฐะฝะพะฒะพะนะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ
cmake --build ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ --target install

ํŠน์ • ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆด๋ฆฌ์Šค ๋ชจ๋“œ๋กœ ๋นŒ๋“œ

cmake -S ะฟัƒั‚ัŒ/ะบ/ะธัั…ะพะดะฝะธะบะฐะผ -B ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++-8 -DCMAKE_PREFIX_PATH=ะฟัƒั‚ัŒ/ะบ/ะดะธั€ะตะบั‚ะพั€ะธะธ/ะบัƒะดะฐ/ัƒัั‚ะฐะฝะพะฒะปะตะฝั‹/ะทะฐะฒะธัะธะผะพัั‚ะธ
cmake --build ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ --parallel 4

์˜์–ด๋กœ ๋ฌธ์„œ ์ƒ์„ฑ

cmake -S ะฟัƒั‚ัŒ/ะบ/ะธัั…ะพะดะฝะธะบะฐะผ -B ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ -DCMAKE_BUILD_TYPE=Release -DMYLIB_DOXYGEN_LANGUAGE=English
cmake --build ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ --target doc

๋„๊ตฌ

  1. CMake 3.13

    ์‹ค์ œ๋กœ CMake ๋ฒ„์ „ 3.13์€ ์ด ๋„์›€๋ง์— ์„ค๋ช…๋œ ์ผ๋ถ€ ์ฝ˜์†” ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐ๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. CMake ์Šคํฌ๋ฆฝํŠธ ๊ตฌ๋ฌธ์˜ ๊ด€์ ์—์„œ ์ƒ์„ฑ์ด ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ํ˜ธ์ถœ๋˜๋Š” ๊ฒฝ์šฐ ๋ฒ„์ „ 3.8์ด๋ฉด ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

  2. ํ…Œ์ŠคํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋…ํ…Œ์ŠคํŠธ

    ํ…Œ์ŠคํŠธ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ฐธ์กฐ: ะพะฟั†ะธัŽ MYLIB_TESTING).

  3. ๋…์†Œ

    ๋ฌธ์„œ๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ์–ธ์–ด๋ฅผ ์ „ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด ์˜ต์…˜์ด ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. MYLIB_DOXYGEN_LANGUAGE.

  4. ์–ธ์–ด ํ†ต์—ญ์‚ฌ ํŒŒ์ด์ฌ 3

    ์ž๋™ ์ƒ์„ฑ์˜ ๊ฒฝ์šฐ ์˜จ๋ผ์ธ ์ƒŒ๋“œ๋ฐ•์Šค.

์ •์  ๋ถ„์„

CMake์™€ ๋ช‡ ๊ฐ€์ง€ ์ข‹์€ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ตœ์†Œํ•œ์˜ ๋…ธ๋ ฅ์œผ๋กœ ์ •์  ๋ถ„์„์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Cppcheck

CMake์—๋Š” ์ •์  ๋ถ„์„ ๋„๊ตฌ์— ๋Œ€ํ•œ ์ง€์›์ด ๋‚ด์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. Cppcheck.

์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. CMAKE_CXX_CPPCHECK:

cmake -S ะฟัƒั‚ัŒ/ะบ/ะธัั…ะพะดะฝะธะบะฐะผ -B ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_CPPCHECK="cppcheck;--enable=all;-Iะฟัƒั‚ัŒ/ะบ/ะธัั…ะพะดะฝะธะบะฐะผ/include"

์ดํ›„์—๋Š” ์†Œ์Šค๊ฐ€ ์ปดํŒŒ์ผ๋˜๊ณ  ๋‹ค์‹œ ์ปดํŒŒ์ผ๋  ๋•Œ๋งˆ๋‹ค ์ •์  ๋ถ„์„์ด ์ž๋™์œผ๋กœ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ์ถ”๊ฐ€๋กœ ์ˆ˜ํ–‰ํ•  ์ž‘์—…์€ ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ ์†Œ๋ฆฌ

ํ›Œ๋ฅญํ•œ ๋„๊ตฌ์˜ ๋„์›€์œผ๋กœ scan-build ๋˜ํ•œ ์ •์  ๋ถ„์„์„ ์ฆ‰์‹œ ์‹คํ–‰ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

scan-build cmake -S ะฟัƒั‚ัŒ/ะบ/ะธัั…ะพะดะฝะธะบะฐะผ -B ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ -DCMAKE_BUILD_TYPE=Debug
scan-build cmake --build ะฟัƒั‚ัŒ/ะบ/ัะฑะพั€ะพั‡ะฝะพะน/ะดะธั€ะตะบั‚ะพั€ะธะธ

์—ฌ๊ธฐ์„œ๋Š” Cppcheck์˜ ๊ฒฝ์šฐ์™€ ๋‹ฌ๋ฆฌ ๋งค๋ฒˆ ๋นŒ๋“œ๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. scan-build.

์‚ฌํ›„

CMake๋Š” ๋ชจ๋“  ์ทจํ–ฅ๊ณผ ์ƒ‰์ƒ์— ๋งž๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๋งค์šฐ ๊ฐ•๋ ฅํ•˜๊ณ  ์œ ์—ฐํ•œ ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ตฌ๋ฌธ์ด ๋•Œ๋•Œ๋กœ ๋ถ€์กฑํ•œ ์ ์ด ๋งŽ์ง€๋งŒ ์•…๋งˆ๋Š” ์—ฌ์ „ํžˆ ๊ทธ๋ ค์ง„ ๊ฒƒ๋งŒํผ ๋”์ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌํšŒ์™€ ๊ฑด๊ฐ•์˜ ์ด์ต์„ ์œ„ํ•ด CMake ๋นŒ๋“œ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

โ†’ ํ”„๋กœ์ ํŠธ ํ…œํ”Œ๋ฆฟ ๋‹ค์šด๋กœ๋“œ

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€