├── .clang-format ├── .clang-tidy ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md └── workflows │ ├── macos.yml │ ├── release.yml │ ├── ubuntu.yml │ └── windows.yml ├── .gitignore ├── CMakeLists.txt ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── Makefile ├── PULL_REQUEST_TEMPLATE.md ├── README.md ├── cmake ├── CompilerWarnings.cmake ├── Conan.cmake ├── Doxygen.cmake ├── ProjectConfig.cmake.in ├── SourcesAndHeaders.cmake ├── StandardSettings.cmake ├── StaticAnalyzers.cmake ├── Utils.cmake ├── Vcpkg.cmake └── version.hpp.in ├── codecov.yaml ├── include └── project │ └── tmp.hpp ├── src └── tmp.cpp └── test ├── CMakeLists.txt └── src └── tmp_test.cpp /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: Google 3 | AlignAfterOpenBracket: 'AlwaysBreak' 4 | AllowAllConstructorInitializersOnNextLine: 'false' 5 | AllowAllParametersOfDeclarationOnNextLine: 'false' 6 | AlignConsecutiveMacros: 'true' 7 | AllowShortCaseLabelsOnASingleLine: 'true' 8 | AllowShortFunctionsOnASingleLine: 'None' 9 | AllowShortIfStatementsOnASingleLine: 'Never' 10 | AllowShortLoopsOnASingleLine: 'false' 11 | BreakBeforeBraces: Allman 12 | BinPackArguments: 'false' 13 | BinPackParameters: 'false' 14 | Cpp11BracedListStyle: 'false' 15 | ColumnLimit: 125 16 | NamespaceIndentation: All 17 | SpaceAfterTemplateKeyword: 'false' 18 | SpaceBeforeCtorInitializerColon: 'true' 19 | SpaceBeforeInheritanceColon: 'true' 20 | SpaceBeforeParens: ControlStatements 21 | SpaceBeforeRangeBasedForLoopColon: 'true' 22 | SpaceInEmptyBlock: true 23 | Standard: 'Latest' 24 | ... 25 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | --- 2 | Checks: '*,-fuchsia-*,-google-*,-zircon-*,-abseil-*,-modernize-use-trailing-return-type,-llvm-*,-llvmlibc-*' 3 | CheckOptions: [{ key: misc-non-private-member-variables-in-classes, value: IgnoreClassesWithAllMemberVariablesBeingPublic }] 4 | WarningsAsErrors: '*' 5 | HeaderFilterRegex: '' 6 | FormatStyle: none 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help me improve 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 16 | 1. Go to '...' 17 | 2. Click on '....' 18 | 3. Scroll down to '....' 19 | 4. See error 20 | 21 | **Expected behavior** 22 | A clear and concise description of what you expected to happen. 23 | 24 | **Screenshots** 25 | If applicable, add screenshots to help explain your problem. 26 | 27 | **Desktop (please complete the following information):** 28 | 29 | * OS: [e.g. Windows] 30 | * Version [e.g. 10] 31 | 32 | **Additional context** 33 | Add any other context about the problem here. 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE]" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated 12 | when [...] 13 | 14 | **Describe the solution you'd like** 15 | A clear and concise description of what you want to happen. 16 | 17 | **Describe alternatives you've considered** 18 | A clear and concise description of any alternative solutions or features you've considered. 19 | 20 | **Provide usage examples** 21 | A few examples of how the feature should be used. Please make sure they are clear 22 | and concise. 23 | 24 | **Additional context** 25 | Add any other context or screenshots about the feature request here. 26 | -------------------------------------------------------------------------------- /.github/workflows/macos.yml: -------------------------------------------------------------------------------- 1 | name: MacOS 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | env: 10 | BUILD_TYPE: Release 11 | INSTALL_LOCATION: .local 12 | 13 | jobs: 14 | build: 15 | 16 | runs-on: macos-latest 17 | if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')" 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | 22 | - name: cache dependencies 23 | uses: actions/cache@v2 24 | id: cache 25 | with: 26 | path: ${{ github.workspace }}/${{ env.INSTALL_LOCATION }} 27 | key: ${{ runner.os }}-dependencies 28 | 29 | - name: install GoogleTest 30 | if: ${{ steps.cache.output.cache-hit != 'true' }} 31 | run: | 32 | cd .. 33 | git clone https://github.com/google/googletest.git --branch release-1.10.0 34 | cd googletest 35 | cmake -Bbuild -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/$INSTALL_LOCATION 36 | cmake --build build --config Release 37 | cmake --build build --target install --config Release 38 | cd ../modern-cpp-template 39 | 40 | - name: configure 41 | run: cmake -Bbuild -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/$INSTALL_LOCATION 42 | 43 | - name: build 44 | run: cmake --build build --config $BUILD_TYPE -j4 45 | 46 | - name: run tests 47 | run: | 48 | cd build 49 | ctest -C $BUILD_TYPE -VV 50 | 51 | - name: install project 52 | run: cmake --build build --target install --config Release 53 | 54 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | env: 9 | PROJECT_NAME: "modern-cpp-template" 10 | BUILD_TYPE: Release 11 | 12 | jobs: 13 | build: 14 | name: ${{ matrix.config.name }} 15 | runs-on: ${{ matrix.config.os }} 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | config: 20 | - { 21 | name: "Windows Latest MSVC", 22 | artifact_ext: '.zip', 23 | os: windows-latest, 24 | cc: "cl", 25 | cxx: "cl", 26 | environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat", 27 | } 28 | - { 29 | name: "Ubuntu Latest GCC", 30 | artifact_ext: '.tar.gz', 31 | os: ubuntu-latest, 32 | cc: "gcc", 33 | cxx: "g++", 34 | } 35 | - { 36 | name: "macOS Latest Clang", 37 | artifact_ext: '.tar.gz', 38 | os: macos-latest, 39 | cc: "clang", 40 | cxx: "clang++", 41 | } 42 | 43 | steps: 44 | - name: set version name (Windows) 45 | id: version_win 46 | if: ${{ runner.os == 'Windows' }} 47 | run: | 48 | $TAG = (${env:GITHUB_REF} -replace 'refs/tags/', '') 49 | echo "::set-output name=name::$TAG" 50 | 51 | - name: set version name 52 | id: version 53 | if: ${{ runner.os != 'Windows' }} 54 | run: echo ::set-output name=name::${GITHUB_REF#refs/tags/} 55 | 56 | - name: Checkout 57 | uses: actions/checkout@v2 58 | with: 59 | submodules: recursive 60 | 61 | - name: cache dependencies 62 | uses: actions/cache@v2 63 | id: cache 64 | with: 65 | path: ${{ github.HOME }}/.local 66 | key: ${{ runner.os }}-dependencies 67 | 68 | - name: install GoogleTest 69 | if: ${{ steps.cache.output.cache-hit != 'true' }} 70 | run: | 71 | cd .. 72 | git clone https://github.com/google/googletest.git --branch release-1.10.0 73 | cd googletest 74 | cmake -Bbuild -DCMAKE_INSTALL_PREFIX="$HOME/.local" -Dgtest_force_shared_crt=1 75 | cmake --build build --config Release 76 | cmake --build build --target install --config Release 77 | cd ../modern-cpp-template 78 | 79 | - name: configure 80 | run: cmake -Bbuild -DCMAKE_INSTALL_PREFIX="$HOME/.local" 81 | 82 | - name: build 83 | run: cmake --build build --config "$env:BUILD_TYPE" -j4 84 | 85 | - name: run tests 86 | run: | 87 | cd build 88 | ctest -C "$env:BUILD_TYPE" -VV 89 | 90 | # for a release not containing directly the source code, replace the files archived 91 | # with the actual files needed (i.e. *.lib/*.a and *.h(pp)) 92 | 93 | - name: generate archive (Windows) 94 | if: ${{ runner.os == 'Windows' }} 95 | run: | 96 | rmdir -r -fo build 97 | 7z a -tzip $HOME/artifact.zip * 98 | 99 | 100 | - name: generate archive 101 | if: ${{ runner.os != 'Windows' }} 102 | run: | 103 | rm -rf build 104 | tar -cvzf $HOME/artifact.tar.gz . 105 | 106 | - name: upload artifacts 107 | uses: actions/upload-artifact@v2 108 | if: ${{ runner.os == 'Windows' }} 109 | with: 110 | name: ${{ runner.os }}-${{ steps.version_win.outputs.name }} 111 | path: '~/artifact.*' 112 | 113 | - name: upload artifacts 114 | uses: actions/upload-artifact@v2 115 | if: ${{ runner.os != 'Windows' }} 116 | with: 117 | name: ${{ runner.os }}-${{ steps.version.outputs.name }} 118 | path: '~/artifact.*' 119 | 120 | release: 121 | if: contains(github.ref, 'tags/v') 122 | runs-on: ubuntu-latest 123 | needs: build 124 | 125 | steps: 126 | - name: set version name 127 | id: version 128 | run: echo ::set-output name=name::${GITHUB_REF#refs/tags/} 129 | 130 | - name: create release 131 | id: create_release 132 | uses: actions/create-release@v1 133 | env: 134 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 135 | with: 136 | tag_name: ${{ github.ref }} 137 | release_name: Release ${{ steps.version.outputs.name }} 138 | # if needed, you can set the release body here 139 | #body: "Release notes" 140 | draft: false 141 | prerelease: false 142 | 143 | - name: download artifact 144 | uses: actions/download-artifact@v2 145 | with: 146 | name: "Linux-${{ steps.version.outputs.name }}" 147 | path: ./ 148 | 149 | - name: upload ubuntu release asset 150 | uses: actions/upload-release-asset@v1 151 | env: 152 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 153 | with: 154 | upload_url: ${{ steps.create_release.outputs.upload_url }} 155 | asset_path: "artifact.tar.gz" 156 | asset_name: "${{ env.PROJECT_NAME }}-Linux-${{ steps.version.outputs.name }}.tar.gz" 157 | asset_content_type: application/x-tar 158 | 159 | - name: download artifact 160 | uses: actions/download-artifact@v2 161 | with: 162 | name: "Windows-${{ steps.version.outputs.name }}" 163 | path: ./ 164 | 165 | - name: upload windows release asset 166 | uses: actions/upload-release-asset@v1 167 | env: 168 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 169 | with: 170 | upload_url: ${{ steps.create_release.outputs.upload_url }} 171 | asset_path: "artifact.zip" 172 | asset_name: "${{ env.PROJECT_NAME }}-Windows-${{ steps.version.outputs.name }}.zip" 173 | asset_content_type: application/zip 174 | 175 | - name: download artifact 176 | uses: actions/download-artifact@v2 177 | with: 178 | name: "macOS-${{ steps.version.outputs.name }}" 179 | path: ./ 180 | 181 | - name: upload macos release asset 182 | uses: actions/upload-release-asset@v1 183 | env: 184 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 185 | with: 186 | upload_url: ${{ steps.create_release.outputs.upload_url }} 187 | asset_path: "./artifact.tar.gz" 188 | asset_name: "${{ env.PROJECT_NAME }}-macOS-${{ steps.version.outputs.name }}.tar.gz" 189 | asset_content_type: application/x-tar 190 | -------------------------------------------------------------------------------- /.github/workflows/ubuntu.yml: -------------------------------------------------------------------------------- 1 | name: Ubuntu 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | env: 10 | BUILD_TYPE: Release 11 | INSTALL_LOCATION: .local 12 | 13 | jobs: 14 | build: 15 | 16 | runs-on: ubuntu-latest 17 | if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')" 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | 22 | - name: cache dependencies 23 | uses: actions/cache@v2 24 | id: cache 25 | with: 26 | path: ${{ github.workspace }}/${{ env.INSTALL_LOCATION }} 27 | key: ${{ runner.os }}-dependencies 28 | 29 | - name: install GoogleTest 30 | if: ${{ steps.cache.output.cache-hit != 'true' }} 31 | run: | 32 | cd .. 33 | git clone https://github.com/google/googletest.git --branch release-1.10.0 34 | cd googletest 35 | cmake -Bbuild -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/$INSTALL_LOCATION 36 | cmake --build build --config Release 37 | cmake --build build --target install --config Release 38 | 39 | - name: configure 40 | run: cmake -Bbuild -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/$INSTALL_LOCATION -DProject_ENABLE_CODE_COVERAGE=1 41 | 42 | - name: build 43 | run: cmake --build build --config $BUILD_TYPE -j4 44 | 45 | - name: run tests 46 | run: | 47 | cd build 48 | ctest -C $BUILD_TYPE -VV 49 | 50 | - name: Code coverage using Codecov 51 | run: bash <(curl -s https://codecov.io/bash) 52 | 53 | - name: install project 54 | run: cmake --build build --target install --config Release 55 | 56 | -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: Windows 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | env: 10 | BUILD_TYPE: Release 11 | INSTALL_LOCATION: ".local" 12 | 13 | jobs: 14 | build: 15 | 16 | runs-on: windows-latest 17 | if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')" 18 | 19 | steps: 20 | - uses: actions/checkout@v2 21 | 22 | - name: cache dependencies 23 | uses: actions/cache@v2 24 | id: cache 25 | with: 26 | path: ${{env.INSTALL_LOCATION}} 27 | key: ${{runner.os}}-dependencies 28 | 29 | - name: install GoogleTest 30 | if: ${{steps.cache.output.cache-hit != 'true'}} 31 | run: | 32 | cd .. 33 | git clone https://github.com/google/googletest.git --branch release-1.10.0 34 | cd googletest 35 | cmake -Bbuild -DCMAKE_INSTALL_PREFIX="$HOME/$env:INSTALL_LOCATION" -Dgtest_force_shared_crt=1 36 | cmake --build build --config Release 37 | cmake --build build --target install --config Release 38 | cd ../modern-cpp-template 39 | 40 | - name: configure 41 | run: cmake -Bbuild -DCMAKE_INSTALL_PREFIX="$HOME/$env:INSTALL_LOCATION" 42 | 43 | - name: build 44 | run: cmake --build build --config "$env:BUILD_TYPE" -j4 45 | 46 | - name: run tests 47 | run: | 48 | cd build 49 | ctest -C "$env:BUILD_TYPE" -VV 50 | 51 | - name: install project 52 | run: cmake --build build --target install --config Release 53 | 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | [Bb]uild/* 2 | [Dd]ocs/* 3 | CMakeCache.* 4 | CMakeFiles/* 5 | [Tt]esting/* 6 | 7 | ### VisualStudioCode ### 8 | .vscode/* 9 | .vscode/settings.json 10 | .vscode/tasks.json 11 | .vscode/launch.json 12 | .vscode/extensions.json 13 | 14 | ### VisualStudioCode Patch ### 15 | # Ignore all local history of files 16 | .history 17 | 18 | ### VisualStudio ### 19 | ## Ignore Visual Studio temporary files, build results, and 20 | ## files generated by popular Visual Studio add-ons. 21 | 22 | # User-specific files 23 | *.rsuser 24 | *.suo 25 | *.user 26 | *.userosscache 27 | *.sln.docstates 28 | 29 | # User-specific files (MonoDevelop/Xamarin Studio) 30 | *.userprefs 31 | 32 | # Mono auto generated files 33 | mono_crash.* 34 | 35 | # Build results 36 | [Dd]ebug/ 37 | [Dd]ebugPublic/ 38 | [Rr]elease/ 39 | [Rr]eleases/ 40 | x64/ 41 | x86/ 42 | [Aa][Rr][Mm]/ 43 | [Aa][Rr][Mm]64/ 44 | bld/ 45 | [Bb]in/ 46 | [Oo]bj/ 47 | [Ll]og/ 48 | 49 | # Visual Studio 2015/2017 cache/options directory 50 | .vs/ 51 | # Uncomment if you have tasks that create the project's static files in wwwroot 52 | #wwwroot/ 53 | 54 | # Visual Studio 2017 auto generated files 55 | Generated\ Files/ 56 | 57 | # MSTest test Results 58 | [Tt]est[Rr]esult*/ 59 | [Bb]uild[Ll]og.* 60 | 61 | # NUnit 62 | *.VisualState.xml 63 | TestResult.xml 64 | nunit-*.xml 65 | 66 | # Build Results of an ATL Project 67 | [Dd]ebugPS/ 68 | [Rr]eleasePS/ 69 | dlldata.c 70 | 71 | # Benchmark Results 72 | BenchmarkDotNet.Artifacts/ 73 | 74 | # .NET Core 75 | project.lock.json 76 | project.fragment.lock.json 77 | artifacts/ 78 | 79 | # StyleCop 80 | StyleCopReport.xml 81 | 82 | # Files built by Visual Studio 83 | *_i.c 84 | *_p.c 85 | *_h.h 86 | *.ilk 87 | *.obj 88 | *.iobj 89 | *.pch 90 | *.pdb 91 | *.ipdb 92 | *.pgc 93 | *.pgd 94 | *.rsp 95 | *.sbr 96 | *.tlb 97 | *.tli 98 | *.tlh 99 | *.tmp 100 | *.tmp_proj 101 | *_wpftmp.csproj 102 | *.log 103 | *.vspscc 104 | *.vssscc 105 | .builds 106 | *.pidb 107 | *.svclog 108 | *.scc 109 | 110 | # Chutzpah Test files 111 | _Chutzpah* 112 | 113 | # Visual C++ cache files 114 | ipch/ 115 | *.aps 116 | *.ncb 117 | *.opendb 118 | *.opensdf 119 | *.sdf 120 | *.cachefile 121 | *.VC.db 122 | *.VC.VC.opendb 123 | 124 | # Visual Studio profiler 125 | *.psess 126 | *.vsp 127 | *.vspx 128 | *.sap 129 | 130 | # Visual Studio Trace Files 131 | *.e2e 132 | 133 | # TFS 2012 Local Workspace 134 | $tf/ 135 | 136 | # Guidance Automation Toolkit 137 | *.gpState 138 | 139 | # ReSharper is a .NET coding add-in 140 | _ReSharper*/ 141 | *.[Rr]e[Ss]harper 142 | *.DotSettings.user 143 | 144 | # JustCode is a .NET coding add-in 145 | .JustCode 146 | 147 | # TeamCity is a build add-in 148 | _TeamCity* 149 | 150 | # DotCover is a Code Coverage Tool 151 | *.dotCover 152 | 153 | # AxoCover is a Code Coverage Tool 154 | .axoCover/* 155 | !.axoCover/settings.json 156 | 157 | # Visual Studio code coverage results 158 | *.coverage 159 | *.coveragexml 160 | 161 | # NCrunch 162 | _NCrunch_* 163 | .*crunch*.local.xml 164 | nCrunchTemp_* 165 | 166 | # MightyMoose 167 | *.mm.* 168 | AutoTest.Net/ 169 | 170 | # Web workbench (sass) 171 | .sass-cache/ 172 | 173 | # Installshield output folder 174 | [Ee]xpress/ 175 | 176 | # DocProject is a documentation generator add-in 177 | DocProject/buildhelp/ 178 | DocProject/Help/*.HxT 179 | DocProject/Help/*.HxC 180 | DocProject/Help/*.hhc 181 | DocProject/Help/*.hhk 182 | DocProject/Help/*.hhp 183 | DocProject/Help/Html2 184 | DocProject/Help/html 185 | 186 | # Click-Once directory 187 | publish/ 188 | 189 | # Publish Web Output 190 | *.[Pp]ublish.xml 191 | *.azurePubxml 192 | # Note: Comment the next line if you want to checkin your web deploy settings, 193 | # but database connection strings (with potential passwords) will be unencrypted 194 | *.pubxml 195 | *.publishproj 196 | 197 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 198 | # checkin your Azure Web App publish settings, but sensitive information contained 199 | # in these scripts will be unencrypted 200 | PublishScripts/ 201 | 202 | # NuGet Packages 203 | *.nupkg 204 | # NuGet Symbol Packages 205 | *.snupkg 206 | # The packages folder can be ignored because of Package Restore 207 | **/[Pp]ackages/* 208 | # except build/, which is used as an MSBuild target. 209 | !**/[Pp]ackages/build/ 210 | # Uncomment if necessary however generally it will be regenerated when needed 211 | #!**/[Pp]ackages/repositories.config 212 | # NuGet v3's project.json files produces more ignorable files 213 | *.nuget.props 214 | *.nuget.targets 215 | 216 | # Microsoft Azure Build Output 217 | csx/ 218 | *.build.csdef 219 | 220 | # Microsoft Azure Emulator 221 | ecf/ 222 | rcf/ 223 | 224 | # Windows Store app package directories and files 225 | AppPackages/ 226 | BundleArtifacts/ 227 | Package.StoreAssociation.xml 228 | _pkginfo.txt 229 | *.appx 230 | *.appxbundle 231 | *.appxupload 232 | 233 | # Visual Studio cache files 234 | # files ending in .cache can be ignored 235 | *.[Cc]ache 236 | # but keep track of directories ending in .cache 237 | !?*.[Cc]ache/ 238 | 239 | # Others 240 | ClientBin/ 241 | ~$* 242 | *~ 243 | *.dbmdl 244 | *.dbproj.schemaview 245 | *.jfm 246 | *.pfx 247 | *.publishsettings 248 | orleans.codegen.cs 249 | 250 | #KDevelop 251 | *.kdev4 252 | .kdev4/* 253 | 254 | # Including strong name files can present a security risk 255 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 256 | #*.snk 257 | 258 | # Since there are multiple workflows, uncomment next line to ignore bower_components 259 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 260 | #bower_components/ 261 | 262 | # RIA/Silverlight projects 263 | Generated_Code/ 264 | 265 | # Backup & report files from converting an old project file 266 | # to a newer Visual Studio version. Backup files are not needed, 267 | # because we have git ;-) 268 | _UpgradeReport_Files/ 269 | Backup*/ 270 | UpgradeLog*.XML 271 | UpgradeLog*.htm 272 | ServiceFabricBackup/ 273 | *.rptproj.bak 274 | 275 | # SQL Server files 276 | *.mdf 277 | *.ldf 278 | *.ndf 279 | 280 | # Business Intelligence projects 281 | *.rdl.data 282 | *.bim.layout 283 | *.bim_*.settings 284 | *.rptproj.rsuser 285 | *- [Bb]ackup.rdl 286 | *- [Bb]ackup ([0-9]).rdl 287 | *- [Bb]ackup ([0-9][0-9]).rdl 288 | 289 | # Microsoft Fakes 290 | FakesAssemblies/ 291 | 292 | # GhostDoc plugin setting file 293 | *.GhostDoc.xml 294 | 295 | # Node.js Tools for Visual Studio 296 | .ntvs_analysis.dat 297 | node_modules/ 298 | 299 | # Visual Studio 6 build log 300 | *.plg 301 | 302 | # Visual Studio 6 workspace options file 303 | *.opt 304 | 305 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 306 | *.vbw 307 | 308 | # Visual Studio LightSwitch build output 309 | **/*.HTMLClient/GeneratedArtifacts 310 | **/*.DesktopClient/GeneratedArtifacts 311 | **/*.DesktopClient/ModelManifest.xml 312 | **/*.Server/GeneratedArtifacts 313 | **/*.Server/ModelManifest.xml 314 | _Pvt_Extensions 315 | 316 | # Paket dependency manager 317 | .paket/paket.exe 318 | paket-files/ 319 | 320 | # FAKE - F# Make 321 | .fake/ 322 | 323 | # CodeRush personal settings 324 | .cr/personal 325 | 326 | # Python Tools for Visual Studio (PTVS) 327 | __pycache__/ 328 | *.pyc 329 | 330 | # Cake - Uncomment if you are using it 331 | # tools/** 332 | # !tools/packages.config 333 | 334 | # Tabs Studio 335 | *.tss 336 | 337 | # Telerik's JustMock configuration file 338 | *.jmconfig 339 | 340 | # BizTalk build output 341 | *.btp.cs 342 | *.btm.cs 343 | *.odx.cs 344 | *.xsd.cs 345 | 346 | # OpenCover UI analysis results 347 | OpenCover/ 348 | 349 | # Azure Stream Analytics local run output 350 | ASALocalRun/ 351 | 352 | # MSBuild Binary and Structured Log 353 | *.binlog 354 | 355 | # NVidia Nsight GPU debugger configuration file 356 | *.nvuser 357 | 358 | # MFractors (Xamarin productivity tool) working folder 359 | .mfractor/ 360 | 361 | # Local History for Visual Studio 362 | .localhistory/ 363 | 364 | # BeatPulse healthcheck temp database 365 | healthchecksdb 366 | 367 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 368 | MigrationBackup/ 369 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | 3 | # 4 | # Project details 5 | # 6 | 7 | project( 8 | "Project" 9 | VERSION 0.1.0 10 | LANGUAGES CXX 11 | ) 12 | 13 | # 14 | # Set project options 15 | # 16 | 17 | include(cmake/StandardSettings.cmake) 18 | include(cmake/StaticAnalyzers.cmake) 19 | include(cmake/Utils.cmake) 20 | if(NOT CMAKE_BUILD_TYPE) 21 | set(CMAKE_BUILD_TYPE "Debug") 22 | endif() 23 | message(STATUS "Started CMake for ${PROJECT_NAME} v${PROJECT_VERSION}...\n") 24 | 25 | if (UNIX) 26 | add_compile_options("$<$:-D_DEBUG>") #this will allow to use same _DEBUG macro available in both Linux as well as Windows - MSCV environment. Easy to put Debug specific code. 27 | endif (UNIX) 28 | 29 | 30 | # 31 | # Setup alternative names 32 | # 33 | 34 | if(${PROJECT_NAME}_USE_ALT_NAMES) 35 | string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWERCASE) 36 | string(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPERCASE) 37 | else() 38 | set(PROJECT_NAME_LOWERCASE ${PROJECT_NAME}) 39 | set(PROJECT_NAME_UPPERCASE ${PROJECT_NAME}) 40 | endif() 41 | 42 | # 43 | # Prevent building in the source directory 44 | # 45 | 46 | if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) 47 | message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.\n") 48 | endif() 49 | 50 | # 51 | # Enable package managers 52 | # 53 | 54 | include(cmake/Conan.cmake) 55 | include(cmake/Vcpkg.cmake) 56 | 57 | # 58 | # Create library, setup header and source files 59 | # 60 | 61 | # Find all headers and implementation files 62 | include(cmake/SourcesAndHeaders.cmake) 63 | 64 | if(${PROJECT_NAME}_BUILD_EXECUTABLE) 65 | add_executable(${PROJECT_NAME} ${exe_sources}) 66 | 67 | if(${PROJECT_NAME}_VERBOSE_OUTPUT) 68 | verbose_message("Found the following sources:") 69 | foreach(source IN LISTS exe_sources) 70 | verbose_message("* ${source}") 71 | endforeach() 72 | endif() 73 | 74 | if(${PROJECT_NAME}_ENABLE_UNIT_TESTING) 75 | add_library(${PROJECT_NAME}_LIB ${headers} ${sources}) 76 | 77 | if(${PROJECT_NAME}_VERBOSE_OUTPUT) 78 | verbose_message("Found the following headers:") 79 | foreach(header IN LISTS headers) 80 | verbose_message("* ${header}") 81 | endforeach() 82 | endif() 83 | endif() 84 | elseif(${PROJECT_NAME}_BUILD_HEADERS_ONLY) 85 | add_library(${PROJECT_NAME} INTERFACE) 86 | 87 | if(${PROJECT_NAME}_VERBOSE_OUTPUT) 88 | verbose_message("Found the following headers:") 89 | foreach(header IN LIST headers) 90 | verbose_message("* ${header}") 91 | endforeach() 92 | endif() 93 | else() 94 | add_library( 95 | ${PROJECT_NAME} 96 | ${headers} 97 | ${sources} 98 | ) 99 | 100 | if(${PROJECT_NAME}_VERBOSE_OUTPUT) 101 | verbose_message("Found the following sources:") 102 | foreach(source IN LISTS sources) 103 | verbose_message("* ${source}") 104 | endforeach() 105 | verbose_message("Found the following headers:") 106 | foreach(header IN LISTS headers) 107 | verbose_message("* ${header}") 108 | endforeach() 109 | endif() 110 | endif() 111 | 112 | set_target_properties( 113 | ${PROJECT_NAME} 114 | PROPERTIES 115 | ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}" 116 | LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}" 117 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}" 118 | ) 119 | if(${PROJECT_NAME}_BUILD_EXECUTABLE AND ${PROJECT_NAME}_ENABLE_UNIT_TESTING) 120 | set_target_properties( 121 | ${PROJECT_NAME}_LIB 122 | PROPERTIES 123 | ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}" 124 | LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE}" 125 | OUTPUT_NAME ${PROJECT_NAME} 126 | ) 127 | endif() 128 | 129 | message(STATUS "Added all header and implementation files.\n") 130 | 131 | # 132 | # Set the project standard and warnings 133 | # 134 | 135 | if(${PROJECT_NAME}_BUILD_HEADERS_ONLY) 136 | target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17) 137 | else() 138 | target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_17) 139 | 140 | if(${PROJECT_NAME}_BUILD_EXECUTABLE AND ${PROJECT_NAME}_ENABLE_UNIT_TESTING) 141 | target_compile_features(${PROJECT_NAME}_LIB PUBLIC cxx_std_17) 142 | endif() 143 | endif() 144 | include(cmake/CompilerWarnings.cmake) 145 | set_project_warnings(${PROJECT_NAME}) 146 | 147 | verbose_message("Applied compiler warnings. Using standard ${CMAKE_CXX_STANDARD}.\n") 148 | 149 | # 150 | # Enable Doxygen 151 | # 152 | 153 | include(cmake/Doxygen.cmake) 154 | 155 | # 156 | # Model project dependencies 157 | # 158 | 159 | # Identify and link with the specific "packages" the project uses 160 | #find_package(package_name package_version REQUIRED package_type [other_options]) 161 | #target_link_libraries( 162 | # ${PROJECT_NAME} 163 | # PUBLIC 164 | # dependency1 ... 165 | # PRIVATE 166 | # dependency2 ... 167 | # ${PROJECT_NAME}_PROJECT_OPTIONS 168 | # ${PROJECT_NAME}_PROJECT_WARNINGS 169 | #) 170 | #if(${PROJECT_NAME}_BUILD_EXECUTABLE AND ${PROJECT_NAME}_ENABLE_UNIT_TESTING) 171 | # target_link_libraries( 172 | # ${PROJECT_NAME}_LIB 173 | # PUBLIC 174 | # dependency1 ... 175 | # ) 176 | #endif() 177 | 178 | # For Windows, it is necessary to link with the MultiThreaded library. 179 | # Depending on how the rest of the project's dependencies are linked, it might be necessary 180 | # to change the line to statically link with the library. 181 | # 182 | # This is done as follows: 183 | # 184 | # set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") 185 | # 186 | # On Linux and Mac this variable is ignored. If any issues rise from it, try commenting it out 187 | # and letting CMake decide how to link with it. 188 | set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") 189 | 190 | verbose_message("Successfully added all dependencies and linked against them.") 191 | 192 | # 193 | # Set the build/user include directories 194 | # 195 | 196 | # Allow usage of header files in the `src` directory, but only for utilities 197 | if(${PROJECT_NAME}_BUILD_HEADERS_ONLY) 198 | target_include_directories( 199 | ${PROJECT_NAME} 200 | INTERFACE 201 | $ 202 | $ 203 | ) 204 | else() 205 | target_include_directories( 206 | ${PROJECT_NAME} 207 | PUBLIC 208 | $ 209 | $ 210 | PRIVATE 211 | ${CMAKE_CURRENT_SOURCE_DIR}/src 212 | ) 213 | if(${PROJECT_NAME}_BUILD_EXECUTABLE AND ${PROJECT_NAME}_ENABLE_UNIT_TESTING) 214 | target_include_directories( 215 | ${PROJECT_NAME}_LIB 216 | PUBLIC 217 | $ 218 | $ 219 | PRIVATE 220 | ${CMAKE_CURRENT_SOURCE_DIR}/src 221 | ) 222 | endif() 223 | endif() 224 | 225 | message(STATUS "Finished setting up include directories.") 226 | 227 | # 228 | # Provide alias to library for 229 | # 230 | 231 | if(${PROJECT_NAME}_BUILD_EXECUTABLE) 232 | add_executable(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) 233 | else() 234 | add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) 235 | endif() 236 | 237 | verbose_message("Project is now aliased as ${PROJECT_NAME}::${PROJECT_NAME}.\n") 238 | 239 | # 240 | # Format the project using the `clang-format` target (i.e: cmake --build build --target clang-format) 241 | # 242 | 243 | add_clang_format_target() 244 | 245 | # 246 | # Install library for easy downstream inclusion 247 | # 248 | 249 | include(GNUInstallDirs) 250 | install( 251 | TARGETS 252 | ${PROJECT_NAME} 253 | EXPORT 254 | ${PROJECT_NAME}Targets 255 | LIBRARY DESTINATION 256 | ${CMAKE_INSTALL_LIBDIR} 257 | RUNTIME DESTINATION 258 | ${CMAKE_INSTALL_BINDIR} 259 | ARCHIVE DESTINATION 260 | ${CMAKE_INSTALL_LIBDIR} 261 | INCLUDES DESTINATION 262 | include 263 | PUBLIC_HEADER DESTINATION 264 | include 265 | ) 266 | 267 | install( 268 | EXPORT 269 | ${PROJECT_NAME}Targets 270 | FILE 271 | ${PROJECT_NAME}Targets.cmake 272 | NAMESPACE 273 | ${PROJECT_NAME}:: 274 | DESTINATION 275 | ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} 276 | ) 277 | 278 | # 279 | # Add version header 280 | # 281 | 282 | configure_file( 283 | ${CMAKE_CURRENT_LIST_DIR}/cmake/version.hpp.in 284 | include/${PROJECT_NAME_LOWERCASE}/version.hpp 285 | @ONLY 286 | ) 287 | 288 | install( 289 | FILES 290 | ${CMAKE_CURRENT_BINARY_DIR}/include/${PROJECT_NAME_LOWERCASE}/version.hpp 291 | DESTINATION 292 | include/${PROJECT_NAME_LOWERCASE} 293 | ) 294 | 295 | # 296 | # Install the `include` directory 297 | # 298 | 299 | install( 300 | DIRECTORY 301 | include/${PROJECT_NAME_LOWERCASE} 302 | DESTINATION 303 | include 304 | ) 305 | 306 | verbose_message("Install targets successfully built. Install with `cmake --build --target install --config `.") 307 | 308 | # 309 | # Quick `ConfigVersion.cmake` creation 310 | # 311 | 312 | include(CMakePackageConfigHelpers) 313 | write_basic_package_version_file( 314 | ${PROJECT_NAME}ConfigVersion.cmake 315 | VERSION 316 | ${PROJECT_VERSION} 317 | COMPATIBILITY 318 | SameMajorVersion 319 | ) 320 | 321 | configure_package_config_file( 322 | ${CMAKE_CURRENT_LIST_DIR}/cmake/${PROJECT_NAME}Config.cmake.in 323 | ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake 324 | INSTALL_DESTINATION 325 | ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} 326 | ) 327 | 328 | install( 329 | FILES 330 | ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake 331 | ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake 332 | DESTINATION 333 | ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} 334 | ) 335 | 336 | # 337 | # Generate export header if specified 338 | # 339 | 340 | if(${PROJECT_NAME}_GENERATE_EXPORT_HEADER) 341 | include(GenerateExportHeader) 342 | generate_export_header(${PROJECT_NAME}) 343 | install( 344 | FILES 345 | ${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWERCASE}_export.h 346 | DESTINATION 347 | include 348 | ) 349 | 350 | message(STATUS "Generated the export header `${PROJECT_NAME_LOWERCASE}_export.h` and installed it.") 351 | endif() 352 | 353 | message(STATUS "Finished building requirements for installing the package.\n") 354 | 355 | # 356 | # Unit testing setup 357 | # 358 | 359 | if(${PROJECT_NAME}_ENABLE_UNIT_TESTING) 360 | enable_testing() 361 | message(STATUS "Build unit tests for the project. Tests should always be found in the test folder\n") 362 | add_subdirectory(test) 363 | endif() 364 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to [INSERT PROJECT NAME] 2 | 3 | The [INSERT PROJECT NAME] team encourages community feedback and contributions. 4 | Thank you for your interest in making [INSERT PROJECT NAME] better! There are several 5 | ways you can get involved. 6 | 7 | If you are looking for a good way to contribute to the project, please: 8 | 9 | * have a look at the [available issue templates](https://github.com/filipdutescu/modern-cpp-template/issues/new/choose) 10 | and checkout the [examples of good first issues](https://github.com/filipdutescu/modern-cpp-template/contribute) 11 | (or [click here](https://github.com/filipdutescu/modern-cpp-template/labels/good%20first%20issue)). 12 | 13 | * look through the [issues that need help](https://github.com/filipdutescu/modern-cpp-template/labels/help%20wanted). 14 | 15 | * take a look at a [Pull Request template](PULL_REQUEST_TEMPLATE.md) to get yourself 16 | started. 17 | 18 | ## Reporting issues and suggesting new features 19 | 20 | If you find that the project is not working properly, please file a report using 21 | the [Bug Report template](https://github.com/filipdutescu/modern-cpp-template/issues/new?assignees=&labels=bug&template=bug_report.md&title=[BUG]). 22 | Should the template provided not suit your needs, feel free to make a 23 | [custom Bug Report](https://github.com/filipdutescu/modern-cpp-template/issues/new/choose), 24 | but please label it accordingly. 25 | 26 | We are happy to hear your ideas for how to further improve [INSERT PROJECT NAME], 27 | ensuring it suits your needs. Check the [Issues](https://github.com/filipdutescu/modern-cpp-template/issues) 28 | and see if others have submitted similar feedback. You can upvote existing feedback 29 | (using the thumbs up reaction/by commenting) or [submit a new suggestion](https://github.com/filipdutescu/modern-cpp-template/labels/feature). 30 | 31 | We always look at upvoted items in [Issues](https://github.com/filipdutescu/modern-cpp-template/issues) 32 | when we decide what to work on next. We read the comments and we look forward to 33 | hearing your input. 34 | 35 | ## Finding issues you can help with 36 | 37 | Looking for something to work on? 38 | Issues marked [`good first issue`](https://github.com/filipdutescu/modern-cpp-template/labels/good%20first%20issue) 39 | are a good place to start. 40 | 41 | You can also check the [`help wanted`](https://github.com/filipdutescu/modern-cpp-template/labels/help%20wanted) 42 | tag to find other issues to help with. If you're interested in working on a fix, 43 | leave a comment to let everyone know and to help avoid duplicated effort from others. 44 | 45 | ## Contributions we accept 46 | 47 | We highly appreciate any contributions that help us improve the end product, with 48 | a high emphasis being put on any bug fixes you can manage to create and direct 49 | improvements which address the top issues reported by Calculator users. Some general 50 | guidelines: 51 | 52 | ### DOs 53 | 54 | * **DO** create one pull request per Issue, and ensure that the Issue is linked 55 | in the pull request. You can follow the [Pull Request Template](PULL_REQUEST_TEMPLATE.md) 56 | for this. 57 | 58 | * **DO** follow our [Coding and Style](#style-guidelines) guidelines, and keep code 59 | changes as small as possible. 60 | 61 | * **DO** include corresponding tests whenever possible. 62 | 63 | * **DO** check for additional occurrences of the same problem in other parts of the 64 | codebase before submitting your PR. 65 | 66 | * **DO** link the issue you are addressing in the pull request. 67 | 68 | * **DO** write a good description for your pull request. More detail is better. 69 | Describe *why* the change is being made and *why* you have chosen a particular solution. 70 | Describe any manual testing you performed to validate your change. 71 | 72 | ### DO NOTs 73 | 74 | * **DO NOT** merge multiple changes into one PR unless they have the same root cause. 75 | * **DO NOT** merge directly into the master branch. 76 | 77 | > Submitting a pull request for an approved Issue is not a guarantee it will be approved. 78 | > The change must meet our high bar for code quality, architecture and performance. 79 | 80 | ## Making changes to the code 81 | 82 | ### Preparing your development environment 83 | 84 | To learn how to build the code and run tests, follow the instructions in the [README](README.md). 85 | 86 | ### Style guidelines 87 | 88 | The code in this project uses several different coding styles, depending on the 89 | age and history of the code. Please attempt to match the style of surrounding 90 | code as much as possible. In new components, prefer the patterns described in the 91 | [C++ core guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines). 92 | 93 | ### Code formatting 94 | 95 | ***Run clang-format*** 96 | 97 | Use the following commands from the project's root directory to run clang-format 98 | (must be installed on the host system). 99 | 100 | **1. Run the CMake target for `clang-format`:** 101 | 102 | ```bash 103 | cmake --build build --target clang-format 104 | ``` 105 | 106 | **2. Using clang-format:** 107 | 108 | ```bash 109 | # !!! clang-format does not run recursively in subdirectories !!! 110 | # for each .cpp file modified 111 | clang-format -i *.cpp 112 | 113 | # for each .h file modified 114 | clang-format -i *.h 115 | 116 | # for each .hpp file modified 117 | clang-format -i *.hpp 118 | ``` 119 | 120 | **3. Using TheLartians' Format.cmake:** 121 | 122 | ```bash 123 | cmake -Htest -Bbuild/test 124 | 125 | # view changes 126 | cmake --build build/test --target format 127 | 128 | # apply changes 129 | cmake --build build/test --target fix-format 130 | ``` 131 | 132 | See [Format.cmake](https://github.com/TheLartians/Format.cmake) for more options. 133 | 134 | ### Testing 135 | 136 | Your change should include tests to verify new functionality wherever possible. 137 | Code should be structured so that it can be unit tested independently of the UI. 138 | Manual test cases should be used where automated testing is not feasible. 139 | 140 | ### Git workflow 141 | 142 | The core principle of the project, when it comes to Git workflows is that the 143 | `master` branch should always be in a healthy state which is ready for release. 144 | Every commit on master should be deployable on push. To ensure this, pull request 145 | **must not** be made directly on master. **Each change** should either be made in 146 | the **development branch** (named a variation of development, i.e. `dev`) or in a 147 | separate branch, named as a short summary of the change. 148 | 149 | If your change is complex, please clean up the branch history before submitting a 150 | pull request. You can use [git rebase](https://git-scm.com/book/en/v2/Git-Branching-Rebasing) 151 | to group your changes into a small number of commits which we can review one at a 152 | time. 153 | 154 | When completing a pull request, we will generally squash your changes into a single 155 | commit. After confirming that the change works as intended, the branch *might* be 156 | deleted, in order to prevent branch polluting. Please let us know if your pull request 157 | needs to be merged as separate commits. 158 | 159 | ### Continuous Integration 160 | 161 | For this project, CI is provided by [GitHub Actions](https://github.com/features/actions), 162 | with workflows found in the [`.github/workflows` folder](.github/workflows). Workflows 163 | are run automatically on every commit made on the master branch, unless told to skip 164 | for that particular commit. 165 | 166 | To skip CI runs on a particular commit, include either `[skip ci]` or `[ci skip]` 167 | in the commit message. 168 | 169 | ```bash 170 | # an example of a commit message that would not trigger CI workflows 171 | git commit -m "my normal commit message [skip ci]" 172 | # or 173 | git commit -m "my normal commit message [ci skip]" 174 | ``` 175 | 176 | ## Review process 177 | 178 | After submitting a pull request, members of the team will review your code. We will 179 | assign the request to an appropriate reviewer (if applicable). Any member of the 180 | community may participate in the review, but at least one member of the project team 181 | will ultimately approve the request. 182 | 183 | Often, multiple iterations or discussions will be needed to responding to feedback 184 | from reviewers. Try looking at [past pull requests](https://github.com/filipdutescu/modern-cpp-template/pulls?q=is%3Apr+is%3Aclosed) 185 | to see what the experience might be like. 186 | 187 | ## Contributor License Agreement 188 | 189 | Before we can review and accept a pull request from you, you'll need to sign a 190 | Contributor License Agreement (CLA). The CLA ensures that the community is free 191 | to use your contributions. Signing the CLA is a manual process, and you need to 192 | do it for each pull request made. This is done by checking the boxes in the 193 | [Pull Request Readiness Checklist of a Pull Request](PULL_REQUEST_TEMPLATE.md#Pull-Request-Readiness-Checklist). 194 | 195 | ### IMPORTANT 196 | 197 | ***Checking the aforementioned boxes means that you agree to provide your change 198 | and/or code FREE TO USE and SUBJECT TO CHANGES for the entire community!*** 199 | 200 | You don't need to sign a CLA until you're ready to create a pull request. When your 201 | pull request is created, it is reviewed by a team member which, if the change is 202 | trivial (i.e. you just fixed a typo) will be labelled as `cla-not-required`. 203 | Otherwise, it's classified as `cla-required`, if not already signed. 204 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | RUN echo "Updating Ubuntu" 4 | RUN apt-get update && apt-get upgrade -y 5 | 6 | RUN echo "Installing dependencies..." 7 | RUN apt install -y \ 8 | ccache \ 9 | clang \ 10 | clang-format \ 11 | clang-tidy \ 12 | cppcheck \ 13 | curl \ 14 | doxygen \ 15 | gcc \ 16 | git \ 17 | graphviz \ 18 | make \ 19 | ninja-build \ 20 | python3 \ 21 | python3-pip \ 22 | tar \ 23 | unzip \ 24 | vim 25 | 26 | RUN echo "Installing dependencies not found in the package repos..." 27 | 28 | RUN apt install -y wget tar build-essential libssl-dev && \ 29 | wget https://github.com/Kitware/CMake/releases/download/v3.15.0/cmake-3.15.0.tar.gz && \ 30 | tar -zxvf cmake-3.15.0.tar.gz && \ 31 | cd cmake-3.15.0 && \ 32 | ./bootstrap && \ 33 | make && \ 34 | make install 35 | 36 | RUN pip3 install conan 37 | 38 | RUN git clone https://github.com/catchorg/Catch2.git && \ 39 | cd Catch2 && \ 40 | cmake -Bbuild -H. -DBUILD_TESTING=OFF && \ 41 | cmake --build build/ --target install 42 | 43 | # Disabled pthread support for GTest due to linking errors 44 | RUN git clone https://github.com/google/googletest.git --branch release-1.10.0 && \ 45 | cd googletest && \ 46 | cmake -Bbuild -Dgtest_disable_pthreads=1 && \ 47 | cmake --build build --config Release && \ 48 | cmake --build build --target install --config Release 49 | 50 | RUN git clone https://github.com/microsoft/vcpkg -b 2020.06 && \ 51 | cd vcpkg && \ 52 | ./bootstrap-vcpkg.sh -disableMetrics -useSystemBinaries 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | 26 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: install coverage test docs help 2 | .DEFAULT_GOAL := help 3 | 4 | define BROWSER_PYSCRIPT 5 | import os, webbrowser, sys 6 | 7 | try: 8 | from urllib import pathname2url 9 | except: 10 | from urllib.request import pathname2url 11 | 12 | webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) 13 | endef 14 | export BROWSER_PYSCRIPT 15 | 16 | define PRINT_HELP_PYSCRIPT 17 | import re, sys 18 | 19 | for line in sys.stdin: 20 | match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line) 21 | if match: 22 | target, help = match.groups() 23 | print("%-20s %s" % (target, help)) 24 | endef 25 | export PRINT_HELP_PYSCRIPT 26 | 27 | BROWSER := python -c "$$BROWSER_PYSCRIPT" 28 | INSTALL_LOCATION := ~/.local 29 | 30 | help: 31 | @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) 32 | 33 | test: ## run tests quickly with ctest 34 | rm -rf build/ 35 | cmake -Bbuild -DCMAKE_INSTALL_PREFIX=$(INSTALL_LOCATION) -Dmodern-cpp-template_ENABLE_UNIT_TESTING=1 -DCMAKE_BUILD_TYPE="Release" 36 | cmake --build build --config Release 37 | cd build/ && ctest -C Release -VV 38 | 39 | coverage: ## check code coverage quickly GCC 40 | rm -rf build/ 41 | cmake -Bbuild -DCMAKE_INSTALL_PREFIX=$(INSTALL_LOCATION) -Dmodern-cpp-template_ENABLE_CODE_COVERAGE=1 42 | cmake --build build --config Release 43 | cd build/ && ctest -C Release -VV 44 | cd .. && (bash -c "find . -type f -name '*.gcno' -exec gcov -pb {} +" || true) 45 | 46 | docs: ## generate Doxygen HTML documentation, including API docs 47 | rm -rf docs/ 48 | rm -rf build/ 49 | cmake -Bbuild -DCMAKE_INSTALL_PREFIX=$(INSTALL_LOCATION) -DProject_ENABLE_DOXYGEN=1 50 | cmake --build build --config Release 51 | cmake --build build --target doxygen-docs 52 | $(BROWSER) docs/html/index.html 53 | 54 | install: ## install the package to the `INSTALL_LOCATION` 55 | rm -rf build/ 56 | cmake -Bbuild -DCMAKE_INSTALL_PREFIX=$(INSTALL_LOCATION) 57 | cmake --build build --config Release 58 | cmake --build build --target install --config Release 59 | 60 | format: ## format the project sources 61 | rm -rf build/ 62 | cmake -Bbuild -DCMAKE_INSTALL_PREFIX=$(INSTALL_LOCATION) 63 | cmake --build build --target clang-format 64 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **IMPORTANT: Please do not create a Pull Request without creating an issue first.** 2 | 3 | *Any change needs to be discussed before proceeding. Failure to do so may result 4 | in the rejection of the pull request.* 5 | 6 | Please provide enough information so that others can review your pull request. You 7 | can skip this if you're fixing a typo or adding an app to the Showcase. 8 | 9 | Explain the **details** for making this change. What existing problem does the pull 10 | request solve? 11 | 12 | Ex: 13 | 14 | 1. If you "Added a/changed the function to do X", explain why: 15 | 16 | * it is necessary to have a way to do X. 17 | * if there already exists a way, why is your implementation better 18 | 19 | 2. If you "Fixed bug/error in X", explain: 20 | 21 | * what was the bug/error (if you already made an issue, please link to it here) 22 | * how does your implementation fix the issue 23 | 24 | ### Code style and formatting 25 | 26 | Check the [Contributors Style Guidelines section](CONTRIBUTING.md#Style-guidelines) 27 | for how to write your code and the [Contributors Code Formatting section](CONTRIBUTING.md#Code-formatting) 28 | for how to format your code. 29 | 30 | #### Closing Issues 31 | 32 | Put `closes #XXXX` in your comment to auto-close the issue that your PR fixes 33 | (if such). 34 | 35 | --- 36 | 37 | Fixes #XXXX 38 | 39 | ## Proposed changes 40 | 41 | * 42 | * 43 | * 44 | 45 | ## Motivation behind changes 46 | 47 | ### Test plan 48 | 49 | Demonstrate the code is solid. Example: The exact commands you ran and their output, 50 | screenshots / videos if the pull request changes UI. 51 | 52 | *Make sure tests pass on all of the [relevant CI workflows](https://github.com/filipdutescu/modern-cpp-template/actions).* 53 | 54 | ### Pull Request Readiness Checklist 55 | 56 | See details at [CONTRIBUTING.md](https://github.com/filipdutescu/modern-cpp-template/blob/master/CONTRIBUTING.md). 57 | 58 | * [ ] I agree to contribute to the project under [INSERT PROJECT NAME] (Unlicense) 59 | [License](LICENSE). 60 | 61 | * [ ] To the best of my knowledge, the proposed patch is not based on a code under 62 | GPL or other license that is incompatible with [INSERT PROJECT NAME] 63 | 64 | * [ ] The PR is proposed to proper branch 65 | 66 | * [ ] There is reference to original bug report and related work 67 | 68 | * [ ] There is accuracy test, performance test and test data in the repository, 69 | if applicable 70 | 71 | * [ ] The feature is well documented and sample code can be built with the project 72 | CMake 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Actions Status](https://github.com/filipdutescu/modern-cpp-template/workflows/MacOS/badge.svg)](https://github.com/filipdutescu/modern-cpp-template/actions) 2 | [![Actions Status](https://github.com/filipdutescu/modern-cpp-template/workflows/Windows/badge.svg)](https://github.com/filipdutescu/modern-cpp-template/actions) 3 | [![Actions Status](https://github.com/filipdutescu/modern-cpp-template/workflows/Ubuntu/badge.svg)](https://github.com/filipdutescu/modern-cpp-template/actions) 4 | [![codecov](https://codecov.io/gh/filipdutescu/modern-cpp-template/branch/master/graph/badge.svg)](https://codecov.io/gh/filipdutescu/modern-cpp-template) 5 | [![GitHub release (latest by date)](https://img.shields.io/github/v/release/filipdutescu/modern-cpp-template)](https://github.com/filipdutescu/modern-cpp-template/releases) 6 | 7 | # Modern C++ Template 8 | 9 | A quick C++ template for modern CMake projects, aimed to be an easy to use 10 | starting point. 11 | 12 | This is my personal take on such a type of template, thus I might not use the 13 | best practices or you might disagree with how I do things. Any and all feedback 14 | is greatly appreciated! 15 | 16 | ## Features 17 | 18 | * Modern **CMake** configuration and project, which, to the best of my 19 | knowledge, uses the best practices, 20 | 21 | * An example of a **Clang-Format** config, inspired from the base *Google* model, 22 | with minor tweaks. This is aimed only as a starting point, as coding style 23 | is a subjective matter, everyone is free to either delete it (for the *LLVM* 24 | default) or supply their own alternative, 25 | 26 | * **Static analyzers** integration, with *Clang-Tidy* and *Cppcheck*, the former 27 | being the default option, 28 | 29 | * **Doxygen** support, through the `ENABLE_DOXYGEN` option, which you can enable 30 | if you wish to use it, 31 | 32 | * **Unit testing** support, through *GoogleTest* (with an option to enable 33 | *GoogleMock*) or *Catch2*, 34 | 35 | * **Code coverage**, enabled by using the `ENABLE_CODE_COVERAGE` option, through 36 | *Codecov* CI integration, 37 | 38 | * **Package manager support**, with *Conan* and *Vcpkg*, through their respective 39 | options 40 | 41 | * **CI workflows for Windows, Linux and MacOS** using *GitHub Actions*, making 42 | use of the caching features, to ensure minimum run time, 43 | 44 | * **.md templates** for: *README*, *Contributing Guideliness*, 45 | *Issues* and *Pull Requests*, 46 | 47 | * **Permissive license** to allow you to integrate it as easily as possible. The 48 | template is licensed under the [Unlicense](https://unlicense.org/), 49 | 50 | * Options to build as a header-only library or executable, not just a static or 51 | shared library. 52 | 53 | * **Ccache** integration, for speeding up rebuild times 54 | 55 | ## Getting Started 56 | 57 | These instructions will get you a copy of the project up and running on your local 58 | machine for development and testing purposes. 59 | 60 | ### Prerequisites 61 | 62 | This project is meant to be only a template, thus versions of the software used 63 | can be change to better suit the needs of the developer(s). If you wish to use the 64 | template *as-is*, meaning using the versions recommended here, then you will need: 65 | 66 | * **CMake v3.15+** - found at [https://cmake.org/](https://cmake.org/) 67 | 68 | * **C++ Compiler** - needs to support at least the **C++17** standard, i.e. *MSVC*, 69 | *GCC*, *Clang* 70 | 71 | > ***Note:*** *You also need to be able to provide ***CMake*** a supported 72 | [generator](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html).* 73 | 74 | ### Installing 75 | 76 | It is fairly easy to install the project, all you need to do is clone if from 77 | [GitHub](https://github.com/filipdutescu/modern-cpp-template) or 78 | [generate a new repository from it](https://github.com/filipdutescu/modern-cpp-template/generate) 79 | (also on **GitHub**). 80 | 81 | If you wish to clone the repository, rather than generate from it, you simply need 82 | to run: 83 | 84 | ```bash 85 | git clone https://github.com/filipdutescu/modern-cpp-template/ 86 | ``` 87 | 88 | After finishing getting a copy of the project, with any of the methods above, create 89 | a new folder in the `include/` folder, with the name of your project. Edit 90 | `cmake/SourcesAndHeaders.cmake` to add your files. 91 | 92 | You will also need to rename the `cmake/ProjectConfig.cmake.in` file to start with 93 | the ***exact name of your project***. Such as `cmake/MyNewProjectConfig.cmake.in`. 94 | You should also make the same changes in the GitHub workflows provided, notably 95 | [`.github/workflows/ubuntu.yml`](.github/workflows/ubuntu.yml), in which you should 96 | replace the CMake option `-DProject_ENABLE_CODE_COVERAGE=1` to 97 | `-DMyNewProject_ENABLE_CODE_COVERAGE=1`. 98 | 99 | Finally, change `"Project"` from `CMakeLists.txt`, from 100 | 101 | ```cmake 102 | project( 103 | "Project" 104 | VERSION 0.1.0 105 | LANGUAGES CXX 106 | ) 107 | ``` 108 | 109 | to the ***exact name of your project***, i.e. using the previous name it will become: 110 | 111 | ```cmake 112 | project( 113 | MyNewProject 114 | VERSION 0.1.0 115 | LANGUAGES CXX 116 | ) 117 | ``` 118 | 119 | To install an already built project, you need to run the `install` target with CMake. 120 | For example: 121 | 122 | ```bash 123 | cmake --build build --target install --config Release 124 | 125 | # a more general syntax for that command is: 126 | cmake --build --target install --config 127 | ``` 128 | 129 | ## Building the project 130 | 131 | To build the project, all you need to do, ***after correctly 132 | [installing the project](README.md#Installing)***, is run a similar **CMake** routine 133 | to the the one below: 134 | 135 | ```bash 136 | mkdir build/ && cd build/ 137 | cmake .. -DCMAKE_INSTALL_PREFIX=/absolute/path/to/custom/install/directory 138 | cmake --build . --target install 139 | ``` 140 | 141 | > ***Note:*** *The custom ``CMAKE_INSTALL_PREFIX`` can be omitted if you wish to 142 | install in [the default install location](https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html).* 143 | 144 | More options that you can set for the project can be found in the 145 | [`cmake/StandardSettings.cmake` file](cmake/StandardSettings.cmake). For certain 146 | options additional configuration may be needed in their respective `*.cmake` files 147 | (i.e. Conan needs the `CONAN_REQUIRES` and might need the `CONAN_OPTIONS` to be setup 148 | for it work correctly; the two are set in the [`cmake/Conan.cmake` file](cmake/Conan.cmake)). 149 | 150 | ## Generating the documentation 151 | 152 | In order to generate documentation for the project, you need to configure the build 153 | to use Doxygen. This is easily done, by modifying the workflow shown above as follows: 154 | 155 | ```bash 156 | mkdir build/ && cd build/ 157 | cmake .. -D_ENABLE_DOXYGEN=1 -DCMAKE_INSTALL_PREFIX=/absolute/path/to/custom/install/directory 158 | cmake --build . --target doxygen-docs 159 | ``` 160 | 161 | > ***Note:*** *This will generate a `docs/` directory in the **project's root directory**.* 162 | 163 | ## Running the tests 164 | 165 | By default, the template uses [Google Test](https://github.com/google/googletest/) 166 | for unit testing. Unit testing can be disabled in the options, by setting the 167 | `ENABLE_UNIT_TESTING` (from 168 | [cmake/StandardSettings.cmake](cmake/StandardSettings.cmake)) to be false. To run 169 | the tests, simply use CTest, from the build directory, passing the desire 170 | configuration for which to run tests for. An example of this procedure is: 171 | 172 | ```bash 173 | cd build # if not in the build directory already 174 | ctest -C Release # or `ctest -C Debug` or any other configuration you wish to test 175 | 176 | # you can also run tests with the `-VV` flag for a more verbose output (i.e. 177 | #GoogleTest output as well) 178 | ``` 179 | 180 | ### End to end tests 181 | 182 | If applicable, should be presented here. 183 | 184 | ### Coding style tests 185 | 186 | If applicable, should be presented here. 187 | 188 | ## Contributing 189 | 190 | Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our how you can 191 | become a contributor and the process for submitting pull requests to us. 192 | 193 | ## Versioning 194 | 195 | This project makes use of [SemVer](http://semver.org/) for versioning. A list of 196 | existing versions can be found in the 197 | [project's releases](https://github.com/filipdutescu/modern-cpp-template/releases). 198 | 199 | ## Authors 200 | 201 | * **Filip-Ioan Dutescu** - [@filipdutescu](https://github.com/filipdutescu) 202 | 203 | ## License 204 | 205 | This project is licensed under the [Unlicense](https://unlicense.org/) - see the 206 | [LICENSE](LICENSE) file for details 207 | -------------------------------------------------------------------------------- /cmake/CompilerWarnings.cmake: -------------------------------------------------------------------------------- 1 | # from here: 2 | # 3 | # https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Avai 4 | # lable.md 5 | # Courtesy of Jason Turner 6 | 7 | function(set_project_warnings project_name) 8 | set(MSVC_WARNINGS 9 | /W4 # Baseline reasonable warnings 10 | /w14242 # 'identifier': conversion from 'type1' to 'type1', possible loss 11 | # of data 12 | /w14254 # 'operator': conversion from 'type1:field_bits' to 13 | # 'type2:field_bits', possible loss of data 14 | /w14263 # 'function': member function does not override any base class 15 | # virtual member function 16 | /w14265 # 'classname': class has virtual functions, but destructor is not 17 | # virtual instances of this class may not be destructed correctly 18 | /w14287 # 'operator': unsigned/negative constant mismatch 19 | /we4289 # nonstandard extension used: 'variable': loop control variable 20 | # declared in the for-loop is used outside the for-loop scope 21 | /w14296 # 'operator': expression is always 'boolean_value' 22 | /w14311 # 'variable': pointer truncation from 'type1' to 'type2' 23 | /w14545 # expression before comma evaluates to a function which is missing 24 | # an argument list 25 | /w14546 # function call before comma missing argument list 26 | /w14547 # 'operator': operator before comma has no effect; expected 27 | # operator with side-effect 28 | /w14549 # 'operator': operator before comma has no effect; did you intend 29 | # 'operator'? 30 | /w14555 # expression has no effect; expected expression with side- effect 31 | /w14619 # pragma warning: there is no warning number 'number' 32 | /w14640 # Enable warning on thread un-safe static member initialization 33 | /w14826 # Conversion from 'type1' to 'type_2' is sign-extended. This may 34 | # cause unexpected runtime behavior. 35 | /w14905 # wide string literal cast to 'LPSTR' 36 | /w14906 # string literal cast to 'LPWSTR' 37 | /w14928 # illegal copy-initialization; more than one user-defined 38 | # conversion has been implicitly applied 39 | /permissive- # standards conformance mode for MSVC compiler. 40 | ) 41 | 42 | set(CLANG_WARNINGS 43 | -Wall 44 | -Wextra # reasonable and standard 45 | -Wshadow # warn the user if a variable declaration shadows one from a 46 | # parent context 47 | -Wnon-virtual-dtor # warn the user if a class with virtual functions has a 48 | # non-virtual destructor. This helps catch hard to 49 | # track down memory errors 50 | -Wold-style-cast # warn for c-style casts 51 | -Wcast-align # warn for potential performance problem casts 52 | -Wunused # warn on anything being unused 53 | -Woverloaded-virtual # warn if you overload (not override) a virtual 54 | # function 55 | -Wpedantic # warn if non-standard C++ is used 56 | -Wconversion # warn on type conversions that may lose data 57 | -Wsign-conversion # warn on sign conversions 58 | -Wnull-dereference # warn if a null dereference is detected 59 | -Wdouble-promotion # warn if float is implicit promoted to double 60 | -Wformat=2 # warn on security issues around functions that format output 61 | # (ie printf) 62 | ) 63 | 64 | if (${PROJECT_NAME}_WARNINGS_AS_ERRORS) 65 | set(CLANG_WARNINGS ${CLANG_WARNINGS} -Werror) 66 | set(MSVC_WARNINGS ${MSVC_WARNINGS} /WX) 67 | endif() 68 | 69 | set(GCC_WARNINGS 70 | ${CLANG_WARNINGS} 71 | -Wmisleading-indentation # warn if indentation implies blocks where blocks 72 | # do not exist 73 | -Wduplicated-cond # warn if if / else chain has duplicated conditions 74 | -Wduplicated-branches # warn if if / else branches have duplicated code 75 | -Wlogical-op # warn about logical operations being used where bitwise were 76 | # probably wanted 77 | -Wuseless-cast # warn if you perform a cast to the same type 78 | ) 79 | 80 | if(MSVC) 81 | set(PROJECT_WARNINGS ${MSVC_WARNINGS}) 82 | elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") 83 | set(PROJECT_WARNINGS ${CLANG_WARNINGS}) 84 | elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 85 | set(PROJECT_WARNINGS ${GCC_WARNINGS}) 86 | else() 87 | message(AUTHOR_WARNING "No compiler warnings set for '${CMAKE_CXX_COMPILER_ID}' compiler.") 88 | endif() 89 | 90 | if(${PROJECT_NAME}_BUILD_HEADERS_ONLY) 91 | target_compile_options(${project_name} INTERFACE ${PROJECT_WARNINGS}) 92 | else() 93 | target_compile_options(${project_name} PUBLIC ${PROJECT_WARNINGS}) 94 | endif() 95 | 96 | if(NOT TARGET ${project_name}) 97 | message(AUTHOR_WARNING "${project_name} is not a target, thus no compiler warning were added.") 98 | endif() 99 | endfunction() 100 | -------------------------------------------------------------------------------- /cmake/Conan.cmake: -------------------------------------------------------------------------------- 1 | if(${PROJECT_NAME}_ENABLE_CONAN) 2 | # 3 | # Setup Conan requires and options here: 4 | # 5 | 6 | set(${PROJECT_NAME}_CONAN_REQUIRES "") 7 | set(${PROJECT_NAME}_CONAN_OPTIONS "") 8 | 9 | # 10 | # If `conan.cmake` (from https://github.com/conan-io/cmake-conan) does not exist, download it. 11 | # 12 | if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake") 13 | message( 14 | STATUS 15 | "Downloading conan.cmake from https://github.com/conan-io/cmake-conan..." 16 | ) 17 | file( 18 | DOWNLOAD "https://github.com/conan-io/cmake-conan/raw/v0.15/conan.cmake" 19 | "${CMAKE_BINARY_DIR}/conan.cmake" 20 | ) 21 | message(STATUS "Cmake-Conan downloaded succesfully.") 22 | endif() 23 | 24 | include(${CMAKE_BINARY_DIR}/conan.cmake) 25 | 26 | conan_add_remote( 27 | NAME bincrafters 28 | URL 29 | https://api.bintray.com/conan/bincrafters/public-conan 30 | ) 31 | 32 | conan_cmake_run( 33 | REQUIRES 34 | ${${PROJECT_NAME}_CONAN_REQUIRES} 35 | OPTIONS 36 | ${${PROJECT_NAME}_CONAN_OPTIONS} 37 | BASIC_SETUP 38 | CMAKE_TARGETS # Individual targets to link to 39 | BUILD 40 | missing 41 | ) 42 | 43 | conan_basic_setup() 44 | 45 | verbose_message("Conan is setup and all requires have been installed.") 46 | endif() 47 | -------------------------------------------------------------------------------- /cmake/Doxygen.cmake: -------------------------------------------------------------------------------- 1 | if(${PROJECT_NAME}_ENABLE_DOXYGEN) 2 | set(DOXYGEN_CALLER_GRAPH YES) 3 | set(DOXYGEN_CALL_GRAPH YES) 4 | set(DOXYGEN_EXTRACT_ALL YES) 5 | set(DOXYGEN_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/docs) 6 | 7 | find_package(Doxygen REQUIRED dot) 8 | doxygen_add_docs(doxygen-docs ${PROJECT_SOURCE_DIR}) 9 | 10 | verbose_message("Doxygen has been setup and documentation is now available.") 11 | endif() 12 | -------------------------------------------------------------------------------- /cmake/ProjectConfig.cmake.in: -------------------------------------------------------------------------------- 1 | set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@) 2 | 3 | @PACKAGE_INIT@ 4 | 5 | set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@") 6 | 7 | include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") 8 | 9 | check_required_components(@PROJECT_NAME@) 10 | -------------------------------------------------------------------------------- /cmake/SourcesAndHeaders.cmake: -------------------------------------------------------------------------------- 1 | set(sources 2 | src/tmp.cpp 3 | ) 4 | 5 | set(exe_sources 6 | src/main.cpp 7 | ${sources} 8 | ) 9 | 10 | set(headers 11 | include/project/tmp.hpp 12 | ) 13 | 14 | set(test_sources 15 | src/tmp_test.cpp 16 | ) 17 | -------------------------------------------------------------------------------- /cmake/StandardSettings.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Project settings 3 | # 4 | 5 | option(${PROJECT_NAME}_BUILD_EXECUTABLE "Build the project as an executable, rather than a library." OFF) 6 | option(${PROJECT_NAME}_BUILD_HEADERS_ONLY "Build the project as a header-only library." OFF) 7 | option(${PROJECT_NAME}_USE_ALT_NAMES "Use alternative names for the project, such as naming the include directory all lowercase." ON) 8 | 9 | # 10 | # Compiler options 11 | # 12 | 13 | option(${PROJECT_NAME}_WARNINGS_AS_ERRORS "Treat compiler warnings as errors." OFF) 14 | 15 | # 16 | # Package managers 17 | # 18 | # Currently supporting: Conan, Vcpkg. 19 | 20 | option(${PROJECT_NAME}_ENABLE_CONAN "Enable the Conan package manager for this project." OFF) 21 | option(${PROJECT_NAME}_ENABLE_VCPKG "Enable the Vcpkg package manager for this project." OFF) 22 | 23 | # 24 | # Unit testing 25 | # 26 | # Currently supporting: GoogleTest, Catch2. 27 | 28 | option(${PROJECT_NAME}_ENABLE_UNIT_TESTING "Enable unit tests for the projects (from the `test` subfolder)." ON) 29 | 30 | option(${PROJECT_NAME}_USE_GTEST "Use the GoogleTest project for creating unit tests." ON) 31 | option(${PROJECT_NAME}_USE_GOOGLE_MOCK "Use the GoogleMock project for extending the unit tests." OFF) 32 | 33 | option(${PROJECT_NAME}_USE_CATCH2 "Use the Catch2 project for creating unit tests." OFF) 34 | 35 | # 36 | # Static analyzers 37 | # 38 | # Currently supporting: Clang-Tidy, Cppcheck. 39 | 40 | option(${PROJECT_NAME}_ENABLE_CLANG_TIDY "Enable static analysis with Clang-Tidy." OFF) 41 | option(${PROJECT_NAME}_ENABLE_CPPCHECK "Enable static analysis with Cppcheck." OFF) 42 | 43 | # 44 | # Code coverage 45 | # 46 | 47 | option(${PROJECT_NAME}_ENABLE_CODE_COVERAGE "Enable code coverage through GCC." OFF) 48 | 49 | # 50 | # Doxygen 51 | # 52 | 53 | option(${PROJECT_NAME}_ENABLE_DOXYGEN "Enable Doxygen documentation builds of source." OFF) 54 | 55 | # 56 | # Miscelanious options 57 | # 58 | 59 | # Generate compile_commands.json for clang based tools 60 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 61 | 62 | option(${PROJECT_NAME}_VERBOSE_OUTPUT "Enable verbose output, allowing for a better understanding of each step taken." ON) 63 | option(${PROJECT_NAME}_GENERATE_EXPORT_HEADER "Create a `project_export.h` file containing all exported symbols." OFF) 64 | 65 | # Export all symbols when building a shared library 66 | if(BUILD_SHARED_LIBS) 67 | set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS OFF) 68 | set(CMAKE_CXX_VISIBILITY_PRESET hidden) 69 | set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) 70 | endif() 71 | 72 | option(${PROJECT_NAME}_ENABLE_LTO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)." OFF) 73 | if(${PROJECT_NAME}_ENABLE_LTO) 74 | include(CheckIPOSupported) 75 | check_ipo_supported(RESULT result OUTPUT output) 76 | if(result) 77 | set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) 78 | else() 79 | message(SEND_ERROR "IPO is not supported: ${output}.") 80 | endif() 81 | endif() 82 | 83 | 84 | option(${PROJECT_NAME}_ENABLE_CCACHE "Enable the usage of Ccache, in order to speed up rebuild times." ON) 85 | find_program(CCACHE_FOUND ccache) 86 | if(CCACHE_FOUND) 87 | set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) 88 | set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) 89 | endif() 90 | 91 | option(${PROJECT_NAME}_ENABLE_ASAN "Enable Address Sanitize to detect memory error." OFF) 92 | if(${PROJECT_NAME}_ENABLE_ASAN) 93 | add_compile_options(-fsanitize=address) 94 | add_link_options(-fsanitize=address) 95 | endif() 96 | -------------------------------------------------------------------------------- /cmake/StaticAnalyzers.cmake: -------------------------------------------------------------------------------- 1 | if(${PROJECT_NAME}_ENABLE_CLANG_TIDY) 2 | find_program(CLANGTIDY clang-tidy) 3 | if(CLANGTIDY) 4 | set(CMAKE_CXX_CLANG_TIDY ${CLANGTIDY} -extra-arg=-Wno-unknown-warning-option) 5 | message("Clang-Tidy finished setting up.") 6 | else() 7 | message(SEND_ERROR "Clang-Tidy requested but executable not found.") 8 | endif() 9 | endif() 10 | 11 | if(${PROJECT_NAME}_ENABLE_CPPCHECK) 12 | find_program(CPPCHECK cppcheck) 13 | if(CPPCHECK) 14 | set(CMAKE_CXX_CPPCHECK ${CPPCHECK} --suppress=missingInclude --enable=all 15 | --inline-suppr --inconclusive -i ${CMAKE_SOURCE_DIR}/imgui/lib) 16 | message("Cppcheck finished setting up.") 17 | else() 18 | message(SEND_ERROR "Cppcheck requested but executable not found.") 19 | endif() 20 | endif() 21 | -------------------------------------------------------------------------------- /cmake/Utils.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Print a message only if the `VERBOSE_OUTPUT` option is on 3 | # 4 | 5 | function(verbose_message content) 6 | if(${PROJECT_NAME}_VERBOSE_OUTPUT) 7 | message(STATUS ${content}) 8 | endif() 9 | endfunction() 10 | 11 | # 12 | # Add a target for formating the project using `clang-format` (i.e: cmake --build build --target clang-format) 13 | # 14 | 15 | function(add_clang_format_target) 16 | if(NOT ${PROJECT_NAME}_CLANG_FORMAT_BINARY) 17 | find_program(${PROJECT_NAME}_CLANG_FORMAT_BINARY clang-format) 18 | endif() 19 | 20 | if(${PROJECT_NAME}_CLANG_FORMAT_BINARY) 21 | if(${PROJECT_NAME}_BUILD_EXECUTABLE) 22 | add_custom_target(clang-format 23 | COMMAND ${${PROJECT_NAME}_CLANG_FORMAT_BINARY} 24 | -i ${exe_sources} ${headers} 25 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) 26 | elseif(${PROJECT_NAME}_BUILD_HEADERS_ONLY) 27 | add_custom_target(clang-format 28 | COMMAND ${${PROJECT_NAME}_CLANG_FORMAT_BINARY} 29 | -i ${headers} 30 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) 31 | else() 32 | add_custom_target(clang-format 33 | COMMAND ${${PROJECT_NAME}_CLANG_FORMAT_BINARY} 34 | -i ${sources} ${headers} 35 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) 36 | endif() 37 | 38 | message(STATUS "Format the project using the `clang-format` target (i.e: cmake --build build --target clang-format).\n") 39 | endif() 40 | endfunction() 41 | -------------------------------------------------------------------------------- /cmake/Vcpkg.cmake: -------------------------------------------------------------------------------- 1 | if(${PROJECT_NAME}_ENABLE_VCPKG) 2 | # 3 | # If `vcpkg.cmake` (from https://github.com/microsoft/vcpkg) does not exist, download it. 4 | # 5 | if(NOT EXISTS "${CMAKE_BINARY_DIR}/vcpkg.cmake") 6 | message( 7 | STATUS 8 | "Downloading `vcpkg.cmake` from https://github.com/microsoft/vcpkg..." 9 | ) 10 | file(DOWNLOAD "https://github.com/microsoft/vcpkg/raw/master/scripts/buildsystems/vcpkg.cmake" 11 | "${CMAKE_BINARY_DIR}/vcpkg.cmake" 12 | ) 13 | message(STATUS "Vcpkg config downloaded succesfully.") 14 | endif() 15 | 16 | if(${PROJECT_NAME}_VERBOSE_OUTPUT) 17 | set(VCPKG_VERBOSE ON) 18 | endif() 19 | set(CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" "${CMAKE_BINARY_DIR}/vcpkg.cmake") 20 | endif() 21 | -------------------------------------------------------------------------------- /cmake/version.hpp.in: -------------------------------------------------------------------------------- 1 | #ifndef @PROJECT_NAME_UPPERCASE@_VERSION_H_ 2 | #define @PROJECT_NAME_UPPERCASE@_VERSION_H_ 3 | 4 | #define @PROJECT_NAME_UPPERCASE@_VERSION "@PROJECT_VERSION@" 5 | 6 | #define @PROJECT_NAME_UPPERCASE@_MAJOR_VERSION @PROJECT_VERSION_MAJOR@ 7 | #define @PROJECT_NAME_UPPERCASE@_MINOR_VERSION @PROJECT_VERSION_MINOR@ 8 | #define @PROJECT_NAME_UPPERCASE@_PATCH_VERSION @PROJECT_VERSION_PATCH@ 9 | 10 | #endif // @PROJECT_NAME_UPPERCASE@_VERSION_H_ 11 | 12 | -------------------------------------------------------------------------------- /codecov.yaml: -------------------------------------------------------------------------------- 1 | ignore: 2 | - "test" 3 | 4 | comment: 5 | require_changes: true 6 | -------------------------------------------------------------------------------- /include/project/tmp.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TMP_TMP_H_ 2 | #define TMP_TMP_H_ 3 | 4 | namespace tmp 5 | { 6 | int add(int, int); 7 | } 8 | 9 | #endif // TMP_TMP_H_ 10 | -------------------------------------------------------------------------------- /src/tmp.cpp: -------------------------------------------------------------------------------- 1 | #include "project/tmp.hpp" 2 | 3 | int tmp::add(int a, int b) { return a + b; } 4 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | 3 | # 4 | # Project details 5 | # 6 | 7 | project( 8 | ${CMAKE_PROJECT_NAME}Tests 9 | LANGUAGES CXX 10 | ) 11 | 12 | verbose_message("Adding tests under ${CMAKE_PROJECT_NAME}Tests...") 13 | 14 | foreach(file ${test_sources}) 15 | string(REGEX REPLACE "(.*/)([a-zA-Z0-9_ ]+)(\.cpp)" "\\2" test_name ${file}) 16 | add_executable(${test_name}_Tests ${file}) 17 | 18 | # 19 | # Set the compiler standard 20 | # 21 | 22 | target_compile_features(${test_name}_Tests PUBLIC cxx_std_17) 23 | 24 | # 25 | # Setup code coverage if enabled 26 | # 27 | 28 | if (${CMAKE_PROJECT_NAME}_ENABLE_CODE_COVERAGE) 29 | target_compile_options(${CMAKE_PROJECT_NAME} PUBLIC -O0 -g -fprofile-arcs -ftest-coverage) 30 | target_link_options(${CMAKE_PROJECT_NAME} PUBLIC -fprofile-arcs -ftest-coverage) 31 | verbose_message("Code coverage is enabled and provided with GCC.") 32 | endif() 33 | 34 | # 35 | # Load the desired unit testing framework 36 | # 37 | # Currently supported: GoogleTest (and GoogleMock), Catch2. 38 | 39 | if(${CMAKE_PROJECT_NAME}_BUILD_EXECUTABLE) 40 | set(${CMAKE_PROJECT_NAME}_TEST_LIB ${CMAKE_PROJECT_NAME}_LIB) 41 | else() 42 | set(${CMAKE_PROJECT_NAME}_TEST_LIB ${CMAKE_PROJECT_NAME}) 43 | endif() 44 | 45 | if(${CMAKE_PROJECT_NAME}_USE_GTEST) 46 | find_package(GTest REQUIRED) 47 | 48 | if(${CMAKE_PROJECT_NAME}_USE_GOOGLE_MOCK) 49 | set(GOOGLE_MOCK_LIBRARIES GTest::gmock GTest::gmock_main) 50 | endif() 51 | 52 | target_link_libraries( 53 | ${test_name}_Tests 54 | PUBLIC 55 | GTest::GTest 56 | GTest::Main 57 | ${GOOGLE_MOCK_LIBRARIES} 58 | ${${CMAKE_PROJECT_NAME}_TEST_LIB} 59 | ) 60 | elseif(${CMAKE_PROJECT_NAME}_USE_CATCH2) 61 | find_package(Catch2 REQUIRED) 62 | target_link_libraries( 63 | ${test_name}_Tests 64 | PUBLIC 65 | Catch2::Catch2 66 | ${${CMAKE_PROJECT_NAME}_TEST_LIB} 67 | ) 68 | else() 69 | message(FATAL_ERROR "Unknown testing library. Please setup your desired unit testing library by using `target_link_libraries`.") 70 | endif() 71 | 72 | # 73 | # Add the unit tests 74 | # 75 | 76 | add_test( 77 | NAME 78 | ${test_name} 79 | COMMAND 80 | ${test_name}_Tests 81 | ) 82 | endforeach() 83 | 84 | verbose_message("Finished adding unit tests for ${CMAKE_PROJECT_NAME}.") 85 | -------------------------------------------------------------------------------- /test/src/tmp_test.cpp: -------------------------------------------------------------------------------- 1 | #include "project/tmp.hpp" 2 | 3 | #include 4 | 5 | TEST(TmpAddTest, CheckValues) 6 | { 7 | ASSERT_EQ(tmp::add(1, 2), 3); 8 | EXPECT_TRUE(true); 9 | } 10 | 11 | int main(int argc, char **argv) 12 | { 13 | ::testing::InitGoogleTest(&argc, argv); 14 | return RUN_ALL_TESTS(); 15 | } 16 | --------------------------------------------------------------------------------