message: Clarify rules for including dependencies in libtensorflow_framework.so.
diff: @@ -491,6 +491,38 @@ cc_library(
  # global symbol table in order to support op registration. This means that
  # projects building with Bazel and importing TensorFlow as a dependency will not
  # depend on libtensorflow_framework.so unless they opt in.
  +#
  +# DEBUGGING DUPLICATE INITIALIZATION
  +# ----------------------------------
  +#
  +# Having a dynamic library introduces a diamond dependency problem:
  +# if a target X is depended on by both libtensorflow_framework.so and the
  +# users of libtensorflow_framework.so, the definitions will get duplicated.
  +# This causes global initializers which need to be run exactly once (e.g.
  +# protobuf registration) to crash, as the initialization is run once from the
  +# statically linked in global, and one by the global which comes in from
  +# libtensorflow_framework.so.
  +# Even worse, global objects which need to be singletons for semantical
  +# correctness (e.g. registers) might get dupliacted.
  +#
  +# In order to avoid these HARD TO DEBUG CRASHES, it is sufficient to follow
  +# these rules:
  +# - All globals with non-trivial static constructors or for which a
  +# single identity is required (e.g. registers) need to live in `*_impl`
  +# targets.
  +#
  +# - An `*_impl` target has to be (transitively) included into
  +# `libtensorflow_framework.so`.
  +#
  +# - A target T1 can depend on `*_impl` target T2 only if:
  +#
  +# -> It's a tf_cc_shared_object, and there is no other tf_cc_shared_object
  +# transitively depending on T2.
  +# -> It's an `*_impl` target by itself
  +# -> The dependency is guarded by `if_static`. This is discouraged,
  +# as it diverges dependency topology between static and dynamic TF.
  +#
  +# TODO(cheshire): write tests to check for rule violations
  tf_cc_shared_object(
  name = "tensorflow_framework",
  framework_so = [],
  