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