C++ dan CMake - saudara selamanya, bahagian II

C++ dan CMake - saudara selamanya, bahagian II

Pada bahagian sebelumnya Kisah menghiburkan ini bercakap tentang mengatur perpustakaan pengepala dalam penjana sistem binaan CMake.

Kali ini kami akan menambah perpustakaan yang disusun kepadanya, dan juga bercakap tentang menghubungkan modul antara satu sama lain.

Seperti sebelum ini, mereka yang tidak sabar boleh segera pergi ke repositori yang dikemas kini dan sentuh semuanya dengan tangan anda sendiri.


Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΠ΅

  1. Bahagikan
  2. Takluk

Bahagikan

Perkara pertama yang perlu kami lakukan untuk mencapai matlamat kami yang tinggi ialah membahagikan perisian yang kami bangunkan kepada blok terpencil universal yang seragam dari sudut pandangan pengguna.

Pada bahagian pertama, blok standard seperti itu diterangkan - projek dengan perpustakaan pengepala. Sekarang mari kita tambah perpustakaan yang disusun pada projek kami.

Untuk melakukan ini, mari kita keluarkan pelaksanaan fungsi tersebut myfunc secara berasingan .cpp-fail:

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;
+    }
+}

Kemudian kami mentakrifkan perpustakaan untuk disusun (myfeature), yang akan terdiri daripada apa yang diperolehi dalam langkah sebelumnya .cpp-fail. Perpustakaan baharu jelas memerlukan pengepala sedia ada, dan untuk menyediakannya, ia boleh dan harus terikat dengan tujuan sedia ada mylib. Selain itu, hubungan antara mereka adalah awam, yang bermaksud bahawa segala-galanya yang sasaran akan disambungkan myfeature, akan menerima beban dan sasaran secara automatik mylib (lebih lanjut mengenai kaedah mengait).

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)
+

Seterusnya, kami akan memastikan bahawa perpustakaan baharu turut dipasang pada sistem:

@@ -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)

Perlu diingatkan bahawa untuk tujuan tersebut myfeature, untuk mylib alias dengan awalan telah dicipta Mylib::. Perkara yang sama ditulis untuk kedua-dua tujuan apabila mengeksportnya untuk pemasangan pada sistem. Ini memungkinkan untuk bekerja secara seragam dengan matlamat untuk mana-mana skema mengikat.

Selepas ini, yang tinggal hanyalah memautkan ujian unit dengan perpustakaan baharu (function myfunc dikeluarkan daripada tajuk, jadi sekarang anda perlu memautkan):

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
 )

Tajuk (Mylib::mylib) kini anda tidak perlu menyambung secara berasingan, kerana, seperti yang telah disebutkan, ia disambungkan secara automatik bersama-sama dengan perpustakaan (Mylib::myfeature).

Dan mari tambahkan beberapa nuansa untuk memastikan pengukuran liputan dengan mengambil kira perpustakaan yang baru tiba:

@@ -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
     )

Anda boleh menambah lebih banyak perpustakaan, boleh laku, dsb. Tidak kira betapa tepatnya mereka disambungkan antara satu sama lain dalam projek. Satu-satunya perkara yang penting ialah sasaran mana yang merupakan antara muka modul kami, iaitu, ia tetap keluar.

Takluk

Kini kami mempunyai modul blok standard, dan kami boleh menguasainya: menyusunnya ke dalam struktur apa-apa kerumitan, memasangnya ke dalam sistem atau memautkannya bersama dalam satu sistem pemasangan.

Pemasangan ke dalam sistem

Salah satu pilihan untuk menggunakan modul ialah memasang modul kami ke dalam sistem.

cmake --build ΠΏΡƒΡ‚ΡŒ/ΠΊ/сборочной/Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ --target install

Selepas itu, ia disambungkan ke mana-mana projek lain menggunakan arahan find_package.

find_package(Mylib 1.0 REQUIRED)

Sambungan sebagai submodul

Pilihan lain ialah menyambungkan folder dengan projek kami ke projek lain sebagai submodul menggunakan arahan add_subdirectory.

Gunakan

Kaedah pengikatan adalah berbeza, tetapi hasilnya adalah sama. Dalam kedua-dua kes, matlamat akan tersedia dalam projek menggunakan modul kami Mylib::myfeature ΠΈ Mylib::mylib, yang boleh digunakan, sebagai contoh, seperti ini:

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

Khususnya dalam kes kami, perpustakaan Mylib::myfeature perlu disambungkan apabila perlu untuk menghubungkan dengan perpustakaan libmyfeature. Sekiranya terdapat pengepala yang mencukupi, maka ia bernilai menggunakan perpustakaan Mylib::mylib.

Sasaran CMake boleh menjadi rumit, contohnya, hanya bertujuan untuk memajukan beberapa sifat, kebergantungan, dsb. Pada masa yang sama, bekerja dengan mereka berlaku dengan cara yang sama.

Itulah yang kami perlu dapatkan.

Sumber: www.habr.com

Tambah komen