A beginners guide to contributing
This document serves as a beginners guide to contributing to gem5. If questions arise while following this guide, we advise consulting 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:
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:
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
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 style guide is outlined here.
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:
#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;
}
}
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:
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:
scons build/NULL/unittests.opt
To compile an individual gem5 binary:
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
:
scons build/X86/gem5.opt
Committing
When you feel your change is done, you may commit. Start by adding the changed files:
git add <changed files>
Then commit using:
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.md 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:
- Create an account at https://gem5-review.googlesource.com.
- Go to
User Settings
. - Select
Obtain password
(underHTTP Credentials
). - 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.md 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:
git commit --amend
Then push the new changes to Gerrit:
git push original 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.