blob: e0663901216a98c487e4d03dc330aeb0a74ddac5 [file] [log] [blame] [view]
---
layout: page
title: A beginners guide to contributing
permalink: contributing
author: Bobby R. Bruce
---
This document serves as a beginners guide to contributing to gem5. If questions
arise while following this guide, we advise consulting [CONTRIBUTING.md](
https://gem5.googlesource.com/public/gem5/+/refs/heads/stable/CONTRIBUTING.md)
which contains more details on how to contribute to gem5.
The following subsections outline, in order, the steps involved in contributing
to the gem5 project.
## Determining what you can contribute
The easiest way to see how you can contribute to gem5 is to check our Jira
issue tracker: <https://gem5.atlassian.net>. From Jira you can check open
issues.
Browse these open issues and see if there are any which you are capable of
handling. When you find a task you are happy to carry out, verify no one else
is presently assigned, then leave a comment asking if you may assign yourself
this task (this will involve creating a Jira account). Though not mandatory, we
advise first-time contributors do this so developers more familiar with the
task may give advice on how best to implement the necessary changes.
Once a developers has replied to your comment (and given any advice they may
have), you may officially assign yourself the task. After this you should
change the status of the task from `Todo` to `In progress`. This helps the gem5
development community understand which parts of the project are presently being
worked on.
**If, for whatever reason, you stop working on a task, please unassign
yourself from the task and change the task's status back to `Todo`.**
## Obtaining the git repo
The gem5 git repository is hosted at <https://gem5.googlesource.com>.
**Please note: contributions made to other gem5 repos (e.g., our GitHub mirror)
will not be considered. Please contribute to <https://gem5.googlesource.com>
exclusively.**
To pull the gem5 git repo:
```Shell
git clone https://gem5.googlesource.com/public/gem5
```
### stable / develop branch
By default, the git repo will have the `stable` branch checked-out. The
`stable` branch is the gem5 stable release branch. I.e., the HEAD
of this branch contains the latest stable release of gem5. (execute `git tag`
on the `stable` branch to see the list of stable releases. A particular
release may be checked out by executing `git checkout <release>`). As the
`stable` branch only contains officially released gem5 code **contributors
should not develop changes on top of the `stable` branch** they should instead
**develop changes on top of the `develop` branch**.
To checkout the `develop` branch:
```Shell
git checkout --track origin/develop
```
Changes may be made on this branch to incorporate changes assigned to yourself.
As the develop branch is frequently updated, regularly obtain the latest
`develop` branch by executing:
```
git pull --rebase
```
Conflicts may need resolved between your local changes and new changes on the
`develop` branch.
## Making modifications
### C/CPP
Different tasks will require the project to be modified in different ways.
Though, in all cases, our style-guide must be adhered to. The full C/C++ style
guide is outlined [here](/documentation/general_docs/development/coding_style).
As a high-level overview:
* Lines must not exceed 79 characters in length.
* There should be no trailing white-space on any line.
* Indentations must be 4 spaces (no tab characters).
* Class names must use upper camel case (e.g., `ThisIsAClass`).
* Class member variables must use lower camel case (e.g.,
`thisIsAMemberVariable`).
* Class member variables with their own public accessor must start with an
underscore (e.g., `_variableWithAccessor`).
* Local variables must use snake case (e.g., `this_is_a_local_variable`).
* Functions must use lower camel case (e.g., `thisIsAFunction`)
* Function parameters must use snake case.
* Macros must be in all caps with underscores (e.g., `THIS_IS_A_MACRO`).
* Function declaration return types must be on their own line.
* Function brackets must be on their own line.
* `for`/`if`/`while` branching operations must be followed by a white-space
before the conditional statement (e.g., `for (...)`).
* `for`/`if`/`while` branching operations' opening bracket must be on the
same line, with the closing bracket on its own line (e.g.,
`for (...) {\n ... \n}\n`). There should be a space between the condition(s)
and the opening bracket.
* C++ access modifies must be indented by two spaces, with method/variables
defined within indented by four spaces.
Below is a simple toy example of how a class should be formatted:
```C++
#DEFINE EXAMPLE_MACRO 7
class ExampleClass
{
private:
int _fooBar;
int barFoo;
public:
int
getFooBar()
{
return _fooBar;
}
int
aFunction(int parameter_one, int parameter_two)
{
int local_variable = 0;
if (true) {
int local_variable = parameter_one + parameter_two + barFoo
+ EXAMPLE_MACRO;
}
return local_variable;
}
}
```
### Python
We use [Python Black](https://github.com/psf/black) to format our Python code
to the correct style. To install:
```sh
pip install black
```
Then run on modified/added python files using:
```sh
black <files/directories>
```
For varibale/method/etc. naming conventions, please follow the [PEP 8 naming
convention recommendations](
https://peps.python.org/pep-0008/#naming-conventions). While we try our best to
enforce naming conventions across the gem5 project, we are aware there are
instances where they are not. In such cases please **follow the convention
of the code you are modifying**.
### Using pre-commit
To help enforce our style guide we use use [pre-commit](
https://pre-commit.com). pre-commit is a git hook and, as such, must be
explicitly installed by a gem5 developer.
To install the gem5 pre-commit checks, execute the following in the gem5
directory:
```sh
pip install pre-commit
pre-commit install
```
Once installed pre-commit will run checks on modified code prior to running the
`git commit` command (see [our section on commiting](#committing) for more
details on commiting your changes). If these tests fail you will not be able to
commit.
These same pre-commit checks are run as part of Gerrit's CI checks (those
which must pass to obtain a "Verified" status required for a change to be
incorporated into the develop branch). It is therefore recommended that
developers install pre-commit to catch style errors early.
**Note:** As of the v22.0 release, the pre-commit hook is only available on the
develop branch.
## Compiling and running tests
The minimum criteria for a change to be submitted is that the code is
compilable and the test cases pass.
The following command both compiles the project and runs our system-level
checks:
```Shell
cd tests
python main.py run
```
**Note: These tests can take several hours to build and execute. `main.py` may
be run on multiple threads with the `-j` flag. E.g.: `python main.py run
-j6`.**
The unit tests should also pass. To run the unit tests:
```Shell
scons build/NULL/unittests.opt
```
To compile an individual gem5 binary:
```Shell
scons build/{ISA}/gem5.opt
```
where `{ISA}` is the target ISA. Common ISAs are `ARM`, `MIPS`, `POWER`,
`RISCV`, `SPARC`, and `X86`. So, to build gem5 for `X86`:
```Shell
scons build/X86/gem5.opt
```
## Committing
When you feel your change is done, you may commit. Start by adding the changed
files:
```Shell
git add <changed files>
```
Then commit using:
```Shell
git commit
```
The commit message must adhere to our style. The first line of the commit is
the "header". The header starts with a tag (or tags, separated by a comma),
then a colon. Which tags are used depend on which components of gem5
you have modified. **Please refer to the [MAINTAINERS.yaml](
https://gem5.googlesource.com/public/gem5/+/refs/heads/stable/MAINTAINERS.yaml) for
a comprehensive list of accepted tags**. After this colon a short description
of the commit must be provided. **This header line must not exceed 65
characters**.
After this, a more detailed description of the commit can be added. This is
inserted below the header, separated by an empty line. Including a description
is optional but it's strongly recommended. The description may span multiple
lines, and multiple paragraphs. **No line in the description may exceed 72
characters.**
To improve the navigability of the gem5 project we would appreciate if commit
messages include a link to the relevant Jira issue/issues.
Below is an example of how a gem5 commit message should be formatted:
```
test,base: This commit tests some classes in the base component
This is a more detailed description of the commit. This can be as long
as is necessary to adequately describe the change.
A description may spawn multiple paragraphs if desired.
Jira Issue: https://gem5.atlassian.net/browse/GEM5-186
```
If you feel the need to change your commit, add the necessary files then
_amend_ the changes to the commit using:
```
git commit --amend
```
This will give you opportunity to edit the commit message.
## Pushing to Gerrit
Pushing to Gerrit will allow others in the gem5 project to review the change to
be fully merged into the gem5 source.
To start this process, execute:
```
git push origin HEAD:refs/for/develop
```
At this stage you may receive an error if you're not registered to contribute
to our Gerrit. To resolve this issue:
1. Create an account at <https://gem5-review.googlesource.com>.
2. Go to `User Settings`.
3. Select `Obtain password` (under `HTTP Credentials`).
4. A new tab shall open, explaining how to authenticate your machine to make
contributions to Gerrit. Follow these instructions and try pushing again.
Gerrit will amend your commit message with a `Change-ID`. Any commit pushed
to Gerrit with this `Change-ID` is assumed to be part of this change.
## Code review
Now, at <https://gem5-review.googlesource.com>, you can view the
change you have submitted (`Your` -> `Changes` -> `Outgoing reviews`). We
suggest that, at this stage, you mark the corresponding Jira issue
as `In Review`. Adding a link to the change on Gerrit as a comment to the
issue is also helpful.
Through the Gerrit portal we strongly advise you add reviewers.
Gerrit will automatically notify those you assign. The "maintainers" of the
components you have modified should be added as reviewers. These should
correspond to the tags you included in the commit header. **Please consult
[MAINTAINERS.yaml](
https://gem5.googlesource.com/public/gem5/+/refs/heads/stable/MAINTAINERS.yaml) to
see who maintains which component**. As an example, for a commit with a header
of `tests,arch : This is testing the arch component` then the maintainers for
both `tests` and `arch` should be included as reviewers.
Reviewers will then review this change. There are three scores which the commit
shall be evaluated: "Code-Review", "Maintainer", and "Verified".
Each reviewer can give a score from `-2` to `+2` to the "Code-Review" score,
where `+2` indicates the reviewer is 100% okay with the patch in its current
state and `-2` when the reviewer is certain they do not want the patch
merged in its current state.
Maintainers can add `+1` or `-1` to the "Maintainer" score. A `+1` score
indicates that the maintainer is okay with the patch.
When a Maintainer gives a `+1` our continuous integration system will process
the change. At the time of writing, the continuous integration system will run:
```
scons build/NULL/unittests.opt
cd tests
python main.py run
```
If this executes successfully (i.e. the project builds and the tests pass) the
continuous integration system will give a `+1` to the "Verifier" score, and a
`-1` if it did not execute successfully.
Gerrit will permit a commit to be merged if at least one reviewer has given a
`+2` to the "Reviewer" score, one maintainer has given a `+1` to the
"Maintainer" score, and the continuous integration system has given a `+1` to
the "Verifier" score.
For non-trivial changes, it is not unusual for a change to receive feedback
from reviewers that they will want incorporated before giving the commit a
score necessary for it to be merged. This leads to an iterative process.
### Making iterative improvements based on feedback
A reviewer will ask questions and post suggestions on Gerrit. You should read
these comments and answer these questions. **All communications between
reviewers and contributors should be done in a polite manner. Rude and/or
dismissive remarks will not be tolerated.**
When you understand what changes are required, using the same workspace as
before, make the necessary modifications to the gem5 repo, and amend the
changes to the commit:
```Shell
git commit --amend
```
Then push the new changes to Gerrit:
```Shell
git push origin HEAD:refs/for/develop
```
If for some reason you no longer have your original workspace, you may pull
the change by going to your change in Gerrit, clicking `Download` and executing
one of the listed commands.
When your new change is uploaded via the `git push` command, the reviewers will
re-review the change to ensure you have incorporated their suggested
improvements. The reviewers may suggest more improvements and, in this case,
you will have to incorporate them using the same process as above. **This
process is therefore iterative, and it may therefore take several cycles until
the patch is in a state in which the reviewers are happy**. Please do not
be deterred, it is very common for a change to require several iterations.
## Submit and merge
Once this iterative process is complete. The patch may be merged. This is done
via Gerrit (Simply click `Submit` within the relevant Gerrit page).
As one last step, you should change the corresponding Jira issue status to
`Done` then link the Gerrit page as a comment on Jira as to provide evidence
that the task has been completed.
Stable releases of gem5 are published three times per year. Therefore, a change
successfully submitted to the `develop` branch will be merged into the `stable`
branch within three to four months after submission.
## gem5 Bootcamp 2022
As part of [gem5's 2022 Bootcamp](/events/boot-camp-2022), contributing to gem5
was taught as a tutorial. Slides for this tutorial can be found [here](
https://ucdavis365-my.sharepoint.com/:p:/g/personal/jlowepower_ucdavis_edu/EQLtRAKI94JKjgk5pBmJtG8B3ssv9MaR0a2i92G0TwHK8Q?e=KN3NIppm2kg&action=embedview&wdbipreview=true).
A video recording of this tutorial can be found [here](
https://www.youtube.com/watch?v=T67wzFd1gVY).