๊ฐ๋ฐ ์ค์๋ ์ปดํ์ผ๋ฌ, ๋น๋ ๋ชจ๋, ์ข ์์ฑ ๋ฒ์ ๋ณ๊ฒฝ, ์ ์ ๋ถ์ ์ํ, ์ฑ๋ฅ ์ธก์ , ์ ์ฉ ๋ฒ์ ์์ง, ๋ฌธ์ ์์ฑ ๋ฑ์ ์ข์ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ ๋ ์ ๊ฐ ์ํ๋ ๋ชจ๋ ๊ฒ์ ํ ์ ์๊ฒ ํด์ฃผ๋ CMake๋ฅผ ์ ๋ง ์ข์ํฉ๋๋ค.
๋ง์ ์ฌ๋๋ค์ด CMake๋ฅผ ๋นํํ๊ณ , ๋น์ฐํ ๊ทธ๋ด ๋๋ ์์ง๋ง, ์ดํด๋ณด๋ฉด ๋ชจ๋ ๊ฒ์ด ๊ทธ๋ ๊ฒ ๋์์ง๋ ์์ผ๋ฉฐ ์ต๊ทผ์๋ ๋์์ง ์์, ๊ฐ๋ฐ ๋ฐฉํฅ์ ์๋นํ ๊ธ์ ์ ์ ๋๋ค.
์ด ๋ ธํธ์์๋ CMake ์์คํ ์์ C++๋ก ํค๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฐ๋จํ ๊ตฌ์ฑํ์ฌ ๋ค์ ๊ธฐ๋ฅ์ ์ป๋ ๋ฐฉ๋ฒ์ ์๋ ค ๋๋ฆฌ๊ณ ์ ํฉ๋๋ค.
- ์งํ;
- ์๋ ์คํ ํ ์คํธ;
- ์ฝ๋ ์ปค๋ฒ๋ฆฌ์ง ์ธก์ ;
- ์ค์น;
- ์๋ ๋ฌธ์ํ;
- ์จ๋ผ์ธ ์๋๋ฐ์ค ์์ฑ;
- ์ ์ ๋ถ์.
์ด๋ฏธ ์ฅ์ ๊ณผ C-make๋ฅผ ์ดํดํ๊ณ ์๋ ์ฌ๋์ด๋ผ๋ฉด ๋๊ตฌ๋ ๊ฐ๋จํ ํ ์ ์์ต๋๋ค.
ํ๋ก์ ํธ ํ ํ๋ฆฟ ๋ค์ด๋ก๋ ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ ์ฌ์ฉํ๊ธฐ ์์ํฉ๋๋ค.
๋ด์ฉ
๋ด๋ถ์์ ํ๋ก์ ํธํ๊ธฐ ์ธ๋ถ ํ๋ก์ ํธ ๋๊ตฌ ์ ์ ๋ถ์ ์ฌํ
๋ด๋ถ์์ ํ๋ก์ ํธํ๊ธฐ
ํ๋ก์ ํธ ๊ตฌ์กฐ
.
โโโ 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_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(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.3
CMake๋ ์๋์ผ๋ก ์ค๋ฅ๋ฅผ ์์ฑํฉ๋๋ค. ์ฆ, ๋ฒ์ ์ ์๋์ผ๋ก ์ถ์ ํ ํ์๊ฐ ์์ต๋๋ค.
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)
ํ
์คํธ
๋ค์์ ์ฌ์ฉํ์ฌ ํ
์คํธ๊ฐ ๋ช
์์ ์ผ๋ก ๋นํ์ฑํ๋ ๊ฒฝ์ฐ 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)
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
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
๋ฌ์์์ด๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋์ด ์์ต๋๋ค.
์กฐ๋ฆฝ๋์
๊ธฐ๋ณธ์ ์ผ๋ก
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
ํ๋ก๊ทธ๋จ์ ์ฌ์ฉํ ํ
์คํธ๋ฅผ ํตํด ์ฝ๋ ์ ์ฉ ๋ฒ์์ ๋ํ ์คํ ์ค์ธ(์์ง ์คํ๋์ง ์์ ๊ฒฝ์ฐ) ๋จ์ ํ
์คํธ๋ฅผ ๋ถ์ํฉ๋๋ค.
์ฝํ ๋ฐฐ๊ธฐ ์ฅ์น๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
------------------------------------------------------------------------------
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
๋๊ตฌ
-
CMake 3.13์ค์ ๋ก CMake ๋ฒ์ 3.13์ ์ด ๋์๋ง์ ์ค๋ช ๋ ์ผ๋ถ ์ฝ์ ๋ช ๋ น์ ์คํํ๋ ๋ฐ๋ง ํ์ํฉ๋๋ค. CMake ์คํฌ๋ฆฝํธ ๊ตฌ๋ฌธ์ ๊ด์ ์์ ์์ฑ์ด ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ํธ์ถ๋๋ ๊ฒฝ์ฐ ๋ฒ์ 3.8์ด๋ฉด ์ถฉ๋ถํฉ๋๋ค.
-
ํ ์คํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
๋ ํ ์คํธ ํ ์คํธ๋ฅผ ๋นํ์ฑํํ ์ ์์ต๋๋ค(์ฐธ์กฐ:
).ะพะฟัะธั MYLIB_TESTING
-
๋ฌธ์๊ฐ ์์ฑ๋๋ ์ธ์ด๋ฅผ ์ ํํ๊ธฐ ์ํด ์ต์ ์ด ์ ๊ณต๋ฉ๋๋ค.
.MYLIB_DOXYGEN_LANGUAGE
-
์ธ์ด ํต์ญ์ฌ
ํ์ด์ฌ 3 ์๋ ์์ฑ์ ๊ฒฝ์ฐ
์จ๋ผ์ธ ์๋๋ฐ์ค .
์ ์ ๋ถ์
CMake์ ๋ช ๊ฐ์ง ์ข์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ฉด ์ต์ํ์ ๋ ธ๋ ฅ์ผ๋ก ์ ์ ๋ถ์์ ์ ๊ณตํ ์ ์์ต๋๋ค.
Cppcheck
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๋ ๋ชจ๋ ์ทจํฅ๊ณผ ์์์ ๋ง๋ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์๋ ๋งค์ฐ ๊ฐ๋ ฅํ๊ณ ์ ์ฐํ ์์คํ ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ตฌ๋ฌธ์ด ๋๋๋ก ๋ถ์กฑํ ์ ์ด ๋ง์ง๋ง ์ ๋ง๋ ์ฌ์ ํ ๊ทธ๋ ค์ง ๊ฒ๋งํผ ๋์ฐํ์ง ์์ต๋๋ค. ์ฌํ์ ๊ฑด๊ฐ์ ์ด์ต์ ์ํด CMake ๋น๋ ์์คํ ์ ์ฌ์ฉํ์ธ์.
โ
์ถ์ฒ : habr.com