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