CMake et C ++ sunt fratres in aeternum

CMake et C ++ sunt fratres in aeternum

Per progressionem placet mutare compilatores, modos aedificare, versiones dependentiae, analysin static efficere, modum effectus, colligere coverage, documenta generare, etc. Et vere amo CMake quia permittit me omnia facere quae volo.

Multi reprehendunt CMake, et saepe merito, sed si bene spectes, non omnia mala sunt, et nuper. Nec omninoac directio evolutionis omnino affirmativa est.

In hac nota tibi dicere volo quomodo bibliothecam principalem in C ++ in CMake systemate simpliciter instituas ut sequentes functiones accipias:

  1. Conventus;
  2. Probat Autoruni;
  3. Codicis coverage mensurae;
  4. Institutionem;
  5. Auto- documentum;
  6. Online sandbox generation;
  7. Analysis statice.

Qui iam intelligit commoda et C-facere potest simpliciter download project template et satus utendo.


contentus

  1. Project ab intus
    1. Project structure
    2. Tabularium principale CMake (./CMakeLists.txt)
      1. Project informationes
      2. Optiones Project
      3. Compilation optiones
      4. primaria metam
      5. occasum
      6. probat
      7. Документация
      8. Online sandbox
    3. Test scriptum (test/CMakeLists.txt)
      1. temptationis
      2. Coverage
    4. Scriptor pro documentis (doc/CMakeLists.txt)
    5. Scriptor pro online sandbox (online/CMakeLists.txt)
  2. Project foris
    1. conventus
      1. generation
      2. conventus
    2. options
      1. MYLIB_COVERAGE
      2. MYLIB_TESTING
      3. MYLIB_DOXYGEN_LANGUAGE
    3. conventus scuta
      1. per default
      2. mylib-unitas probat
      3. reprehendo
      4. coverage
      5. doc
      6. wandbox
    4. exempla
  3. vasa cantici
  4. Static analysis
  5. afterword

Project ab intus

Project structure

.
├── 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

Maxime loquemur quomodo scripta CMake ordinanda sunt, ergo singillatim discutientur. Quisque videre potes reliquum files directe in Formula project pagina.

Tabularium principale CMake (./CMakeLists.txt)

Project informationes

Imprimis, postulare debes CMake versionem debitam systematis. CMake evolvendo, mandatum signaturae et mores in diversis conditionibus mutantur. Ut CMake ad ea quae ex eo cupimus statim intellegamus, necesse est ut statim notare nostra requisita pro eo.

cmake_minimum_required(VERSION 3.13)

Deinde designabimus consilium nostrum, nomen, versionem, linguas adhibitas, etc. команду project).

In hoc casu lingua indicamus CXX (hoc significat C++) ut CMake non intendit et investigat pro C compilator linguae (per default CMake duas linguas: C et C++).

project(Mylib VERSION 1.0 LANGUAGES CXX)

Hic statim inspicere potes num consilium nostrum in alio incluso includatur tamquam subiectum. Hoc multum proderit in futurum.

get_directory_property(IS_SUBPROJECT PARENT_DIRECTORY)

Optiones Project

Duo optiones dabimus.

Primum optio est MYLIB_TESTING - ut disable unitas probat. Hoc sit necessarium, si certi sumus omnia ordinare cum tentationibus, sed solum volumus, exempli gratia, inaugurationem vel sarcinam propositi nostri. Vel consilium nostrum includitur ut subprojectum - in hoc casu, uter nostri consilii non est interested in currendo nostras probationes. Non probas clientelas uteris?

option(MYLIB_TESTING "Включить модульное тестирование" ON)

Praeterea optionem separatam faciemus MYLIB_COVERAGE ad mensurandum codicem coverage per probationes, sed instrumenta additional requiret, ut explicite efficere possit.

option(MYLIB_COVERAGE "Включить измерение покрытия кода тестами" OFF)

Compilation optiones

Nimirum plus programmatores frigidi sumus, sic volumus maximam gradum diagnostica compilatoris temporis a compilatore. Nullus mus praeteribit.

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
)

Etiam extensiones disable faciemus ut vexillum linguae C++ plene impleamus. Possunt per defaltam in CMake.

if(NOT CMAKE_CXX_EXTENSIONS)
    set(CMAKE_CXX_EXTENSIONS OFF)
endif()

primaria metam

Bibliotheca nostra tantum consistit in files header, quod significat nos non habemus in forma bibliothecae static vel dynamicae. Aliunde vero, ut nostra bibliotheca extrinsecus utatur, institui debet, necesse est ut deprehendatur in systemate et connexo cum consilio tuo, et simul iisdem capitibus, ac fortasse nonnullis additis; adnectuntur ei proprietates.

Ad hanc rem bibliothecam instrumenti efficimus.

add_library(mylib INTERFACE)

Capituli nostri bibliothecam instrumenti adstringimus.

Modern, fashionable, adolescentia uti CMake implicat capitis, possessiones, etc. traducitur per unum unum scopum. Sufficit ergo hoc dicere target_link_libraries(target PRIVATE dependency)et omnes capitis qui cum scopo coniunguntur dependency, erit praesto ad scopum pertinentes target. Et non opus est omnibus [target_]include_directories. Hoc infra in analysi demonstrabitur CMake scriptor unitatis probat.

Valet etiam animadversio sic dicta. выражения-генераторы: $<...>.

Hoc mandatum adnectitur praefectis quibus opus est cum bibliotheca nostra interfaciei, et si bibliotheca nostra cuilibet scopo in eadem CMake hierarchia coniuncta, tum caput ex directorio associetur. ${CMAKE_CURRENT_SOURCE_DIR}/include, et si bibliotheca nostra in systemate instituatur et alteri adnexa utens mandato find_package, tum capitis ex indicem cum eo coniungetur include ad institutionem presul.

target_include_directories(mylib INTERFACE
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

Vexillum linguae transeamus. Nempe ipsa ultima. Eodem tempore non solum vexillum comprehendimus, sed etiam porrigimus iis qui nostra bibliotheca utentur. Hoc fit ex eo quod paro proprietas categoriam habet INTERFACE (Am. target_compile_features imperium).

target_compile_features(mylib INTERFACE cxx_std_17)

Alias ​​nostras bibliothecam faciamus. Praeterea, ad pulchritudinem, in speciali "nominis spatio" erit. Hoc utile erit, cum in nostra bibliotheca diversi moduli apparent, eosque separatim inter se coniungemus. Sicut in Busta, e.g.

add_library(Mylib::mylib ALIAS mylib)

occasum

Nostram capitis rationem inaugurari. Omnia hic simplicia sunt. Dicimus folder cum omnibus titulis in indicem ire include ad institutionem locus.

install(DIRECTORY include/mylib DESTINATION include)

Deinde informamus systema aedificandi quod imperium vocare in inceptis tertia factionis posse volumus find_package(Mylib) atque finis Mylib::mylib.

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

Sequens carmen hoc modo intelligendum est. Cum in tertia parte consilii imperium vocamus find_package(Mylib 1.2.3 REQUIRED)ac vera versio bibliothecae inauguratus cum versioni repugnat 1.2.3CMake sponte generabit errorem. Hoc est, versiones manuales indagare non debes.

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)

probat

Nisi probat erret expressis verbis utens correspondentes optionem vel consilium nostrum est subpro- iectum, id est, annexum alteri CMake proiecto utens imperio add_subdirectoryulterius per Hierarchiam non movemur, et scriptura, quae praecepta generandi ac cursus probationes describit, simpliciter non currit.

if(NOT MYLIB_TESTING)
    message(STATUS "Тестирование проекта Mylib выключено")
elseif(IS_SUBPROJECT)
    message(STATUS "Mylib не тестируется в режиме подмодуля")
else()
    add_subdirectory(test)
endif()

Документация

Documenta etiam in casu subiecti non generabuntur.

if(NOT IS_SUBPROJECT)
    add_subdirectory(doc)
endif()

Online sandbox

Item, subiectum sandbox vel online non habebit.

if(NOT IS_SUBPROJECT)
    add_subdirectory(online)
endif()

Test scriptum (test/CMakeLists.txt)

temptationis

Primum involucrum invenimus cum testi inquisitione (repone cum uno tuo gratissimo).

find_package(doctest 2.3.3 REQUIRED)

Faciamus nostrum documentum exsecutabile cum probat. Plerumque directe addo binarium exsecutabile solum tabellam quae munus continebit main.

add_executable(mylib-unit-tests test_main.cpp)

Et addo fasciculos in quibus probationes ipsae postea describuntur. Sed id non facere.

target_sources(mylib-unit-tests PRIVATE mylib/myfeature.cpp)

clientelas conectimus. Quaeso nota nos tantum CMake scuta coniungi quae binario nostro necessaria sunt nec mandatum vocavimus target_include_directories. Capitula ex testi compage et ex nostra Mylib::mylibatque parametri (in nostro casu, hoc est vexillum linguae C++) cum his metis pervenerunt.

target_link_libraries(mylib-unit-tests
    PRIVATE
        Mylib::mylib
        doctest::doctest
)

Denique scopum phantasticum creamus, cuius "aedificare" aequivalet cum probationibus currentibus, hoc clypeum addimus ad fabricandum default (proprietas huius responsabilis est. ALL). Hoc significat quod default aedificandi triggers probationes ad currendum, significationes numquam eas currere obliviscetur.

add_custom_target(check ALL COMMAND mylib-unit-tests)

Coverage

Deinde efficimus codicem mensurationis coverage si optio opportuna specificatur. Singula non ingrediar, quia plus referunt instrumentum ad coverage metiendae quam CMake. Solum interest notare quod finis ex eventibus creabitur coveragecum quo commode metiri coverage committitur.

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

Scriptor pro documentis (doc/CMakeLists.txt)

Inveni Doxygen.

find_package(Doxygen)

Deinde inspicimus utrum usor linguam variabilem ponat. Si sic, non tangimus, sin minus, sumimus Russicum. Deinde configuramus tabularum systematis Doxygen. Omnes variabiles necessariae, incluso sermone, ibi per processum conformationem ituri (videatur. команду configure_file).

Deinde finis creare doc, quae documenta gignere incipiet. Cum documenta generare non est maxima necessitas in processu evolutionis, scopus per defaltam non poterit, explicite deduci debebit.

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

Scriptor pro online sandbox (online/CMakeLists.txt)

Hic tertiam Pythonem invenimus et scopo creamus wandboxquae petitio debita servitio API . generat Wandboxac dimittit. Responsum venit cum ligamento sandbox perfecti.

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

Project foris

Nunc videamus quomodo haec omnia utantur.

conventus

Hoc inceptum aedificium, sicut quodlibet propositum in CMake fabricandi systemate, duobus gradibus consistit:

generation

cmake -S путь/к/исходникам -B путь/к/сборочной/директории [опции ...]

Si mandatum superius non ob vetus versionem CMake operandum, omitte tenta -S:

cmake путь/к/исходникам -B путь/к/сборочной/директории [опции ...]

De options.

Aedificationem project

cmake --build путь/к/сборочной/директории [--target target]

De ecclesia proposita.

options

MYLIB_COVERAGE

cmake -S ... -B ... -DMYLIB_COVERAGE=ON [прочие опции ...]

Includes target coverage, cum quo codicem metiri potes coverage per experimenta.

MYLIB_TESTING

cmake -S ... -B ... -DMYLIB_TESTING=OFF [прочие опции ...]

Facultatem praebet inactivandi unitas test constructum et scopum check. Quam ob rem mensuratio codicis coverage per probationes subversa est (videatur. MYLIB_COVERAGE).

Testis etiam automatice debilis est, si consilium alteri incepto coniungitur ut subiectum cum imperio utens add_subdirectory.

MYLIB_DOXYGEN_LANGUAGE

cmake -S ... -B ... -DMYLIB_DOXYGEN_LANGUAGE=English [прочие опции ...]

Lingua documentorum permutat quod scopum generat doc dato. Ad Indicem linguarum promptarum, vide Doxygen systema website.

Russian defaltam facit.

conventus scuta

per default

cmake --build path/to/build/directory
cmake --build path/to/build/directory --target all

Si scopum non est certa (quae est equivalent ad scopum all) omnia quae potest colligit et etiam scopo vocat check.

mylib-unitas probat

cmake --build path/to/build/directory --target mylib-unit-tests

Componit unitatem probat. Defalta.

reprehendo

cmake --build путь/к/сборочной/директории --target check

Currit collecta (si nondum collecta) unitas probat. Defalta.

Vide. Item mylib-unit-tests.

coverage

cmake --build путь/к/сборочной/директории --target coverage

Cursus analyses (currit, nisi iam) unitas probat in codice coverage per programmata probat gcovr.

Exhauriendi litura aliquid simile spectabit:

------------------------------------------------------------------------------
                           GCC Code Coverage Report
Directory: /path/to/cmakecpptemplate/include/
------------------------------------------------------------------------------
File                                       Lines    Exec  Cover   Missing
------------------------------------------------------------------------------
mylib/myfeature.hpp                            2       2   100%   
------------------------------------------------------------------------------
TOTAL                                          2       2   100%
------------------------------------------------------------------------------

Scopum solum praesto est cum optio possit MYLIB_COVERAGE.

Vide. Item check.

doc

cmake --build путь/к/сборочной/директории --target doc

Incipit generatio codice documenta utens ratio doxygen.

wandbox

cmake --build путь/к/сборочной/директории --target wandbox

Responsio e ministerio hoc aliquid spectat:

{
    "permlink" :    "QElvxuMzHgL9fqci",
    "status" :  "0",
    "url" : "https://wandbox.org/permlink/QElvxuMzHgL9fqci"
}

Ministerium adhibetur pro hoc Wandbox. Nescio quam flexibiles sint servientes, sed occasionem hanc vituperandam non puto.

exempla

Aedificare project in lusione cum coverage measurement

cmake -S путь/к/исходникам -B путь/к/сборочной/директории -DCMAKE_BUILD_TYPE=Debug -DMYLIB_COVERAGE=ON
cmake --build путь/к/сборочной/директории --target coverage --parallel 16

Inaugurari consilium sine praevia conventu et probatione

cmake -S путь/к/исходникам -B путь/к/сборочной/директории -DMYLIB_TESTING=OFF -DCMAKE_INSTALL_PREFIX=путь/к/установойной/директории
cmake --build путь/к/сборочной/директории --target install

Aedificare in release modus dato compilator

cmake -S путь/к/исходникам -B путь/к/сборочной/директории -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++-8 -DCMAKE_PREFIX_PATH=путь/к/директории/куда/установлены/зависимости
cmake --build путь/к/сборочной/директории --parallel 4

Documenta generans Anglice

cmake -S путь/к/исходникам -B путь/к/сборочной/директории -DCMAKE_BUILD_TYPE=Release -DMYLIB_DOXYGEN_LANGUAGE=English
cmake --build путь/к/сборочной/директории --target doc

vasa cantici

  1. CMake 3.13

    Re vera, CMake versio 3.13 tantum requiritur ad aliquid decurrendum de mandatorum console hoc auxilio descriptorum. Secundum syntaxin scriptorum CMake, versio 3.8 satis est si aliis modis generatio appellatur.

  2. Testis bibliotheca doctest

    Testis potest erret (videatur опцию MYLIB_TESTING).

  3. doxygen

    Ad linguam commutandam in qua documentum generabitur, optio datur MYLIB_DOXYGEN_LANGUAGE.

  4. Linguae interpres Python 3

    Automatic generation online sandboxes.

Static analysis

Cum CMake et duobus instrumentorum bonorum instrumentorum, stabilis analysin minimo conatu praebere potes.

Cppcheck

CMake aedificavit in subsidium stabili analysis instrumentum Cppcheck.

Hoc facere debes uti optione CMAKE_CXX_CPPCHECK:

cmake -S путь/к/исходникам -B путь/к/сборочной/директории -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_CPPCHECK="cppcheck;--enable=all;-Iпуть/к/исходникам/include"

Postea analysis stabilis omni tempore sponte deducetur fons est compilatus et compilatus. Non opus est facere aliquid addito.

SONUS

Ope mira instrumentum scan-build Currere etiam potes analysin statam nullo tempore:

scan-build cmake -S путь/к/исходникам -B путь/к/сборочной/директории -DCMAKE_BUILD_TYPE=Debug
scan-build cmake --build путь/к/сборочной/директории

Hic, dissimilis causa cum Cppcheck, currere debes omni tempore aedificandi scan-build.

afterword

CMake ratio validissima est et flexibilis quae te permittit ad omnem saporem et colorem functionem efficiendam. Et licet syntaxin aliquando multum appetenda relinquit, diabolus tamen non tam terribilis est quam pingitur. Utere CMake systema aedificandi ad utilitatem societatis et sanitatis.

Download project template

Source: www.habr.com

Add a comment