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!");
}