• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 -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 Travis CI for continuous integration. You can see the latest CI runs in Travis CI
39[here](https://travis-ci.org/google/fruit/builds). The CI configuration is defined in
40`extras/scripts/travis_yml_generator.py`, that generates a `.travis.yml` file (which must also be checked in, due to the
41way Travis CI is configured).
42
43When editing the `travis_yml_generator.py` script you should also update the `.travis.yml` file (in the same commit)
44by running:
45
46```bash
47cd $PATH_TO_FRUIT
48extras/scripts/travis_yml_generator.py >.travis.yml
49```
50
51Fruit tests run in Travis CI in various configurations/environments, notably:
52
53* In Linux or OS X
54* In various Ubuntu versions
55* Using GCC or Clang
56* Optionally running under Valgrind
57* Optionally running with ASan/UBSan
58* Using CMake or Bazel
59
60These tests run after every commit in master and for every pull request (as soon as the pull request is sent).
61
62Linux tests run in Docker, using a set of images built for this purpose
63([list of images](https://hub.docker.com/r/polettimarco/fruit-basesystem/tags/)).
64
65If a test fails in Travis CI in some configuration, look at the beginning of the Travis CI Job log for a line such as:
66
67```bash
68export OS=linux; export COMPILER='clang-3.9'; export STL='libstdc++'; export UBUNTU='16.04'; extras/scripts/postsubmit.sh DebugValgrind
69```
70
71You can then run the same command locally (from your fruit directory) to reproduce the issue. Running this
72`postsubmit.sh` script will run the tests under Docker to ensure repeatability of the results.
73
74For example, even if the failure only happens with an old Ubuntu/GCC version you don't have installed, it will download
75a Docker image containing that old Ubuntu/GCC and then run the tests inside a VM started from that image.
76
77Once `postsubmit.sh` completes, if you want you can attach to the stopped VM used to run the tests by running:
78
79```bash
80docker attach fruit
81```
82
83This is often very useful to e.g. re-run a compilation manually with additional debug flags.
84
85When running `postsubmit.sh` manually in this way, it will run using the latest changes in your fruit directory, even if
86they aren't staged/committed yet. This allows to do a quicker edit/test cycle.
87
88To speed up the execution of `postsubmit.sh` you can also set the `NJOBS` variable, e.g.:
89
90```bash
91export NJOBS=16; export OS=linux; export COMPILER='clang-3.9'; export STL='libstdc++'; export UBUNTU='16.04'; extras/scripts/postsubmit.sh DebugValgrind
92```
93
94The default number of jobs (used in Travis CI) is 2.
95
96### How to run Fruit tests on Windows
97
98You can import Fruit in Visual Studio (2017 and later) as a CMake project. You need to set the relevant CMake flags in
99the `CMakeSettings.json` file that Visual Studio will create.
100For example, if you installed Boost in `C:\boost\boost_1_62_0`, you can put this configuration in your
101`CMakeSettings.json`:
102
103    {
104        // See https://go.microsoft.com//fwlink//?linkid=834763 for more information about this file.
105        "configurations": [
106            {
107                "name": "x86-Debug",
108                "generator": "Visual Studio 15 2017",
109                "configurationType": "Debug",
110                "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
111                "cmakeCommandArgs": "-DBOOST_DIR=C:\\boost\\boost_1_62_0 -DCMAKE_BUILD_TYPE=Debug -DFRUIT_ADDITIONAL_CXX_FLAGS=/Z7",
112                "buildCommandArgs": "-m -v:minimal"
113            },
114            {
115                "name": "x86-Release",
116                "generator": "Visual Studio 15 2017",
117                "configurationType": "Release",
118                "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
119                "cmakeCommandArgs": "-DBOOST_DIR=C:\\boost\\boost_1_62_0 -DCMAKE_BUILD_TYPE=Release",
120                "buildCommandArgs": "-m -v:minimal"
121            },
122            {
123                "name": "x64-Debug",
124                "generator": "Visual Studio 15 2017 Win64",
125                "configurationType": "Debug",
126                "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
127                "cmakeCommandArgs": "-DBOOST_DIR=C:\\boost\\boost_1_62_0 -DCMAKE_BUILD_TYPE=Debug -DFRUIT_ADDITIONAL_CXX_FLAGS=/Z7",
128                "buildCommandArgs": "-m -v:minimal"
129            },
130            {
131                "name": "x64-Release",
132                "generator": "Visual Studio 15 2017 Win64",
133                "configurationType": "Release",
134                "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
135                "cmakeCommandArgs": "-DBOOST_DIR=C:\\boost\\boost_1_62_0 -DCMAKE_BUILD_TYPE=Release",
136                "buildCommandArgs": "-m -v:minimal"
137            }
138        ]
139    }
140
141The `/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.
142
143If you don't want to use Boost, you can replace the `-DBOOST_DIR=...` flags above with `-DFRUIT_USES_BOOST=False`.
144
145You can now run CMake within Visual Studio (from the menu: CMake -> Cache -> Generate -> CMakeLists.txt) and build Fruit (from the menu: CMake -> Build All).
146
147You can also run tests, but *only* from the command-line (after building Fruit from Visual Studio), running tests from Visual Studio doesn't work.
148
149To do that, you'll need python3 installed (you can download it [here](https://www.python.org/downloads/)).
150
151You'll also the `pytest` and `pytest-xdist` packages. You can install them with:
152
153    pip install pytest
154    pip install pytest-xdist
155
156To do so:
157
158* Open the Start menu
159* 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".
160* In Visual Studio, open the Output view (from the menu: View -> Output) and select "CMake" in the "Show output from:" dropdown menu.
161* Scroll to the beginning of that view. You should see two lines starting with "Command line" and "Working directory" respectively.
162* 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"`.
163* Cd to the "tests" subdirectory ("cd tests").
164* Then run pytest, e.g. `py.test -n auto`.
165
166### Sending pull requests
167
168If you send a pull request, you should make sure that these CI tests are passing. They will run automatically on your
169pull request as soon as you send it.
170
171As an exception, if the current master also failed the last CI run feel free to send the pull request anyway (you can go
172[here](https://travis-ci.org/google/fruit) to check if that's the case).
173
174If a test fails, see the CI section above for informations on how to reproduce.
175
176You should also make sure that your code:
177
178* Is formatted correctly ([more details here](#code-style))
179* Has appropriate tests (if your change is user-visible, or if you're introducing new branches that should be tested)
180
181### What to install in order to develop Fruit code
182
183In addition to
184[the compiler you need to install to build Fruit](https://github.com/google/fruit/wiki/install#dependencies),
185when developing Fruit code you might need some of the following software. Note that depending on your change you may or
186may not need all of these; you might want to go ahead without these and then only install additional things if you get
187an error about a missing tool.
188
189* CMake
190* Bazel ([installation instructions](https://www.bazel.io/docs/install.html))
191* Valgrind
192* Docker
193
194## Useful command for fast edit/rebuild/retest cycles
195
196This command uses Bazel to run the tests (so you need to have it installed in order to use this).
197Bazel has a much more fine-grained picture of what tests depend on what source files, so it will often avoid running
198tests that have passed before when it knows that they will pass (unlike py.test that runs the entire test suite every
199time). This is especially relevant for incremental builds when only test sources have changed (e.g. after adjusting an
200expectation in a test or fixing a bug in the test); there is little difference when changing `src/` or `include/`
201because all tests will be re-run anyway.
202
203```bash
204cd $PATH_TO_FRUIT/extras/bazel_root
205bazel test --python_path=/usr/bin/python3 \
206           --test_output=errors \
207           --test_summary=terse \
208           //third_party/fruit/...
209```
210
211## Checking test coverage
212
213Fruit's test suite supports collecting test coverage (only when building with GCC on Linux using CMake).
214Example commands:
215
216```bash
217cd $PATH_TO_FRUIT
218mkdir build-coverage
219cd build-coverage
220CXX=g++-6 cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DFRUIT_ENABLE_COVERAGE=ON
221make -j 10
222(cd tests; py.test-3 -n auto)
223lcov --rc lcov_branch_coverage=1 --capture --directory . --output-file coverage.info
224lcov --rc lcov_branch_coverage=1 --remove coverage.info '/usr/include/*' '/tmp/*' -o coverage-filtered.info
225genhtml --no-function-coverage --rc lcov_branch_coverage=1 --rc genhtml_hi_limit=100 coverage-filtered.info --output-directory html
226google-chrome html/index.html
227```
228
229The important figures for each file are:
230* Percentage of lines covered
231* Percentage of branches covered
232
233Ideally, they should both be 100%. The `LCOV_EXCL_LINE` and `LCOV_EXCL_BR_LINE` markers can be used to mark lines and
234branches (respectively) that can't be covered and therefore should be excluded.
235
236Note that the "percentage of **functions** covered" metric is not meaningful for Fruit, since it considers each
237instantiation of a template function/method as separate (even if they share the same source lines).
238
239## Code style
240
241C++ code in Fruit should be indented using clang-format (a `.clang-format` file is provided in the Fruit root
242directory). You can re-indent all code using this command:
243
244```bash
245$ clang-format -i $(git ls-files | egrep '\.cpp|\.h' )
246```
247
248## Reporting vulnerabilities
249
250In 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.
251