xref: /aosp_15_r20/external/tensorflow/third_party/repo.bzl (revision b6fb3261f9314811a0f4371741dbb8839866f948)
1*b6fb3261SAndroid Build Coastguard Worker# Copyright 2017 The TensorFlow Authors. All rights reserved.
2*b6fb3261SAndroid Build Coastguard Worker#
3*b6fb3261SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*b6fb3261SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*b6fb3261SAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*b6fb3261SAndroid Build Coastguard Worker#
7*b6fb3261SAndroid Build Coastguard Worker#    http://www.apache.org/licenses/LICENSE-2.0
8*b6fb3261SAndroid Build Coastguard Worker#
9*b6fb3261SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*b6fb3261SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*b6fb3261SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*b6fb3261SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*b6fb3261SAndroid Build Coastguard Worker# limitations under the License.
14*b6fb3261SAndroid Build Coastguard Worker
15*b6fb3261SAndroid Build Coastguard Worker"""Utilities for defining TensorFlow Bazel dependencies."""
16*b6fb3261SAndroid Build Coastguard Worker
17*b6fb3261SAndroid Build Coastguard Workerdef tf_mirror_urls(url):
18*b6fb3261SAndroid Build Coastguard Worker    """A helper for generating TF-mirror versions of URLs.
19*b6fb3261SAndroid Build Coastguard Worker
20*b6fb3261SAndroid Build Coastguard Worker    Given a URL, it returns a list of the TF-mirror cache version of that URL
21*b6fb3261SAndroid Build Coastguard Worker    and the original URL, suitable for use in `urls` field of `tf_http_archive`.
22*b6fb3261SAndroid Build Coastguard Worker    """
23*b6fb3261SAndroid Build Coastguard Worker    if not url.startswith("https://"):
24*b6fb3261SAndroid Build Coastguard Worker        return [url]
25*b6fb3261SAndroid Build Coastguard Worker    return [
26*b6fb3261SAndroid Build Coastguard Worker        "https://storage.googleapis.com/mirror.tensorflow.org/%s" % url[8:],
27*b6fb3261SAndroid Build Coastguard Worker        url,
28*b6fb3261SAndroid Build Coastguard Worker    ]
29*b6fb3261SAndroid Build Coastguard Worker
30*b6fb3261SAndroid Build Coastguard Workerdef _get_env_var(ctx, name):
31*b6fb3261SAndroid Build Coastguard Worker    if name in ctx.os.environ:
32*b6fb3261SAndroid Build Coastguard Worker        return ctx.os.environ[name]
33*b6fb3261SAndroid Build Coastguard Worker    else:
34*b6fb3261SAndroid Build Coastguard Worker        return None
35*b6fb3261SAndroid Build Coastguard Worker
36*b6fb3261SAndroid Build Coastguard Worker# Checks if we should use the system lib instead of the bundled one
37*b6fb3261SAndroid Build Coastguard Workerdef _use_system_lib(ctx, name):
38*b6fb3261SAndroid Build Coastguard Worker    syslibenv = _get_env_var(ctx, "TF_SYSTEM_LIBS")
39*b6fb3261SAndroid Build Coastguard Worker    if not syslibenv:
40*b6fb3261SAndroid Build Coastguard Worker        return False
41*b6fb3261SAndroid Build Coastguard Worker    return name in [n.strip() for n in syslibenv.split(",")]
42*b6fb3261SAndroid Build Coastguard Worker
43*b6fb3261SAndroid Build Coastguard Workerdef _get_link_dict(ctx, link_files, build_file):
44*b6fb3261SAndroid Build Coastguard Worker    link_dict = {ctx.path(v): ctx.path(Label(k)) for k, v in link_files.items()}
45*b6fb3261SAndroid Build Coastguard Worker    if build_file:
46*b6fb3261SAndroid Build Coastguard Worker        # Use BUILD.bazel because it takes precedence over BUILD.
47*b6fb3261SAndroid Build Coastguard Worker        link_dict[ctx.path("BUILD.bazel")] = ctx.path(Label(build_file))
48*b6fb3261SAndroid Build Coastguard Worker    return link_dict
49*b6fb3261SAndroid Build Coastguard Worker
50*b6fb3261SAndroid Build Coastguard Workerdef _tf_http_archive_impl(ctx):
51*b6fb3261SAndroid Build Coastguard Worker    # Construct all paths early on to prevent rule restart. We want the
52*b6fb3261SAndroid Build Coastguard Worker    # attributes to be strings instead of labels because they refer to files
53*b6fb3261SAndroid Build Coastguard Worker    # in the TensorFlow repository, not files in repos depending on TensorFlow.
54*b6fb3261SAndroid Build Coastguard Worker    # See also https://github.com/bazelbuild/bazel/issues/10515.
55*b6fb3261SAndroid Build Coastguard Worker    link_dict = _get_link_dict(ctx, ctx.attr.link_files, ctx.attr.build_file)
56*b6fb3261SAndroid Build Coastguard Worker
57*b6fb3261SAndroid Build Coastguard Worker    # For some reason, we need to "resolve" labels once before the
58*b6fb3261SAndroid Build Coastguard Worker    # download_and_extract otherwise it'll invalidate and re-download the
59*b6fb3261SAndroid Build Coastguard Worker    # archive each time.
60*b6fb3261SAndroid Build Coastguard Worker    # https://github.com/bazelbuild/bazel/issues/10515
61*b6fb3261SAndroid Build Coastguard Worker    patch_files = ctx.attr.patch_file
62*b6fb3261SAndroid Build Coastguard Worker    for patch_file in patch_files:
63*b6fb3261SAndroid Build Coastguard Worker        if patch_file:
64*b6fb3261SAndroid Build Coastguard Worker            ctx.path(Label(patch_file))
65*b6fb3261SAndroid Build Coastguard Worker
66*b6fb3261SAndroid Build Coastguard Worker    if _use_system_lib(ctx, ctx.attr.name):
67*b6fb3261SAndroid Build Coastguard Worker        link_dict.update(_get_link_dict(
68*b6fb3261SAndroid Build Coastguard Worker            ctx = ctx,
69*b6fb3261SAndroid Build Coastguard Worker            link_files = ctx.attr.system_link_files,
70*b6fb3261SAndroid Build Coastguard Worker            build_file = ctx.attr.system_build_file,
71*b6fb3261SAndroid Build Coastguard Worker        ))
72*b6fb3261SAndroid Build Coastguard Worker    else:
73*b6fb3261SAndroid Build Coastguard Worker        ctx.download_and_extract(
74*b6fb3261SAndroid Build Coastguard Worker            url = ctx.attr.urls,
75*b6fb3261SAndroid Build Coastguard Worker            sha256 = ctx.attr.sha256,
76*b6fb3261SAndroid Build Coastguard Worker            type = ctx.attr.type,
77*b6fb3261SAndroid Build Coastguard Worker            stripPrefix = ctx.attr.strip_prefix,
78*b6fb3261SAndroid Build Coastguard Worker        )
79*b6fb3261SAndroid Build Coastguard Worker        if patch_files:
80*b6fb3261SAndroid Build Coastguard Worker            for patch_file in patch_files:
81*b6fb3261SAndroid Build Coastguard Worker                patch_file = ctx.path(Label(patch_file)) if patch_file else None
82*b6fb3261SAndroid Build Coastguard Worker                if patch_file:
83*b6fb3261SAndroid Build Coastguard Worker                    ctx.patch(patch_file, strip = 1)
84*b6fb3261SAndroid Build Coastguard Worker
85*b6fb3261SAndroid Build Coastguard Worker    for dst, src in link_dict.items():
86*b6fb3261SAndroid Build Coastguard Worker        ctx.delete(dst)
87*b6fb3261SAndroid Build Coastguard Worker        ctx.symlink(src, dst)
88*b6fb3261SAndroid Build Coastguard Worker
89*b6fb3261SAndroid Build Coastguard Worker_tf_http_archive = repository_rule(
90*b6fb3261SAndroid Build Coastguard Worker    implementation = _tf_http_archive_impl,
91*b6fb3261SAndroid Build Coastguard Worker    attrs = {
92*b6fb3261SAndroid Build Coastguard Worker        "sha256": attr.string(mandatory = True),
93*b6fb3261SAndroid Build Coastguard Worker        "urls": attr.string_list(mandatory = True),
94*b6fb3261SAndroid Build Coastguard Worker        "strip_prefix": attr.string(),
95*b6fb3261SAndroid Build Coastguard Worker        "type": attr.string(),
96*b6fb3261SAndroid Build Coastguard Worker        "patch_file": attr.string_list(),
97*b6fb3261SAndroid Build Coastguard Worker        "build_file": attr.string(),
98*b6fb3261SAndroid Build Coastguard Worker        "system_build_file": attr.string(),
99*b6fb3261SAndroid Build Coastguard Worker        "link_files": attr.string_dict(),
100*b6fb3261SAndroid Build Coastguard Worker        "system_link_files": attr.string_dict(),
101*b6fb3261SAndroid Build Coastguard Worker    },
102*b6fb3261SAndroid Build Coastguard Worker    environ = ["TF_SYSTEM_LIBS"],
103*b6fb3261SAndroid Build Coastguard Worker)
104*b6fb3261SAndroid Build Coastguard Worker
105*b6fb3261SAndroid Build Coastguard Workerdef tf_http_archive(name, sha256, urls, **kwargs):
106*b6fb3261SAndroid Build Coastguard Worker    """Downloads and creates Bazel repos for dependencies.
107*b6fb3261SAndroid Build Coastguard Worker
108*b6fb3261SAndroid Build Coastguard Worker    This is a swappable replacement for both http_archive() and
109*b6fb3261SAndroid Build Coastguard Worker    new_http_archive() that offers some additional features. It also helps
110*b6fb3261SAndroid Build Coastguard Worker    ensure best practices are followed.
111*b6fb3261SAndroid Build Coastguard Worker
112*b6fb3261SAndroid Build Coastguard Worker    File arguments are relative to the TensorFlow repository by default. Dependent
113*b6fb3261SAndroid Build Coastguard Worker    repositories that use this rule should refer to files either with absolute
114*b6fb3261SAndroid Build Coastguard Worker    labels (e.g. '@foo//:bar') or from a label created in their repository (e.g.
115*b6fb3261SAndroid Build Coastguard Worker    'str(Label("//:bar"))').
116*b6fb3261SAndroid Build Coastguard Worker    """
117*b6fb3261SAndroid Build Coastguard Worker    if len(urls) < 2:
118*b6fb3261SAndroid Build Coastguard Worker        fail("tf_http_archive(urls) must have redundant URLs.")
119*b6fb3261SAndroid Build Coastguard Worker
120*b6fb3261SAndroid Build Coastguard Worker    if not any([mirror in urls[0] for mirror in (
121*b6fb3261SAndroid Build Coastguard Worker        "mirror.tensorflow.org",
122*b6fb3261SAndroid Build Coastguard Worker        "mirror.bazel.build",
123*b6fb3261SAndroid Build Coastguard Worker        "storage.googleapis.com",
124*b6fb3261SAndroid Build Coastguard Worker    )]):
125*b6fb3261SAndroid Build Coastguard Worker        fail("The first entry of tf_http_archive(urls) must be a mirror " +
126*b6fb3261SAndroid Build Coastguard Worker             "URL, preferrably mirror.tensorflow.org. Even if you don't have " +
127*b6fb3261SAndroid Build Coastguard Worker             "permission to mirror the file, please put the correctly " +
128*b6fb3261SAndroid Build Coastguard Worker             "formatted mirror URL there anyway, because someone will come " +
129*b6fb3261SAndroid Build Coastguard Worker             "along shortly thereafter and mirror the file.")
130*b6fb3261SAndroid Build Coastguard Worker
131*b6fb3261SAndroid Build Coastguard Worker    if native.existing_rule(name):
132*b6fb3261SAndroid Build Coastguard Worker        print("\n\033[1;33mWarning:\033[0m skipping import of repository '" +
133*b6fb3261SAndroid Build Coastguard Worker              name + "' because it already exists.\n")
134*b6fb3261SAndroid Build Coastguard Worker        return
135*b6fb3261SAndroid Build Coastguard Worker
136*b6fb3261SAndroid Build Coastguard Worker    _tf_http_archive(
137*b6fb3261SAndroid Build Coastguard Worker        name = name,
138*b6fb3261SAndroid Build Coastguard Worker        sha256 = sha256,
139*b6fb3261SAndroid Build Coastguard Worker        urls = urls,
140*b6fb3261SAndroid Build Coastguard Worker        **kwargs
141*b6fb3261SAndroid Build Coastguard Worker    )
142