1 2# Contributing to Fruit 3 4This file contains various information and documentation for Fruit contributors. 5If you only want to use Fruit, see the [wiki](https://github.com/google/fruit/wiki); 6you can find instructions for building Fruit manually 7[here](https://github.com/google/fruit/wiki/install#building-fruit-manually). 8 9If you actually want to change Fruit itself, that's great! Read on. 10 11### Basics 12 13#### Build systems 14 15Fruit supports two build systems: CMake (configured in `CMakeLists.txt` files) and 16[Bazel](https://www.bazel.io) (configured in `BUILD` files). 17 18This means that when you build/test Fruit code you have a choice of what build system you want to use, 19but also that for larger changes (typically, if you add new files) you might need changes in both 20`CMakeLists.txt` and `BUILD` files, to make sure that Fruit keeps building (and passing its tests) under both build 21systems. 22Both build systems are tested in Travis CI (see below). 23 24Example commands to build a development version of Fruit using CMake (with all assertions enabled) and run the tests: 25 26```bash 27cd $PATH_TO_FRUIT 28mkdir build-debug 29cd build-debug 30cmake .. -DCMAKE_BUILD_TYPE=Debug -DFRUIT_ENABLE_CLANG_TIDY=TRUE -DCMAKE_CXX_FLAGS="-Werror -DFRUIT_DEBUG=1 -DFRUIT_EXTRA_DEBUG=1 -D_GLIBCXX_DEBUG=1" 31make -j 16 32cd tests 33py.test-3 -n auto 34``` 35 36### Continuous Integration (CI) 37 38Fruit uses Github actions for continuous integration. You can see the latest CI runs in Github 39[here](https://github.com/google/fruit/actions). The CI configuration is defined in 40`.github/workflows`. 41 42Fruit tests run as Github actions run in various configurations/environments, notably: 43 44* In Linux, OS X and Windows 45* In various OS versions 46* Using GCC, Clang, Apple-Clang or MSVC 47* Optionally running with ASan/UBSan 48* Using CMake or Bazel 49 50These tests run after every commit in master and for every pull request (as soon as the pull request is sent). 51 52Linux tests run in Docker, using a set of images built for this purpose 53([list of images](https://hub.docker.com/r/polettimarco/fruit-basesystem/tags/)). 54 55If a test fails in CI in some configuration, look at the beginning of the CI Job log for a line such as: 56 57```bash 58export OS=linux; export COMPILER='clang-3.9'; export STL='libstdc++'; export UBUNTU='16.04'; extras/scripts/postsubmit.sh DebugValgrind 59``` 60 61You can then run the same command locally (from your fruit directory) to reproduce the issue. Running this 62`postsubmit.sh` script will run the tests under Docker to ensure repeatability of the results. 63 64For example, even if the failure only happens with an old Ubuntu/GCC version you don't have installed, it will download 65a Docker image containing that old Ubuntu/GCC and then run the tests inside a VM started from that image. 66 67Once `postsubmit.sh` completes, if you want you can attach to the stopped VM used to run the tests by running: 68 69```bash 70docker attach fruit 71``` 72 73This is often very useful to e.g. re-run a compilation manually with additional debug flags. 74 75When running `postsubmit.sh` manually in this way, it will run using the latest changes in your fruit directory, even if 76they aren't staged/committed yet. This allows to do a quicker edit/test cycle. 77 78To speed up the execution of `postsubmit.sh` you can also set the `NJOBS` variable, e.g.: 79 80```bash 81export NJOBS=16; export OS=linux; export COMPILER='clang-3.9'; export STL='libstdc++'; export UBUNTU='16.04'; extras/scripts/postsubmit.sh DebugValgrind 82``` 83 84### How to run Fruit tests on Windows 85 86You can import Fruit in Visual Studio (2017 and later) as a CMake project. You need to set the relevant CMake flags in 87the `CMakeSettings.json` file that Visual Studio will create. 88For example, if you installed Boost in `C:\boost\boost_1_62_0`, you can put this configuration in your 89`CMakeSettings.json`: 90 91 { 92 // See https://go.microsoft.com//fwlink//?linkid=834763 for more information about this file. 93 "configurations": [ 94 { 95 "name": "x64-Debug", 96 "generator": "Visual Studio 16 2019 Win64", 97 "configurationType": "Debug", 98 "buildRoot": "${projectDir}\\out\\build\\${name}", 99 "cmakeCommandArgs": "-DBoost_INCLUDE_DIR=C:\\boost\\boost_1_62_0 -DCMAKE_BUILD_TYPE=Debug -DFRUIT_ADDITIONAL_CXX_FLAGS=/Z7", 100 "buildCommandArgs": "-m -v:minimal", 101 "intelliSenseMode": "windows-msvc-x64" 102 }, 103 { 104 "name": "x64-Debug-noboost", 105 "generator": "Visual Studio 16 2019 Win64", 106 "configurationType": "Debug", 107 "buildRoot": "${projectDir}\\out\\build\\${name}", 108 "cmakeCommandArgs": "-DFRUIT_USES_BOOST=False -DCMAKE_BUILD_TYPE=Debug -DFRUIT_ADDITIONAL_CXX_FLAGS=/Z7", 109 "buildCommandArgs": "-m -v:minimal", 110 "intelliSenseMode": "windows-msvc-x64" 111 } 112 113 ] 114 } 115 116The `/Z7` flag instructs Visual Studio to use the C7 format for debugging information, which allows Fruit's tests to run in parallel without interfering with each other. 117 118If you don't want to use Boost, you can replace the `-DBoost_INCLUDE_DIR=...` flags above with `-DFRUIT_USES_BOOST=False`. 119 120You can now run CMake within Visual Studio (from the menu: CMake -> Cache -> Generate -> CMakeLists.txt) and build Fruit (from the menu: CMake -> Build All). 121 122You can also run tests, but *only* from the command-line (after building Fruit from Visual Studio), running tests from Visual Studio doesn't work. 123 124To do that, you'll need python3 installed (you can download it [here](https://www.python.org/downloads/)). 125 126You'll also some Python packages. You can install them with: 127 128 pip install absl-py 129 pip install pytest 130 pip install pytest-xdist 131 132To do so: 133 134* Open the Start menu 135* From there, open the "Native Tools Command Prompt for VS 2017" shell for the chosen architecture. For example, "x64 Native Tools Command Prompt for VS 2017". 136* In Visual Studio, open the Output view (from the menu: View -> Output) and select "CMake" in the "Show output from:" dropdown menu. 137* Scroll to the beginning of that view. You should see two lines starting with "Command line" and "Working directory" respectively. 138* Cd to that working directory in the shell. For example, if the path in the "Working directory" line is `C:\Users\Marco\AppData\Local\CMakeBuild\fa17dda0-4eec-6438-a358-e1253b7e86ff\build\x64-Debug`, you can run `cd "C:\Users\Marco\AppData\Local\CMakeBuild\fa17dda0-4eec-6438-a358-e1253b7e86ff\build\x64-Debug"`. 139* Cd to the "tests" subdirectory ("cd tests"). 140* Then run pytest, e.g. `py.test -n auto`. 141 142### Sending pull requests 143 144If you send a pull request, you should make sure that these CI tests are passing. They will run automatically on your 145pull request as soon as you send it. 146 147As an exception, if the current master also failed the last CI run feel free to send the pull request anyway (you can go 148[here](https://travis-ci.org/google/fruit) to check if that's the case). 149 150If a test fails, see the CI section above for informations on how to reproduce. 151 152You should also make sure that your code: 153 154* Is formatted correctly ([more details here](#code-style)) 155* Has appropriate tests (if your change is user-visible, or if you're introducing new branches that should be tested) 156 157### What to install in order to develop Fruit code 158 159In addition to 160[the compiler you need to install to build Fruit](https://github.com/google/fruit/wiki/install#dependencies), 161when developing Fruit code you might need some of the following software. Note that depending on your change you may or 162may not need all of these; you might want to go ahead without these and then only install additional things if you get 163an error about a missing tool. 164 165* CMake 166* Bazel ([installation instructions](https://www.bazel.io/docs/install.html)) 167* Valgrind 168* Docker 169 170## Useful command for fast edit/rebuild/retest cycles 171 172This command uses Bazel to run the tests (so you need to have it installed in order to use this). 173Bazel has a much more fine-grained picture of what tests depend on what source files, so it will often avoid running 174tests that have passed before when it knows that they will pass (unlike py.test that runs the entire test suite every 175time). This is especially relevant for incremental builds when only test sources have changed (e.g. after adjusting an 176expectation in a test or fixing a bug in the test); there is little difference when changing `src/` or `include/` 177because all tests will be re-run anyway. 178 179```bash 180cd $PATH_TO_FRUIT/extras/bazel_root 181bazel test --test_output=errors \ 182 --test_summary=terse \ 183 //third_party/fruit/... 184``` 185 186## Checking test coverage 187 188Fruit's test suite supports collecting test coverage (only when building with GCC on Linux using CMake). 189Example commands: 190 191```bash 192cd $PATH_TO_FRUIT 193mkdir build-coverage 194cd build-coverage 195CXX=g++-6 cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DFRUIT_ENABLE_COVERAGE=ON 196make -j 10 197(cd tests; py.test-3 -n auto) 198lcov --rc lcov_branch_coverage=1 --capture --directory . --output-file coverage.info 199lcov --rc lcov_branch_coverage=1 --remove coverage.info '/usr/include/*' '/tmp/*' -o coverage-filtered.info 200genhtml --no-function-coverage --rc lcov_branch_coverage=1 --rc genhtml_hi_limit=100 coverage-filtered.info --output-directory html 201google-chrome html/index.html 202``` 203 204The important figures for each file are: 205* Percentage of lines covered 206* Percentage of branches covered 207 208Ideally, they should both be 100%. The `LCOV_EXCL_LINE` and `LCOV_EXCL_BR_LINE` markers can be used to mark lines and 209branches (respectively) that can't be covered and therefore should be excluded. 210 211Note that the "percentage of **functions** covered" metric is not meaningful for Fruit, since it considers each 212instantiation of a template function/method as separate (even if they share the same source lines). 213 214## Code style 215 216C++ code in Fruit should be indented using clang-format (a `.clang-format` file is provided in the Fruit root 217directory). You can re-indent all code using this command: 218 219```bash 220$ clang-format -i $(git ls-files | egrep '\.cpp|\.h' ) 221``` 222 223## Reporting vulnerabilities 224 225In case of a security vulnerability in Fruit, please contact [poletti.marco@gmail.com](mailto:poletti.marco@gmail.com) directly instead of using the public issue tracker. 226