xref: /aosp_15_r20/external/bazelbuild-rules_android/rules/java.bzl (revision 9e965d6fece27a77de5377433c2f7e6999b8cc0b)
1*9e965d6fSRomain Jobredeaux# Copyright 2018 The Bazel Authors. All rights reserved.
2*9e965d6fSRomain Jobredeaux#
3*9e965d6fSRomain Jobredeaux# Licensed under the Apache License, Version 2.0 (the "License");
4*9e965d6fSRomain Jobredeaux# you may not use this file except in compliance with the License.
5*9e965d6fSRomain Jobredeaux# You may obtain a copy of the License at
6*9e965d6fSRomain Jobredeaux#
7*9e965d6fSRomain Jobredeaux#    http://www.apache.org/licenses/LICENSE-2.0
8*9e965d6fSRomain Jobredeaux#
9*9e965d6fSRomain Jobredeaux# Unless required by applicable law or agreed to in writing, software
10*9e965d6fSRomain Jobredeaux# distributed under the License is distributed on an "AS IS" BASIS,
11*9e965d6fSRomain Jobredeaux# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9e965d6fSRomain Jobredeaux# See the License for the specific language governing permissions and
13*9e965d6fSRomain Jobredeaux# limitations under the License.
14*9e965d6fSRomain Jobredeaux
15*9e965d6fSRomain Jobredeaux"""Bazel Java APIs for the Android rules."""
16*9e965d6fSRomain Jobredeaux
17*9e965d6fSRomain Jobredeauxload(":path.bzl", _path = "path")
18*9e965d6fSRomain Jobredeauxload(":utils.bzl", "log")
19*9e965d6fSRomain Jobredeaux
20*9e965d6fSRomain Jobredeaux_ANDROID_CONSTRAINT_MISSING_ERROR = (
21*9e965d6fSRomain Jobredeaux    "A list of constraints provided without the 'android' constraint."
22*9e965d6fSRomain Jobredeaux)
23*9e965d6fSRomain Jobredeaux
24*9e965d6fSRomain Jobredeaux# TODO(b/283499746): Reduce singlejar memory if possible.
25*9e965d6fSRomain Jobredeaux_SINGLEJAR_MEMORY_FOR_DEPLOY_JAR_MB = 1600
26*9e965d6fSRomain Jobredeaux
27*9e965d6fSRomain Jobredeauxdef _segment_idx(path_segments):
28*9e965d6fSRomain Jobredeaux    """Finds the index of the segment in the path that preceeds the source root.
29*9e965d6fSRomain Jobredeaux
30*9e965d6fSRomain Jobredeaux    Args:
31*9e965d6fSRomain Jobredeaux      path_segments: A list of strings, where each string is the segment of a
32*9e965d6fSRomain Jobredeaux        filesystem path.
33*9e965d6fSRomain Jobredeaux
34*9e965d6fSRomain Jobredeaux    Returns:
35*9e965d6fSRomain Jobredeaux      An index to the path segment that represents the Java segment or -1 if
36*9e965d6fSRomain Jobredeaux      none found.
37*9e965d6fSRomain Jobredeaux    """
38*9e965d6fSRomain Jobredeaux    if _path.is_absolute(path_segments[0]):
39*9e965d6fSRomain Jobredeaux        log.error("path must not be absolute: %s" % _path.join(path_segments))
40*9e965d6fSRomain Jobredeaux
41*9e965d6fSRomain Jobredeaux    root_idx = -1
42*9e965d6fSRomain Jobredeaux    for idx, segment in enumerate(path_segments):
43*9e965d6fSRomain Jobredeaux        if segment in ["java", "javatests", "src", "testsrc"]:
44*9e965d6fSRomain Jobredeaux            root_idx = idx
45*9e965d6fSRomain Jobredeaux            break
46*9e965d6fSRomain Jobredeaux    if root_idx < 0:
47*9e965d6fSRomain Jobredeaux        return root_idx
48*9e965d6fSRomain Jobredeaux
49*9e965d6fSRomain Jobredeaux    is_src = path_segments[root_idx] == "src"
50*9e965d6fSRomain Jobredeaux    check_maven_idx = root_idx if is_src else -1
51*9e965d6fSRomain Jobredeaux    if root_idx == 0 or is_src:
52*9e965d6fSRomain Jobredeaux        # Check for a nested root directory.
53*9e965d6fSRomain Jobredeaux        for idx in range(root_idx + 1, len(path_segments) - 2):
54*9e965d6fSRomain Jobredeaux            segment = path_segments[idx]
55*9e965d6fSRomain Jobredeaux            if segment == "src" or (is_src and segment in ["java", "javatests"]):
56*9e965d6fSRomain Jobredeaux                next_segment = path_segments[idx + 1]
57*9e965d6fSRomain Jobredeaux                if next_segment in ["com", "org", "net"]:
58*9e965d6fSRomain Jobredeaux                    root_idx = idx
59*9e965d6fSRomain Jobredeaux                elif segment == "src":
60*9e965d6fSRomain Jobredeaux                    check_maven_idx = idx
61*9e965d6fSRomain Jobredeaux                break
62*9e965d6fSRomain Jobredeaux
63*9e965d6fSRomain Jobredeaux    if check_maven_idx >= 0 and check_maven_idx + 2 < len(path_segments):
64*9e965d6fSRomain Jobredeaux        next_segment = path_segments[check_maven_idx + 1]
65*9e965d6fSRomain Jobredeaux        if next_segment in ["main", "test"]:
66*9e965d6fSRomain Jobredeaux            next_segment = path_segments[check_maven_idx + 2]
67*9e965d6fSRomain Jobredeaux            if next_segment in ["java", "resources"]:
68*9e965d6fSRomain Jobredeaux                root_idx = check_maven_idx + 2
69*9e965d6fSRomain Jobredeaux    return root_idx
70*9e965d6fSRomain Jobredeaux
71*9e965d6fSRomain Jobredeauxdef _resolve_package(path):
72*9e965d6fSRomain Jobredeaux    """Determines the Java package name from the given path.
73*9e965d6fSRomain Jobredeaux
74*9e965d6fSRomain Jobredeaux    Examples:
75*9e965d6fSRomain Jobredeaux        "{workspace}/java/foo/bar/wiz" -> "foo.bar.wiz"
76*9e965d6fSRomain Jobredeaux        "{workspace}/javatests/foo/bar/wiz" -> "foo.bar.wiz"
77*9e965d6fSRomain Jobredeaux
78*9e965d6fSRomain Jobredeaux    Args:
79*9e965d6fSRomain Jobredeaux      path: A string, representing a file path.
80*9e965d6fSRomain Jobredeaux
81*9e965d6fSRomain Jobredeaux    Returns:
82*9e965d6fSRomain Jobredeaux      A string representing a Java package name or None if could not be
83*9e965d6fSRomain Jobredeaux      determined.
84*9e965d6fSRomain Jobredeaux    """
85*9e965d6fSRomain Jobredeaux    path_segments = _path.split(path.partition(":")[0])
86*9e965d6fSRomain Jobredeaux    java_idx = _segment_idx(path_segments)
87*9e965d6fSRomain Jobredeaux    if java_idx < 0:
88*9e965d6fSRomain Jobredeaux        return None
89*9e965d6fSRomain Jobredeaux    else:
90*9e965d6fSRomain Jobredeaux        return ".".join(path_segments[java_idx + 1:])
91*9e965d6fSRomain Jobredeaux
92*9e965d6fSRomain Jobredeauxdef _resolve_package_from_label(
93*9e965d6fSRomain Jobredeaux        label,
94*9e965d6fSRomain Jobredeaux        custom_package = None):
95*9e965d6fSRomain Jobredeaux    """Resolves the Java package from a Label.
96*9e965d6fSRomain Jobredeaux
97*9e965d6fSRomain Jobredeaux    When no legal Java package can be resolved from the label, None will be
98*9e965d6fSRomain Jobredeaux    returned unless fallback is specified.
99*9e965d6fSRomain Jobredeaux
100*9e965d6fSRomain Jobredeaux    When a fallback is requested, a not safe for Java compilation package will
101*9e965d6fSRomain Jobredeaux    be returned. The fallback value will be derrived by taking the label.package
102*9e965d6fSRomain Jobredeaux    and replacing all path separators with ".".
103*9e965d6fSRomain Jobredeaux    """
104*9e965d6fSRomain Jobredeaux    if custom_package:
105*9e965d6fSRomain Jobredeaux        return custom_package
106*9e965d6fSRomain Jobredeaux
107*9e965d6fSRomain Jobredeaux    # For backwards compatibility, also include directories
108*9e965d6fSRomain Jobredeaux    # from the label's name
109*9e965d6fSRomain Jobredeaux    # Ex: "//foo/bar:java/com/google/baz" is a legal one and
110*9e965d6fSRomain Jobredeaux    # results in "com.google"
111*9e965d6fSRomain Jobredeaux    label_path = _path.join(
112*9e965d6fSRomain Jobredeaux        [label.package] +
113*9e965d6fSRomain Jobredeaux        _path.split(label.name)[:-1],
114*9e965d6fSRomain Jobredeaux    )
115*9e965d6fSRomain Jobredeaux    return _resolve_package(label_path)
116*9e965d6fSRomain Jobredeaux
117*9e965d6fSRomain Jobredeauxdef _root(path):
118*9e965d6fSRomain Jobredeaux    """Determines the Java root from the given path.
119*9e965d6fSRomain Jobredeaux
120*9e965d6fSRomain Jobredeaux    Examples:
121*9e965d6fSRomain Jobredeaux        "{workspace}/java/foo/bar/wiz" -> "{workspace}/java"
122*9e965d6fSRomain Jobredeaux        "{workspace}/javatests/foo/bar/wiz" -> "{workspace}/javatests"
123*9e965d6fSRomain Jobredeaux        "java/foo/bar/wiz" -> "java"
124*9e965d6fSRomain Jobredeaux        "javatests/foo/bar/wiz" -> "javatests"
125*9e965d6fSRomain Jobredeaux
126*9e965d6fSRomain Jobredeaux    Args:
127*9e965d6fSRomain Jobredeaux      path: A string, representing a file path.
128*9e965d6fSRomain Jobredeaux
129*9e965d6fSRomain Jobredeaux    Returns:
130*9e965d6fSRomain Jobredeaux      A string representing the Java root path or None if could not be
131*9e965d6fSRomain Jobredeaux      determined.
132*9e965d6fSRomain Jobredeaux    """
133*9e965d6fSRomain Jobredeaux    path_segments = _path.split(path.partition(":")[0])
134*9e965d6fSRomain Jobredeaux    java_idx = _segment_idx(path_segments)
135*9e965d6fSRomain Jobredeaux    if java_idx < 0:
136*9e965d6fSRomain Jobredeaux        return None
137*9e965d6fSRomain Jobredeaux    else:
138*9e965d6fSRomain Jobredeaux        return _path.join(path_segments[0:java_idx + 1])
139*9e965d6fSRomain Jobredeaux
140*9e965d6fSRomain Jobredeauxdef _check_for_invalid_java_package(java_package):
141*9e965d6fSRomain Jobredeaux    return "-" in java_package or len(java_package.split(".")) < 2
142*9e965d6fSRomain Jobredeaux
143*9e965d6fSRomain Jobredeauxdef _invalid_java_package(custom_package, java_package):
144*9e965d6fSRomain Jobredeaux    """Checks if the given java package is invalid.
145*9e965d6fSRomain Jobredeaux
146*9e965d6fSRomain Jobredeaux    Only checks if either custom_package or java_package contains the
147*9e965d6fSRomain Jobredeaux    illegal character "-" or if they are composed of only one word.
148*9e965d6fSRomain Jobredeaux    Only checks java_package if custom_package is an empty string or None.
149*9e965d6fSRomain Jobredeaux
150*9e965d6fSRomain Jobredeaux    Args:
151*9e965d6fSRomain Jobredeaux      custom_package: string. Java package given as an attribute to a rule to override
152*9e965d6fSRomain Jobredeaux      the java_package.
153*9e965d6fSRomain Jobredeaux      java_package: string. Java package inferred from the directory where the BUILD
154*9e965d6fSRomain Jobredeaux      containing the rule is.
155*9e965d6fSRomain Jobredeaux
156*9e965d6fSRomain Jobredeaux    Returns:
157*9e965d6fSRomain Jobredeaux      A boolean. True if custom_package or java_package contains "-" or is only one word.
158*9e965d6fSRomain Jobredeaux      Only checks java_package if custom_package is an empty string or None.
159*9e965d6fSRomain Jobredeaux    """
160*9e965d6fSRomain Jobredeaux    return (
161*9e965d6fSRomain Jobredeaux        (custom_package and _check_for_invalid_java_package(custom_package)) or
162*9e965d6fSRomain Jobredeaux        (not custom_package and _check_for_invalid_java_package(java_package))
163*9e965d6fSRomain Jobredeaux    )
164*9e965d6fSRomain Jobredeaux
165*9e965d6fSRomain Jobredeaux# The Android specific Java compile.
166*9e965d6fSRomain Jobredeauxdef _compile_android(
167*9e965d6fSRomain Jobredeaux        ctx,
168*9e965d6fSRomain Jobredeaux        output_jar,
169*9e965d6fSRomain Jobredeaux        output_srcjar = None,
170*9e965d6fSRomain Jobredeaux        srcs = [],
171*9e965d6fSRomain Jobredeaux        resources = [],
172*9e965d6fSRomain Jobredeaux        javac_opts = [],
173*9e965d6fSRomain Jobredeaux        r_java = None,
174*9e965d6fSRomain Jobredeaux        deps = [],
175*9e965d6fSRomain Jobredeaux        exports = [],
176*9e965d6fSRomain Jobredeaux        plugins = [],
177*9e965d6fSRomain Jobredeaux        exported_plugins = [],
178*9e965d6fSRomain Jobredeaux        annotation_processor_additional_outputs = [],
179*9e965d6fSRomain Jobredeaux        annotation_processor_additional_inputs = [],
180*9e965d6fSRomain Jobredeaux        enable_deps_without_srcs = False,
181*9e965d6fSRomain Jobredeaux        neverlink = False,
182*9e965d6fSRomain Jobredeaux        constraints = ["android"],
183*9e965d6fSRomain Jobredeaux        strict_deps = "Error",
184*9e965d6fSRomain Jobredeaux        java_toolchain = None):
185*9e965d6fSRomain Jobredeaux    """Compiles the Java and IDL sources for Android.
186*9e965d6fSRomain Jobredeaux
187*9e965d6fSRomain Jobredeaux    Args:
188*9e965d6fSRomain Jobredeaux      ctx: The context.
189*9e965d6fSRomain Jobredeaux      output_jar: File. The artifact to place the compilation unit.
190*9e965d6fSRomain Jobredeaux      output_srcjar: File. The artifact to place the sources of the compilation
191*9e965d6fSRomain Jobredeaux        unit. Optional.
192*9e965d6fSRomain Jobredeaux      srcs: sequence of Files. A list of files and jars to be compiled.
193*9e965d6fSRomain Jobredeaux      resources: sequence of Files. Will be added to the output jar - see
194*9e965d6fSRomain Jobredeaux        java_library.resources. Optional.
195*9e965d6fSRomain Jobredeaux      javac_opts: sequence of strings. A list of the desired javac options.
196*9e965d6fSRomain Jobredeaux        Optional.
197*9e965d6fSRomain Jobredeaux      r_java: JavaInfo. The R.jar dependency. Optional.
198*9e965d6fSRomain Jobredeaux      deps: sequence of JavaInfo providers. A list of dependencies. Optional.
199*9e965d6fSRomain Jobredeaux      exports: sequence of JavaInfo providers. A list of exports. Optional.
200*9e965d6fSRomain Jobredeaux      plugins: sequence of JavaPluginInfo providers. A list of plugins. Optional.
201*9e965d6fSRomain Jobredeaux      exported_plugins: sequence of JavaPluginInfo providers. A list of exported
202*9e965d6fSRomain Jobredeaux        plugins. Optional.
203*9e965d6fSRomain Jobredeaux      annotation_processor_additional_outputs: sequence of Files. A list of
204*9e965d6fSRomain Jobredeaux        files produced by an annotation processor.
205*9e965d6fSRomain Jobredeaux      annotation_processor_additional_inputs: sequence of Files. A list of
206*9e965d6fSRomain Jobredeaux        files consumed by an annotation processor.
207*9e965d6fSRomain Jobredeaux      enable_deps_without_srcs: Enables the behavior from b/14473160.
208*9e965d6fSRomain Jobredeaux      neverlink: Bool. Makes the compiled unit a compile-time only dependency.
209*9e965d6fSRomain Jobredeaux      constraints: sequence of Strings. A list of constraints, to constrain the
210*9e965d6fSRomain Jobredeaux        target. Optional. By default [].
211*9e965d6fSRomain Jobredeaux      strict_deps: string. A string that specifies how to handle strict deps.
212*9e965d6fSRomain Jobredeaux        Possible values: 'OFF', 'ERROR','WARN' and 'DEFAULT'. For more details
213*9e965d6fSRomain Jobredeaux        see https://docs.bazel.build/versions/master/user-manual.html#flag--strict_java_deps.
214*9e965d6fSRomain Jobredeaux        By default 'ERROR'.
215*9e965d6fSRomain Jobredeaux      java_toolchain: The java_toolchain Target.
216*9e965d6fSRomain Jobredeaux
217*9e965d6fSRomain Jobredeaux    Returns:
218*9e965d6fSRomain Jobredeaux      A JavaInfo provider representing the Java compilation.
219*9e965d6fSRomain Jobredeaux    """
220*9e965d6fSRomain Jobredeaux    if "android" not in constraints:
221*9e965d6fSRomain Jobredeaux        log.error(_ANDROID_CONSTRAINT_MISSING_ERROR)
222*9e965d6fSRomain Jobredeaux
223*9e965d6fSRomain Jobredeaux    if not srcs:
224*9e965d6fSRomain Jobredeaux        if deps and enable_deps_without_srcs:
225*9e965d6fSRomain Jobredeaux            # TODO(b/122039567): Produces a JavaInfo that exports the deps, but
226*9e965d6fSRomain Jobredeaux            # not the plugins. To reproduce the "deps without srcs" bug,
227*9e965d6fSRomain Jobredeaux            # b/14473160, behavior in Starlark.
228*9e965d6fSRomain Jobredeaux            exports = exports + [
229*9e965d6fSRomain Jobredeaux                android_common.enable_implicit_sourceless_deps_exports_compatibility(dep)
230*9e965d6fSRomain Jobredeaux                for dep in deps
231*9e965d6fSRomain Jobredeaux            ]
232*9e965d6fSRomain Jobredeaux        if not exports:
233*9e965d6fSRomain Jobredeaux            # Add a "no-op JavaInfo" to propagate the exported_plugins when
234*9e965d6fSRomain Jobredeaux            # deps or exports have not been specified by the target and
235*9e965d6fSRomain Jobredeaux            # additionally forces java_common.compile method to create the
236*9e965d6fSRomain Jobredeaux            # empty output jar and srcjar when srcs have not been specified.
237*9e965d6fSRomain Jobredeaux            noop_java_info = java_common.merge([])
238*9e965d6fSRomain Jobredeaux            exports = exports + [noop_java_info]
239*9e965d6fSRomain Jobredeaux
240*9e965d6fSRomain Jobredeaux    r_java_info = [r_java] if r_java else []
241*9e965d6fSRomain Jobredeaux
242*9e965d6fSRomain Jobredeaux    java_info = _compile(
243*9e965d6fSRomain Jobredeaux        ctx,
244*9e965d6fSRomain Jobredeaux        output_jar,
245*9e965d6fSRomain Jobredeaux        output_srcjar = output_srcjar,
246*9e965d6fSRomain Jobredeaux        srcs = srcs,
247*9e965d6fSRomain Jobredeaux        resources = resources,
248*9e965d6fSRomain Jobredeaux        javac_opts = javac_opts,
249*9e965d6fSRomain Jobredeaux        deps = r_java_info + deps,
250*9e965d6fSRomain Jobredeaux        # In native, the JavaInfo exposes two Jars as compile-time deps, the
251*9e965d6fSRomain Jobredeaux        # compiled sources and the Android R.java jars. To simulate this
252*9e965d6fSRomain Jobredeaux        # behavior, the JavaInfo of the R.jar is also exported.
253*9e965d6fSRomain Jobredeaux        exports = r_java_info + exports,
254*9e965d6fSRomain Jobredeaux        plugins = plugins,
255*9e965d6fSRomain Jobredeaux        exported_plugins = exported_plugins,
256*9e965d6fSRomain Jobredeaux        annotation_processor_additional_outputs = (
257*9e965d6fSRomain Jobredeaux            annotation_processor_additional_outputs
258*9e965d6fSRomain Jobredeaux        ),
259*9e965d6fSRomain Jobredeaux        annotation_processor_additional_inputs = (
260*9e965d6fSRomain Jobredeaux            annotation_processor_additional_inputs
261*9e965d6fSRomain Jobredeaux        ),
262*9e965d6fSRomain Jobredeaux        neverlink = neverlink,
263*9e965d6fSRomain Jobredeaux        constraints = constraints,
264*9e965d6fSRomain Jobredeaux        strict_deps = strict_deps,
265*9e965d6fSRomain Jobredeaux        java_toolchain = java_toolchain,
266*9e965d6fSRomain Jobredeaux    )
267*9e965d6fSRomain Jobredeaux    return java_info
268*9e965d6fSRomain Jobredeaux
269*9e965d6fSRomain Jobredeauxdef _compile(
270*9e965d6fSRomain Jobredeaux        ctx,
271*9e965d6fSRomain Jobredeaux        output_jar,
272*9e965d6fSRomain Jobredeaux        output_srcjar = None,
273*9e965d6fSRomain Jobredeaux        srcs = [],
274*9e965d6fSRomain Jobredeaux        resources = [],
275*9e965d6fSRomain Jobredeaux        javac_opts = [],
276*9e965d6fSRomain Jobredeaux        deps = [],
277*9e965d6fSRomain Jobredeaux        exports = [],
278*9e965d6fSRomain Jobredeaux        plugins = [],
279*9e965d6fSRomain Jobredeaux        exported_plugins = [],
280*9e965d6fSRomain Jobredeaux        annotation_processor_additional_outputs = [],
281*9e965d6fSRomain Jobredeaux        annotation_processor_additional_inputs = [],
282*9e965d6fSRomain Jobredeaux        neverlink = False,
283*9e965d6fSRomain Jobredeaux        constraints = [],
284*9e965d6fSRomain Jobredeaux        strict_deps = "Error",
285*9e965d6fSRomain Jobredeaux        java_toolchain = None):
286*9e965d6fSRomain Jobredeaux    """Compiles the Java and IDL sources for Android.
287*9e965d6fSRomain Jobredeaux
288*9e965d6fSRomain Jobredeaux    Args:
289*9e965d6fSRomain Jobredeaux      ctx: The context.
290*9e965d6fSRomain Jobredeaux      output_jar: File. The artifact to place the compilation unit.
291*9e965d6fSRomain Jobredeaux      output_srcjar: File. The artifact to place the sources of the compilation
292*9e965d6fSRomain Jobredeaux        unit. Optional.
293*9e965d6fSRomain Jobredeaux      srcs: sequence of Files. A list of files and jars to be compiled.
294*9e965d6fSRomain Jobredeaux      resources: sequence of Files. Will be added to the output jar - see
295*9e965d6fSRomain Jobredeaux        java_library.resources. Optional.
296*9e965d6fSRomain Jobredeaux      javac_opts: sequence of strings. A list of the desired javac options.
297*9e965d6fSRomain Jobredeaux        Optional.
298*9e965d6fSRomain Jobredeaux      deps: sequence of JavaInfo providers. A list of dependencies. Optional.
299*9e965d6fSRomain Jobredeaux      exports: sequence of JavaInfo providers. A list of exports. Optional.
300*9e965d6fSRomain Jobredeaux      plugins: sequence of JavaPluginInfo providers. A list of plugins. Optional.
301*9e965d6fSRomain Jobredeaux      exported_plugins: sequence of JavaPluginInfo providers. A list of exported
302*9e965d6fSRomain Jobredeaux        plugins. Optional.
303*9e965d6fSRomain Jobredeaux      annotation_processor_additional_outputs: sequence of Files. A list of
304*9e965d6fSRomain Jobredeaux        files produced by an annotation processor.
305*9e965d6fSRomain Jobredeaux      annotation_processor_additional_inputs: sequence of Files. A list of
306*9e965d6fSRomain Jobredeaux        files consumed by an annotation processor.
307*9e965d6fSRomain Jobredeaux      resources: sequence of Files. Will be added to the output jar - see
308*9e965d6fSRomain Jobredeaux        java_library.resources. Optional.
309*9e965d6fSRomain Jobredeaux      neverlink: Bool. Makes the compiled unit a compile-time only dependency.
310*9e965d6fSRomain Jobredeaux      constraints: sequence of Strings. A list of constraints, to constrain the
311*9e965d6fSRomain Jobredeaux        target. Optional. By default [].
312*9e965d6fSRomain Jobredeaux      strict_deps: string. A string that specifies how to handle strict deps.
313*9e965d6fSRomain Jobredeaux        Possible values: 'OFF', 'ERROR','WARN' and 'DEFAULT'. For more details
314*9e965d6fSRomain Jobredeaux        see https://docs.bazel.build/versions/master/user-manual.html#flag--strict_java_deps.
315*9e965d6fSRomain Jobredeaux        By default 'ERROR'.
316*9e965d6fSRomain Jobredeaux      java_toolchain: The java_toolchain Target.
317*9e965d6fSRomain Jobredeaux
318*9e965d6fSRomain Jobredeaux    Returns:
319*9e965d6fSRomain Jobredeaux      A JavaInfo provider representing the Java compilation.
320*9e965d6fSRomain Jobredeaux    """
321*9e965d6fSRomain Jobredeaux
322*9e965d6fSRomain Jobredeaux    # Split javac opts.
323*9e965d6fSRomain Jobredeaux    opts = []
324*9e965d6fSRomain Jobredeaux    for opt in javac_opts:
325*9e965d6fSRomain Jobredeaux        opts.extend(opt.split(" "))
326*9e965d6fSRomain Jobredeaux
327*9e965d6fSRomain Jobredeaux    # Separate the sources *.java from *.srcjar.
328*9e965d6fSRomain Jobredeaux    source_files = []
329*9e965d6fSRomain Jobredeaux    source_jars = []
330*9e965d6fSRomain Jobredeaux    for src in srcs:
331*9e965d6fSRomain Jobredeaux        if src.path.endswith(".srcjar"):
332*9e965d6fSRomain Jobredeaux            source_jars.append(src)
333*9e965d6fSRomain Jobredeaux        else:
334*9e965d6fSRomain Jobredeaux            source_files.append(src)
335*9e965d6fSRomain Jobredeaux
336*9e965d6fSRomain Jobredeaux    return java_common.compile(
337*9e965d6fSRomain Jobredeaux        ctx,
338*9e965d6fSRomain Jobredeaux        output = output_jar,
339*9e965d6fSRomain Jobredeaux        output_source_jar = output_srcjar,
340*9e965d6fSRomain Jobredeaux        source_files = source_files,
341*9e965d6fSRomain Jobredeaux        source_jars = source_jars,
342*9e965d6fSRomain Jobredeaux        resources = resources,
343*9e965d6fSRomain Jobredeaux        javac_opts = opts,
344*9e965d6fSRomain Jobredeaux        deps = deps,
345*9e965d6fSRomain Jobredeaux        exports = exports,
346*9e965d6fSRomain Jobredeaux        plugins = plugins,
347*9e965d6fSRomain Jobredeaux        exported_plugins = exported_plugins,
348*9e965d6fSRomain Jobredeaux        annotation_processor_additional_outputs = (
349*9e965d6fSRomain Jobredeaux            annotation_processor_additional_outputs
350*9e965d6fSRomain Jobredeaux        ),
351*9e965d6fSRomain Jobredeaux        annotation_processor_additional_inputs = (
352*9e965d6fSRomain Jobredeaux            annotation_processor_additional_inputs
353*9e965d6fSRomain Jobredeaux        ),
354*9e965d6fSRomain Jobredeaux        neverlink = neverlink,
355*9e965d6fSRomain Jobredeaux        strict_deps = strict_deps,
356*9e965d6fSRomain Jobredeaux        java_toolchain = java_toolchain[java_common.JavaToolchainInfo],
357*9e965d6fSRomain Jobredeaux    )
358*9e965d6fSRomain Jobredeaux
359*9e965d6fSRomain Jobredeauxdef _singlejar(
360*9e965d6fSRomain Jobredeaux        ctx,
361*9e965d6fSRomain Jobredeaux        inputs,
362*9e965d6fSRomain Jobredeaux        output,
363*9e965d6fSRomain Jobredeaux        mnemonic = "SingleJar",
364*9e965d6fSRomain Jobredeaux        progress_message = "Merge into a single jar.",
365*9e965d6fSRomain Jobredeaux        build_target = "",
366*9e965d6fSRomain Jobredeaux        check_desugar_deps = False,
367*9e965d6fSRomain Jobredeaux        compression = True,
368*9e965d6fSRomain Jobredeaux        deploy_manifest_lines = [],
369*9e965d6fSRomain Jobredeaux        include_build_data = False,
370*9e965d6fSRomain Jobredeaux        include_prefixes = [],
371*9e965d6fSRomain Jobredeaux        java_toolchain = None,
372*9e965d6fSRomain Jobredeaux        resource_set = None):
373*9e965d6fSRomain Jobredeaux    args = ctx.actions.args()
374*9e965d6fSRomain Jobredeaux    args.add("--output")
375*9e965d6fSRomain Jobredeaux    args.add(output)
376*9e965d6fSRomain Jobredeaux    if compression:
377*9e965d6fSRomain Jobredeaux        args.add("--compression")
378*9e965d6fSRomain Jobredeaux    args.add("--normalize")
379*9e965d6fSRomain Jobredeaux    if not include_build_data:
380*9e965d6fSRomain Jobredeaux        args.add("--exclude_build_data")
381*9e965d6fSRomain Jobredeaux    args.add("--warn_duplicate_resources")
382*9e965d6fSRomain Jobredeaux    if inputs:
383*9e965d6fSRomain Jobredeaux        args.add("--sources")
384*9e965d6fSRomain Jobredeaux        args.add_all(inputs)
385*9e965d6fSRomain Jobredeaux
386*9e965d6fSRomain Jobredeaux    if build_target:
387*9e965d6fSRomain Jobredeaux        args.add("--build_target", build_target)
388*9e965d6fSRomain Jobredeaux    if check_desugar_deps:
389*9e965d6fSRomain Jobredeaux        args.add("--check_desugar_deps")
390*9e965d6fSRomain Jobredeaux    if deploy_manifest_lines:
391*9e965d6fSRomain Jobredeaux        args.add_all("--deploy_manifest_lines", deploy_manifest_lines)
392*9e965d6fSRomain Jobredeaux    if include_prefixes:
393*9e965d6fSRomain Jobredeaux        args.add_all("--include_prefixes", include_prefixes)
394*9e965d6fSRomain Jobredeaux
395*9e965d6fSRomain Jobredeaux    args.use_param_file("@%s")
396*9e965d6fSRomain Jobredeaux    args.set_param_file_format("multiline")
397*9e965d6fSRomain Jobredeaux
398*9e965d6fSRomain Jobredeaux    ctx.actions.run(
399*9e965d6fSRomain Jobredeaux        executable = java_toolchain[java_common.JavaToolchainInfo].single_jar,
400*9e965d6fSRomain Jobredeaux        toolchain = "@bazel_tools//tools/jdk:toolchain_type",
401*9e965d6fSRomain Jobredeaux        arguments = [args],
402*9e965d6fSRomain Jobredeaux        inputs = inputs,
403*9e965d6fSRomain Jobredeaux        outputs = [output],
404*9e965d6fSRomain Jobredeaux        mnemonic = mnemonic,
405*9e965d6fSRomain Jobredeaux        progress_message = progress_message,
406*9e965d6fSRomain Jobredeaux        resource_set = resource_set,
407*9e965d6fSRomain Jobredeaux    )
408*9e965d6fSRomain Jobredeaux
409*9e965d6fSRomain Jobredeauxdef _run(
410*9e965d6fSRomain Jobredeaux        ctx,
411*9e965d6fSRomain Jobredeaux        host_javabase,
412*9e965d6fSRomain Jobredeaux        jvm_flags = [],
413*9e965d6fSRomain Jobredeaux        **args):
414*9e965d6fSRomain Jobredeaux    """Run a java binary
415*9e965d6fSRomain Jobredeaux
416*9e965d6fSRomain Jobredeaux    Args:
417*9e965d6fSRomain Jobredeaux      ctx: The context.
418*9e965d6fSRomain Jobredeaux      host_javabase: Target. The host_javabase.
419*9e965d6fSRomain Jobredeaux      jvm_flags: Additional arguments to the JVM itself.
420*9e965d6fSRomain Jobredeaux      **args: Additional arguments to pass to ctx.actions.run(). Some will get modified.
421*9e965d6fSRomain Jobredeaux    """
422*9e965d6fSRomain Jobredeaux
423*9e965d6fSRomain Jobredeaux    if type(ctx) != "ctx":
424*9e965d6fSRomain Jobredeaux        fail("Expected type ctx for argument ctx, got %s" % type(ctx))
425*9e965d6fSRomain Jobredeaux
426*9e965d6fSRomain Jobredeaux    if type(host_javabase) != "Target":
427*9e965d6fSRomain Jobredeaux        fail("Expected type Target for argument host_javabase, got %s" % type(host_javabase))
428*9e965d6fSRomain Jobredeaux
429*9e965d6fSRomain Jobredeaux    # Set reasonable max heap default. Required to prevent runaway memory usage.
430*9e965d6fSRomain Jobredeaux    # Can still be overridden by callers of this method.
431*9e965d6fSRomain Jobredeaux    jvm_flags = ["-Xms4G", "-Xmx4G", "-XX:+ExitOnOutOfMemoryError"] + jvm_flags
432*9e965d6fSRomain Jobredeaux
433*9e965d6fSRomain Jobredeaux    # executable should be a File or a FilesToRunProvider
434*9e965d6fSRomain Jobredeaux    jar = args.get("executable")
435*9e965d6fSRomain Jobredeaux    if type(jar) == "FilesToRunProvider":
436*9e965d6fSRomain Jobredeaux        jar = jar.executable
437*9e965d6fSRomain Jobredeaux    elif type(jar) != "File":
438*9e965d6fSRomain Jobredeaux        fail("Expected type File or FilesToRunProvider for argument executable, got %s" % type(jar))
439*9e965d6fSRomain Jobredeaux
440*9e965d6fSRomain Jobredeaux    java_runtime = host_javabase[java_common.JavaRuntimeInfo]
441*9e965d6fSRomain Jobredeaux    args["executable"] = java_runtime.java_executable_exec_path
442*9e965d6fSRomain Jobredeaux    args["toolchain"] = "@bazel_tools//tools/jdk:toolchain_type"
443*9e965d6fSRomain Jobredeaux
444*9e965d6fSRomain Jobredeaux    # inputs can be a list or a depset of File
445*9e965d6fSRomain Jobredeaux    inputs = args.get("inputs", default = [])
446*9e965d6fSRomain Jobredeaux    if type(inputs) == type([]):
447*9e965d6fSRomain Jobredeaux        args["inputs"] = depset(direct = inputs + [jar], transitive = [java_runtime.files])
448*9e965d6fSRomain Jobredeaux    else:  # inputs is a depset
449*9e965d6fSRomain Jobredeaux        args["inputs"] = depset(direct = [jar], transitive = [inputs, java_runtime.files])
450*9e965d6fSRomain Jobredeaux
451*9e965d6fSRomain Jobredeaux    jar_args = ctx.actions.args()
452*9e965d6fSRomain Jobredeaux    jar_args.add("-jar", jar)
453*9e965d6fSRomain Jobredeaux
454*9e965d6fSRomain Jobredeaux    args["arguments"] = jvm_flags + [jar_args] + args.get("arguments", default = [])
455*9e965d6fSRomain Jobredeaux
456*9e965d6fSRomain Jobredeaux    ctx.actions.run(**args)
457*9e965d6fSRomain Jobredeaux
458*9e965d6fSRomain Jobredeauxdef _create_deploy_jar(
459*9e965d6fSRomain Jobredeaux        ctx,
460*9e965d6fSRomain Jobredeaux        output = None,
461*9e965d6fSRomain Jobredeaux        runtime_jars = depset(),
462*9e965d6fSRomain Jobredeaux        java_toolchain = None,
463*9e965d6fSRomain Jobredeaux        build_target = "",
464*9e965d6fSRomain Jobredeaux        deploy_manifest_lines = []):
465*9e965d6fSRomain Jobredeaux    _singlejar(
466*9e965d6fSRomain Jobredeaux        ctx,
467*9e965d6fSRomain Jobredeaux        inputs = runtime_jars,
468*9e965d6fSRomain Jobredeaux        output = output,
469*9e965d6fSRomain Jobredeaux        mnemonic = "JavaDeployJar",
470*9e965d6fSRomain Jobredeaux        progress_message = "Building deploy jar %s" % output.short_path,
471*9e965d6fSRomain Jobredeaux        java_toolchain = java_toolchain,
472*9e965d6fSRomain Jobredeaux        build_target = build_target,
473*9e965d6fSRomain Jobredeaux        check_desugar_deps = True,
474*9e965d6fSRomain Jobredeaux        compression = False,
475*9e965d6fSRomain Jobredeaux        deploy_manifest_lines = deploy_manifest_lines,
476*9e965d6fSRomain Jobredeaux        resource_set = _resource_set_for_deploy_jar,
477*9e965d6fSRomain Jobredeaux    )
478*9e965d6fSRomain Jobredeaux    return output
479*9e965d6fSRomain Jobredeaux
480*9e965d6fSRomain Jobredeauxdef _resource_set_for_deploy_jar(_os, _inputs_size):
481*9e965d6fSRomain Jobredeaux    # parameters are unused but required by the resource_set API
482*9e965d6fSRomain Jobredeaux    return {"memory": _SINGLEJAR_MEMORY_FOR_DEPLOY_JAR_MB, "cpu": 1}
483*9e965d6fSRomain Jobredeaux
484*9e965d6fSRomain Jobredeauxjava = struct(
485*9e965d6fSRomain Jobredeaux    compile = _compile,
486*9e965d6fSRomain Jobredeaux    compile_android = _compile_android,
487*9e965d6fSRomain Jobredeaux    resolve_package = _resolve_package,
488*9e965d6fSRomain Jobredeaux    resolve_package_from_label = _resolve_package_from_label,
489*9e965d6fSRomain Jobredeaux    root = _root,
490*9e965d6fSRomain Jobredeaux    invalid_java_package = _invalid_java_package,
491*9e965d6fSRomain Jobredeaux    run = _run,
492*9e965d6fSRomain Jobredeaux    singlejar = _singlejar,
493*9e965d6fSRomain Jobredeaux    create_deploy_jar = _create_deploy_jar,
494*9e965d6fSRomain Jobredeaux)
495