Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_env_setup / docs.rst
1 .. _module-pw_env_setup:
2
3 ------------
4 pw_env_setup
5 ------------
6 A classic problem in the embedded space is reducing the time from git clone
7 to having a binary executing on a device. The issue is that an entire suite
8 of tools is needed for non-trivial production embedded projects. For example:
9
10  - A C++ compiler for your target device, and also for your host
11  - A build system or three; for example, GN, Ninja, CMake, Bazel
12  - A code formatting program like clang-format
13  - A debugger like OpenOCD to flash and debug your embedded device
14  - A known Python version with known modules installed for scripting
15  - A Go compiler for the Go-based command line tools
16
17 ...and so on
18
19 In the server space, container solutions like Docker or Podman solve this;
20 however, in our experience container solutions are a mixed bag for embedded
21 systems development where one frequently needs access to native system
22 resources like USB devices, or must operate on Windows.
23
24 ``pw_env_setup`` is our compromise solution for this problem that works on Mac,
25 Windows, and Linux. It leverages the Chrome packaging system `CIPD`_ to
26 bootstrap a Python installation, which in turn inflates a virtual
27 environment. The tooling is installed into your workspace, and makes no
28 changes to your system. This tooling is designed to be reused by any
29 project.
30
31 .. _CIPD: https://github.com/luci/luci-go/tree/master/cipd
32
33 Users interact with  ``pw_env_setup`` with two commands: ``. bootstrap.sh`` and
34 ``. activate.sh``. The bootstrap command always pulls down the current versions
35 of CIPD packages and sets up the Python virtual environment. The activate
36 command reinitializes a previously configured environment, and if none is found,
37 runs bootstrap.
38
39 .. note::
40   On Windows the scripts used to set up the environment are ``bootstrap.bat``
41   and ``activate.bat``. For simplicity they will be referred to with the ``.sh``
42   endings unless the distinction is relevant.
43
44 .. warning::
45   At this time ``pw_env_setup`` works for us, but isn’t well tested. We don’t
46   suggest relying on it just yet. However, we are interested in experience
47   reports; if you give it a try, please `send us a note`_ about your
48   experience.
49
50 .. _send us a note: pigweed@googlegroups.com
51
52 ==================================
53 Using pw_env_setup in your project
54 ==================================
55
56 Downstream Projects Using Pigweed's Packages
57 ********************************************
58
59 Projects using Pigweed can leverage ``pw_env_setup`` to install Pigweed's
60 dependencies or their own dependencies. Projects that only want to use Pigweed's
61 dependencies without modifying them can just source Pigweed's ``bootstrap.sh``
62 and ``activate.sh`` scripts.
63
64 An example of what your project's `bootstrap.sh` could look like is below. This
65 assumes `bootstrap.sh` is at the top level of your repository.
66
67 .. code-block:: bash
68
69   # Do not include a "#!" line, this must be sourced and not executed.
70
71   # This assumes the user is sourcing this file from it's parent directory. See
72   # below for a more flexible way to handle this.
73   PROJ_SETUP_SCRIPT_PATH="$(pwd)/bootstrap.sh"
74
75   export PW_PROJECT_ROOT="$(_python_abspath "$(dirname "$PROJ_SETUP_SCRIPT_PATH")")"
76
77   # You may wish to check if the user is attempting to execute this script
78   # instead of sourcing it. See below for an example of how to handle that
79   # situation.
80
81   # Source Pigweed's bootstrap utility script.
82   # Using '.' instead of 'source' for POSIX compatibility. Since users don't use
83   # dash directly, using 'source' in most documentation so users don't get
84   # confused and try to `./bootstrap.sh`.
85   . "$PW_PROJECT_ROOT/third_party/pigweed/pw_env_setup/util.sh"
86
87   pw_check_root "$PW_ROOT"
88   _PW_ACTUAL_ENVIRONMENT_ROOT="$(pw_get_env_root)"
89   export _PW_ACTUAL_ENVIRONMENT_ROOT
90   SETUP_SH="$_PW_ACTUAL_ENVIRONMENT_ROOT/activate.sh"
91   pw_bootstrap --args...  # See below for details about args.
92   pw_finalize bootstrap "$SETUP_SH"
93
94 User-Friendliness
95 -----------------
96
97 You may wish to allow sourcing `bootstrap.sh` from a different directory. In
98 that case you'll need the following at the top of `bootstrap.sh`.
99
100 .. code-block:: bash
101
102   _python_abspath () {
103     python -c "import os.path; print(os.path.abspath('$@'))"
104   }
105
106   # Use this code from Pigweed's bootstrap to find the path to this script when
107   # sourced. This should work with common shells. PW_CHECKOUT_ROOT is only used in
108   # presubmit tests with strange setups, and can be omitted if you're not using
109   # Pigweed's automated testing infrastructure.
110   if test -n "$PW_CHECKOUT_ROOT"; then
111     PROJ_SETUP_SCRIPT_PATH="$(_python_abspath "$PW_CHECKOUT_ROOT/bootstrap.sh")"
112     unset PW_CHECKOUT_ROOT
113   # Shell: bash.
114   elif test -n "$BASH"; then
115     PROJ_SETUP_SCRIPT_PATH="$(_python_abspath "$BASH_SOURCE")"
116   # Shell: zsh.
117   elif test -n "$ZSH_NAME"; then
118     PROJ_SETUP_SCRIPT_PATH="$(_python_abspath "${(%):-%N}")"
119   # Shell: dash.
120   elif test ${0##*/} = dash; then
121     PROJ_SETUP_SCRIPT_PATH="$(_python_abspath \
122       "$(lsof -p $$ -Fn0 | tail -1 | sed 's#^[^/]*##;')")"
123   # If everything else fails, try $0. It could work.
124   else
125     PROJ_SETUP_SCRIPT_PATH="$(_python_abspath "$0")"
126   fi
127
128 You may also wish to check if the user is attempting to execute `bootstrap.sh`
129 instead of sourcing it. Executing `bootstrap.sh` would download everything
130 required for the environment, but cannot modify the environment of the parent
131 process. To check for this add the following.
132
133 .. code-block:: bash
134
135   # Check if this file is being executed or sourced.
136   _pw_sourced=0
137   # If not running in Pigweed's automated testing infrastructure the
138   # SWARMING_BOT_ID check is unnecessary.
139   if [ -n "$SWARMING_BOT_ID" ]; then
140     # If set we're running on swarming and don't need this check.
141     _pw_sourced=1
142   elif [ -n "$ZSH_EVAL_CONTEXT" ]; then
143     case $ZSH_EVAL_CONTEXT in *:file) _pw_sourced=1;; esac
144   elif [ -n "$KSH_VERSION" ]; then
145     [ "$(cd $(dirname -- $0) && pwd -P)/$(basename -- $0)" != \
146       "$(cd $(dirname -- ${.sh.file}) && pwd -P)/$(basename -- ${.sh.file})" ] \
147       && _pw_sourced=1
148   elif [ -n "$BASH_VERSION" ]; then
149     (return 0 2>/dev/null) && _pw_sourced=1
150   else  # All other shells: examine $0 for known shell binary filenames
151     # Detects `sh` and `dash`; add additional shell filenames as needed.
152     case ${0##*/} in sh|dash) _pw_sourced=1;; esac
153   fi
154
155   _pw_eval_sourced "$_pw_sourced"
156
157 Downstream Projects Using Different Packages
158 ********************************************
159
160 Projects depending on Pigweed but using additional or different packages should
161 copy the Pigweed `sample project`'s ``bootstrap.sh`` and update the call to
162 ``pw_bootstrap``. Search for "downstream" for other places that may require
163 changes, like setting the ``PW_ROOT`` and ``PW_PROJECT_ROOT`` environment
164 variables. Relevant arguments to ``pw_bootstrap`` are listed here.
165
166 .. _sample project: https://pigweed.googlesource.com/pigweed/sample_project/+/master
167
168 ``--use-pigweed-defaults``
169   Use Pigweed default values in addition to the other switches.
170
171 ``--cipd-package-file path/to/packages.json``
172   CIPD package file. JSON file consisting of a list of dictionaries with "path"
173   and "tags" keys, where "tags" is a list of strings.
174
175 ``--virtualenv-requierements path/to/requirements.txt``
176   Pip requirements file. Compiled with pip-compile.
177
178 ``--virtualenv-gn-target path/to/directory#package-install-target``
179   Target for installing Python packages, and the directory from which it must be
180   run. Example for Pigweed: ``third_party/pigweed#:python.install`` (assuming
181   Pigweed is included in the project at ``third_party/pigweed``). Downstream
182   projects will need to create targets to install their packages and either
183   choose a subset of Pigweed packages or use
184   ``third_party/pigweed#:python.install`` to install all Pigweed packages.
185
186 ``--cargo-package-file path/to/packages.txt``
187   Rust cargo packages to install. Lines with package name and version separated
188   by a space. Has no effect without ``--enable-cargo``.
189
190 ``--enable-cargo``
191   Enable cargo package installation.
192
193 An example of the changed env_setup.py line is below.
194
195 .. code-block:: bash
196
197   pw_bootstrap \
198     --shell-file "$SETUP_SH" \
199     --install-dir "$_PW_ACTUAL_ENVIRONMENT_ROOT" \
200     --use-pigweed-defaults \
201     --cipd-package-file "$PW_PROJECT_ROOT/path/to/cipd.json" \
202     --virtualenv-gn-target "$PW_PROJECT_ROOT#:python.install"
203
204 Projects wanting some of the Pigweed environment packages but not all of them
205 should not use ``--use-pigweed-defaults`` and must manually add the references
206 to Pigweed default packages through the other arguments. The arguments below
207 are identical to using ``--use-pigweed-defaults``.
208
209 .. code-block:: bash
210
211   --cipd-package-file
212   "$PW_ROOT/pw_env_setup/py/pw_env_setup/cipd_setup/pigweed.json"
213   --cipd-package-file
214   "$PW_ROOT/pw_env_setup/py/pw_env_setup/cipd_setup/luci.json"
215   --virtualenv-requirements
216   "$PW_ROOT/pw_env_setup/py/pw_env_setup/virtualenv_setup/requirements.txt"
217   --virtualenv-gn-target
218   "$PW_ROOT#:python.install"
219   --cargo-package-file
220   "$PW_ROOT/pw_env_setup/py/pw_env_setup/cargo_setup/packages.txt"
221
222 Environment Variables
223 *********************
224 The following environment variables affect env setup behavior. Most users will
225 never need to set these.
226
227 ``CIPD_CACHE_DIR``
228   Location of CIPD cache dir. Defaults to ``$HOME/.cipd-cache-dir``.
229
230 ``PW_ACTIVATE_SKIP_CHECKS``
231   If set, skip running ``pw doctor`` at end of bootstrap/activate. Intended to
232   be used by automated tools but not interactively.
233
234 ``PW_BOOTSTRAP_PYTHON``
235   Python executable to be used, for example "python2" or "python3". Defaults to
236   "python".
237
238 ``PW_ENVIRONMENT_ROOT``
239   Location to which packages are installed. Defaults to ``.environment`` folder
240   within the checkout root.
241
242 ``PW_ENVSETUP_DISABLE_SPINNER``
243   Disable the spinner during env setup. Intended to be used when the output is
244   being redirected to a log.
245
246 ``PW_ENVSETUP_QUIET``
247   Disables all non-error output.
248
249 Implementation
250 **************
251
252 The environment is set up by installing CIPD and Python packages in
253 ``PW_ENVIRONMENT_ROOT`` or ``<checkout>/.environment``, and saving modifications
254 to environment variables in setup scripts in those directories. To support
255 multiple operating systems this is done in an operating system-agnostic manner
256 and then written into operating system-specific files to be sourced now and in
257 the future when running ``activate.sh`` instead of ``bootstrap.sh``. In the
258 future these could be extended to C shell and PowerShell. A logical mapping of
259 high-level commands to system-specific initialization files is shown below.
260
261 .. image:: doc_resources/pw_env_setup_output.png
262    :alt: Mapping of high-level commands to system-specific commands.
263    :align: left