3ccc65e6862ca7ec92f8967dd8903ec37b7c2a5d
[platform/upstream/connectedhomeip.git] / docs / BUILDING.md
1 ## Build Documentation
2
3 CHIP supports configuring the build with [GN](https://gn.googlesource.com/gn/),
4 a fast and scalable meta-build system that generates inputs to
5 [ninja](https://ninja-build.org/).
6
7 Tested on:
8
9 -   macOS 10.15
10 -   Debian 10
11 -   Ubuntu 20.04 LTS
12
13 Build system features:
14
15 -   Very fast and small footprint
16 -   Cross-platform handling: (Linux, Darwin, embedded arm, etc.)
17 -   Multiple toolchains & cross toolchain dependencies
18 -   Integrates automated testing framework: `ninja check`
19 -   Introspection: `gn desc`
20 -   Automatic formatting: `gn format`
21
22 ### Checking out the Code
23
24 To check out the CHIP repostiory:
25
26 ```
27 git clone --recurse-submodules git@github.com:project-chip/connectedhomeip.git
28 ```
29
30 If you already have a checkout, run the following command to sync submodules:
31
32 ```
33 git submodule update --init
34 ```
35
36 ### Prerequisites
37
38 Before building, you'll need to install a few OS specific dependencies.
39
40 #### How to install prerequisites on Linux
41
42 On Debian-based Linux distributions such as Ubuntu, these dependencies can be
43 satisfied with the following:
44
45 ```
46 sudo apt-get install git gcc g++ python pkg-config libssl-dev libdbus-1-dev libglib2.0-dev libavahi-client-dev ninja-build python3-venv python3-dev unzip
47 ```
48
49 #### How to install prerequisites on macOS
50
51 On macOS, first install Xcode from the Mac App Store. The remaining dependencies
52 can be installed and satisfied using [Brew](https://brew.sh/):
53
54 ```
55 brew install openssl pkg-config
56 ```
57
58 However, that does not expose the package to `pkg-config`. To fix that, one
59 needs to run something like the following:
60
61 ```
62 cd /usr/local/lib/pkgconfig
63 ln -s ../../Cellar/openssl@1.1/1.1.1g/lib/pkgconfig/* .
64 ```
65
66 where `openssl@1.1/1.1.1g` may need to be replaced with the actual version of
67 OpenSSL installed by Brew.
68
69 Note: If using MacPorts, `port install openssl` is sufficient to satisfy this
70 dependency.
71
72 #### How to install prerequisites on Raspberry Pi 4
73
74 Using `rpi-imager`, install the Ubuntu _20.10_ LTS 64-bit _server_ OS for arm64
75 architectures on a micro SD card. This release will have bluez 5.55 which is
76 required for BLE functionality.
77
78 Boot the SD card, login with the default user account "ubuntu" and password
79 "ubuntu", then proceed with "How to install prerequisites on Linux".
80
81 Finally, install some Raspberry Pi specific dependencies:
82
83 ```
84 sudo apt-get install pi-bluetooth
85 ```
86
87 You need to reboot your RPi after install `pi-bluetooth`.
88
89 ### Build Preparation
90
91 Before running any other build command, the `scripts/activate.sh` environment
92 setup script should be sourced at the top level. This script takes care of
93 downloading GN, ninja, and setting up a Python environment with libraries used
94 to build and test.
95
96 ```
97 source scripts/activate.sh
98 ```
99
100 If this script says the environment is out of date, it can be updated by
101 running:
102
103 ```
104 source scripts/bootstrap.sh
105 ```
106
107 The `scripts/bootstrap.sh` script re-creates the environment from scratch, which
108 is expensive, so avoid running it unless the environment is out of date.
109
110 ### Build for the Host OS (Linux or macOS)
111
112 This will build all sources, libraries, and tests for the host platform:
113
114 ```
115 source scripts/activate.sh
116
117 gn gen out/host
118
119 ninja -C out/host
120 ```
121
122 This generates a configuration suitable for debugging. To configure an optimized
123 build, specify `is_debug=false`:
124
125 ```
126 gn gen out/host --args='is_debug=false'
127
128 ninja -C out/host
129 ```
130
131 The directory name `out/host` can be any directory, although it's conventional
132 to build within the `out` directory. This example uses `host` to emphasize that
133 we're building for the host system. Different build directories can be used for
134 different configurations, or a single directory can be used and reconfigured as
135 necessary via `gn args`.
136
137 To run all tests, run:
138
139 ```
140 ninja -C out/host check
141 ```
142
143 To run only the tests in src/inet/tests, you can run:
144
145 ```
146 ninja -C out/host src/inet/tests:tests_run
147 ```
148
149 Note that the build system caches passing tests, so if you see
150
151 ```
152 ninja: no work to do
153 ```
154
155 that means that the tests passed in a previous build.
156
157 ### Build Custom configuration
158
159 The build is configured by setting build arguments. These are set by passing the
160 `--args` option to `gn gen`, by running `gn args` on the output directory, or by
161 hand editing `args.gn` in the output directory. To configure a new build or edit
162 the arguments to existing build, run:
163
164 ```
165 source scripts/activate.sh
166
167 gn args out/custom
168
169 ninja -C out/custom
170 ```
171
172 Two key builtin build arguments are `target_os` and `target_cpu`, which control
173 the OS & CPU of the build.
174
175 To see help for all available build arguments:
176
177 ```
178 gn gen out/custom
179 gn args --list out/custom
180 ```
181
182 ### Build Examples
183
184 Examples can be built in two ways, as separate projects that add CHIP in the
185 third_party directory, or in the top level CHIP project.
186
187 To build the `chip-shell` example as a separate project:
188
189 ```
190 cd examples/shell
191 gn gen out/debug
192 ninja -C out/debug
193 ```
194
195 To build it at the top level, see below under "Unified Builds".
196
197 ### Unified Builds
198
199 To build a unified configuration that approximates the set of continuous builds:
200
201 ```
202 source scripts/activate.sh
203
204 gn gen out/unified --args='is_debug=true target_os="all"'
205
206 ninja -C out/unified all
207 ```
208
209 This can be used prior to change submission to configure, build, and test the
210 gcc, clang, mbedtls, & examples configurations all together in one parallel
211 build. Each configuration has a separate subdirectory in the output dir.
212
213 This unified build can be used for day to day development, although it's more
214 expensive to build everything for every edit. To save time, you can name the
215 configuration to build:
216
217 ```
218 ninja -C out/unified host_gcc
219 ninja -C out/unified check_host_gcc
220 ```
221
222 Replace `host_gcc` with the name of the configuration, which is found in the
223 root `BUILD.gn`.
224
225 You can also fine tune the configurations generated via arguments such as:
226
227 ```
228 gn gen out/unified --args='is_debug=true target_os="all" enable_host_clang_build=false'
229 ```
230
231 For a full list, see the root `BUILD.gn`.
232
233 Note that in the unified build, targets have multiple instances and need to be
234 disambiguated by adding a `(toolchain)` suffix. Use `gn ls out/debug` to list
235 all of the target instances. For example:
236
237 ```
238 gn desc out/unified '//src/controller(//build/toolchain/host:linux_x64_clang)'
239 ```
240
241 Note: Some platforms that can be build as part of the unified build require
242 downloading additional SDKs. To add these to the build, the location of the SDK
243 installation must be provided as a build argument. For example, to add the
244 Simplelink cc13x2_26x2 examples to the unified build, install the
245 [SDK](https://ti.com/chip_sdk) and add the following build arguments:
246
247 ```
248 gn gen out/unified --args="target_os=\"all\" enable_ti_simplelink_builds=true ti_simplelink_sdk_root=\"/path/to/sdk\" ti_sysconfig_root=\"/path/to/sysconfig\""
249 ```
250
251 ### Getting Help
252
253 GN has builtin help via
254
255 ```
256 gn help
257 ```
258
259 Recommended topics:
260
261 ```
262 gn help execution
263 gn help grammar
264 gn help toolchain
265 ```
266
267 Also see the
268 [quick start guide](https://gn.googlesource.com/gn/+/master/docs/quick_start.md).
269
270 ### Introspection
271
272 GN has various introspection tools to help examine the build configuration.
273
274 To show all of the targets in an output directory:
275
276 ```
277 gn ls out/host
278 ```
279
280 To show all of the files that will be built:
281
282 ```
283 gn outputs out/host '*'
284 ```
285
286 To show the GN representation of a configured target:
287
288 ```
289 gn desc out/host //src/inet --all
290 ```
291
292 To dump the GN representation of the entire build as JSON:
293
294 ```
295 gn desc out/host/ '*' --all --format=json
296 ```
297
298 To show the dependency tree:
299
300 ```
301 gn desc out/host //:all deps --tree --all
302 ```
303
304 To find dependency paths:
305
306 ```
307 gn path out/host //src/transport/tests:tests //src/system
308 ```
309
310 To list useful information for linking against libCHIP:
311
312 ```
313 gn desc out/host //src/lib include_dirs
314 gn desc out/host //src/lib defines
315 gn desc out/host //src/lib outputs
316
317 # everything as JSON
318 gn desc out/host //src/lib --format=json
319 ```
320
321 ## Maintaining CHIP
322
323 If you make any change to the GN build system, the next build will regenerate
324 the ninja files automatically. No need to do anything.