xref: /aosp_15_r20/external/pigweed/docs/get_started/upstream.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1.. _docs-get-started-upstream:
2
3=============================================
4Get started with upstream Pigweed development
5=============================================
6This guide will walk you through the typical upstream development workflow.
7"Upstream development" means that you're contributing to the main Pigweed
8repository, ``https://pigweed.googlesource.com/pigweed/pigweed``. See
9:ref:`docs-get-started` if you're looking for instructions on how to use
10Pigweed in your own project.
11
12.. _prerequisites:
13
14Prerequisites
15=============
16If you haven't already, :ref:`docs-first-time-setup`.
17
18-------------
19Express setup
20-------------
21If you'd like to skip the detailed explanations, below is the shorter version
22of getting setup for Pigweed. If you run into trouble, ensure you've followed
23all the steps to :ref:`docs-first-time-setup`. The express setup
24configures Pigweed's watcher for three targets to give a taste of Pigweed:
25
26#. **Host** - Mac, Linux, or Windows. Builds and runs tests
27#. **Device/STM32F429** - Build only; Optionally, the STM32F429I-DISC1 kit to
28   follow along later in the guide to run tests directly on said device(s)
29#. **Docs** - Builds the Pigweed docs
30
31To get setup:
32
33#. Make sure you have Git and Python installed and on your path.
34
35#. Clone Pigweed and bootstrap the environment (compiler setup & more). **Be
36   patient, this step downloads ~1GB of LLVM, GCC, and other tooling**.
37
38   .. code-block:: bash
39
40      $ cd ~
41      $ git clone https://pigweed.googlesource.com/pigweed/pigweed
42      ...
43      $ cd pigweed
44      $ source ./bootstrap.sh (On Linux & Mac)
45      $ bootstrap.bat         (On Windows)
46      ...
47
48   .. tip::
49
50      If you use the `Fish shell <https://fishshell.com/>`_ run `source
51      ./bootstrap.fish` instead.
52
53#. Configure the GN build.
54
55   .. code-block:: bash
56
57      $ gn gen out
58      Done. Made 1047 targets from 91 files in 114ms
59
60#. Start the watcher. The watcher will invoke Ninja to build all the targets
61
62   .. code-block:: bash
63
64      $ pw watch
65
66       ▒█████▄   █▓  ▄███▒  ▒█    ▒█ ░▓████▒ ░▓████▒ ▒▓████▄
67        ▒█░  █░ ░█▒ ██▒ ▀█▒ ▒█░ █ ▒█  ▒█   ▀  ▒█   ▀  ▒█  ▀█▌
68        ▒█▄▄▄█░ ░█▒ █▓░ ▄▄░ ▒█░ █ ▒█  ▒███    ▒███    ░█   █▌
69        ▒█▀     ░█░ ▓█   █▓ ░█░ █ ▒█  ▒█   ▄  ▒█   ▄  ░█  ▄█▌
70        ▒█      ░█░ ░▓███▀   ▒█▓▀▓█░ ░▓████▒ ░▓████▒ ▒▓████▀
71
72      20200707 17:24:06 INF Starting Pigweed build watcher
73      20200707 17:24:06 INF Will build [1/1]: out
74      20200707 17:24:06 INF Attaching filesystem watcher to $HOME/wrk/pigweed/...
75      20200707 17:24:06 INF Triggering initial build...
76      ...
77
78#. **Congratulations, you're ready to go!** Now take Pigweed for a spin by
79   making a test fail.
80
81#. With the watcher running in a separate window, edit
82   ``pw_status/status_test.cc`` to make an expectation fail; for example, add
83   ``EXPECT_EQ(0, 1);`` in a test.
84
85#. Save the file. Observe the watcher rebuild & retest, and fail. Restore the
86   test if you feel like it.
87
88#. Open the generated docs in ``out/docs/gen/docs/html/index.html`` in your
89   browser.
90
91#. Edit ``docs/getting_started.rst`` (this file!) and make any change. Save.
92   See the watcher rebuild the docs. Reload your browser, and see the changes.
93
94See below for equivalent Windows commands, and for more details on what each
95part does.
96
97**Note:** After running bootstrap once, use ``source ./activate.sh`` (or
98``activate.bat`` on Windows) to re-activate the environment without
99re-bootstrapping.
100
101---------
102Bootstrap
103---------
104Once you satisfied the prerequisites, you will be able to clone Pigweed and
105run the bootstrap that initializes the Pigweed virtual environment. The
106bootstrap may take several minutes to complete, so please be patient.
107
108**Linux & macOS**
109
110.. code-block:: bash
111
112   $ git clone https://pigweed.googlesource.com/pigweed/pigweed pigweed
113   $ cd pigweed
114   $ source ./bootstrap.sh
115
116**Windows**
117
118.. code-block:: batch
119
120   :: Run git commands from the shell you set up to use with Git during install.
121   > git clone https://pigweed.googlesource.com/pigweed/pigweed %HOMEPATH%\pigweed
122   > cd %HOMEPATH%\pigweed
123   > bootstrap.bat
124
125Below is a real-time demo with roughly what you should expect to see as output:
126
127.. image:: https://storage.googleapis.com/pigweed-media/pw_env_setup_demo.gif
128  :width: 800
129  :alt: build example using pw watch
130
131Congratulations, you are now set up to start using Pigweed!
132
133.. _activate-pigweed-environment:
134
135---------------------------------
136Activate your Pigweed environment
137---------------------------------
138After going through the initial setup process, your current terminal will be in
139the Pigweed development environment that provides all the tools you should need
140to develop on Pigweed. If you leave that session, you can activate the
141environment in a new session with the following command:
142
143**Linux & macOS**
144
145.. code-block:: bash
146
147   $ source ./activate.sh
148
149**Windows**
150
151.. code-block:: batch
152
153   > activate.bat
154
155Some major changes may require triggering the bootstrap again, so if you run
156into host tooling changes after a pull it may be worth re-running bootstrap.
157
158----------------------
159Build Pigweed for host
160----------------------
161Pigweed's primary build system is GN/Ninja based. There are CMake and Bazel
162builds in-development, but they are incomplete and don't have feature parity
163with the GN build. We strongly recommend you stick to the GN build system.
164
165GN (Generate Ninja) just does what it says on the tin; GN generates
166`Ninja <https://ninja-build.org/>`_ build files.
167
168The default GN configuration generates build files that allow you to build host
169binaries, device binaries, and upstream documentation all in one Ninja
170invocation.
171
172Run GN as seen below:
173
174.. code-block:: bash
175
176   $ gn gen out
177
178.. note::
179  ``out`` is simply the directory the build files are saved to. Unless
180  this directory is deleted or you desire to do a clean build, there's no need
181  to run GN again; just rebuild using Ninja directly.
182
183.. warning::
184  Unless your build directory (the ``out`` in ``gn gen out``) is exactly one
185  directory away from the project root directory (the Pigweed repo root in this
186  case), there will be issues finding source files while debugging and while
187  generating coverage reports. This is due an issue in upstream LLVM reordering
188  debug and coverage path mappings (tracked by
189  `b/278898014 <https://issuetracker.google.com/278898014>`_ and
190  `b/278906020 <https://issuetracker.google.com/278906020>`_). **Stick to
191  simple, single directory build directories for now.**
192
193Now that we have build files, it's time to build Pigweed!
194
195Now you *could* manually invoke the host build using ``ninja -C out`` every
196time you make a change, but that's tedious. Instead, let's use ``pw_watch``.
197
198Go ahead and start ``pw_watch``:
199
200.. code-block:: bash
201
202   $ pw watch
203
204When ``pw_watch`` starts up, it will automatically build the directory we
205generated in ``out``. Additionally, ``pw_watch`` watches source code files for
206changes, and triggers a Ninja build whenever it notices a file has been saved.
207You might be surprised how much time it can save you!
208
209With ``pw watch`` running, try modifying
210``pw_status/public/pw_status/status.h`` and watch the build re-trigger when you
211save the file.
212
213See below for a demo of this in action:
214
215.. image:: https://storage.googleapis.com/pigweed-media/pw_watch_build_demo.gif
216  :width: 800
217  :alt: build example using pw watch
218
219------------------
220Running unit tests
221------------------
222Fun fact, you've been running the unit tests already! Ninja builds targeting
223the host automatically build and run the unit tests. Unit tests err on the side
224of being quiet in the success case, and only output test results when there's a
225failure.
226
227To see a test failure, modify ``pw_status/status_test.cc`` to fail by changing
228one of the strings in the "KnownString" test.
229
230.. image:: https://storage.googleapis.com/pigweed-media/pw_watch_test_demo.gif
231  :width: 800
232  :alt: example test failure using pw watch
233
234Running tests as part of the build isn't particularly expensive because GN
235caches passing tests. Each time you build, only the tests that are affected
236(whether directly or transitively) by the code changes since the last build
237will be re-built and re-run.
238
239Try running the ``pw_status`` test manually:
240
241.. code-block:: bash
242
243   $ ./out/pw_strict_host_{clang,gcc}_debug/obj/pw_status/test/status_test
244
245Depending on your host OS, the compiler will default to either ``clang`` or
246``gcc``.
247
248---------------------
249Building for a device
250---------------------
251A Pigweed "target" is a build configuration that includes a toolchain, default
252library configurations, and more to result in binaries that run natively on the
253target. With the default build invocation, you're already building for a device
254target (the STMicroelectronics STM32F429I-DISC1) in parallel with the host
255build!
256
257If you want to build JUST for the device, you can kick of watch with:
258
259.. code-block:: bash
260
261   $ pw watch stm32f429i
262
263This is equivalent to the following Ninja invocation:
264
265.. code-block:: bash
266
267   $ ninja -C out stm32f429i
268
269-------------------------
270Running tests on a device
271-------------------------
272While tests run automatically on the host, it takes a few more steps to get
273tests to run automatically on a device, too. Even though we've verified tests
274pass on the host, it's crucial to verify the same with on-device testing. We've
275encountered some unexpected bugs that can only be found by running the unit
276tests directly on the device.
277
2781. Connect device(s)
279====================
280Connect any number of STM32F429I-DISC1 boards to your computer using the mini
281USB port on the board (**not** the micro USB). Pigweed will automatically
282detect the boards and distribute the tests across the devices. More boards =
283faster tests! Keep in mind that you may have to make some environment specific
284updates to ensure you have permissions to use the USB device. For example, on
285Linux you may need to update your udev rules and ensure you're in the plugdev
286and dialout groups.
287
288.. image:: https://storage.googleapis.com/pigweed-media/stm32f429i-disc1_connected.jpg
289  :width: 800
290  :alt: development boards connected via USB
291
2922. Launch test server
293=====================
294To allow Ninja to run tests on an arbitrary number of devices, Ninja will send
295test requests to a server running in the background. Launch the server in
296another window using the command below (remember, you'll need to activate the
297Pigweed environment first).
298
299.. code-block:: bash
300
301   $ stm32f429i_disc1_test_server
302
303**Note:** If you attach or detach any more boards to your workstation you'll
304need to relaunch this server.
305
3063. Configure GN
307===============
308Tell GN to use the testing server by enabling a build arg specific to the
309stm32f429i-disc1 target.
310
311.. code-block:: bash
312
313   $ gn args out
314   # Append this line to the file that opens in your editor to tell GN to run
315   # on-device unit tests.
316   pw_use_test_server = true
317
318Done!
319=====
320Whenever you make code changes and trigger a build, all the affected unit tests
321will be run across the attached boards!
322
323See the demo below for an example of what this all looks like put together:
324
325.. image:: https://storage.googleapis.com/pigweed-media/pw_watch_on_device_demo.gif
326  :width: 800
327  :alt: pw watch running on-device tests
328
329--------------------------
330Building the documentation
331--------------------------
332In addition to the markdown documentation, Pigweed has a collection of
333information-rich RST files that are used to generate HTML documentation. All
334the docs are hosted at https://pigweed.dev/, and are built as a part of the
335default build invocation. This makes it easier to make changes and see how they
336turn out. Once built, you can find the rendered HTML documentation at
337``out/docs/gen/docs/html``.
338
339You can explicitly build just the documentation with the command below.
340
341.. code-block:: bash
342
343   $ ninja -C out docs
344
345This concludes the introduction to developing for upstream Pigweed.
346
347---------------------------
348Building tests individually
349---------------------------
350Sometimes it's faster to incrementally build a single test target rather than
351waiting for the whole world to build and all tests to run. GN has a built-in
352tool, ``gn outputs``, that will translate a GN build step into a Ninja build
353step. In order to build and run the right test, it's important to explicitly
354specify which target to build the test under (e.g. host, SM32F529I-DISC1).
355This can be done by appending the GN path to the target toolchain in parenthesis
356after the desired GN build step label as seen in the example below.
357
358.. code-block:: none
359
360   $ gn outputs out "//pw_status:status_test.run(//targets/host/pigweed_internal:pw_strict_host_clang_debug)"
361   pw_strict_host_clang_debug/obj/pw_status/status_test.run.pw_pystamp
362
363   $ ninja -C out pw_strict_host_clang_debug/obj/pw_status/status_test.run.pw_pystamp
364   ninja: Entering directory `out'
365   [4/4] ACTION //pw_status:status_test.run(//targets/host/pigweed_internal:pw_strict_host_clang_debug)
366
367The ``.run`` following the test target name is a sub-target created as part of
368the ``pw_test`` GN template. If you remove ``.run``, the test will build but
369not attempt to run.
370
371In macOS and Linux, ``xargs`` can be used to turn this into a single command:
372
373.. code-block:: bash
374
375   $ gn outputs out "//pw_status:status_test.run(//targets/host/pigweed_internal:pw_strict_host_clang_debug)" | xargs ninja -C out
376
377----------
378Next steps
379----------
380
381Quickstarts
382===========
383Visit :ref:`docs-get-started` to learn how to set up a new Bazel-based
384project, how to add Pigweed to an existing Bazel-based project, and more.
385
386Other modules
387=============
388If you'd like to see more of what Pigweed has to offer, dive into the
389:ref:`docs-module-guides`.
390
391The :ref:`docs-kudzu` repo demonstrates how to use Pigweed in your own project.
392Note that there are many ways to leverage Pigweed and Kudzu is just one
393approach.
394
395Editor setup
396============
397Check out the :ref:`module-pw_ide` for setting up editor configurations or run
398the following for a quick setup:
399
400.. code-block:: bash
401
402   pw ide sync
403
404Hackaday Supercon talk about Pigweed
405====================================
406We gave a talk at Hackaday's 2021 supercon, `Give Pigweed a Whirl
407<https://hackaday.com/2021/01/13/remoticon-video-pigweed-brings-embedded-unit-testing-library-integration-to-commandline/>`_
408
409We've made improvements since we gave the talk; for example, we now have RTOS
410primitives.
411
412Get help
413========
414Dropping into our `chat room <https://discord.gg/M9NSeTA>`_ is the most
415immediate way to get help from the Pigweed team.
416