C++ рд░ CMake - рд╕рдзреИрдВрднрд░рд┐ рднрд╛рдЗрд╣рд░реВ, рднрд╛рдЧ II

C++ рд░ CMake - рд╕рдзреИрдВрднрд░рд┐ рднрд╛рдЗрд╣рд░реВ, рднрд╛рдЧ II

рдЕрдШрд┐рд▓реНрд▓реЛ рднрд╛рдЧрдорд╛ рдпреЛ рдордиреЛрд░рдЮреНрдЬрдирд╛рддреНрдордХ рдХрдерд╛рд▓реЗ CMake рдирд┐рд░реНрдорд╛рдг рдкреНрд░рдгрд╛рд▓реА рдЬрдирд░реЗрдЯрд░ рднрд┐рддреНрд░ рд╣реЗрдбрд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдЧрд░реНрдиреЗ рдмрд╛рд░реЗ рдХреБрд░рд╛ рдЧрд░реНрдпреЛред

рдпрд╕ рдкрдЯрдХ рд╣рд╛рдореА рдпрд╕рдорд╛ рдХрдореНрдкрд╛рдЗрд▓ рдЧрд░рд┐рдПрдХреЛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдердкреНрдиреЗрдЫреМрдВ, рд░ рдПрдХрдЕрд░реНрдХрд╛рд╕рдБрдЧ рдореЛрдбреНрдпреБрд▓рд╣рд░реВ рд▓рд┐рдЩреНрдХ рдЧрд░реНрдиреЗ рдмрд╛рд░реЗ рдкрдирд┐ рдХреБрд░рд╛ рдЧрд░реНрдиреЗрдЫреМрдВред

рдкрд╣рд┐рд▓реЗ рдЬрд╕реНрддреИ, рдЬреЛ рдЕрдзреАрд░ рдЫрдиреН рддреБрд░реБрдиреНрддреИ рдЧрд░реНрди рд╕рдХреНрдЫрдиреН рдЕрджреНрдпрд╛рд╡рдзрд┐рдХ рднрдгреНрдбрд╛рд░рдорд╛ рдЬрд╛рдиреБрд╣реЛрд╕реН рд░ рдЖрдлреНрдиреЛ рд╣рд╛рддрд▓реЗ рд╕рдмреИ рдХреБрд░рд╛ рдЫреБрдиреБрд╣реЛрд╕реНред


рд╕рд╛рдордЧреНрд░реАрд╣рд░реВ

  1. рд╡рд┐рднрд╛рдЬрди рдЧрд░реНрдиреБрд╣реЛрд╕реН
  2. рдЬрд┐рддреНрдиреБрд╣реЛрд╕реН

рд╡рд┐рднрд╛рдЬрди рдЧрд░реНрдиреБрд╣реЛрд╕реН

рд╣рд╛рдореАрд▓реЗ рд╣рд╛рдореНрд░реЛ рдЙрдЪреНрдЪ рд▓рдХреНрд╖реНрдп рд╣рд╛рд╕рд┐рд▓ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐ рдЧрд░реНрдиреБ рдкрд░реНрдиреЗ рдкрд╣рд┐рд▓реЛ рдХреБрд░рд╛ рднрдиреЗрдХреЛ рд╣рд╛рдореАрд▓реЗ рд╡рд┐рдХрд╛рд╕ рдЧрд░реНрдиреЗ рд╕рдлреНрдЯрд╡реЗрдпрд░рд▓рд╛рдИ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛рдХреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдгрдмрд╛рдЯ рдПрдХрд░реВрдкрддрд╛ рднрдПрдХрд╛ рд╡рд┐рд╢реНрд╡рд╡реНрдпрд╛рдкреА, рдкреГрдердХ рдмреНрд▓рдХрд╣рд░реВрдорд╛ рд╡рд┐рднрд╛рдЬрди рдЧрд░реНрдиреБ рд╣реЛред

рдкрд╣рд┐рд▓реЛ рднрд╛рдЧрдорд╛, рдпрд╕реНрддреЛ рдорд╛рдирдХ рдмреНрд▓рдХ рд╡рд░реНрдгрди рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛ - рд╣реЗрдбрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕рдВрдЧ рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ред рдЕрдм рд╣рд╛рдореНрд░реЛ рдкрд░рд┐рдпреЛрдЬрдирд╛рдорд╛ тАЛтАЛрдХрдореНрдкрд╛рдЗрд▓ рдЧрд░рд┐рдПрдХреЛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдердкреМрдВред

рдпреЛ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐, рдХрд╛рд░реНрдпрдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирд▓рд╛рдИ рдмрд╛рд╣рд┐рд░ рдирд┐рдХрд╛рд▓реМрдВ myfunc рдЕрд▓рдЧ рдорд╛ .cpp-рдлрд╛рдЗрд▓:

diff --git a/include/mylib/myfeature.hpp b/include/mylib/myfeature.hpp
index 43db388..ba62b4f 100644
--- a/include/mylib/myfeature.hpp
+++ b/include/mylib/myfeature.hpp
@@ -46,8 +46,5 @@ namespace mylib

         ~  see mystruct
      */
-    inline bool myfunc (mystruct)
-    {
-        return true;
-    }
+    bool myfunc (mystruct);
 }
diff --git a/src/mylib/myfeature.cpp b/src/mylib/myfeature.cpp
new file mode 100644
index 0000000..abb5004
--- /dev/null
+++ b/src/mylib/myfeature.cpp
@@ -0,0 +1,9 @@
+#include <mylib/myfeature.hpp>
+
+namespace mylib
+{
+    bool myfunc (mystruct)
+    {
+        return true;
+    }
+}

рддреНрдпрд╕рдкрдЫрд┐ рд╣рд╛рдореА рдХрдореНрдкрд╛рдЗрд▓ рдЧрд░реНрди рдХреЛ рд▓рд╛рдЧреА рдкреБрд╕реНрддрдХрд╛рд▓рдп рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧрд░реНрджрдЫ (myfeature), рдЬрд╕рдорд╛ рдЕрдШрд┐рд▓реНрд▓реЛ рдЪрд░рдгрдорд╛ рдкреНрд░рд╛рдкреНрдд рднрдПрдХреЛ рдХреБрд░рд╛ рд╕рдорд╛рд╡реЗрд╢ рд╣реБрдиреЗрдЫ .cpp-рдлрд╛рдЗрд▓ред рдирдпрд╛рдБ рдкреБрд╕реНрддрдХрд╛рд▓рдпрд▓рд╛рдИ рд╕реНрдкрд╖реНрдЯ рд░реВрдкрдорд╛ рдЕрд╡рд╕реНрдерд┐рдд рд╣реЗрдбрд░рд╣рд░реВ рдЪрд╛рд╣рд┐рдиреНрдЫ, рд░ рдпреЛ рдкреНрд░рджрд╛рди рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐, рдпрд╕рд▓рд╛рдИ рдЕрд╡рд╕реНрдерд┐рдд рдЙрджреНрджреЗрд╢реНрдпрд╕рдБрдЧ рдЬреЛрдбреНрди рд╕рдХрд┐рдиреНрдЫ рд░ рд╣реБрдиреБрдкрд░реНрдЫред mylibред рдпрд╕рдмрд╛рд╣реЗрдХ, рддрд┐рдиреАрд╣рд░реВ рдмреАрдЪрдХреЛ рдЬрдбрд╛рди рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдЫ, рдЬрд╕рдХреЛ рдорддрд▓рдм рд▓рдХреНрд╖реНрдпрдорд╛ рдЬрдбрд╛рди рдЧрд░рд┐рдиреЗ рд╕рдмреИ рдХреБрд░рд╛ рд╣реЛ myfeature, рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдкрдорд╛ рд▓реЛрдб рд░ рд▓рдХреНрд╖реНрдп рдкреНрд░рд╛рдкреНрдд рд╣реБрдиреЗрдЫ mylib (рдмреБрдирд╛рдИ рд╡рд┐рдзрд┐рд╣рд░реВрдХреЛ рдмрд╛рд░реЗрдорд╛ рдердк).

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 108045c..0de77b8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -64,6 +64,17 @@ target_compile_features(mylib INTERFACE cxx_std_17)

 add_library(Mylib::mylib ALIAS mylib)

+###################################################################################################
+##
+##      ╨Ъ╨╛╨╝╨┐╨╕╨╗╨╕╤А╤Г╨╡╨╝╨░╤П ╨▒╨╕╨▒╨╗╨╕╨╛╤В╨╡╨║╨░
+##
+###################################################################################################
+
+add_library(myfeature src/mylib/myfeature.cpp)
+target_link_libraries(myfeature PUBLIC mylib)
+
+add_library(Mylib::myfeature ALIAS myfeature)
+

рдЕрд░реНрдХреЛ, рд╣рд╛рдореА рдпреЛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдЧрд░реНрдиреЗрдЫреМрдВ рдХрд┐ рдирдпрд╛рдБ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдкрдирд┐ рдкреНрд░рдгрд╛рд▓реАрдорд╛ рд╕реНрдерд╛рдкрд┐рдд рдЫ:

@@ -72,7 +83,7 @@ add_library(Mylib::mylib ALIAS mylib)

 install(DIRECTORY include/mylib DESTINATION include)

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

 include(CMakePackageConfigHelpers)

рдпреЛ рдЙрджреНрджреЗрд╢реНрдп рдХреЛ рд▓рд╛рдЧреА рдзреНрдпрд╛рди рджрд┐рдиреБрдкрд░реНрдЫ myfeature, рдХреЛ рд░реВрдкрдорд╛ mylib рдЙрдкрд╕рд░реНрдЧрдХреЛ рд╕рд╛рде рдПрдЙрдЯрд╛ рдЙрдкрдирд╛рдо рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░рд┐рдпреЛ Mylib::ред рдкреНрд░рдгрд╛рд▓реАрдорд╛ рд╕реНрдерд╛рдкрдирд╛рдХреЛ рд▓рд╛рдЧрд┐ рдирд┐рд░реНрдпрд╛рдд рдЧрд░реНрджрд╛ рджреБрд╡реИ рдЙрджреНрджреЗрд╢реНрдпрдХрд╛ рд▓рд╛рдЧрд┐ рд╕рдорд╛рди рд▓реЗрдЦрд┐рдПрдХреЛ рдЫред рдпрд╕рд▓реЗ рдХреБрдиреИ рдкрдирд┐ рд▓рдХреНрд╖реНрдпрдХреЛ рд╕рд╛рде рд╕рдорд╛рди рд░реВрдкрдорд╛ рдХрд╛рдо рдЧрд░реНрди рд╕рдореНрднрд╡ рдмрдирд╛рдЙрдБрдЫ рдмрд╛рдзреНрдпрдХрд╛рд░реА рдпреЛрдЬрдирд╛.

рдпрд╕ рдкрдЫрд┐, рдмрд╛рдБрдХреА рд╕рдмреИ рдПрдХрд╛рдЗ рдкрд░реАрдХреНрд╖рдгрд╣рд░реВрд▓рд╛рдИ рдирдпрд╛рдБ рдкреБрд╕реНрддрдХрд╛рд▓рдпрд╕рдБрдЧ рд▓рд┐рдЩреНрдХ рдЧрд░реНрди рдмрд╛рдБрдХреА рдЫ myfunc рд╢реАрд░реНрд╖рдХрдмрд╛рдЯ рд╣рдЯрд╛рдЗрдпреЛ, рддреНрдпрд╕реИрд▓реЗ рдЕрдм рддрдкрд╛рдИрдВрд▓реЗ рд▓рд┐рдЩреНрдХ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫ):

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 5620be4..bc1266c 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -4,7 +4,7 @@ add_executable(mylib-unit-tests test_main.cpp)
 target_sources(mylib-unit-tests PRIVATE mylib/myfeature.cpp)
 target_link_libraries(mylib-unit-tests
     PRIVATE
-        Mylib::mylib
+        Mylib::myfeature
         doctest::doctest
 )

рд╢реАрд░реНрд╖рдХ (Mylib::mylib) рдЕрдм рддрдкрд╛рдИрд▓рд╛рдИ рдЫреБрдЯреНрдЯреИ рдЬрдбрд╛рди рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫреИрди, рдХрд┐рдирдХрд┐ рдкрд╣рд┐рд▓реЗ рдиреИ рдЙрд▓реНрд▓реЗрдЦ рдЧрд░рд┐рдПрдЭреИрдВ, рддрд┐рдиреАрд╣рд░реВ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдкрдорд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдпрд╕рдБрдЧ рдЬреЛрдбрд┐рдПрдХрд╛ рдЫрдиреН (Mylib::myfeature).

рд░ рднрд░реНрдЦрд░реИ рдЖрдЗрдкреБрдЧреЗрдХреЛ рдкреБрд╕реНрддрдХрд╛рд▓рдпрд▓рд╛рдИ рдзреНрдпрд╛рдирдорд╛ рд░рд╛рдЦреЗрд░ рдХрднрд░реЗрдЬ рдорд╛рдкрди рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐ рдХреЗрд╣реА рдмрд╛рд░реАрдХрддрд╛рд╣рд░реВ рдердкреМрдВ:

@@ -15,11 +15,16 @@ if(MYLIB_COVERAGE AND GCOVR_EXECUTABLE)
     target_compile_options(mylib-unit-tests PRIVATE --coverage)
     target_link_libraries(mylib-unit-tests PRIVATE gcov)

+    target_compile_options(myfeature PRIVATE --coverage)
+    target_link_libraries(myfeature PRIVATE gcov)
+
     add_custom_target(coverage
         COMMAND
             ${GCOVR_EXECUTABLE}
-                --root=${PROJECT_SOURCE_DIR}/include/
-                --object-directory=${CMAKE_CURRENT_BINARY_DIR}
+                --root=${PROJECT_SOURCE_DIR}/
+                --filter=${PROJECT_SOURCE_DIR}/include
+                --filter=${PROJECT_SOURCE_DIR}/src
+                --object-directory=${PROJECT_BINARY_DIR}
         DEPENDS
             check
     )

рддрдкрд╛рдИрдВ рдердк рдкреБрд╕реНрддрдХрд╛рд▓рдпрд╣рд░реВ, рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдпреЛрдЧреНрдпрд╣рд░реВ, рдЖрджрд┐ рдердкреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред рддрд┐рдиреАрд╣рд░реВ рдкрд░рд┐рдпреЛрдЬрдирд╛ рднрд┐рддреНрд░ рдХрд╕рд░реА рдПрдХ рдЕрд░реНрдХрд╛рд╕рдБрдЧ рдЬреЛрдбрд┐рдПрдХрд╛ рдЫрдиреН рднрдиреНрдиреЗ рдХреБрд░рд╛рд▓реЗ рдлрд░рдХ рдкрд╛рд░реНрджреИрдиред рдХреЗрд╡рд▓ рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рдХреБрд░рд╛ рдпреЛ рд╣реЛ рдХрд┐ рдХреБрди рд▓рдХреНрд╖реНрдпрд╣рд░реВ рд╣рд╛рдореНрд░реЛ рдореЛрдбреНрдпреБрд▓рдХреЛ рдЗрдиреНрдЯрд░рдлреЗрд╕ рд╣реБрдиреН, рддреНрдпреЛ рд╣реЛ, рддрд┐рдиреАрд╣рд░реВ рдЯрд╛рдБрд╕реНрдЫрдиреНред

рдЬрд┐рддреНрдиреБрд╣реЛрд╕реН

рдЕрдм рд╣рд╛рдореАрд╕рдБрдЧ рдорд╛рдирдХ рдмреНрд▓рдХ рдореЛрдбреНрдпреБрд▓рд╣рд░реВ рдЫрдиреН, рд░ рд╣рд╛рдореА рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рд╣рд╛рд╡реА рдЧрд░реНрди рд╕рдХреНрдЫреМрдВ: рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдХреБрдиреИ рдкрдирд┐ рдЬрдЯрд┐рд▓рддрд╛рдХреЛ рд╕рдВрд░рдЪрдирд╛рдорд╛ рд░рдЪрдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН, рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдкреНрд░рдгрд╛рд▓реАрдорд╛ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН рд╡рд╛ рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдПрдХрд▓ рдЕрд╕реЗрдВрдмрд▓реА рдкреНрд░рдгрд╛рд▓реА рднрд┐рддреНрд░ рдПрдХрд╕рд╛рде рдЬреЛрдбреНрдиреБрд╣реЛрд╕реНред

рдкреНрд░рдгрд╛рд▓реАрдорд╛ рд╕реНрдерд╛рдкрдирд╛

рдореЛрдбреНрдпреБрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдирдХрд╛ рд▓рд╛рдЧрд┐ рд╡рд┐рдХрд▓реНрдкрд╣рд░реВ рдордзреНрдпреЗ рдПрдХ рдкреНрд░рдгрд╛рд▓реАрдорд╛ рд╣рд╛рдореНрд░реЛ рдореЛрдбреНрдпреБрд▓ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрди рд╣реЛред

cmake --build ╨┐╤Г╤В╤М/╨║/╤Б╨▒╨╛╤А╨╛╤З╨╜╨╛╨╣/╨┤╨╕╤А╨╡╨║╤В╨╛╤А╨╕╨╕ --target install

рддреНрдпрд╕ рдкрдЫрд┐, рдпреЛ рдХрдорд╛рдгреНрдб рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдХреБрдиреИ рдкрдирд┐ рдЕрдиреНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛рд╕рдБрдЧ рдЬреЛрдбрд┐рдПрдХреЛ рдЫ find_package.

find_package(Mylib 1.0 REQUIRED)

рд╕рдмрдореЛрдбреНрдпреБрд▓рдХреЛ рд░реВрдкрдорд╛ рдЬрдбрд╛рди

рдЕрд░реНрдХреЛ рд╡рд┐рдХрд▓реНрдк рднрдиреЗрдХреЛ рд╣рд╛рдореНрд░реЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯрд╕рдБрдЧ рдлреЛрд▓реНрдбрд░рд▓рд╛рдИ рдЕрд░реНрдХреЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯрдорд╛ рдХрдорд╛рдгреНрдб рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рд╕рдмрдореЛрдбреНрдпреБрд▓рдХреЛ рд░реВрдкрдорд╛ рдЬрдбрд╛рди рдЧрд░реНрдиреБ рд╣реЛ add_subdirectory.

рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБрд╣реЛрд╕реН

рдмрд╛рдзреНрдпрдХрд╛рд░реА рд╡рд┐рдзрд┐рд╣рд░реВ рдлрд░рдХ рдЫрдиреН, рддрд░ рдкрд░рд┐рдгрд╛рдо рдПрдЙрдЯреИ рдЫред рджреБрдмреИ рдЕрд╡рд╕реНрдерд╛рдорд╛, рд╣рд╛рдореНрд░реЛ рдореЛрдбреНрдпреБрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛рдорд╛ тАЛтАЛрд▓рдХреНрд╖реНрдпрд╣рд░реВ рдЙрдкрд▓рдмреНрдз рд╣реБрдиреЗрдЫрдиреН Mylib::myfeature ╨╕ Mylib::mylib, рдЬреБрди рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рдпреЛ рдЬрд╕реНрддреИ:

add_executable(some_executable some.cpp sources.cpp)
target_link_libraries(some_executable PRIVATE Mylib::myfeature)

рд╡рд┐рд╢реЗрд╖ рдЧрд░реА рд╣рд╛рдореНрд░реЛ рдорд╛рдорд▓рд╛ рдорд╛, рдкреБрд╕реНрддрдХрд╛рд▓рдп Mylib::myfeature рдкреБрд╕реНрддрдХрд╛рд▓рдпрд╕рдБрдЧ рд▓рд┐рдЩреНрдХ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рд╣реБрдБрджрд╛ рдЬрдбрд╛рди рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫ libmyfeatureред рдпрджрд┐ рддреНрдпрд╣рд╛рдБ рдкрд░реНрдпрд╛рдкреНрдд рд╣реЗрдбрд░рд╣рд░реВ рдЫрдиреН рднрдиреЗ, рдпреЛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд▓рд╛рдпрдХ рдЫ Mylib::mylib.

CMake рд▓рдХреНрд╖реНрдпрд╣рд░реВ рдХрдард┐рди рд╣реБрди рд╕рдХреНрдЫрдиреН, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рдХреЗрд╣реА рдЧреБрдгрд╣рд░реВ, рдирд┐рд░реНрднрд░рддрд╛рд╣рд░реВ, рдЖрджрд┐ рдлрд░реНрд╡рд╛рд░реНрдб рдЧрд░реНрдирдХрд╛ рд▓рд╛рдЧрд┐ рдорд╛рддреНрд░ред рдПрдХреИ рд╕рдордпрдорд╛, рддрд┐рдиреАрд╣рд░реВрд╕рдБрдЧ рдХрд╛рдо рд╕рдорд╛рди рд░реВрдкрдорд╛ рд╣реБрдиреНрдЫред

рддреНрдпреЛ рд╣рд╛рдореАрд▓реЗ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдерд┐рдпреЛред

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди