{"id":13755278,"url":"https://github.com/ainfosec/ci_helloworld","last_synced_at":"2025-04-06T10:14:12.583Z","repository":{"id":90836660,"uuid":"93552771","full_name":"ainfosec/ci_helloworld","owner":"ainfosec","description":"A simple example of how to setup a complete CI environment for C and C++","archived":false,"fork":false,"pushed_at":"2020-10-01T11:12:54.000Z","size":57,"stargazers_count":393,"open_issues_count":5,"forks_count":76,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-03-30T09:07:17.010Z","etag":null,"topics":["appveyor","astyle","c","c-plus-plus","clang","clang-tidy","codecov","coveralls","coverity-scan","doxygen","gcc","google-sanitizer","travis-ci","valgrind","visual-studio","xcode"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ainfosec.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-06-06T18:52:39.000Z","updated_at":"2025-03-08T11:35:30.000Z","dependencies_parsed_at":null,"dependency_job_id":"077d005f-1ef8-4225-b33c-4b98213ed0fe","html_url":"https://github.com/ainfosec/ci_helloworld","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ainfosec%2Fci_helloworld","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ainfosec%2Fci_helloworld/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ainfosec%2Fci_helloworld/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ainfosec%2Fci_helloworld/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ainfosec","download_url":"https://codeload.github.com/ainfosec/ci_helloworld/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247464225,"owners_count":20942970,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["appveyor","astyle","c","c-plus-plus","clang","clang-tidy","codecov","coveralls","coverity-scan","doxygen","gcc","google-sanitizer","travis-ci","valgrind","visual-studio","xcode"],"created_at":"2024-08-03T10:00:50.771Z","updated_at":"2025-04-06T10:14:12.554Z","avatar_url":"https://github.com/ainfosec.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"[![GitHub version](https://badge.fury.io/gh/ainfosec%2Fci_helloworld.svg)](https://badge.fury.io/gh/ainfosec%2Fci_helloworld)\n[![Build Status](https://travis-ci.org/ainfosec/ci_helloworld.svg?branch=master)](https://travis-ci.org/ainfosec/ci_helloworld)\n[![Build status](https://ci.appveyor.com/api/projects/status/b8ceqhe5n1884ek5/branch/master?svg=true)](https://ci.appveyor.com/project/rianquinn/ci-helloworld/branch/master)\n[![codecov](https://codecov.io/gh/ainfosec/ci_helloworld/branch/master/graph/badge.svg)](https://codecov.io/gh/ainfosec/ci_helloworld)\n[![Coverage Status](https://coveralls.io/repos/github/ainfosec/ci_helloworld/badge.svg?branch=master)](https://coveralls.io/github/ainfosec/ci_helloworld?branch=master)\n\u003ca href=\"https://scan.coverity.com/projects/ainfosec-ci_helloworld\"\u003e\n  \u003cimg alt=\"Coverity Scan Build Status\"\n       src=\"https://img.shields.io/coverity/scan/12883.svg\"/\u003e\n\u003c/a\u003e\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/8e0fdf1c93ab47f1ab3bbe5777f747ba)](https://www.codacy.com/app/rianquinn/ci_helloworld?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=ainfosec/ci_helloworld\u0026amp;utm_campaign=Badge_Grade)\n[![Join the chat at https://gitter.im/ci_helloworld/Lobby](https://badges.gitter.im/ci_helloworld/Lobby.svg)](https://gitter.im/ci_helloworld/Lobby?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\n## Description\n\nThis repo provides a simple example for how to setup various CI services as\nwell as integrating analysis tools into these services. These tools should be\nused as part of a comprehensive Software Development Process (SDP) and can also\nbe used as a starting template for any C or C++ application. The following CI\ntools are used, providing testing support for Windows, Cygwin, Linux and macOS\n\n- [Travis CI](https://travis-ci.org/)\n- [AppVeyor](https://www.appveyor.com/)\n\nThe following checks are performed:\n\n- [Doxygen](http://www.doxygen.org)\n- [Git Check](https://git-scm.com/docs/git-diff)\n- [Astyle](http://astyle.sourceforge.net/)\n- [Clang Tidy](http://clang.llvm.org/extra/clang-tidy/)\n- [CppCheck](http://cppcheck.sourceforge.net/)\n- [Codacy](https://www.codacy.com)\n- [Coverity Scan](https://scan.coverity.com/)\n- [Codecov](https://codecov.io/)\n- [Coveralls](https://coveralls.io/)\n- [Google Sanitizers](https://github.com/google/sanitizers)\n- [Valgrind](http://valgrind.org/)\n- [GCC Compiler Tests](https://gcc.gnu.org/)\n- [Clang Compiler Tests](https://clang.llvm.org/)\n- [XCode Compiler Tests](https://developer.apple.com/xcode/)\n- [Visual Studio Compiler Tests](https://www.visualstudio.com/)\n\nThe following real world projects use a variety of these techniques as part\nof their SDP:\n\n- [Bareflank Hypervisor](https://github.com/Bareflank/hypervisor)\n- [JSON](https://github.com/nlohmann/json)\n- [Neovim](https://github.com/neovim/neovim)\n- [GSL](https://github.com/Microsoft/GSL)\n\n## Dependencies\n\nAlthough this repo can be made to run on most systems, the following are the\nsupported platforms and their dependencies:\n\n#### Ubuntu 16.10 (or Higher):\n```\nsudo apt-get install git build-essential cmake\n```\n\n#### Windows (Cygwin):\n```\nsetup-x86_64.exe -q -P git,make,gcc-core,gcc-g++,cmake\n```\n\n#### Windows (Visual Studio):\n\nInstall the following packages:\n- [Visual Studio SDK 10](https://go.microsoft.com/fwlink/?linkid=838916)\n- [Visual Studio 2017](https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Community\u0026rel=15#)\n  - Check \"Desktop development with C++\"\n  - Check \"C++ CLI / Support\"\n  - Check \"Standard Library Modules\"\n- [CMake v3.6+](https://cmake.org/download/)\n- [Git for Windows](https://github.com/git-for-windows/git/releases)\n\n#### macOS:\n- [XCode 7.3+](https://developer.apple.com/xcode/)\n- [CMake v3.6+](https://cmake.org/download/)\n\n## Compilation / Testing / Installation\n\nTo compile and install this example, use the following instructions:\n\n#### GCC / Clang\n```\ngit clone https://github.com/ainfosec/ci_helloworld.git\n\nmkdir ci_helloworld/build\ncd ci_helloworld/build\n\ncmake ..\n\nmake\nmake test\n```\n\n#### Visual Studio 2017 (NMake)\n```\ngit clone https://github.com/ainfosec/ci_helloworld.git\n\nmkdir ci_helloworld/build\ncd ci_helloworld/build\n\ncmake -G \"NMake Makefiles\" ..\n\nnmake\nnmake test\n```\n\n#### Visual Studio 2017 (MSBuild)\n```\ngit clone https://github.com/ainfosec/ci_helloworld.git\n\nmkdir ci_helloworld/build\ncd ci_helloworld/build\n\ncmake -G \"Visual Studio 15 2017 Win64\" ..\n\nmsbuild ci_helloworld.sln\nctest\n```\n\n#### XCode 7.3+\n```\ngit clone https://github.com/ainfosec/ci_helloworld.git\n\nmkdir ci_helloworld/build\ncd ci_helloworld/build\n\ncmake ..\n\nmake\nmake test\n```\n\n## Analysis Tools\n\nThe following provides a description of all of the analysis tools that have\nbeen integrated into the CI services used by this project including an\nexplanation of how it works.\n\n### Doxygen\n\nThe CI is setup to check for missing documentation using doxygen. Unlike most\nof the analysis tools used in this project, there is no make target for\ndoxygen, and instead it is run using doxygen manually with the following\nscript:\n\n```yml\n- doxygen .doxygen.txt\n- |\n  if [[ -s doxygen_warnings.txt ]]; then\n    echo \"You must fix doxygen before submitting a pull request\"\n    echo \"\"\n    cat doxygen_warnings.txt\n    exit -1\n  fi\n```\n\nThis script runs doxygen against the source code and any warnings are placed\ninto a file called `doxygen_warnings.txt`. If this file is empty, it means that\nthe doxygen analysis passed, and all of the code is documented based on the\nsettings in the `.doxygen.txt` configuration file. If this files is not\nempty, the test fails, and prints the warnings generated by doxygen.\n\n### Git Check\n\n`git diff --check` provides a simple way to detect when whitespace errors\nhas been checked into the repo, as well as checking when end-of-file newlines\nare either missing, or contain too many. More information about this check\ncan be found [here](https://git-scm.com/docs/git-diff). This check is extremely\nuseful for developers when PRs contain modifications unrelated to their specific\nchanges.\n\n```yml\n- |\n  if [[ -n $(git diff --check HEAD^) ]]; then\n    echo \"You must remove whitespace before submitting a pull request\"\n    echo \"\"\n    git diff --check HEAD^\n    exit -1\n  fi\n```\n\nThis check simply runs `git diff --check`, which returns with an error if the\ncheck fails. If this occurs, the diff is displayed for the user to see.\n\n### Astyle\n\nSource code formatting is a great way to keep a consistent look and feel with\nthe code. The problem with source formatting is, unless everyone is using it,\ndevelopers PRs will contain modifications unrelated to their specific\nchanges, or worse, attempting to fix source formatting periodically will\ndestroy your repo's git history each time you format the source. Therefore,\nif source formatting is to be used, it should be checked on every code\ndiff to ensure the formatting is correct.\n\nFor this example, we use Astyle, but Clang Format will also work. To support\nAstyle in a simple way, we provide a make target that allows the developer\nto format their source code by simply running `make format`. To do this,\nwe must first get Astyle:\n\n```cmake\nlist(APPEND ASTYLE_CMAKE_ARGS\n    \"-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}\"\n)\n\nExternalProject_Add(\n    astyle\n    GIT_REPOSITORY      https://github.com/Bareflank/astyle.git\n    GIT_TAG             v1.2\n    GIT_SHALLOW         1\n    CMAKE_ARGS          ${ASTYLE_CMAKE_ARGS}\n    PREFIX              ${CMAKE_BINARY_DIR}/astyle/prefix\n    TMP_DIR             ${CMAKE_BINARY_DIR}/astyle/tmp\n    STAMP_DIR           ${CMAKE_BINARY_DIR}/astyle/stamp\n    DOWNLOAD_DIR        ${CMAKE_BINARY_DIR}/astyle/download\n    SOURCE_DIR          ${CMAKE_BINARY_DIR}/astyle/src\n    BINARY_DIR          ${CMAKE_BINARY_DIR}/astyle/build\n)\n```\n\nThis cmake logic uses ExternalProject_Add to automatically download Astyle,\ncompile it for your platform, and install it into your build directory so that\nit can be used by our custom make target. Note that we use our own patched\nversion of Astyle that changes the build system from Astyle's custom set of\nMakefiles to a CMake build system for simplicity.\n\n```cmake\nlist(APPEND ASTYLE_ARGS\n    --style=1tbs\n    --lineend=linux\n    --suffix=none\n    --pad-oper\n    --unpad-paren\n    --break-closing-brackets\n    --align-pointer=name\n    --align-reference=name\n    --indent-preproc-define\n    --indent-switches\n    --indent-col1-comments\n    --keep-one-line-statements\n    --keep-one-line-blocks\n    --pad-header\n    --convert-tabs\n    --min-conditional-indent=0\n    --indent=spaces=4\n    --close-templates\n    --add-brackets\n    --break-after-logical\n    ${CMAKE_SOURCE_DIR}/include/*.h\n    ${CMAKE_SOURCE_DIR}/src/*.cpp\n    ${CMAKE_SOURCE_DIR}/test/*.cpp\n)\n\nif(NOT WIN32 STREQUAL \"1\")\n    add_custom_target(\n        format\n        COMMAND ${CMAKE_SOURCE_DIR}/bin/astyle ${ASTYLE_ARGS}\n        COMMENT \"running astyle\"\n    )\nelse()\n    add_custom_target(\n        format\n        COMMAND ${CMAKE_SOURCE_DIR}/bin/astyle.exe ${ASTYLE_ARGS}\n        COMMENT \"running astyle\"\n    )\nendif()\n```\n\nTo create our custom astyle make target, we use the above CMake code. This\npoints CMake to the resulting astyle binary depending on the platform, and\nprovides astyle with the formatting options and source files specific to this\nproject.\n\n```yml\n- cmake -DENABLE_ASTYLE=ON -DCMAKE_CXX_COMPILER=\"g++-6\" ..\n- make\n- make format\n- |\n  if [[ -n $(git diff) ]]; then\n    echo \"You must run make format before submitting a pull request\"\n    echo \"\"\n    git diff\n    exit -1\n  fi\n```\n\nFinally, to verify on each PR that a code change adheres to our Astyle\nconfiguration, we add the above code to our Travis CI script. This creates\nour `make format` target and executes it to format the code. If `make format`\nformats the code, a diff will be created which `git diff` can be used to detect.\nIf no diff is created, it means all of the source adheres to our Astyle\nconfiguration, and the test passes.\n\n### Clang Tidy\n\nClang Tidy provides static analysis. Support for this tool starts by adding the\nfollowing to the CMakeLists.txt:\n\n```cmake\nset(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n```\n\nThis tells CMake to record all of the compilation instructions used to compile\nyour project including flags and definitions. Clang Tidy will use this\ninformation to statically analyze your project the same way it was compiled.\nThe advantage to this approach is a significant improvement in accuracy. The\nmain disadvantage to this approach is Clang Tidy is not good at statically\nanalyzing files that do not show up in this compilation database (such as\nheader files). For this reason, if you want to analyze a header, it has to\nbe included by a source file that is included in the compilation database.\n\n```cmake\nlist(APPEND RUN_CLANG_TIDY_BIN_ARGS\n    -clang-tidy-binary ${CLANG_TIDY_BIN}\n    -header-filter=.*\n    -checks=clan*,cert*,misc*,perf*,cppc*,read*,mode*,-cert-err58-cpp,-misc-noexcept-move-constructor\n)\n\nadd_custom_target(\n    tidy\n    COMMAND ${RUN_CLANG_TIDY_BIN} ${RUN_CLANG_TIDY_BIN_ARGS}\n    COMMENT \"running clang tidy\"\n)\n```\n\nFinally, Clang Tidy is given its own make target to simplify its use. Here\nwe tell the `run-clang-tidy-4.0.py` script which clang tidy binary to use,\nas well as which checks to perform, and what header files to include, which\nis all of them. We turn off the -cert-err58-cpp test because it triggers\ncode from catch.hpp, and -misc-noexcept-move-constructor because it is still\nbuggy in 4.0. Note that we choose a specific version of Clang Tidy which is\nimportant because each new version of Clang Tidy fixes bugs and adds new\nchecks, resulting in different results depending on which version you use.\n\n```yml\n- cmake -DENABLE_CLANG_TIDY=ON -DCMAKE_CXX_COMPILER=\"g++-6\" ..\n- make\n- make tidy \u003e output.txt\n- |\n  if [[ -n $(grep \"warning: \" output.txt) ]] || [[ -n $(grep \"error: \" output.txt) ]]; then\n      echo \"You must pass the clang tidy checks before submitting a pull request\"\n      echo \"\"\n      grep --color -E '^|warning: |error: ' output.txt\n      exit -1;\n  else\n      echo -e \"\\033[1;32m\\xE2\\x9C\\x93 passed:\\033[0m $1\";\n  fi\n```\n\nFrom Travis CI, we enable Clang Tidy, and dump its output to a file. If this\nfile contains \"warning\" or \"error\" we fail the test, and output the issues\nreported by Clang Tidy to the user to be fixed. This ensures that every\nPR has been statically checked.\n\n### CppCheck\n\nCppCheck is another static analysis tool.\n\n```cmake\nlist(APPEND CPPCHECK_CMAKE_ARGS\n    \"-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}\"\n)\n\nExternalProject_Add(\n    cppcheck\n    GIT_REPOSITORY      https://github.com/danmar/cppcheck.git\n    GIT_TAG             1.79\n    GIT_SHALLOW         1\n    CMAKE_ARGS          ${CPPCHECK_CMAKE_ARGS}\n    PREFIX              ${CMAKE_BINARY_DIR}/external/cppcheck/prefix\n    TMP_DIR             ${CMAKE_BINARY_DIR}/external/cppcheck/tmp\n    STAMP_DIR           ${CMAKE_BINARY_DIR}/external/cppcheck/stamp\n    DOWNLOAD_DIR        ${CMAKE_BINARY_DIR}/external/cppcheck/download\n    SOURCE_DIR          ${CMAKE_BINARY_DIR}/external/cppcheck/src\n    BINARY_DIR          ${CMAKE_BINARY_DIR}/external/cppcheck/build\n)\n```\n\nThe version of CppCheck provided by Ubuntu 14.04 is old, and does not support\nC++11 well, so we grab a specific version of CppCheck from GitHub, allowing\nall users of the project to use the same version.\n\n```cmake\nlist(APPEND CPPCHECK_ARGS\n    --enable=warning,style,performance,portability,unusedFunction\n    --std=c++11\n    --verbose\n    --error-exitcode=1\n    --language=c++\n    -DMAIN=main\n    -I ${CMAKE_SOURCE_DIR}/include\n    ${CMAKE_SOURCE_DIR}/include/*.h\n    ${CMAKE_SOURCE_DIR}/src/*.cpp\n    ${CMAKE_SOURCE_DIR}/test/*.cpp\n)\n\nadd_custom_target(\n    check\n    COMMAND ${CMAKE_BINARY_DIR}/bin/cppcheck ${CPPCHECK_ARGS}\n    COMMENT \"running cppcheck\"\n)\n```\n\nWe then add a custom target for our newly built CppCheck application, telling\nCppCheck to enable all of its checks (minus pedantic warnings) and to check\nall of our source files. Note that CppCheck needs to know that MAIN=main,\notherwise it will think that the main function is not executed, and we need\nto tell CppCheck to error with a non-0 error code so that Travis CI reports\na failed test if any of the checks fail.\n\n```yml\n- cmake -DENABLE_CPPCHECK=ON -DCMAKE_CXX_COMPILER=\"g++-6\" ..\n- make\n- make check\n```\n\nRunning the Travis CI test is as simply as turning on CppCheck, and running\nthe custom make target.\n\n### Coverity Scan\n\nCoverity Scan is another static analysis tool that is very good at finding hard\nto find structural issues with your code. If you have access to Coverity Scan,\nit is well worth adding to your SDP.\n\n```yml\n- os: linux\n  env:\n    - TEST=\"Coverity Scan\"\n  addons:\n    apt:\n      sources:\n        - ubuntu-toolchain-r-test\n      packages:\n        - gcc-6\n        - g++-6\n    coverity_scan:\n      project:\n        name: \"ainfosec/ci_helloworld\"\n        description: \"A simple example of how to setup a complete CI environment for C and C++\"\n      notification_email: rianquinn@gmail.com\n      build_command_prepend: \"cmake -DCMAKE_CXX_COMPILER=g++-6 ..\"\n      build_command: \"make\"\n      branch_pattern: master\n  script:\n    - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-\n```\n\nCoverity Scan is also very simple to setup. The above Travis CI test is\na cut/paste from their website after you register your project. All we have to\ndo is compile the source which tells Coverity Scan how the source code is\ncompiled. From there, their website will provide a means to exclude directories\nand see issues with the code. In our example, we do a scan on every change to\nmaster as the number of changes to master is small, but on large projects with\na lot of merges per day, Coverity Scan suggests using a specific coverity_scan\nbranch for scans. If this is done, a nightly scan should be setup by grabbing\nthe master branch, and pushing it to the coverity_scan branch each night.\nThis way, issues with Coverity Scan can be identified quickly.\n\n### Codecov\n\nCodecov is a powerful, yet simple to setup coverage tool.\n\n```cmake\nif(ENABLE_COVERAGE)\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -g \")\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -O0\")\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fprofile-arcs\")\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -ftest-coverage\")\n    set(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} --coverage\")\nendif()\n```\n\nTo setup coverage, we must enable GCOV support in our compiler (assumes\nGCC or Clang). Once this support is enabled, running `make test` will generate\ncoverage stats that Codecov can analyze to give you a report of what code has\nor has not been unit tested.\n\n```yml\n- cmake -DENABLE_COVERAGE=ON -DCMAKE_CXX_COMPILER=\"g++-6\" ..\n- make\n- make test\n- cd ..\n- bash \u003c(curl -s https://codecov.io/bash)\n```\n\nThe Travis CI test is as simple as compiling and running the unit tests,\nand then running Codecov's bash script. Once this is done, the results can\nbe see on Codecov's website.\n\n### Coveralls\n\nCoveralls is another coverage tool.\n\n```cmake\nif(ENABLE_COVERAGE)\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -g \")\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -O0\")\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fprofile-arcs\")\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -ftest-coverage\")\n    set(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} --coverage\")\nendif()\n```\n\nLike Codecov, GCOV has to be enabled.\n\n```yml\n- pip install --user git+git://github.com/eddyxu/cpp-coveralls.git\n- cmake -DENABLE_COVERAGE=ON -DCMAKE_CXX_COMPILER=\"g++-6\" ..\n- make\n- make test\n- cd ..\n- |\n  coveralls --build-root build --gcov-options '\\-lp' \\\n    -e build/external \\\n    -e build/include \\\n    -e build/CMakeFiles/3.8.0 \\\n    -e build/CMakeFiles/feature_tests.c \\\n    -e build/CMakeFiles/feature_tests.cxx\n```\n\nUnlike Codecov, Coveralls is a lot harder to setup. Codecov keeps track of\nwhich files are in your git repository and only generates reports for files\nin the repo, while Coveralls will generate coverage reports for all files it\nsees, including generated files by CMake. Coveralls also does not have a\nsimple bash script to report coverage data to their server, but instead requires\nthe installation of an external C++ specific tool for collecting GCOV data.\nFor these reasons, we have to install cpp-coveralls, and then tell it to\nexclude specific files / directories that are being collected that should not\nbe.\n\n### Google Sanitizers\n\nThe Google Sanitizers are a dynamic analysis tool that is included in GCC\nand Clang/LLVM.\n\n```cmake\nif(ENABLE_ASAN)\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -g\")\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -O1\")\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fuse-ld=gold\")\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer\")\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fsanitize=address\")\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fsanitize=leak\")\nendif()\n\nif(ENABLE_USAN)\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fuse-ld=gold\")\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fsanitize=undefined\")\nendif()\n\nif(ENABLE_TSAN)\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fuse-ld=gold\")\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fsanitize=thread\")\nendif()\n```\n\nEach sanitizer has to be run in isolation, and thus we have one test per\nsanitizer group. The flags for each set can be found on Google's GitHub page\nas well as Clang's usage documentation.\n\n```cmake\n- cmake -DENABLE_ASAN=ON -DCMAKE_CXX_COMPILER=\"g++-6\" ..\n- make\n- make test\n```\n\nFor each test, we turn on the specific check, and the unit tests, and if\na check fails, the unit test will exit with a non-0 exit code, causing\nTravis CI to fail the test. It should be noted that each new version of\nGCC and Clang comes with better support, and thus, like some of the other\ntools, you should stick to a specific version.\n\n### Valgrind\n\nValgrind is another dynamic analysis tool that provides leak detection.\n\n```cmake\nset(MEMORYCHECK_COMMAND_OPTIONS \"${MEMORYCHECK_COMMAND_OPTIONS} --leak-check=full\")\nset(MEMORYCHECK_COMMAND_OPTIONS \"${MEMORYCHECK_COMMAND_OPTIONS} --track-fds=yes\")\nset(MEMORYCHECK_COMMAND_OPTIONS \"${MEMORYCHECK_COMMAND_OPTIONS} --trace-children=yes\")\nset(MEMORYCHECK_COMMAND_OPTIONS \"${MEMORYCHECK_COMMAND_OPTIONS} --error-exitcode=1\")\n```\n\nThe easiest way to execute Valgrind is to use CMake's built-in support as it\nwill handle error logic for you. For this reason, we need to tell CMake what\nflags to give Valgrind. In this case we enable all of its checks and tell\nValgrind to exit with a non-0 exit code so that if a check fails, Travis CI\nwill fail the test.\n\n```yml\n- cmake -DCMAKE_CXX_COMPILER=\"g++-6\" ..\n- make\n- ctest -T memcheck\n```\n\nTo run the test, all we need to do is compile the code, and run the unit tests\nusing ctest, enabling the memcheck mode.\n\n## License\n\nThis project is licensed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fainfosec%2Fci_helloworld","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fainfosec%2Fci_helloworld","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fainfosec%2Fci_helloworld/lists"}