Merge pull request #999 from colincross/dumbstatus
[platform/upstream/ninja.git] / HACKING.md
1 ## Basic overview
2
3 `./configure.py` generates the `build.ninja` files used to build
4 ninja.  It accepts various flags to adjust build parameters.
5 Run './configure.py --help' for more configuration options.
6
7 The primary build target of interest is `ninja`, but when hacking on
8 Ninja your changes should be testable so it's more useful to build and
9 run `ninja_test` when developing.
10
11 ### Bootstrapping
12
13 Ninja is built using itself.  To bootstrap the first binary, run the
14 configure script as `./configure.py --bootstrap`.  This first compiles
15 all non-test source files together, then re-builds Ninja using itself.
16 You should end up with a `ninja` binary (or `ninja.exe`) in the source root.
17
18 #### Windows
19
20 On Windows, you'll need to install Python to run `configure.py`, and
21 run everything under a Visual Studio Tools Command Prompt (or after
22 running `vcvarsall` in a normal command prompt).  See below if you
23 want to use mingw or some other compiler instead using Visual Studio.
24
25 ### Adjusting build flags
26
27 Build in "debug" mode while developing (disables optimizations and builds
28 way faster on Windows):
29
30     ./configure.py --debug
31
32 To use clang, set `CXX`:
33
34     CXX=clang++ ./configure.py
35
36 ## How to successfully make changes to Ninja
37
38 Github pull requests are convenient for me to merge (I can just click
39 a button and it's all handled server-side), but I'm also comfortable
40 accepting pre-github git patches (via `send-email` etc.).
41
42 Good pull requests have all of these attributes:
43
44 * Are scoped to one specific issue
45 * Include a test to demonstrate their correctness
46 * Update the docs where relevant
47 * Match the Ninja coding style (see below)
48 * Don't include a mess of "oops, fix typo" commits
49
50 These are typically merged without hesitation.  If a change is lacking
51 any of the above I usually will ask you to fix it, though there are
52 obvious exceptions (fixing typos in comments don't need tests).
53
54 I am very wary of changes that increase the complexity of Ninja (in
55 particular, new build file syntax or command-line flags) or increase
56 the maintenance burden of Ninja.  Ninja is already successfully used
57 by hundreds of developers for large projects and it already achieves
58 (most of) the goals I set out for it to do.  It's probably best to
59 discuss new feature ideas on the mailing list before I shoot down your
60 patch.
61
62 ## Testing
63
64 ### Test-driven development
65
66 Set your build command to
67
68     ./ninja ninja_test && ./ninja_test --gtest_filter=MyTest.Name
69
70 now you can repeatedly run that while developing until the tests pass
71 (I frequently set it as my compilation command in Emacs).  Remember to
72 build "all" before committing to verify the other source still works!
73
74 ## Testing performance impact of changes
75
76 If you have a Chrome build handy, it's a good test case.  Otherwise,
77 [the github downoads page](https://github.com/ninja-build/ninja/releases)
78 has a copy of the Chrome build files (and depfiles). You can untar
79 that, then run
80
81     path/to/my/ninja chrome
82
83 and compare that against a baseline Ninja.
84
85 There's a script at `misc/measure.py` that repeatedly runs a command like
86 the above (to address variance) and summarizes its runtime.  E.g.
87
88     path/to/misc/measure.py path/to/my/ninja chrome
89
90 For changing the depfile parser, you can also build `parser_perftest`
91 and run that directly on some representative input files.
92
93 ## Coding guidelines
94
95 Generally it's the [Google C++ coding style][], but in brief:
96
97 * Function name are camelcase.
98 * Member methods are camelcase, expect for trivial getters which are
99   underscore separated.
100 * Local variables are underscore separated.
101 * Member variables are underscore separated and suffixed by an extra
102   underscore.
103 * Two spaces indentation.
104 * Opening braces is at the end of line.
105 * Lines are 80 columns maximum.
106 * All source files should have the Google Inc. license header.
107
108 [Google C++ coding style]: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
109
110 ## Documentation
111
112 ### Style guidelines
113
114 * Use `///` for doxygen.
115 * Use `\a` to refer to arguments.
116 * It's not necessary to document each argument, especially when they're
117   relatively self-evident (e.g. in `CanonicalizePath(string* path, string* err)`,
118   the arguments are hopefully obvious)
119
120 ### Building the manual
121
122     sudo apt-get install asciidoc --no-install-recommends
123     ./ninja manual
124
125 ### Building the code documentation
126
127     sudo apt-get install doxygen
128     ./ninja doxygen
129
130 ## Building for Windows
131
132 While developing, it's helpful to copy `ninja.exe` to another name like
133 `n.exe`; otherwise, rebuilds will be unable to write `ninja.exe` because
134 it's locked while in use.
135
136 ### Via Visual Studio
137
138 * Install Visual Studio (Express is fine), [Python for Windows][],
139   and (if making changes) googletest (see above instructions)
140 * In a Visual Studio command prompt: `python configure.py --bootstrap`
141
142 [Python for Windows]: http://www.python.org/getit/windows/
143
144 ### Via mingw on Windows (not well supported)
145
146 * Install mingw, msys, and python
147 * In the mingw shell, put Python in your path, and
148   `python configure.py --bootstrap`
149 * To reconfigure, run `python configure.py`
150 * Remember to strip the resulting executable if size matters to you
151
152 ### Via mingw on Linux (not well supported)
153
154 Setup on Ubuntu Lucid:
155 * `sudo apt-get install gcc-mingw32 wine`
156 * `export CC=i586-mingw32msvc-cc CXX=i586-mingw32msvc-c++ AR=i586-mingw32msvc-ar`
157
158 Setup on Ubuntu Precise:
159 * `sudo apt-get install gcc-mingw-w64-i686 g++-mingw-w64-i686 wine`
160 * `export CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ AR=i686-w64-mingw32-ar`
161
162 Setup on Arch:
163 * Uncomment the `[multilib]` section of `/etc/pacman.conf` and `sudo pacman -Sy`.
164 * `sudo pacman -S mingw-w64-gcc wine`
165 * `export CC=x86_64-w64-mingw32-cc CXX=x86_64-w64-mingw32-c++ AR=x86_64-w64-mingw32-ar`
166 * `export CFLAGS=-I/usr/x86_64-w64-mingw32/include`
167
168 Then run:
169 * `./configure.py --platform=mingw --host=linux`
170 * Build `ninja.exe` using a Linux ninja binary: `/path/to/linux/ninja`
171 * Run: `./ninja.exe`  (implicitly runs through wine(!))
172
173 ### Using Microsoft compilers on Linux (extremely flaky)
174
175 The trick is to install just the compilers, and not all of Visual Studio,
176 by following [these instructions][win7sdk].
177
178 [win7sdk]: http://www.kegel.com/wine/cl-howto-win7sdk.html
179
180 ### Using gcov
181
182 Do a clean debug build with the right flags:
183
184     CFLAGS=-coverage LDFLAGS=-coverage ./configure.py --debug
185     ninja -t clean ninja_test && ninja ninja_test
186
187 Run the test binary to generate `.gcda` and `.gcno` files in the build
188 directory, then run gcov on the .o files to generate `.gcov` files in the
189 root directory:
190
191     ./ninja_test
192     gcov build/*.o
193
194 Look at the generated `.gcov` files directly, or use your favorite gcov viewer.
195
196 ### Using afl-fuzz
197
198 Build with afl-clang++:
199
200     CXX=path/to/afl-1.20b/afl-clang++ ./configure.py
201     ninja
202
203 Then run afl-fuzz like so:
204
205     afl-fuzz -i misc/afl-fuzz -o /tmp/afl-fuzz-out ./ninja -n -f @@
206
207 You can pass `-x misc/afl-fuzz-tokens` to use the token dictionary. In my
208 testing, that did not seem more effective though.
209
210 #### Using afl-fuzz with asan
211
212 If you want to use asan (the `isysroot` bit is only needed on OS X; if clang
213 can't find C++ standard headers make sure your LLVM checkout includes a libc++
214 checkout and has libc++ installed in the build directory):
215
216     CFLAGS="-fsanitize=address -isysroot $(xcrun -show-sdk-path)" \
217         LDFLAGS=-fsanitize=address CXX=path/to/afl-1.20b/afl-clang++ \
218         ./configure.py
219     AFL_CXX=path/to/clang++ ninja
220
221 Make sure ninja can find the asan runtime:
222
223     DYLD_LIBRARY_PATH=path/to//lib/clang/3.7.0/lib/darwin/ \
224         afl-fuzz -i misc/afl-fuzz -o /tmp/afl-fuzz-out ./ninja -n -f @@