diff --git a/.github/workflows/documentation.yaml b/.github/workflows/documentation.yaml new file mode 100644 index 0000000..6ca043a --- /dev/null +++ b/.github/workflows/documentation.yaml @@ -0,0 +1,27 @@ +name: Documentation + +on: + push: + tags: + - '*' + +jobs: + build: + name: Build and publish documentation + runs-on: macos-latest + steps: + - uses: actions/checkout@v1 + + - name: Install doxygen + run: brew install doxygen + + - name: Build + run: | + cmake -Hdocumentation -Bbuild + cmake --build build --target GenerateDocs + + - name: Publish + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./build/doxygen/html diff --git a/CMakeLists.txt b/CMakeLists.txt index 7613cc1..20ba77d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ include(cmake/CPM.cmake) CPMAddPackage( NAME PackageProject.cmake GITHUB_REPOSITORY TheLartians/PackageProject.cmake - VERSION 1.2 + VERSION 1.2.1 ) # ---- Add source files ---- diff --git a/README.md b/README.md index 079be2e..2e82cc8 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,8 @@ This template is the result of learnings from many previous projects and should - Code formatting enforced by [clang-format](https://clang.llvm.org/docs/ClangFormat.html) via [Format.cmake](https://github.com/TheLartians/Format.cmake) - Reproducible dependency management via [CPM.cmake](https://github.com/TheLartians/CPM.cmake) - Installable target with versioning information via [PackageProject.cmake](https://github.com/TheLartians/PackageProject.cmake) -- Support for [sanitizer tools and more](#additional-tools) +- Automatic documentation generation with [Doxygen](https://www.doxygen.nl) +- Support for [sanitizer tools, and more](#additional-tools) ## Usage @@ -81,14 +82,36 @@ cmake --build build/test --target fix-format See [Format.cmake](https://github.com/TheLartians/Format.cmake) for more options. +### Build the documentation + +The documentation is automatically built and updated after every [release](https://help.github.com/en/github/administering-a-repository/managing-releases-in-a-repository). +To manually build documentation, call the following command. + +```bash +cmake -Hdocumentation -Bbuild/doc +cmake --build build/doc --target GenerateDocs +# view the docs +open build/doc/doxygen/html/index.html +``` + ### Additional tools The test and standalone subprojects include the [tools.cmake](cmake/tools.cmake) file which is used to import additional tools on-demand through CMake configuration arguments. The following are currently supported. -- **Sanitizers**, by setting `-DUSE_SANITIZER=
`. -- **Static Analyzers**, by setting `-DUSE_STATIC_ANALYZER=`, or a combination of those in quotation marks, separated by semicolons. Arguments can be passed to the analyzers by setting the `CLANG_TIDY_ARGS`, `IWYU_ARGS` or `CPPCHECK_ARGS` variables. -- **Ccache**, by setting `-DUSE_CCACHE=`. +#### Sanitizers + +Sanitizers can be enabled by configuring CMake with `-DUSE_SANITIZER=
`. + +#### Static Analyzers + +Static Analyzers can be enabled by setting `-DUSE_STATIC_ANALYZER=`, or a combination of those in quotation marks, separated by semicolons. +By default, analyzers will automatically find configuration files such as `.clang-format`. +Additional arguments can be passed to the analyzers by setting the `CLANG_TIDY_ARGS`, `IWYU_ARGS` or `CPPCHECK_ARGS` variables. + +#### Ccache + +Ccache can be enabled by configuring with `-DUSE_CCACHE=`. ## FAQ @@ -97,9 +120,15 @@ The following are currently supported. Yes, however you will need to change the library type to an `INTERFACE` library as documented in the [CMakeLists.txt](CMakeLists.txt). See [here](https://github.com/TheLartians/StaticTypeInfo) for an example header-only library based on the template. -> I don't need a standalone target. How can I get rid of it? +> I don't need a standalone target / documentation. How can I get rid of it? -Simply remove the standalone directory and github workflow file. +Simply remove the standalone / documentation directory and according github workflow file. + +> Can I build the standalone and tests at the same time? + +To keep the template modular, projects have been separated into their own CMake modules. +However it's easy to create a new directory, say `all`, that uses `CPMAddProject` to add both the standalone and the tests as well as any other subprojects to a single build. +Note, that it's not recommended to include the standalone or tests from the main CMakeLists, as it will make the project more difficult for others to use as a library. > I see you are using `GLOB` to add source files in CMakeLists.txt. Isn't that evil? @@ -108,7 +137,7 @@ Glob is considered bad because any changes to the source file structure [might n > I want create additional targets that depend on my library. Should I modify the main CMakeLists to include them? -Always 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. +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 [standalone](standalone/CMakeLists.txt) 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. diff --git a/documentation/CMakeLists.txt b/documentation/CMakeLists.txt new file mode 100644 index 0000000..0a16fb9 --- /dev/null +++ b/documentation/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.5 FATAL_ERROR) + +project(GreeterDocs) + +# ---- Dependencies ---- + +include(../cmake/CPM.cmake) + +CPMAddPackage( + NAME Greeter + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/.. +) + +CPMAddPackage( + NAME StableCoder-cmake-scripts + GITHUB_REPOSITORY StableCoder/cmake-scripts + GIT_TAG 3d2d5a9fb26f0ce24e3e4eaeeff686ec2ecfb3fb +) + +# ---- Doxygen ---- + +set(BUILD_DOCUMENTATION ON CACHE INTERNAL "") +include(${StableCoder-cmake-scripts_SOURCE_DIR}/doxygen.cmake) + +# set Doxyfile variables +set(DOXYGEN_PROJECT_NAME Greeter) +set(DOXYGEN_PROJECT_VERSION ${Greeter_VERSION}) +set(DOXYGEN_PROJECT_ROOT "${CMAKE_CURRENT_LIST_DIR}/..") + +# see https://github.com/StableCoder/cmake-scripts#doxygen-doxygencmake for additional options +build_docs( + TARGET_NAME GenerateDocs + DOXYFILE_PATH ${CMAKE_CURRENT_LIST_DIR}/Doxyfile + OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/doxygen + PROCESS_DOXYFILE ON +) diff --git a/documentation/Doxyfile b/documentation/Doxyfile new file mode 100644 index 0000000..c771bf3 --- /dev/null +++ b/documentation/Doxyfile @@ -0,0 +1,25 @@ +# Configuration for Doxygen for use with CMake +# Only options that deviate from the default are included +# To create a new Doxyfile containing all available options, call `doxygen -g` + +# Get Project name and version from CMake +PROJECT_NAME = @DOXYGEN_PROJECT_NAME@ +PROJECT_NUMBER = @DOXYGEN_PROJECT_VERSION@ + +# Add sources +INPUT = @DOXYGEN_PROJECT_ROOT@/README.md @DOXYGEN_PROJECT_ROOT@/include @DOXYGEN_PROJECT_ROOT@/source +EXTRACT_ALL = YES +RECURSIVE = YES + +# We don't want local paths in the documentation +FULL_PATH_NAMES = NO + +# Use the README as a main page +USE_MDFILE_AS_MAINPAGE = @DOXYGEN_PROJECT_ROOT@/README.md + +# Create nicer looking HTML +HTML_DYNAMIC_SECTIONS = YES +GENERATE_TREEVIEW = YES + +# We don't need LaTeX generation +GENERATE_LATEX = NO diff --git a/include/greeter.h b/include/greeter.h index e55f53e..e3ff923 100644 --- a/include/greeter.h +++ b/include/greeter.h @@ -4,13 +4,27 @@ namespace greeter { + /** Language codes to be used with the Greeter class */ enum class LanguageCode { EN, DE, ES, FR }; + /** + * A class for saying hello in multiple languages + */ class Greeter { std::string name; public: + /** + * Creates a new greeter + * @param name the name to greet + */ Greeter(std::string name); + + /** + * Creates a localized string containing the greeting + * @param lang the language to greet in + * @return a string containing the greeting + */ std::string greet(LanguageCode lang = LanguageCode::EN) const; }; diff --git a/test/source/greeter.cpp b/test/source/greeter.cpp index ca8834d..eb12ab3 100644 --- a/test/source/greeter.cpp +++ b/test/source/greeter.cpp @@ -4,10 +4,10 @@ TEST_CASE("Greeter") { using namespace greeter; - Greeter greeter("World"); + Greeter greeter("Tests"); - CHECK(greeter.greet(LanguageCode::EN) == "Hello, World!"); - CHECK(greeter.greet(LanguageCode::DE) == "Hallo World!"); - CHECK(greeter.greet(LanguageCode::ES) == "¡Hola World!"); - CHECK(greeter.greet(LanguageCode::FR) == "Bonjour World!"); + CHECK(greeter.greet(LanguageCode::EN) == "Hello, Tests!"); + CHECK(greeter.greet(LanguageCode::DE) == "Hallo Tests!"); + CHECK(greeter.greet(LanguageCode::ES) == "¡Hola Tests!"); + CHECK(greeter.greet(LanguageCode::FR) == "Bonjour Tests!"); }