CMake เช…เชจเซ‡ C++ เช•เชพเชฏเชฎ เชญเชพเชˆเช“ เช›เซ‡

CMake เช…เชจเซ‡ C++ เช•เชพเชฏเชฎ เชญเชพเชˆเช“ เช›เซ‡

เชตเชฟเช•เชพเชธ เชฆเชฐเชฎเชฟเชฏเชพเชจ, เชฎเชจเซ‡ เช•เชฎเซเชชเชพเชˆเชฒเชฐ เชฌเชฆเชฒเชตเชพ, เชฌเชฟเชฒเซเชก เชฎเซ‹เชกเซเชธ, เชกเชฟเชชเซ‡เชจเซเชกเชจเซเชธเซ€ เชตเชฐเซเชเชจ, เชธเซเชŸเซ‡เชŸเชฟเช• เชเชจเชพเชฒเชฟเชธเชฟเชธ, เชชเชฐเชซเซ‹เชฐเซเชฎเชจเซเชธ เชฎเชพเชชเชตเชพ, เช•เชตเชฐเซ‡เชœ เชเช•เชคเซเชฐเชฟเชค เช•เชฐเชตเชพ, เชฆเชธเซเชคเชพเชตเซ‡เชœเซ€เช•เชฐเชฃ เชตเช—เซ‡เชฐเซ‡ เชฌเชจเชพเชตเชตเชพเชจเซเช‚ เช—เชฎเซ‡ เช›เซ‡. เช…เชจเซ‡ เชนเซเช‚ เช–เชฐเซ‡เช–เชฐ CMake เชจเซ‡ เชชเซเชฐเซ‡เชฎ เช•เชฐเซเช‚ เช›เซเช‚ เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡ เชฎเชจเซ‡ เชœเซ‡ เชœเซ‹เชˆเช เช›เซ‡ เชคเซ‡ เช•เชฐเชตเชพ เชฆเซ‡ เช›เซ‡.

เช˜เชฃเชพ เชฒเซ‹เช•เซ‹ เชธเซ€เชฎเซ‡เช•เชจเซ€ เชŸเซ€เช•เชพ เช•เชฐเซ‡ เช›เซ‡, เช…เชจเซ‡ เช˜เชฃเซ€ เชตเชพเชฐ เชคเซ‡ เชฏเซ‹เช—เซเชฏ เชฐเซ€เชคเซ‡, เชชเชฐเช‚เชคเซ เชœเซ‹ เชคเชฎเซ‡ เชคเซ‡เชจเซ‡ เชœเซเช“, เชคเซ‹ เชฌเชงเซเช‚ เชเชŸเชฒเซเช‚ เช–เชฐเชพเชฌ เชจเชฅเซ€, เช…เชจเซ‡ เชคเชพเชœเซ‡เชคเชฐเชฎเชพเช‚ เชฌเชฟเชฒเช•เซเชฒ เช–เชฐเชพเชฌ เชจเชฅเซ€, เช…เชจเซ‡ เชตเชฟเช•เชพเชธเชจเซ€ เชฆเชฟเชถเชพ เชคเชฆเซเชฆเชจ เชนเช•เชพเชฐเชพเชคเซเชฎเช• เช›เซ‡.

เช† เชจเซ‹เช‚เชงเชฎเชพเช‚, เชนเซเช‚ เชคเชฎเชจเซ‡ เชœเชฃเชพเชตเชตเชพ เชฎเชพเช‚เช—เซ เช›เซเช‚ เช•เซ‡ เชจเซ€เชšเซ‡เชจเซ€ เช•เชพเชฐเซเชฏเช•เซเชทเชฎเชคเชพ เชฎเซ‡เชณเชตเชตเชพ เชฎเชพเชŸเซ‡ เชธเซ€เชฎเซ‡เช• เชธเชฟเชธเซเชŸเชฎเชฎเชพเช‚ C++ เชฎเชพเช‚ เชนเซ‡เชกเชฐ เชฒเชพเช‡เชฌเซเชฐเซ‡เชฐเซ€ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช—เซ‹เช เชตเชตเซ€:

  1. เชตเชฟเชงเชพเชจเชธเชญเชพ;
  2. เช‘เชŸเซ‹เชฐเชจ เชชเชฐเซ€เช•เซเชทเชฃเซ‹;
  3. เช•เซ‹เชก เช•เชตเชฐเซ‡เชœ เชฎเชพเชชเชจ;
  4. เชธเซเชฅเชพเชชเชจ;
  5. เชธเซเชตเชคเชƒ-เชฆเชธเซเชคเชพเชตเซ‡เชœเซ€เช•เชฐเชฃ;
  6. เช‘เชจเชฒเชพเช‡เชจ เชธเซ‡เชจเซเชกเชฌเซ‹เช•เซเชธ เชœเชจเชฐเซ‡เชถเชจ;
  7. เชธเซเชฅเชฟเชฐ เชตเชฟเชถเซเชฒเซ‡เชทเชฃ.

เช•เซ‹เชˆเชชเชฃ เชœเซ‡ เชชเชนเซ‡เชฒเชพเชฅเซ€ เชœ เชซเชพเชฏเชฆเชพ เช…เชจเซ‡ เชธเซ€-เชฎเซ‡เช•เชจเซ‡ เชธเชฎเชœเซ‡ เช›เซ‡ เชคเซ‡ เชธเชฐเชณ เชฐเซ€เชคเซ‡ เช•เชฐเซ€ เชถเช•เซ‡ เช›เซ‡ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชŸเซ‡เชฎเซเชชเชฒเซ‡เชŸ เชกเชพเช‰เชจเชฒเซ‹เชก เช•เชฐเซ‹ เช…เชจเซ‡ เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซเช‚ เชถเชฐเซ‚ เช•เชฐเซ‹.


เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพ

  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. เชชเซ‡rationเซ€
      2. เชตเชฟเชงเชพเชจเชธเชญเชพ
    2. เชตเชฟเช•เชฒเซเชชเซ‹
      1. MYLIB_COVERAGE
      2. MYLIB_TESTING
      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 เชซเชพเช‡เชฒ (./CMakeLists.txt)

เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชฎเชพเชนเชฟเชคเซ€

เชธเซŒ เชชเซเชฐเชฅเชฎ, เชคเชฎเชพเชฐเซ‡ เชธเซ€เชฎเซ‡เช• เชธเชฟเชธเซเชŸเชฎเชจเชพ เช†เชตเชถเซเชฏเช• เชธเช‚เชธเซเช•เชฐเชฃเชจเซ€ เชตเชฟเชจเช‚เชคเซ€ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡. 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)

เช…เชฎเซ‡ เชนเซ‡เชกเชฐเซ‹เชจเซ‡ เช…เชฎเชพเชฐเซ€ เช‡เชจเซเชŸเชฐเชซเซ‡เชธ เชฒเชพเช‡เชฌเซเชฐเซ‡เชฐเซ€เชฎเชพเช‚ เชฌเชพเช‚เชงเซ€เช เช›เซ€เช.

เชธเซ€เชฎเซ‡เช•เชจเซ‹ เช†เชงเซเชจเชฟเช•, เชซเซ‡เชถเชจเซ‡เชฌเชฒ, เชฏเซเชตเชพ เช‰เชชเชฏเซ‹เช— เชธเซ‚เชšเชตเซ‡ เช›เซ‡ เช•เซ‡ เชนเซ‡เชกเชฐเซเชธ, เชชเซเชฐเซ‹เชชเชฐเซเชŸเซ€เช เชตเช—เซ‡เชฐเซ‡. เชเช• เชœ เชฒเช•เซเชทเซเชฏ เชฆเซเชตเชพเชฐเชพ เชชเซเชฐเชธเชพเชฐเชฟเชค. เชคเซ‡เชฅเซ€ เชคเซ‡ เช•เชนเซ‡เชตเซเช‚ เชชเซ‚เชฐเชคเซเช‚ เช›เซ‡ 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)

เชšเชพเชฒเซ‹ เช†เชชเชฃเซ€ เชฒเชพเชˆเชฌเซเชฐเซ‡เชฐเซ€ เชฎเชพเชŸเซ‡ เช‰เชชเชจเชพเชฎ เชฌเชจเชพเชตเซ€เช. เชคเชฆเซเชชเชฐเชพเช‚เชค, เชธเซŒเช‚เชฆเชฐเซเชฏ เชฎเชพเชŸเซ‡, เชคเซ‡ เชตเชฟเชถเชฟเชทเซเชŸ "เชจเซ‡เชฎเชธเซเชชเซ‡เชธ" เชฎเชพเช‚ เชนเชถเซ‡. เชœเซเชฏเชพเชฐเซ‡ เช…เชฎเชพเชฐเซ€ เชฒเชพเช‡เชฌเซเชฐเซ‡เชฐเซ€เชฎเชพเช‚ เชตเชฟเชตเชฟเชง เชฎเซ‹เชกเซเชฏเซเชฒ เชฆเซ‡เช–เชพเชฏ เชคเซเชฏเชพเชฐเซ‡ เช† เช‰เชชเชฏเซ‹เช—เซ€ เชฅเชถเซ‡, เช…เชจเซ‡ เช…เชฎเซ‡ เชคเซ‡เชจเซ‡ เชเช•เชฌเซ€เชœเชพเชฅเซ€ เชธเซเชตเชคเช‚เชคเซเชฐ เชฐเซ€เชคเซ‡ เช•เชจเซ‡เช•เซเชŸ เช•เชฐเชตเชพ เชœเชˆเช เช›เซ€เช. เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชฌเซเชธเซเชŸเชพเชจเซ€ เชœเซ‡เชฎ.

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)

เช…เชฎเซ‡ เชจเชฟเชฐเซเชญเชฐเชคเชพเชจเซ‡ เชœเซ‹เชกเซ€เช เช›เซ€เช. เชฎเชนเซ‡เชฐเชฌเชพเชจเซ€ เช•เชฐเซ€เชจเซ‡ เชจเซ‹เช‚เชง เช•เชฐเซ‹ เช•เซ‡ เช…เชฎเซ‡ เชซเช•เซเชค เชธเซ€เชฎเซ‡เช• เชฒเช•เซเชทเซเชฏเซ‹เชจเซ‡ เช…เชฎเชพเชฐเซ€ เชฌเชพเชˆเชจเชฐเซ€ เชธเชพเชฅเซ‡ เชฒเชฟเช‚เช• เช•เชฐเซเชฏเชพ เช›เซ‡ เช…เชจเซ‡ เช†เชฆเซ‡เชถเชจเซ‡ เช•เซ‰เชฒ เช•เชฐเซเชฏเซ‹ เชจเชฅเซ€ 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)

เชกเซ‹เช•เซเชธเชฟเชœเชจ เชฎเชณเซเชฏเซ‹.

find_package(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)

เช…เชนเซ€เช‚ เช†เชชเชฃเซ‡ เชคเซเชฐเซ€เชœเซ‹ เชชเชพเชฏเชฅเซ‹เชจ เชถเซ‹เชงเซ€เช เช›เซ€เช เช…เชจเซ‡ เชฒเช•เซเชทเซเชฏ เชฌเชจเชพเชตเซ€เช เช›เซ€เช 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()

เชฌเชนเชพเชฐ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ

เชนเชตเซ‡ เช† เชฌเชงเชพเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชฐเชตเซ‹ เชคเซ‡ เชœเซ‹เชˆเช.

เชตเชฟเชงเชพเชจเชธเชญเชพ

เชธเซ€เชฎเซ‡เช• เชฌเชฟเชฒเซเชก เชธเชฟเชธเซเชŸเชฎ เชชเชฐเชจเชพ เช•เซ‹เชˆเชชเชฃ เช…เชจเซเชฏ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเชจเซ€ เชœเซ‡เชฎ เช† เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเชจเซเช‚ เชจเชฟเชฐเซเชฎเชพเชฃ, เชฌเซ‡ เชคเชฌเช•เซเช•เชพเช“เชจเซ‹ เชธเชฎเชพเชตเซ‡เชถ เช•เชฐเซ‡ เช›เซ‡:

เชชเซ‡rationเซ€

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

เชœเซ‹ เช‰เชชเชฐเซ‹เช•เซเชค เช†เชฆเซ‡เชถ เชธเซ€เชฎเซ‡เช•เชจเชพ เชœเซ‚เชจเชพ เชธเช‚เชธเซเช•เชฐเชฃเชจเซ‡ เช•เชพเชฐเชฃเซ‡ เช•เชพเชฎ เช•เชฐเชคเซเช‚ เชจเชฅเซ€, เชคเซ‹ เช…เชตเช—เชฃเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ‹ -S:

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

เชตเชฟเช•เชฒเซเชชเซ‹ เชตเชฟเชถเซ‡ เชตเชงเซ.

เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเชจเซเช‚ เชจเชฟเชฐเซเชฎเชพเชฃ

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

เชเชธเซ‡เชฎเซเชฌเชฒเซ€ เชฒเช•เซเชทเซเชฏเซ‹ เชตเชฟเชถเซ‡ เชตเชงเซ.

เชตเชฟเช•เชฒเซเชชเซ‹

MYLIB_COVERAGE

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

เชฒเช•เซเชทเซเชฏเชจเซ‹ เชธเชฎเชพเชตเซ‡เชถ เชฅเชพเชฏ เช›เซ‡ coverage, เชœเซ‡เชจเซ€ เชธเชพเชฅเซ‡ เชคเชฎเซ‡ เชชเชฐเซ€เช•เซเชทเชฃเซ‹ เชฆเซเชตเชพเชฐเชพ เช•เซ‹เชก เช•เชตเชฐเซ‡เชœเชจเซ‡ เชฎเชพเชชเชตเชพเชจเซเช‚ เชถเชฐเซ‚ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹.

MYLIB_TESTING

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

เชฏเซเชจเชฟเชŸ เชŸเซ‡เชธเซเชŸ เชฌเชฟเชฒเซเชก เช…เชจเซ‡ เชฒเช•เซเชทเซเชฏเชจเซ‡ เช…เช•เซเชทเชฎ เช•เชฐเชตเชพเชจเซ€ เช•เซเชทเชฎเชคเชพ เชชเซเชฐเชฆเชพเชจ เช•เชฐเซ‡ เช›เซ‡ check. เชชเชฐเชฟเชฃเชพเชฎเซ‡, เชชเชฐเซ€เช•เซเชทเชฃเซ‹ เชฆเซเชตเชพเชฐเชพ เช•เซ‹เชก เช•เชตเชฐเซ‡เชœเชจเซเช‚ เชฎเชพเชชเชจ เชฌเช‚เชง เช›เซ‡ (เชœเซเช“. MYLIB_COVERAGE).

เชœเซ‹ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เช†เชฆเซ‡เชถเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชธเชฌเชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชคเชฐเซ€เช•เซ‡ เชฌเซ€เชœเชพ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชธเชพเชฅเซ‡ เชœเซ‹เชกเชพเชฏเซ‡เชฒ เชนเซ‹เชฏ เชคเซ‹ เชชเชฐเซ€เช•เซเชทเชฃ เชชเชฃ เช†เชชเชฎเซ‡เชณเซ‡ เช…เช•เซเชทเชฎ เชฅเชˆ เชœเชพเชฏ เช›เซ‡ add_subdirectory.

MYLIB_DOXYGEN_LANGUAGE

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

เชฒเช•เซเชทเซเชฏ เชœเชจเชฐเซ‡เชŸ เช•เชฐเซ‡ เช›เซ‡ เชคเซ‡ เชฆเชธเซเชคเชพเชตเซ‡เชœเซ‹เชจเซ€ เชญเชพเชทเชพเชจเซ‡ เชธเซเชตเชฟเชš เช•เชฐเซ‡ เช›เซ‡ doc เช†เชชเซ‡เชฒเชจเซ‡. เช‰เชชเชฒเชฌเซเชง เชญเชพเชทเชพเช“เชจเซ€ เชธเซ‚เชšเชฟ เชฎเชพเชŸเซ‡, เชœเซเช“ เชกเซ‹เช•เซเชธเชฟเชœเชจ เชธเชฟเชธเซเชŸเชฎ เชตเซ‡เชฌเชธเชพเช‡เชŸ.

เชฐเชถเชฟเชฏเชจ เชฎเซ‚เชณเชญเซ‚เชค เชฐเซ€เชคเซ‡ เชธเช•เซเชทเชฎ เช›เซ‡.

เชเชธเซ‡เชฎเซเชฌเชฒเซ€ เชฒเช•เซเชทเซเชฏเซ‹

เชฎเซ‚เชณเชญเซ‚เชค เชฐเซ€เชคเซ‡

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. เชธเซ€.เชเชฎ.เช•เซ‡. 3.13

    เชตเชพเชธเซเชคเชตเชฎเชพเช‚, CMake เชธเช‚เชธเซเช•เชฐเชฃ 3.13 เชฎเชพเชคเซเชฐ เช† เชฎเชฆเชฆเชฎเชพเช‚ เชตเชฐเซเชฃเชตเซ‡เชฒ เช•เซ‡เชŸเชฒเชพเช• เช•เชจเซเชธเซ‹เชฒ เช†เชฆเซ‡เชถเซ‹เชจเซ‡ เชšเชฒเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เชœเชฐเซ‚เชฐเซ€ เช›เซ‡. เชธเซ€เชฎเซ‡เช• เชธเซเช•เซเชฐเชฟเชชเซเชŸเซเชธเชจเชพ เชตเชพเช•เซเชฏเชฐเชšเชจเชพเชจเชพเช‚ เชฆเซƒเชทเซเชŸเชฟเช•เซ‹เชฃเชฅเซ€, เชœเซ‹ เชœเชจเชฐเซ‡เชถเชจเชจเซ‡ เช…เชจเซเชฏ เชฐเซ€เชคเซ‡ เชฌเซ‹เชฒเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เชคเซ‹ เช†เชตเซƒเชคเซเชคเชฟ 3.8 เชชเชฐเซเชฏเชพเชชเซเชค เช›เซ‡.

  2. เชชเชฐเซ€เช•เซเชทเชฃ เชชเซเชธเซเชคเช•เชพเชฒเชฏ doctest

    เชชเชฐเซ€เช•เซเชทเชฃ เช…เช•เซเชทเชฎ เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡ (เชœเซเช“ ะพะฟั†ะธัŽ MYLIB_TESTING).

  3. เชกเซ‹เช•เซเชธเชฟเชœเชจ

    เชœเซ‡ เชญเชพเชทเชพเชฎเชพเช‚ เชฆเชธเซเชคเชพเชตเซ‡เชœเซ€เช•เชฐเชฃ เชœเชจเชฐเซ‡เชŸ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡ เชคเซ‡เชจเซ‡ เชฌเชฆเชฒเชตเชพ เชฎเชพเชŸเซ‡, เชเช• เชตเชฟเช•เชฒเซเชช เช†เชชเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ MYLIB_DOXYGEN_LANGUAGE.

  4. เชญเชพเชทเชพ เชฆเซเชญเชพเชทเชฟเชฏเชพ เชชเชพเชฏเชฅเซ‹เชจ 3

    เช†เชชเซ‹เช†เชช เชœเชจเชฐเซ‡เชถเชจ เชฎเชพเชŸเซ‡ เช‘เชจเชฒเชพเช‡เชจ เชธเซ‡เชจเซเชกเชฌเซ‹เช•เซเชธ.

เชธเซเชฅเชฟเชฐ เชตเชฟเชถเซเชฒเซ‡เชทเชฃ

CMake เช…เชจเซ‡ เช•เซ‡เชŸเชฒเชพเช• เชธเชพเชฐเชพ เชธเชพเชงเชจเซ‹ เชธเชพเชฅเซ‡, เชคเชฎเซ‡ เชจเซเชฏเซ‚เชจเชคเชฎ เชชเซเชฐเชฏเชคเซเชจเซ‹ เชธเชพเชฅเซ‡ เชธเซเชฅเชฟเชฐ เชตเชฟเชถเซเชฒเซ‡เชทเชฃ เชชเซเชฐเชฆเชพเชจ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹.

เชธเซ€เชชเซ€เชชเซ€เชšเซ‡เช•

CMake เชชเชพเชธเซ‡ เชธเซเชŸเซ‡เชŸเชฟเช• เชเชจเชพเชฒเชฟเชธเชฟเชธ เชŸเซ‚เชฒ เชฎเชพเชŸเซ‡ เชฌเชฟเชฒเซเชŸ-เช‡เชจ เชธเชชเซ‹เชฐเซเชŸ เช›เซ‡ เชธเซ€เชชเซ€เชชเซ€เชšเซ‡เช•.

เช† เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชคเชฎเชพเชฐเซ‡ เชตเชฟเช•เชฒเซเชชเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ 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 เชเช• เช–เซ‚เชฌ เชœ เชถเช•เซเชคเชฟเชถเชพเชณเซ€ เช…เชจเซ‡ เชฒเชตเชšเซ€เช• เชธเชฟเชธเซเชŸเชฎ เช›เซ‡ เชœเซ‡ เชคเชฎเชจเซ‡ เชฆเชฐเซ‡เช• เชธเซเชตเชพเชฆ เช…เชจเซ‡ เชฐเช‚เช— เชฎเชพเชŸเซ‡ เช•เชพเชฐเซเชฏเช•เซเชทเชฎเชคเชพ เช…เชฎเชฒเชฎเชพเช‚ เชฎเซ‚เช•เชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡. เช…เชจเซ‡, เชœเซ‹ เช•เซ‡ เชตเชพเช•เซเชฏเชฐเชšเชจเชพ เช•เซเชฏเชพเชฐเซ‡เช• เช‡เชšเซเช›เชฟเชค เชฅเชตเชพ เชฎเชพเชŸเซ‡ เช˜เชฃเซเช‚ เช›เซ‹เชกเซ€ เชฆเซ‡ เช›เซ‡, เชถเซ‡เชคเชพเชจ เชนเชœเซ เชชเชฃ เชคเซ‡เชŸเชฒเซ‹ เชญเชฏเช‚เช•เชฐ เชจเชฅเซ€ เชœเซ‡เชŸเชฒเซ‹ เชคเซ‡เชจเซ‡ เชฆเซ‹เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซ‹ เช›เซ‡. เชธเชฎเชพเชœ เช…เชจเซ‡ เช†เชฐเซ‹เช—เซเชฏเชจเชพ เชฒเชพเชญ เชฎเชพเชŸเซ‡ เชธเซ€เชฎเซ‡เช• เชฌเชฟเชฒเซเชก เชธเชฟเชธเซเชŸเชฎเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‹.

โ†’ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชŸเซ‡เชฎเซเชชเชฒเซ‡เชŸ เชกเชพเช‰เชจเชฒเซ‹เชก เช•เชฐเซ‹

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹