xref: /aosp_15_r20/external/tflite-support/third_party/repo.bzl (revision b16991f985baa50654c05c5adbb3c8bbcfb40082)
1*b16991f9SAndroid Build Coastguard Worker# Copyright 2020 The TensorFlow Authors. All rights reserved.
2*b16991f9SAndroid Build Coastguard Worker#
3*b16991f9SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*b16991f9SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*b16991f9SAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*b16991f9SAndroid Build Coastguard Worker#
7*b16991f9SAndroid Build Coastguard Worker#    http://www.apache.org/licenses/LICENSE-2.0
8*b16991f9SAndroid Build Coastguard Worker#
9*b16991f9SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*b16991f9SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*b16991f9SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*b16991f9SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*b16991f9SAndroid Build Coastguard Worker# limitations under the License.
14*b16991f9SAndroid Build Coastguard Worker
15*b16991f9SAndroid Build Coastguard Worker"""Utilities for defining TensorFlow Lite Support Bazel dependencies."""
16*b16991f9SAndroid Build Coastguard Worker
17*b16991f9SAndroid Build Coastguard Worker_SINGLE_URL_WHITELIST = []
18*b16991f9SAndroid Build Coastguard Worker
19*b16991f9SAndroid Build Coastguard Workerdef _is_windows(ctx):
20*b16991f9SAndroid Build Coastguard Worker    return ctx.os.name.lower().find("windows") != -1
21*b16991f9SAndroid Build Coastguard Worker
22*b16991f9SAndroid Build Coastguard Workerdef _wrap_bash_cmd(ctx, cmd):
23*b16991f9SAndroid Build Coastguard Worker    if _is_windows(ctx):
24*b16991f9SAndroid Build Coastguard Worker        bazel_sh = _get_env_var(ctx, "BAZEL_SH")
25*b16991f9SAndroid Build Coastguard Worker        if not bazel_sh:
26*b16991f9SAndroid Build Coastguard Worker            fail("BAZEL_SH environment variable is not set")
27*b16991f9SAndroid Build Coastguard Worker        cmd = [bazel_sh, "-l", "-c", " ".join(["\"%s\"" % s for s in cmd])]
28*b16991f9SAndroid Build Coastguard Worker    return cmd
29*b16991f9SAndroid Build Coastguard Worker
30*b16991f9SAndroid Build Coastguard Workerdef _get_env_var(ctx, name):
31*b16991f9SAndroid Build Coastguard Worker    if name in ctx.os.environ:
32*b16991f9SAndroid Build Coastguard Worker        return ctx.os.environ[name]
33*b16991f9SAndroid Build Coastguard Worker    else:
34*b16991f9SAndroid Build Coastguard Worker        return None
35*b16991f9SAndroid Build Coastguard Worker
36*b16991f9SAndroid Build Coastguard Worker# Checks if we should use the system lib instead of the bundled one
37*b16991f9SAndroid Build Coastguard Workerdef _use_system_lib(ctx, name):
38*b16991f9SAndroid Build Coastguard Worker    syslibenv = _get_env_var(ctx, "TF_SYSTEM_LIBS")
39*b16991f9SAndroid Build Coastguard Worker    if syslibenv:
40*b16991f9SAndroid Build Coastguard Worker        for n in syslibenv.strip().split(","):
41*b16991f9SAndroid Build Coastguard Worker            if n.strip() == name:
42*b16991f9SAndroid Build Coastguard Worker                return True
43*b16991f9SAndroid Build Coastguard Worker    return False
44*b16991f9SAndroid Build Coastguard Worker
45*b16991f9SAndroid Build Coastguard Worker# Executes specified command with arguments and calls 'fail' if it exited with
46*b16991f9SAndroid Build Coastguard Worker# non-zero code
47*b16991f9SAndroid Build Coastguard Workerdef _execute_and_check_ret_code(repo_ctx, cmd_and_args):
48*b16991f9SAndroid Build Coastguard Worker    result = repo_ctx.execute(cmd_and_args, timeout = 60)
49*b16991f9SAndroid Build Coastguard Worker    if result.return_code != 0:
50*b16991f9SAndroid Build Coastguard Worker        fail(("Non-zero return code({1}) when executing '{0}':\n" + "Stdout: {2}\n" +
51*b16991f9SAndroid Build Coastguard Worker              "Stderr: {3}").format(
52*b16991f9SAndroid Build Coastguard Worker            " ".join([str(x) for x in cmd_and_args]),
53*b16991f9SAndroid Build Coastguard Worker            result.return_code,
54*b16991f9SAndroid Build Coastguard Worker            result.stdout,
55*b16991f9SAndroid Build Coastguard Worker            result.stderr,
56*b16991f9SAndroid Build Coastguard Worker        ))
57*b16991f9SAndroid Build Coastguard Worker
58*b16991f9SAndroid Build Coastguard Worker# Apply a patch_file to the repository root directory
59*b16991f9SAndroid Build Coastguard Worker# Runs 'patch -p1' on both Windows and Unix.
60*b16991f9SAndroid Build Coastguard Workerdef _apply_patch(ctx, patch_file):
61*b16991f9SAndroid Build Coastguard Worker    patch_command = ["patch", "-p1", "-d", ctx.path("."), "-i", ctx.path(patch_file)]
62*b16991f9SAndroid Build Coastguard Worker    cmd = _wrap_bash_cmd(ctx, patch_command)
63*b16991f9SAndroid Build Coastguard Worker    _execute_and_check_ret_code(ctx, cmd)
64*b16991f9SAndroid Build Coastguard Worker
65*b16991f9SAndroid Build Coastguard Workerdef _apply_delete(ctx, paths):
66*b16991f9SAndroid Build Coastguard Worker    for path in paths:
67*b16991f9SAndroid Build Coastguard Worker        if path.startswith("/"):
68*b16991f9SAndroid Build Coastguard Worker            fail("refusing to rm -rf path starting with '/': " + path)
69*b16991f9SAndroid Build Coastguard Worker        if ".." in path:
70*b16991f9SAndroid Build Coastguard Worker            fail("refusing to rm -rf path containing '..': " + path)
71*b16991f9SAndroid Build Coastguard Worker    cmd = _wrap_bash_cmd(ctx, ["rm", "-rf"] + [ctx.path(path) for path in paths])
72*b16991f9SAndroid Build Coastguard Worker    _execute_and_check_ret_code(ctx, cmd)
73*b16991f9SAndroid Build Coastguard Worker
74*b16991f9SAndroid Build Coastguard Workerdef _third_party_http_archive(ctx):
75*b16991f9SAndroid Build Coastguard Worker    """Downloads and creates Bazel repos for dependencies.
76*b16991f9SAndroid Build Coastguard Worker
77*b16991f9SAndroid Build Coastguard Worker    This is a swappable replacement for both http_archive() and
78*b16991f9SAndroid Build Coastguard Worker    new_http_archive() that offers some additional features. It also helps
79*b16991f9SAndroid Build Coastguard Worker    ensure best practices are followed.
80*b16991f9SAndroid Build Coastguard Worker    """
81*b16991f9SAndroid Build Coastguard Worker    if ("mirror.tensorflow.org" not in ctx.attr.urls[0] and
82*b16991f9SAndroid Build Coastguard Worker        (len(ctx.attr.urls) < 2 and
83*b16991f9SAndroid Build Coastguard Worker         ctx.attr.name not in _SINGLE_URL_WHITELIST.to_list())):
84*b16991f9SAndroid Build Coastguard Worker        fail("third_party_http_archive(urls) must have redundant URLs. The " +
85*b16991f9SAndroid Build Coastguard Worker             "mirror.tensorflow.org URL must be present and it must come first. " +
86*b16991f9SAndroid Build Coastguard Worker             "Even if you don't have permission to mirror the file, please " +
87*b16991f9SAndroid Build Coastguard Worker             "put the correctly formatted mirror URL there anyway, because " +
88*b16991f9SAndroid Build Coastguard Worker             "someone will come along shortly thereafter and mirror the file.")
89*b16991f9SAndroid Build Coastguard Worker
90*b16991f9SAndroid Build Coastguard Worker    use_syslib = _use_system_lib(ctx, ctx.attr.name)
91*b16991f9SAndroid Build Coastguard Worker
92*b16991f9SAndroid Build Coastguard Worker    # Use "BUILD.bazel" to avoid conflict with third party projects that contain a
93*b16991f9SAndroid Build Coastguard Worker    # file or directory called "BUILD"
94*b16991f9SAndroid Build Coastguard Worker    buildfile_path = ctx.path("BUILD.bazel")
95*b16991f9SAndroid Build Coastguard Worker
96*b16991f9SAndroid Build Coastguard Worker    if use_syslib:
97*b16991f9SAndroid Build Coastguard Worker        if ctx.attr.system_build_file == None:
98*b16991f9SAndroid Build Coastguard Worker            fail("Bazel was configured with TF_SYSTEM_LIBS to use a system " +
99*b16991f9SAndroid Build Coastguard Worker                 "library for %s, but no system build file for %s was configured. " +
100*b16991f9SAndroid Build Coastguard Worker                 "Please add a system_build_file attribute to the repository rule" +
101*b16991f9SAndroid Build Coastguard Worker                 "for %s." % (ctx.attr.name, ctx.attr.name, ctx.attr.name))
102*b16991f9SAndroid Build Coastguard Worker        ctx.symlink(Label(ctx.attr.system_build_file), buildfile_path)
103*b16991f9SAndroid Build Coastguard Worker
104*b16991f9SAndroid Build Coastguard Worker    else:
105*b16991f9SAndroid Build Coastguard Worker        ctx.download_and_extract(
106*b16991f9SAndroid Build Coastguard Worker            ctx.attr.urls,
107*b16991f9SAndroid Build Coastguard Worker            "",
108*b16991f9SAndroid Build Coastguard Worker            ctx.attr.sha256,
109*b16991f9SAndroid Build Coastguard Worker            ctx.attr.type,
110*b16991f9SAndroid Build Coastguard Worker            ctx.attr.strip_prefix,
111*b16991f9SAndroid Build Coastguard Worker        )
112*b16991f9SAndroid Build Coastguard Worker        if ctx.attr.delete:
113*b16991f9SAndroid Build Coastguard Worker            _apply_delete(ctx, ctx.attr.delete)
114*b16991f9SAndroid Build Coastguard Worker        if ctx.attr.patch_file != None:
115*b16991f9SAndroid Build Coastguard Worker            _apply_patch(ctx, ctx.attr.patch_file)
116*b16991f9SAndroid Build Coastguard Worker        ctx.symlink(Label(ctx.attr.build_file), buildfile_path)
117*b16991f9SAndroid Build Coastguard Worker
118*b16991f9SAndroid Build Coastguard Worker    link_dict = {}
119*b16991f9SAndroid Build Coastguard Worker    if use_syslib:
120*b16991f9SAndroid Build Coastguard Worker        link_dict.update(ctx.attr.system_link_files)
121*b16991f9SAndroid Build Coastguard Worker
122*b16991f9SAndroid Build Coastguard Worker    for internal_src, external_dest in ctx.attr.link_files.items():
123*b16991f9SAndroid Build Coastguard Worker        # if syslib and link exists in both, use the system one
124*b16991f9SAndroid Build Coastguard Worker        if external_dest not in link_dict.values():
125*b16991f9SAndroid Build Coastguard Worker            link_dict[internal_src] = external_dest
126*b16991f9SAndroid Build Coastguard Worker
127*b16991f9SAndroid Build Coastguard Worker    for internal_src, external_dest in link_dict.items():
128*b16991f9SAndroid Build Coastguard Worker        ctx.symlink(Label(internal_src), ctx.path(external_dest))
129*b16991f9SAndroid Build Coastguard Worker
130*b16991f9SAndroid Build Coastguard Worker# For link_files, specify each dict entry as:
131*b16991f9SAndroid Build Coastguard Worker# "//path/to/source:file": "localfile"
132*b16991f9SAndroid Build Coastguard Workerthird_party_http_archive = repository_rule(
133*b16991f9SAndroid Build Coastguard Worker    attrs = {
134*b16991f9SAndroid Build Coastguard Worker        "sha256": attr.string(mandatory = True),
135*b16991f9SAndroid Build Coastguard Worker        "urls": attr.string_list(
136*b16991f9SAndroid Build Coastguard Worker            mandatory = True,
137*b16991f9SAndroid Build Coastguard Worker            allow_empty = False,
138*b16991f9SAndroid Build Coastguard Worker        ),
139*b16991f9SAndroid Build Coastguard Worker        "strip_prefix": attr.string(),
140*b16991f9SAndroid Build Coastguard Worker        "type": attr.string(),
141*b16991f9SAndroid Build Coastguard Worker        "delete": attr.string_list(),
142*b16991f9SAndroid Build Coastguard Worker        "build_file": attr.string(mandatory = True),
143*b16991f9SAndroid Build Coastguard Worker        "system_build_file": attr.string(mandatory = False),
144*b16991f9SAndroid Build Coastguard Worker        "patch_file": attr.label(),
145*b16991f9SAndroid Build Coastguard Worker        "link_files": attr.string_dict(),
146*b16991f9SAndroid Build Coastguard Worker        "system_link_files": attr.string_dict(),
147*b16991f9SAndroid Build Coastguard Worker    },
148*b16991f9SAndroid Build Coastguard Worker    environ = [
149*b16991f9SAndroid Build Coastguard Worker        "TF_SYSTEM_LIBS",
150*b16991f9SAndroid Build Coastguard Worker    ],
151*b16991f9SAndroid Build Coastguard Worker    implementation = _third_party_http_archive,
152*b16991f9SAndroid Build Coastguard Worker)
153