diff --git a/pw_build/docs.rst b/pw_build/docs.rst index d4e2479305..d70e14fb94 100644 --- a/pw_build/docs.rst +++ b/pw_build/docs.rst @@ -37,6 +37,29 @@ compiler defaults. (See Pigweed's ``//BUILDCONFIG.gn``) ``pw_build`` also provides several useful GN templates that are used throughout Pigweed. +Build system philosophies +------------------------- +While Pigweed's GN build is not hermetic, it strives to adhere to principles of +`hermeticity `_. Some guidelines to +move towards the ideal of hermeticity include: + +* Only rely on pre-compiled tools provided by CIPD (or some other versioned, + pre-compiled binary distribution mechanism). This eliminates build artifact + differences caused by different tool versions or variations (e.g. same tool + version built with slightly different compilation flags). +* Do not use absolute paths in Ninja commands. Typically, these appear when + using ``rebase_path("//path/to/my_script.py")``. Most of the time, Ninja + steps should be passed paths rebased relative to the build directory (i.e. + ``rebase_path("//path/to/my_script.py", root_build_dir)``). This ensures build + commands are the same across different machines. +* Prevent produced artifacts from relying on or referencing system state. This + includes time stamps, writing absolute paths to generated artifacts, or + producing artifacts that reference system state in a way that prevents them + from working the same way on a different machine. +* Isolate build actions to the build directory. In general, the build system + should not add or modify files outside of the build directory. This can cause + confusion to users, and makes the concept of a clean build more ambiguous. + Target types ------------ .. code-block:: diff --git a/pw_env_setup/py/pw_env_setup/gni_visitor.py b/pw_env_setup/py/pw_env_setup/gni_visitor.py index cd60d80edd..03121a0a82 100644 --- a/pw_env_setup/py/pw_env_setup/gni_visitor.py +++ b/pw_env_setup/py/pw_env_setup/gni_visitor.py @@ -15,6 +15,9 @@ from __future__ import print_function +import ntpath +import os +import posixpath import re # Disable super() warnings since this file must be Python 2 compatible. @@ -27,13 +30,13 @@ class GNIVisitor(object): # pylint: disable=useless-object-inheritance Example gni file: declare_args() { - dir_cipd_default = "/cipd/packages/default" - dir_cipd_pigweed = "/cipd/packages/pigweed" - dir_cipd_arm = "/cipd/packages/arm" - dir_cipd_python = "/cipd/packages/python" - dir_cipd_bazel = "/cipd/packages/bazel" - dir_cipd_luci = "/cipd/packages/luci" - dir_virtual_env = "/pigweed-venv" + dir_cipd_default = "///cipd/packages/default" + dir_cipd_pigweed = "///cipd/packages/pigweed" + dir_cipd_arm = "///cipd/packages/arm" + dir_cipd_python = "///cipd/packages/python" + dir_cipd_bazel = "///cipd/packages/bazel" + dir_cipd_luci = "///cipd/packages/luci" + dir_virtual_env = "///pigweed-venv" } """ def __init__(self, project_root, *args, **kwargs): @@ -57,14 +60,25 @@ def serialize(self, env, outs): print(line, file=outs) self._lines = [] + def _abspath_to_gn_path(self, path): + gn_path = os.path.relpath(path, start=self._project_root) + if os.name == 'nt': + # GN paths are posix-style, so convert to posix. This + # find-and-replace is a little crude, but python 2.7 doesn't support + # pathlib. + gn_path = gn_path.replace(ntpath.sep, posixpath.sep) + return '//{}'.format(gn_path) + def visit_set(self, set): # pylint: disable=redefined-builtin match = re.search(r'PW_(.*)_CIPD_INSTALL_DIR', set.name) if match: name = 'dir_cipd_{}'.format(match.group(1).lower()) - self._lines.append(' {} = "{}"'.format(name, set.value)) + self._lines.append(' {} = "{}"'.format( + name, self._abspath_to_gn_path(set.value))) if set.name == 'VIRTUAL_ENV': - self._lines.append(' dir_virtual_env = "{}"'.format(set.value)) + self._lines.append(' dir_virtual_env = "{}"'.format( + self._abspath_to_gn_path(set.value))) def visit_clear(self, clear): pass diff --git a/pw_toolchain/host_clang/BUILD.gn b/pw_toolchain/host_clang/BUILD.gn index bed41fbc8c..921fe460c0 100644 --- a/pw_toolchain/host_clang/BUILD.gn +++ b/pw_toolchain/host_clang/BUILD.gn @@ -123,7 +123,7 @@ config("no_system_libcpp") { "-nostdlib++", # Use the libc++ from CIPD. - dir_cipd_pigweed + "/lib/libc++.a", + rebase_path(dir_cipd_pigweed + "/lib/libc++.a", root_build_dir), ] } }