Authors: | Merijn Verstraaten |
---|---|
Date: | 2014/11/22 |
So you have a pet peeve/bug/feature request that you'd like to see added to GHC. You made sure there was a Trac ticket for it, but despite your patient waiting no one is solving your problem. Those selfish GHC hackers!
What's an open source programmer like you supposed to do? Roll up your sleeves and get to work, of course! Now, I can already hear you say "I don't know how to get started hacking on GHC!". No worries, that's what this post is for!
So what do we need to start hacking GHC? If, like me, you're on OSX there's not a lot to do. You need the following:
- A working GHC and haskell build tools
- docbook-xsl, docbook-xml-4.2 & docbook-xml-4.5
I recommend just installing the Haskell platform to get #1 out of the way, this ensures you have alex, happy and whatever else I may be forgetting. You need #2 to build the docs (you were planning to document you work, right?). You can grab them from your favourite package manager. That's it for OSX users, you can skip to the next section.
I generally don't use linux, so until someone who does fills me in, this section only includes the bits I just happen to know. At the very least you will need to have all the following available:
- Working GHC and build tools
- libgmp
- docbook-xsl, docbook-xml-4.2 & docbook-xml-4.5
- php5-cli & php5-curl
First check out the GHC sources and bootstrap libraries:
git clone --recursive git://git.haskell.org/ghc.git
Since you won't be able to push changes here, you may want to fork the GHC GitHub mirror and add it as default push target:
git remote add merijn [email protected]:merijn/ghc.git git remote set-url --push origin [email protected]:merijn/ghc.git git checkout -b merijn/master origin/master
Set up a Phabricator account on https://phabricator.haskell.org/. You can browse around and review other people's changes to get a feel for the source and explore the interface. Once you're done playing around it's time to set up arcanist for our GHC checkout.
Clone the following repositories somewhere:
git clone https://github.com/phacility/libphutil.git git clone https://github.com/phacility/arcanist.git
Add the arcanist/bin
directory your PATH
and we're ready to move on.
Switch to the directory containing your GHC check out and run:
arc install-certificate
This will prompt you to a Phabricator URL, copy a token, and paste it into the arcanist command line prompt. Once this is done arcanist is configured for the GHC Phabricator instance and we can get to the fun part!
First we need to setup all the relevant build directories and run the configure script:
perl boot ./configure --prefix=$HOME/ghc-head cp mk/build.mk.sample mk/build.mk
The --prefix
flag, as usual, specifies the directory where GHC should be
installed. To finish up this step, open up mk/build.mk
in your favourite
editor and uncomment BuildFlavour = quick
on line 21.
To test everything works, and because we like wasting CPU cycles let's test if it builds:
make -j
Your shiny new compiler is now inplace/ghc-stage2
, or you can run make
install
to have the compiler installed under your selected --prefix
. If
you make a few small changes to only the compiler and only want to rebuild the
last stage of the compiler, simply use:
cd ghc make stage=2
With all that out of the way, we can finally get to hacking!
After hours of reckless hacking, frustration, grepping the GHC tree, and wrestling with Haskell your patch finally works. Hurray! Time to hit the bar and party!
Well, not quite yet, you should probably add some tests and verify you didn't
break anything. You can find tests hiding under testsuite/tests
in the tree
and in the tests
folder of the various libraries. You can use make test
or the slightly more convenient validate
script to run them. However, if
you're lazy and don't want to burden your own CPU, we can offload those to
Phabricator, so we'll skip running them for now.
To add your own tests to the test suite, choose a suitable category/directory
under testsuite/tests
and create a haskell file containing your test. The
existing naming convention names the tests after the associated Trac ticket, so
T8089 is a test corresponding to Trac ticket 8089. Every folder with tests
contains an all.T
file, listing the tests in the folder. A minimal entry in
all.T
looks like:
test('T8089', normal, compile, [''])
This entry corresponds to haskell source file named T8089.hs, which is compiled
in the normal
configuration. The test succeeds if the compilation succeeds
with no errors. The empty list specifies that the test requires no flags during
compilation. Besides compile
There are two other common categories of
tests. These are compile_fail
and compile_and_run
, the former expecting
compilation to fail and the latter expecting the produced binary to run and
exit with a 0 exit status.
Additionally each test can have an option T8089.stdin
, T8089.stdout
,
and T8089.stderr
file. If these files exist, the output of the test will be
compared with the stored output. While we were too lazy to run the entire test
suite, we should probably check that at least our new test(s) work correctly
and pass! To run all variations of a single test, change to the
testsuite/tests
directory and run:
make TEST=T8089
If you forgot to add the proper stdin/stdout/stderr output for your test, or, if you were simply to lazy to add these files, the test suite will complain that the test failed due to a mismatch between stored and produced output. Fortunately, if we already checked the test output is correct, we have a convenient way to update the stored output:
make accept TEST=T8089
This will create the appropriate stdin/stdout/stderr files with the tests current output.
Patch done. Tests done. Finally done, right? Wrong! You weren't going to forget
updating the documentation to explain your changes, right? That's why I told
you to install docbook in the first place. You will find the user's guide under
docs/users_guide
. The most important files to update are: flags.xml
,
using.xml
and glasgow_exts.xml
. These files cover, GHC's command line
flag reference, how to use different flags, and GHC specific extensions to
Haskell.
Whew! Now it's time to get our new patch reviewed and check we didn't break anything else. For simplicity's sake I'll assume a patch consisting of a single commit for out interaction with Arcanist. First, commit the changes and tests. Don't bother specifying a long commit message, we'll deal with that in Arcanist:
git commit -sm "A short summary of the commit."
Note the use of -s
to add a sign-off to the commit. Now that we have our
commit ready to go, it's time to put a differential on phabricator so that it
can be reviewed. If you are developing on a branch other than master
(which
you probably should be!), simply run:
arc diff
If you were developing on master and your changes are just a single commit, you can use the following:
arc diff HEAD^
If you run into more complex scenarios, just shoot an email to ghc-devs@ or ask on #ghc.
Arcanist will now turn the last commit on our branch into a differential. First it will prompt to ask whether you want to amend any untracked files to your commit, double check you're not missing anything. Next Arcanist drops you into an editor with the differential template and your commit message:
<Your commit message> Summary: Test Plan: Reviewers: Subscribers: GHC Trac Issues:
You should write the long form summary of your commit/changes in the
summary field. Set the test plan should be set to validate
, add austin
after reviewers, and update. Don't worry too much, these things can be updated
later. You can leave the subscribers field empty, the GHC Trac Issues field
should be set to all relevant Trac issues. For example, to add Trac issue
8089:
GHC Trac Issues: #8089
When you save and exit, Arcanist will lint your code and yell at you if you
violate the style rules. If it complains, fix any problems, run git commit
--amend
to update your commit, and rerun arc diff HEAD^
. You have now
successfully opened a differential for review on Phabricator. You can go
explore it in your browser and ask people in the #ghc channel on FreeNode to review it and
comment.
Phabricator will automatically kick off a build and validate run of your patch. You can check whether your patch passes the test suite online via a link on your differential. If the validate run fails you'll get an email and you'll be able to check the tests output from the differential page.
After people have reviewed the patch and commented on the code, you probably
want to revise your patch to accommodate the feedback. Simply make whatever
changes are necessary, run git commit --amend
to update your commit and
rerun arc diff HEAD^
to update the differential. Any subscribed people and
reviewers will be notified of your changes since the last comment. When, after
several iterations, both you and the reviewers are happy with your commit and
the test suite passes, you are finally done. One of the GHC committers will at
some point (if you prod them enough) grab your patch, land it, and push it out
to the GHC master branch. Congratulations, you are now a GHC contributor!.
If you have any more advanced questions about GHC development, want to do more complicated tests, or simply have some questions about some GHC code, don't hesitate to contact other developers:
Additionally, the following wiki pages may contain helpful information to supplement this quick start guide: