aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/tensorflow.bzl
diff options
context:
space:
mode:
authorGravatar Manjunath Kudlur <keveman@gmail.com>2016-05-18 06:59:43 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2016-05-18 08:02:16 -0700
commitcf9d71a203cb3cf14c864d0b549c9ee72806c3ad (patch)
tree204add4b7899e96e5a3968b4a1fbab150a5d2278 /tensorflow/tensorflow.bzl
parent1c7a268a1f4ae3f853fd5de0d4a1909ea0b72814 (diff)
Enforce the rule that custom op libraries don't depend on core:framework or
core:lib Change: 122631122
Diffstat (limited to 'tensorflow/tensorflow.bzl')
-rw-r--r--tensorflow/tensorflow.bzl58
1 files changed, 57 insertions, 1 deletions
diff --git a/tensorflow/tensorflow.bzl b/tensorflow/tensorflow.bzl
index 56bf3a4808..c7fcbc81e8 100644
--- a/tensorflow/tensorflow.bzl
+++ b/tensorflow/tensorflow.bzl
@@ -154,7 +154,7 @@ def tf_gen_op_wrapper_cc(name, out_ops_file, pkg=""):
# tf_gen_op_wrappers_cc("tf_ops_lib", [ "array_ops", "math_ops" ])
#
#
-#This will ultimately generate ops/* files and a library like:
+# This will ultimately generate ops/* files and a library like:
#
# cc_library(name = "tf_ops_lib",
# srcs = [ "ops/array_ops.cc",
@@ -520,6 +520,56 @@ def tf_custom_op_library_additional_deps():
"//tensorflow/core:framework_headers_lib",
]
+# Traverse the dependency graph along the "deps" attribute of the
+# target and return a struct with one field called 'tf_collected_deps'.
+# tf_collected_deps will be the union of the deps of the current target
+# and the tf_collected_deps of the dependencies of this target.
+def _collect_deps_aspect_impl(target, ctx):
+ alldeps = set()
+ if hasattr(ctx.rule.attr, "deps"):
+ for dep in ctx.rule.attr.deps:
+ alldeps = alldeps | set([dep.label])
+ if hasattr(dep, "tf_collected_deps"):
+ alldeps = alldeps | dep.tf_collected_deps
+ return struct(tf_collected_deps=alldeps)
+
+collect_deps_aspect = aspect(
+ implementation=_collect_deps_aspect_impl,
+ attr_aspects=["deps"])
+
+def _dep_label(dep):
+ label = dep.label
+ return label.package + ":" + label.name
+
+# This rule checks that the transitive dependencies of targets listed
+# in the 'deps' attribute don't depend on the targets listed in
+# the 'disallowed_deps' attribute.
+def _check_deps_impl(ctx):
+ disallowed_deps = ctx.attr.disallowed_deps
+ for input_dep in ctx.attr.deps:
+ if not hasattr(input_dep, "tf_collected_deps"):
+ continue
+ for dep in input_dep.tf_collected_deps:
+ for disallowed_dep in disallowed_deps:
+ if dep == disallowed_dep.label:
+ fail(_dep_label(input_dep) + " cannot depend on " +
+ _dep_label(disallowed_dep))
+ return struct()
+
+check_deps = rule(
+ _check_deps_impl,
+ attrs = {
+ "deps": attr.label_list(
+ aspects=[collect_deps_aspect],
+ mandatory = True,
+ allow_files = True
+ ),
+ "disallowed_deps": attr.label_list(
+ mandatory = True,
+ allow_files = True
+ )},
+)
+
# Helper to build a dynamic library (.so) from the sources containing
# implementations of custom ops and kernels.
def tf_custom_op_library(name, srcs=[], gpu_srcs=[], deps=[]):
@@ -537,9 +587,15 @@ def tf_custom_op_library(name, srcs=[], gpu_srcs=[], deps=[]):
deps = deps + if_cuda(cuda_deps))
cuda_deps.extend([":" + basename + "_gpu"])
+ check_deps(name=name+"_check_deps",
+ deps=deps + if_cuda(cuda_deps),
+ disallowed_deps=["//tensorflow/core:framework",
+ "//tensorflow/core:lib"])
+
native.cc_binary(name=name,
srcs=srcs,
deps=deps + if_cuda(cuda_deps),
+ data=[name + "_check_deps"],
linkshared=1,
linkopts = select({
"//conditions:default": [