aboutsummaryrefslogtreecommitdiff
path: root/pw_assert
diff options
context:
space:
mode:
authorWyatt Hepler <hepler@google.com>2021-05-03 15:30:58 -0700
committerCQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>2021-05-04 22:30:42 +0000
commit8bd4fb003ca6d4fb86f606572d80d2e3d23524d4 (patch)
tree98c68844bbf99320db87b5025ce5848bcf37f00f /pw_assert
parentbf3a3aff814fed0444fb101bd712cbf76617a509 (diff)
downloadpigweed-8bd4fb003ca6d4fb86f606572d80d2e3d23524d4.tar.gz
pw_build: Support specifying final link dependencies
- pw_build_LINK_DEPS is a list of build targets that are linked into all build artifacts produced by pw_executable, pw_static_library, and pw_shared_library. - Add a ":deps" group to the pw_assert build interface. Require $dir_pw_assert:deps to be listed in pw_build_LINK_DEPS if pw_assert_BACKEND is set. Change-Id: Icc01dbe86f95d971e76aa357c7b7174ce85546ba Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/43521 Pigweed-Auto-Submit: Wyatt Hepler <hepler@google.com> Commit-Queue: Auto-Submit <auto-submit@pigweed.google.com.iam.gserviceaccount.com> Reviewed-by: Armando Montanez <amontanez@google.com>
Diffstat (limited to 'pw_assert')
-rw-r--r--pw_assert/BUILD.gn40
-rw-r--r--pw_assert/docs.rst36
2 files changed, 65 insertions, 11 deletions
diff --git a/pw_assert/BUILD.gn b/pw_assert/BUILD.gn
index 2b78c00a3..0362da628 100644
--- a/pw_assert/BUILD.gn
+++ b/pw_assert/BUILD.gn
@@ -83,6 +83,46 @@ pw_source_set("assert") {
public_deps = [ dir_pw_preprocessor ]
}
+# pw_assert is low-level and ubiquitous. Because of this, it can often cause
+# circular dependencies. This target collects dependencies from the backend that
+# cannot be used because they would cause circular deps.
+#
+# This group ("$dir_pw_assert:deps") must listed in pw_build_LINK_DEPS if
+# pw_assert_BACKEND is set.
+#
+# pw_assert backends must provide their own "deps" group that collects their
+# actual dependencies. The backend "deps" group may be empty.
+group("deps") {
+ public_deps = []
+
+ if (pw_assert_BACKEND != "") {
+ public_deps += [ get_label_info(pw_assert_BACKEND, "dir") + ":deps" ]
+
+ # Make sure this target is listed in pw_build_LINK_DEPS. This
+ # ensures these dependencies are available during linking, even if nothing
+ # else in the build depends on them.
+ _deps_label = get_label_info(":$target_name", "label_no_toolchain")
+ _deps_is_in_link_dependencies = false
+
+ foreach(label, pw_build_LINK_DEPS) {
+ if (get_label_info(label, "label_no_toolchain") == _deps_label) {
+ _deps_is_in_link_dependencies = true
+ }
+ }
+
+ # TODO(pwbug/372): Update projects with pw_assert to link the :deps target.
+ _disable_this_check_for_now = true
+ not_needed([
+ "_deps_is_in_link_dependencies",
+ "_deps_label",
+ ])
+
+ assert(_disable_this_check_for_now || _deps_is_in_link_dependencies,
+ "\$dir_pw_assert:$target_name must be listed in " +
+ "pw_build_LINK_DEPS when pw_assert_BACKEND is set")
+ }
+}
+
# Note: While this is technically a test, doesn't verify any of the output and
# is more of a compile test. The results can be visually verified if desired.
pw_test("assert_test") {
diff --git a/pw_assert/docs.rst b/pw_assert/docs.rst
index 6a6576ee5..a66c3f7e1 100644
--- a/pw_assert/docs.rst
+++ b/pw_assert/docs.rst
@@ -472,20 +472,26 @@ The ``PW_ASSERT`` API ultimately calls the C function
``pw_assert_HandleFailure()``, which must be provided by the ``pw_assert``
backend.
+.. _module-pw_assert-circular-deps:
+
Avoiding circular dependencies with ``PW_ASSERT``
-------------------------------------------------
Because asserts are so widely used, including in low-level libraries, it is
-common for the ``pw_assert`` backend to cause circular dependencies. These can
-be avoided by only using the ``PW_ASSERT`` macro and depending directly on the
-library that provides it, rather than the whole ``pw_assert`` module. The
-``pw_assert`` backend, which defines ``pw_assert_HandleFailure()``, will need to
-be linked in elsewhere in the build, so only depend directly on the
-``pw_assert`` build target when necessary.
-
-In GN, depend on ``"$dir_pw_assert:assert"`` rather than on ``dir_pw_assert`` to
-access only ``PW_ASSERT`` without risking circular dependencies. The
-``pw_assert_HandleFailure()`` function is provided by the
-``$dir_pw_assert:pw_assert`` or ``"$dir_pw_assert:check"`` target.
+common for the ``pw_assert`` backend to cause circular dependencies. Because of
+this, assert backends may avoid declaring explicit dependencies, instead relying
+on include paths to access header files.
+
+In GN, the ``pw_assert`` backend's true dependencies are made available through
+the ``$dir_pw_assert:deps`` group. When ``pw_assert_BACKEND`` is set,
+``$dir_pw_assert:deps`` must be listed in the ``pw_build_LINK_DEPS`` variable.
+See :ref:`module-pw_build-link-deps`.
+
+If necessary, ``pw_assert`` backends can access dependencies from include paths
+rather than GN ``deps``. In this case, the may disable GN header checking with
+``check_includes = false``. The true build dependencies must be listed in a
+``deps`` group, which the ``pw_assert`` facade depends on. The ``deps`` group
+may be empty if the backend can use its dependencies directly without causing
+circular dependencies.
.. _module-pw_assert-backend_api:
@@ -574,6 +580,14 @@ header, but instead is in a ``.cc`` file.
file, expression, or other rich assert information. Backends should do
something reasonable in this case; typically, capturing the stack is useful.
+Backend build targets
+---------------------
+In GN, the backend must provide a ``deps`` build target in the same directory as
+the backend target. The ``deps`` target contains the backend's dependencies that
+could result in a dependency cycle. In the simplest case, it can be an empty
+group. Circular dependencies are a common problem with ``pw_assert`` because it
+is so widely used. See :ref:`module-pw_assert-circular-deps`.
+
--------------------------
Frequently asked questions
--------------------------