Semasa pembangunan, saya suka menukar penyusun, membina mod, versi pergantungan, melakukan analisis statik, mengukur prestasi, mengumpul liputan, menjana dokumentasi, dsb. Dan saya sangat menyukai CMake kerana ia membolehkan saya melakukan semua yang saya mahu.
Ramai orang mengkritik CMake, dan selalunya sepatutnya begitu, tetapi jika anda melihatnya, tidak semuanya begitu buruk, dan baru-baru ini boleh tahan juga, dan hala tuju pembangunan agak positif.
Dalam nota ini, saya ingin memberitahu anda cara mengatur perpustakaan pengepala dalam C++ dalam sistem CMake untuk mendapatkan fungsi berikut:
Perhimpunan;
Ujian autorun;
Pengukuran liputan kod;
Pemasangan;
Autodokumentasi;
Penjanaan kotak pasir dalam talian;
Analisis statik.
Sesiapa yang sudah faham kelebihan dan C-make boleh sahaja muat turun templat projek dan mula menggunakannya.
Kami terutamanya akan bercakap tentang cara mengatur skrip CMake, jadi ia akan dibincangkan secara terperinci. Sesiapa sahaja boleh melihat seluruh fail secara langsung pada halaman projek templat.
Pertama sekali, anda perlu meminta versi sistem CMake yang diperlukan. CMake sedang berkembang, tandatangan perintah dan tingkah laku dalam keadaan berbeza berubah. Untuk membolehkan CMake memahami dengan segera apa yang kami mahu daripadanya, kami perlu segera merekodkan keperluan kami untuknya.
cmake_minimum_required(VERSION 3.13)
Kemudian kami akan menetapkan projek kami, namanya, versi, bahasa yang digunakan, dll. (lihat. ΠΊΠΎΠΌΠ°Π½Π΄Ρ project).
Dalam kes ini kami menunjukkan bahasa CXX (dan ini bermakna C++) supaya CMake tidak meneran dan mencari pengkompil bahasa C (secara lalai, CMake termasuk dua bahasa: C dan C++).
project(Mylib VERSION 1.0 LANGUAGES CXX)
Di sini anda boleh segera menyemak sama ada projek kami termasuk dalam projek lain sebagai subprojek. Ini akan banyak membantu pada masa hadapan.
Pilihan pertama ialah MYLIB_TESTING β untuk melumpuhkan ujian unit. Ini mungkin perlu jika kami yakin bahawa semuanya teratur dengan ujian, tetapi kami hanya mahu, sebagai contoh, memasang atau membungkus projek kami. Atau projek kami disertakan sebagai subprojek - dalam kes ini, pengguna projek kami tidak berminat untuk menjalankan ujian kami. Anda tidak menguji kebergantungan yang anda gunakan, bukan?
Di samping itu, kami akan membuat pilihan yang berasingan MYLIB_COVERAGE untuk mengukur liputan kod melalui ujian, tetapi ia memerlukan alat tambahan, jadi ia perlu didayakan secara eksplisit.
Sudah tentu, kami adalah pengaturcara tambah yang hebat, jadi kami mahukan tahap maksimum diagnostik masa kompilasi daripada pengkompil. Tiada satu tetikus pun akan tergelincir.
Pustaka kami hanya terdiri daripada fail pengepala, yang bermaksud kami tidak mempunyai sebarang ekzos dalam bentuk perpustakaan statik atau dinamik. Sebaliknya, untuk menggunakan perpustakaan kami secara luaran, ia perlu dipasang, ia perlu dikesan dalam sistem dan disambungkan ke projek anda, dan pada masa yang sama pengepala yang sama ini, serta mungkin beberapa tambahan, adalah melekat padanya sifat.
Untuk tujuan ini, kami mencipta perpustakaan antara muka.
add_library(mylib INTERFACE)
Kami mengikat pengepala ke perpustakaan antara muka kami.
Penggunaan CMake yang moden, bergaya, belia membayangkan bahawa pengepala, sifat, dsb. dihantar melalui satu sasaran. Jadi cukuplah untuk mengatakannya target_link_libraries(target PRIVATE dependency), dan semua pengepala yang dikaitkan dengan sasaran dependency, akan tersedia untuk sumber milik sasaran target. Dan anda tidak memerlukan apa-apa [target_]include_directories. Ini akan ditunjukkan di bawah dalam analisis Skrip CMake untuk ujian unit.
Perintah ini mengaitkan pengepala yang kami perlukan dengan pustaka antara muka kami, dan jika pustaka kami disambungkan ke mana-mana sasaran dalam hierarki CMake yang sama, maka pengepala daripada direktori akan dikaitkan dengannya ${CMAKE_CURRENT_SOURCE_DIR}/include, dan jika perpustakaan kami dipasang pada sistem dan disambungkan ke projek lain menggunakan arahan find_package, maka pengepala daripada direktori akan dikaitkan dengannya include berbanding dengan direktori pemasangan.
Mari kita tetapkan standard bahasa. Sudah tentu, yang terakhir. Pada masa yang sama, kami bukan sahaja memasukkan standard, tetapi juga memanjangkannya kepada mereka yang akan menggunakan perpustakaan kami. Ini dicapai kerana hakikat bahawa harta yang ditetapkan mempunyai kategori INTERFACE (Lihat. arahan target_compile_features).
Mari buat alias untuk perpustakaan kami. Lebih-lebih lagi, untuk kecantikan, ia akan berada dalam "ruang nama" khas. Ini akan berguna apabila modul berbeza muncul dalam pustaka kami, dan kami menyambungkannya secara berasingan antara satu sama lain. Seperti di Busta, sebagai contoh.
Memasang pengepala kami ke dalam sistem. Semuanya mudah di sini. Kami mengatakan bahawa folder dengan semua pengepala harus masuk ke dalam direktori include berbanding dengan lokasi pemasangan.
Seterusnya, kami memaklumkan sistem binaan bahawa kami ingin dapat memanggil arahan dalam projek pihak ketiga find_package(Mylib) dan dapatkan matlamat Mylib::mylib.
Mantera seterusnya harus difahami dengan cara ini. Apabila dalam projek pihak ketiga kami memanggil arahan find_package(Mylib 1.2.3 REQUIRED), dan versi sebenar pustaka yang dipasang akan tidak serasi dengan versi 1.2.3CMake akan menjana ralat secara automatik. Iaitu, anda tidak perlu menjejak versi secara manual.
Jika ujian dilumpuhkan secara eksplisit menggunakan pilihan yang sepadan atau projek kami ialah subprojek, iaitu, ia disambungkan kepada projek CMake yang lain menggunakan arahan add_subdirectory, kami tidak bergerak lebih jauh mengikut hierarki, dan skrip, yang menerangkan arahan untuk menjana dan menjalankan ujian, langsung tidak berjalan.
Kami menyambung kebergantungan. Sila ambil perhatian bahawa kami hanya memautkan sasaran CMake yang kami perlukan kepada binari kami dan tidak memanggil arahan itu target_include_directories. Tajuk daripada rangka kerja ujian dan daripada kami Mylib::mylib, serta parameter binaan (dalam kes kami, ini ialah standard bahasa C++) dicapai bersama-sama dengan matlamat ini.
Akhir sekali, kami mencipta sasaran tiruan, "binaan" yang bersamaan dengan menjalankan ujian dan menambah sasaran ini pada binaan lalai (atribut bertanggungjawab untuk ini ALL). Ini bermakna binaan lalai mencetuskan ujian untuk dijalankan, bermakna kita tidak akan lupa untuk menjalankannya.
add_custom_target(check ALL COMMAND mylib-unit-tests)
Seterusnya, kami mendayakan pengukuran liputan kod jika pilihan yang sesuai ditentukan. Saya tidak akan menerangkan secara terperinci, kerana ia lebih berkaitan dengan alat untuk mengukur liputan berbanding CMake. Hanya penting untuk ambil perhatian bahawa berdasarkan keputusan matlamat akan dibuat coverage, yang mudah untuk mula mengukur liputan.
Seterusnya, kami menyemak sama ada pengguna telah menetapkan pembolehubah bahasa. Jika ya, maka kami tidak menyentuhnya, jika tidak, maka kami mengambil bahasa Rusia. Kemudian kami mengkonfigurasi fail sistem Doxygen. Semua pembolehubah yang diperlukan, termasuk bahasa, pergi ke sana semasa proses konfigurasi (lihat. ΠΊΠΎΠΌΠ°Π½Π΄Ρ configure_file).
Kemudian kita mencipta matlamat doc, yang akan mula menjana dokumentasi. Memandangkan penjanaan dokumentasi bukanlah keperluan terbesar dalam proses pembangunan, sasaran tidak akan didayakan secara lalai; ia perlu dilancarkan secara eksplisit.
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 ()
Di sini kita dapati Python ketiga dan mencipta sasaran wandbox, yang menjana permintaan yang sepadan dengan API perkhidmatan Kotak tongkat, dan menghantarnya pergi. Sambutan datang dengan pautan ke kotak pasir yang telah siap.
Menyediakan keupayaan untuk melumpuhkan binaan dan sasaran ujian unit check. Akibatnya, pengukuran liputan kod melalui ujian dimatikan (lihat. MYLIB_COVERAGE).
Pengujian juga dilumpuhkan secara automatik jika projek disambungkan ke projek lain sebagai subprojek menggunakan arahan add_subdirectory.
Perkhidmatan ini digunakan untuk ini Kotak tongkat. Saya tidak tahu betapa fleksibelnya pelayan mereka, tetapi saya berpendapat bahawa peluang ini tidak seharusnya disalahgunakan.
Sebenarnya, CMake versi 3.13 hanya diperlukan untuk menjalankan beberapa arahan konsol yang diterangkan dalam bantuan ini. Dari sudut pandangan sintaks skrip CMake, versi 3.8 adalah mencukupi jika penjanaan dipanggil dengan cara lain.
CMake ialah sistem yang sangat berkuasa dan fleksibel yang membolehkan anda melaksanakan fungsi untuk setiap rasa dan warna. Dan, walaupun sintaks kadang-kadang meninggalkan banyak yang diingini, syaitan masih tidak seteruk yang dilukisnya. Gunakan sistem binaan CMake untuk manfaat masyarakat dan kesihatan.