mirror of
https://github.com/TheLartians/ModernCppStarter.git
synced 2025-08-30 21:51:12 +02:00
131 lines
21 KiB
HTML
131 lines
21 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<title>Greeter</title>
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,400i,600,600i%7CSource+Code+Pro:400,400i,600" />
|
|
<link rel="stylesheet" href="m-dark+documentation.compiled.css" />
|
|
<link rel="icon" href="favicon-dark.png" type="image/png" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<meta name="theme-color" content="#22272e" />
|
|
</head>
|
|
<body>
|
|
<header><nav id="navigation">
|
|
<div class="m-container">
|
|
<div class="m-row">
|
|
<a href="index.html" id="m-navbar-brand" class="m-col-t-8 m-col-m-none m-left-m">Greeter</a>
|
|
<div class="m-col-t-4 m-hide-m m-text-right m-nopadr">
|
|
<a href="#search" class="m-doc-search-icon" title="Search" onclick="return showSearch()"><svg style="height: 0.9rem;" viewBox="0 0 16 16">
|
|
<path id="m-doc-search-icon-path" d="m6 0c-3.31 0-6 2.69-6 6 0 3.31 2.69 6 6 6 1.49 0 2.85-0.541 3.89-1.44-0.0164 0.338 0.147 0.759 0.5 1.15l3.22 3.79c0.552 0.614 1.45 0.665 2 0.115 0.55-0.55 0.499-1.45-0.115-2l-3.79-3.22c-0.392-0.353-0.812-0.515-1.15-0.5 0.895-1.05 1.44-2.41 1.44-3.89 0-3.31-2.69-6-6-6zm0 1.56a4.44 4.44 0 0 1 4.44 4.44 4.44 4.44 0 0 1-4.44 4.44 4.44 4.44 0 0 1-4.44-4.44 4.44 4.44 0 0 1 4.44-4.44z"/>
|
|
</svg></a>
|
|
<a id="m-navbar-show" href="#navigation" title="Show navigation"></a>
|
|
<a id="m-navbar-hide" href="#" title="Hide navigation"></a>
|
|
</div>
|
|
<div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
|
|
<div class="m-row">
|
|
<ol class="m-col-t-6 m-col-m-none">
|
|
<li>
|
|
<a href="pages.html">Pages</a>
|
|
<ol>
|
|
<li><a href="about.html">About</a></li>
|
|
</ol>
|
|
</li>
|
|
<li><a href="namespaces.html">Namespaces</a></li>
|
|
</ol>
|
|
<ol class="m-col-t-6 m-col-m-none" start="3">
|
|
<li><a href="annotated.html">Classes</a></li>
|
|
<li><a href="files.html">Files</a></li>
|
|
<li class="m-show-m"><a href="#search" class="m-doc-search-icon" title="Search" onclick="return showSearch()"><svg style="height: 0.9rem;" viewBox="0 0 16 16">
|
|
<use href="#m-doc-search-icon-path" />
|
|
</svg></a></li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav></header>
|
|
<main><article>
|
|
<div class="m-container m-container-inflatable">
|
|
<div class="m-row">
|
|
<div class="m-col-l-10 m-push-l-1">
|
|
<h1>
|
|
Greeter
|
|
</h1>
|
|
<p><a name="md__r_e_a_d_m_e"></a> <a href="https://github.com/TheLartians/ModernCppStarter/actions"><img class="m-image" src="https://github.com/TheLartians/ModernCppStarter/workflows/MacOS/badge.svg" alt="Image" /></a> <a href="https://github.com/TheLartians/ModernCppStarter/actions"><img class="m-image" src="https://github.com/TheLartians/ModernCppStarter/workflows/Windows/badge.svg" alt="Image" /></a> <a href="https://github.com/TheLartians/ModernCppStarter/actions"><img class="m-image" src="https://github.com/TheLartians/ModernCppStarter/workflows/Ubuntu/badge.svg" alt="Image" /></a> <a href="https://github.com/TheLartians/ModernCppStarter/actions"><img class="m-image" src="https://github.com/TheLartians/ModernCppStarter/workflows/Style/badge.svg" alt="Image" /></a> <a href="https://github.com/TheLartians/ModernCppStarter/actions"><img class="m-image" src="https://github.com/TheLartians/ModernCppStarter/workflows/Install/badge.svg" alt="Image" /></a> <a href="https://codecov.io/gh/TheLartians/ModernCppStarter"><img class="m-image" src="https://codecov.io/gh/TheLartians/ModernCppStarter/branch/master/graph/badge.svg" alt="Image" /></a></p><img class="m-image" src="https://repository-images.githubusercontent.com/254842585/4dfa7580-7ffb-11ea-99d0-46b8fe2f4170" alt="Image" /><section id="autotoc_md0"><h2><a href="#autotoc_md0">ModernCppStarter</a></h2><p>Setting up a new C++ project usually requires a significant amount of preparation and boilerplate code, even more so for modern C++ projects with tests, executables and continuous integration. This template is the result of learnings from many previous projects and should help reduce the work required to setup up a modern C++ project.</p><section id="autotoc_md1"><h3><a href="#autotoc_md1">Features</a></h3><ul><li><a href="https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/">Modern CMake practices</a></li><li>Suited for single header libraries and projects of any scale</li><li>Clean separation of library and executable code</li><li>Integrated test suite</li><li>Continuous integration via <a href="https://help.github.com/en/actions/">GitHub Actions</a></li><li>Code coverage via <a href="https://codecov.io">codecov</a></li><li>Code formatting enforced by <a href="https://clang.llvm.org/docs/ClangFormat.html">clang-format</a> and <a href="https://github.com/cheshirekow/cmake_format">cmake-format</a> via <a href="https://github.com/TheLartians/Format.cmake">Format.cmake</a></li><li>Reproducible dependency management via <a href="https://github.com/TheLartians/CPM.cmake">CPM.cmake</a></li><li>Installable target with automatic versioning information and header generation via <a href="https://github.com/TheLartians/PackageProject.cmake">PackageProject.cmake</a></li><li>Automatic <a href="https://thelartians.github.io/ModernCppStarter">documentation</a> and deployment with <a href="https://www.doxygen.nl">Doxygen</a> and <a href="https://pages.github.com">GitHub Pages</a></li><li>Support for sanitizer tools, and more</li></ul></section><section id="autotoc_md2"><h3><a href="#autotoc_md2">Usage</a></h3><section id="autotoc_md3"><h4><a href="#autotoc_md3">Adjust the template to your needs</a></h4><ul><li>Use this repo <a href="https://help.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-from-a-template">as a template</a>.</li><li>Replace all occurrences of "Greeter" in the relevant CMakeLists.txt with the name of your project<ul><li>Capitalization matters here: <code>Greeter</code> means the name of the project, while <code>greeter</code> is used in file names.</li><li>Remember to rename the <code>include/greeter</code> directory to use your project's lowercase name and update all relevant <code>#include</code>s accordingly.</li></ul></li><li>Replace the source files with your own</li><li>For header-only libraries: see the comments in <a href="CMakeLists.txt">CMakeLists.txt</a></li><li>Add <a href="https://docs.codecov.io/docs/quick-start">your project's codecov token</a> to your project's github secrets under <code>CODECOV_TOKEN</code></li><li>Happy coding!</li></ul><p>Eventually, you can remove any unused files, such as the standalone directory or irrelevant github workflows for your project. Feel free to replace the License with one suited for your project.</p><p>To cleanly separate the library and subproject code, the outer <code>CMakeList.txt</code> only defines the library itself while the tests and other subprojects are self-contained in their own directories. During development it is usually convenient to build all subprojects at once.</p></section><section id="autotoc_md4"><h4><a href="#autotoc_md4">Build and run the standalone target</a></h4><p>Use the following command to build and run the executable target.</p><pre class="m-code">cmake<span class="w"> </span>-S<span class="w"> </span>standalone<span class="w"> </span>-B<span class="w"> </span>build/standalone
|
|
cmake<span class="w"> </span>--build<span class="w"> </span>build/standalone
|
|
./build/standalone/Greeter<span class="w"> </span>--help</pre></section><section id="autotoc_md5"><h4><a href="#autotoc_md5">Build and run test suite</a></h4><p>Use the following commands from the project's root directory to run the test suite.</p><pre class="m-code">cmake<span class="w"> </span>-S<span class="w"> </span><span class="nb">test</span><span class="w"> </span>-B<span class="w"> </span>build/test
|
|
cmake<span class="w"> </span>--build<span class="w"> </span>build/test
|
|
<span class="nv">CTEST_OUTPUT_ON_FAILURE</span><span class="o">=</span><span class="m">1</span><span class="w"> </span>cmake<span class="w"> </span>--build<span class="w"> </span>build/test<span class="w"> </span>--target<span class="w"> </span><span class="nb">test</span>
|
|
|
|
<span class="c1"># or simply call the executable: </span>
|
|
./build/test/GreeterTests</pre><p>To collect code coverage information, run CMake with the <code>-DENABLE_TEST_COVERAGE=1</code> option.</p></section><section id="autotoc_md6"><h4><a href="#autotoc_md6">Run clang-format</a></h4><p>Use the following commands from the project's root directory to check and fix C++ and CMake source style. This requires <em>clang-format</em>, <em>cmake-format</em> and <em>pyyaml</em> to be installed on the current system.</p><pre class="m-code">cmake<span class="w"> </span>-S<span class="w"> </span><span class="nb">test</span><span class="w"> </span>-B<span class="w"> </span>build/test
|
|
|
|
<span class="c1"># view changes</span>
|
|
cmake<span class="w"> </span>--build<span class="w"> </span>build/test<span class="w"> </span>--target<span class="w"> </span>format
|
|
|
|
<span class="c1"># apply changes</span>
|
|
cmake<span class="w"> </span>--build<span class="w"> </span>build/test<span class="w"> </span>--target<span class="w"> </span>fix-format</pre><p>See <a href="https://github.com/TheLartians/Format.cmake">Format.cmake</a> for details. These dependencies can be easily installed using pip.</p><pre class="m-code">pip<span class="w"> </span>install<span class="w"> </span>clang-format<span class="o">==</span><span class="m">14</span>.0.6<span class="w"> </span><span class="nv">cmake_format</span><span class="o">==</span><span class="m">0</span>.6.11<span class="w"> </span>pyyaml</pre></section><section id="autotoc_md7"><h4><a href="#autotoc_md7">Build the documentation</a></h4><p>The documentation is automatically built and <a href="https://thelartians.github.io/ModernCppStarter">published</a> whenever a <a href="https://help.github.com/en/github/administering-a-repository/managing-releases-in-a-repository">GitHub Release</a> is created. To manually build documentation, call the following command.</p><pre class="m-code">cmake<span class="w"> </span>-S<span class="w"> </span>documentation<span class="w"> </span>-B<span class="w"> </span>build/doc
|
|
cmake<span class="w"> </span>--build<span class="w"> </span>build/doc<span class="w"> </span>--target<span class="w"> </span>GenerateDocs
|
|
<span class="c1"># view the docs</span>
|
|
open<span class="w"> </span>build/doc/doxygen/html/index.html</pre><p>To build the documentation locally, you will need Doxygen, jinja2 and Pygments installed on your system.</p></section><section id="autotoc_md8"><h4><a href="#autotoc_md8">Build everything at once</a></h4><p>The project also includes an <code>all</code> directory that allows building all targets at the same time. This is useful during development, as it exposes all subprojects to your IDE and avoids redundant builds of the library.</p><pre class="m-code">cmake<span class="w"> </span>-S<span class="w"> </span>all<span class="w"> </span>-B<span class="w"> </span>build
|
|
cmake<span class="w"> </span>--build<span class="w"> </span>build
|
|
|
|
<span class="c1"># run tests</span>
|
|
./build/test/GreeterTests
|
|
<span class="c1"># format code</span>
|
|
cmake<span class="w"> </span>--build<span class="w"> </span>build<span class="w"> </span>--target<span class="w"> </span>fix-format
|
|
<span class="c1"># run standalone</span>
|
|
./build/standalone/Greeter<span class="w"> </span>--help
|
|
<span class="c1"># build docs</span>
|
|
cmake<span class="w"> </span>--build<span class="w"> </span>build<span class="w"> </span>--target<span class="w"> </span>GenerateDocs</pre></section><section id="autotoc_md9"><h4><a href="#autotoc_md9">Additional tools</a></h4><p>The test and standalone subprojects include the <a href="cmake/tools.cmake">tools.cmake</a> file which is used to import additional tools on-demand through CMake configuration arguments. The following are currently supported.</p><section id="autotoc_md10"><h5><a href="#autotoc_md10">Sanitizers</a></h5><p>Sanitizers can be enabled by configuring CMake with ‘-DUSE_SANITIZER=<Address | Memory | MemoryWithOrigins | Undefined | Thread | Leak | 'Address;Undefined’>`.</p></section><section id="autotoc_md11"><h5><a href="#autotoc_md11">Static Analyzers</a></h5><p>Static Analyzers can be enabled by setting <code>-DUSE_STATIC_ANALYZER=<clang-tidy | iwyu | cppcheck></code>, or a combination of those in quotation marks, separated by semicolons. By default, analyzers will automatically find configuration files such as <code>.clang-format</code>. Additional arguments can be passed to the analyzers by setting the <code>CLANG_TIDY_ARGS</code>, <code>IWYU_ARGS</code> or <code>CPPCHECK_ARGS</code> variables.</p></section><section id="autotoc_md12"><h5><a href="#autotoc_md12">Ccache</a></h5><p>Ccache can be enabled by configuring with <code>-DUSE_CCACHE=<ON | OFF></code>.</p></section></section></section><section id="autotoc_md13"><h3><a href="#autotoc_md13">FAQ</a></h3><blockquote><p>Can I use this for header-only libraries?</p></blockquote><p>Yes, however you will need to change the library type to an <code>INTERFACE</code> library as documented in the <a href="CMakeLists.txt">CMakeLists.txt</a>. See <a href="https://github.com/TheLartians/StaticTypeInfo">here</a> for an example header-only library based on the template.</p><blockquote><p>I don't need a standalone target / documentation. How can I get rid of it?</p></blockquote><p>Simply remove the standalone / documentation directory and according github workflow file.</p><blockquote><p>Can I build the standalone and tests at the same time? / How can I tell my IDE about all subprojects?</p></blockquote><p>To keep the template modular, all subprojects derived from the library have been separated into their own CMake modules. This approach makes it trivial for third-party projects to re-use the projects library code. To allow IDEs to see the full scope of the project, the template includes the <code>all</code> directory that will create a single build for all subprojects. Use this as the main directory for best IDE support.</p><blockquote><p>I see you are using <code>GLOB</code> to add source files in CMakeLists.txt. Isn't that evil?</p></blockquote><p>Glob is considered bad because any changes to the source file structure <a href="https://cmake.org/cmake/help/latest/command/file.html#filesystem">might not be automatically caught</a> by CMake's builders and you will need to manually invoke CMake on changes. I personally prefer the <code>GLOB</code> solution for its simplicity, but feel free to change it to explicitly listing sources.</p><blockquote><p>I want create additional targets that depend on my library. Should I modify the main CMakeLists to include them?</p></blockquote><p>Avoid including derived projects from the libraries CMakeLists (even though it is a common sight in the C++ world), as this effectively inverts the dependency tree and makes the build system hard to reason about. Instead, create a new directory or project with a CMakeLists that adds the library as a dependency (e.g. like the <a href="standalone/CMakeLists.txt">standalone</a> directory). Depending type it might make sense move these components into a separate repositories and reference a specific commit or version of the library. This has the advantage that individual libraries and components can be improved and updated independently.</p><blockquote><p>You recommend to add external dependencies using CPM.cmake. Will this force users of my library to use CPM.cmake as well?</p></blockquote><p><a href="https://github.com/TheLartians/CPM.cmake">CPM.cmake</a> should be invisible to library users as it's a self-contained CMake Script. If problems do arise, users can always opt-out by defining the CMake or env variable <a href="https://github.com/cpm-cmake/CPM.cmake#options"><code>CPM_USE_LOCAL_PACKAGES</code></a>, which will override all calls to <code>CPMAddPackage</code> with the according <code>find_package</code> call. This should also enable users to use the project with their favorite external C++ dependency manager, such as vcpkg or Conan.</p><blockquote><p>Can I configure and build my project offline?</p></blockquote><p>No internet connection is required for building the project, however when using CPM missing dependencies are downloaded at configure time. To avoid redundant downloads, it's highly recommended to set a CPM.cmake cache directory, e.g.: <code>export CPM_SOURCE_CACHE=$HOME/.cache/CPM</code>. This will enable shallow clones and allow offline configurations dependencies are already available in the cache.</p><blockquote><p>Can I use CPack to create a package installer for my project?</p></blockquote><p>As there are a lot of possible options and configurations, this is not (yet) in the scope of this template. See the <a href="https://cmake.org/cmake/help/latest/module/CPack.html">CPack documentation</a> for more information on setting up CPack installers.</p><blockquote><p>This is too much, I just want to play with C++ code and test some libraries.</p></blockquote><p>Perhaps the <a href="https://github.com/TheLartians/MiniCppStarter">MiniCppStarter</a> is something for you!</p></section><section id="autotoc_md14"><h3><a href="#autotoc_md14">Related projects and alternatives</a></h3><ul><li><a href="https://github.com/viva64/pvs-studio-cmake-examples/tree/master/modern-cpp-starter"><strong>ModernCppStarter & PVS-Studio Static Code Analyzer</strong></a>: Official instructions on how to use the ModernCppStarter with the PVS-Studio Static Code Analyzer.</li><li><a href="https://github.com/cpp-best-practices/gui_starter_template/"><strong>cpp-best-practices/gui_starter_template</strong></a>: A popular C++ starter project, created in 2017.</li><li><a href="https://github.com/filipdutescu/modern-cpp-template"><strong>filipdutescu/modern-cpp-template</strong></a>: A recent starter using a more traditional approach for CMake structure and dependency management.</li><li><a href="https://github.com/vector-of-bool/pitchfork/"><strong>vector-of-bool/pitchfork</strong></a>: Pitchfork is a Set of C++ Project Conventions.</li></ul></section><section id="autotoc_md15"><h3><a href="#autotoc_md15">Star History</a></h3><p><a href="https://star-history.com/#TheLartians/ModernCppStarter&cpp-best-practices/gui_starter_template&filipdutescu/modern-cpp-template&Date"><img class="m-image" src="https://api.star-history.com/svg?repos=TheLartians/ModernCppStarter,cpp-best-practices/gui_starter_template,filipdutescu/modern-cpp-template&type=Date" alt="Image" /></a></p></section></section>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</article></main>
|
|
<div class="m-doc-search" id="search">
|
|
<a href="#!" onclick="return hideSearch()"></a>
|
|
<div class="m-container">
|
|
<div class="m-row">
|
|
<div class="m-col-m-8 m-push-m-2">
|
|
<div class="m-doc-search-header m-text m-small">
|
|
<div><span class="m-label m-default">Tab</span> / <span class="m-label m-default">T</span> to search, <span class="m-label m-default">Esc</span> to close</div>
|
|
<div id="search-symbolcount">…</div>
|
|
</div>
|
|
<div class="m-doc-search-content">
|
|
<form>
|
|
<input type="search" name="q" id="search-input" placeholder="Loading …" disabled="disabled" autofocus="autofocus" autocomplete="off" spellcheck="false" />
|
|
</form>
|
|
<noscript class="m-text m-danger m-text-center">Unlike everything else in the docs, the search functionality <em>requires</em> JavaScript.</noscript>
|
|
<div id="search-help" class="m-text m-dim m-text-center">
|
|
<p class="m-noindent">Search for symbols, directories, files, pages or
|
|
modules. You can omit any prefix from the symbol or file path; adding a
|
|
<code>:</code> or <code>/</code> suffix lists all members of given symbol or
|
|
directory.</p>
|
|
<p class="m-noindent">Use <span class="m-label m-dim">↓</span>
|
|
/ <span class="m-label m-dim">↑</span> to navigate through the list,
|
|
<span class="m-label m-dim">Enter</span> to go.
|
|
<span class="m-label m-dim">Tab</span> autocompletes common prefix, you can
|
|
copy a link to the result using <span class="m-label m-dim">⌘</span>
|
|
<span class="m-label m-dim">L</span> while <span class="m-label m-dim">⌘</span>
|
|
<span class="m-label m-dim">M</span> produces a Markdown link.</p>
|
|
</div>
|
|
<div id="search-notfound" class="m-text m-warning m-text-center">Sorry, nothing was found.</div>
|
|
<ul id="search-results"></ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script src="search-v2.js"></script>
|
|
<script src="searchdata-v2.js" async="async"></script>
|
|
<footer><nav>
|
|
<div class="m-container">
|
|
<div class="m-row">
|
|
<div class="m-col-l-10 m-push-l-1">
|
|
<p>Greeter. Created with <a href="https://doxygen.org/">Doxygen</a> 1.9.8 and <a href="https://mcss.mosra.cz/">m.css</a>.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav></footer>
|
|
</body>
|
|
</html>
|