# Copyright 2021 The Bazel Authors. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Definition of java_library rule. """ load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") load("//java/common:java_semantics.bzl", "semantics") load("//java/private:java_common.bzl", "java_common") load("//java/private:java_info.bzl", "JavaInfo", "JavaPluginInfo") load(":basic_java_library.bzl", "BASIC_JAVA_LIBRARY_IMPLICIT_ATTRS") load(":rule_util.bzl", "merge_attrs") # copybara: default visibility BootClassPathInfo = java_common.BootClassPathInfo JAVA_LIBRARY_IMPLICIT_ATTRS = BASIC_JAVA_LIBRARY_IMPLICIT_ATTRS JAVA_LIBRARY_ATTRS = merge_attrs( JAVA_LIBRARY_IMPLICIT_ATTRS, # buildifier: disable=attr-licenses { "srcs": attr.label_list( allow_files = [".java", ".srcjar", ".properties"] + semantics.EXTRA_SRCS_TYPES, flags = ["DIRECT_COMPILE_TIME_INPUT", "ORDER_INDEPENDENT"], doc = """ The list of source files that are processed to create the target. This attribute is almost always required; see exceptions below.

Source files of type .java are compiled. In case of generated .java files it is generally advisable to put the generating rule's name here instead of the name of the file itself. This not only improves readability but makes the rule more resilient to future changes: if the generating rule generates different files in the future, you only need to fix one place: the outs of the generating rule. You should not list the generating rule in deps because it is a no-op.

Source files of type .srcjar are unpacked and compiled. (This is useful if you need to generate a set of .java files with a genrule.)

Rules: if the rule (typically genrule or filegroup) generates any of the files listed above, they will be used the same way as described for source files.

Source files of type .properties are treated as resources.

All other files are ignored, as long as there is at least one file of a file type described above. Otherwise an error is raised.

This argument is almost always required, except if you specify the runtime_deps argument.

""", ), "data": attr.label_list( allow_files = True, flags = ["SKIP_CONSTRAINTS_OVERRIDE"], doc = """ The list of files needed by this library at runtime. See general comments about data at Typical attributes defined by most build rules.

When building a java_library, Bazel doesn't put these files anywhere; if the data files are generated files then Bazel generates them. When building a test that depends on this java_library Bazel copies or links the data files into the runfiles area.

""" + semantics.DOCS.for_attribute("data"), ), "resources": attr.label_list( allow_files = True, flags = ["SKIP_CONSTRAINTS_OVERRIDE", "ORDER_INDEPENDENT"], doc = """ A list of data files to include in a Java jar.

Resources may be source files or generated files.

""" + semantics.DOCS.for_attribute("resources"), ), "plugins": attr.label_list( providers = [JavaPluginInfo], allow_files = True, cfg = "exec", doc = """ Java compiler plugins to run at compile-time. Every java_plugin specified in this attribute will be run whenever this rule is built. A library may also inherit plugins from dependencies that use exported_plugins. Resources generated by the plugin will be included in the resulting jar of this rule. """, ), "deps": attr.label_list( allow_files = [".jar"], allow_rules = semantics.ALLOWED_RULES_IN_DEPS + semantics.ALLOWED_RULES_IN_DEPS_WITH_WARNING, providers = [ [CcInfo], [JavaInfo], ], flags = ["SKIP_ANALYSIS_TIME_FILETYPE_CHECK"], doc = """ The list of libraries to link into this library. See general comments about deps at Typical attributes defined by most build rules.

The jars built by java_library rules listed in deps will be on the compile-time classpath of this rule. Furthermore the transitive closure of their deps, runtime_deps and exports will be on the runtime classpath.

By contrast, targets in the data attribute are included in the runfiles but on neither the compile-time nor runtime classpath.

""", ), "runtime_deps": attr.label_list( allow_files = [".jar"], allow_rules = semantics.ALLOWED_RULES_IN_DEPS, providers = [[CcInfo], [JavaInfo]], flags = ["SKIP_ANALYSIS_TIME_FILETYPE_CHECK"], doc = """ Libraries to make available to the final binary or test at runtime only. Like ordinary deps, these will appear on the runtime classpath, but unlike them, not on the compile-time classpath. Dependencies needed only at runtime should be listed here. Dependency-analysis tools should ignore targets that appear in both runtime_deps and deps. """, ), "exports": attr.label_list( allow_rules = semantics.ALLOWED_RULES_IN_DEPS, providers = [[JavaInfo], [CcInfo]], doc = """ Exported libraries.

Listing rules here will make them available to parent rules, as if the parents explicitly depended on these rules. This is not true for regular (non-exported) deps.

Summary: a rule X can access the code in Y if there exists a dependency path between them that begins with a deps edge followed by zero or more exports edges. Let's see some examples to illustrate this.

Assume A depends on B and B depends on C. In this case C is a transitive dependency of A, so changing C's sources and rebuilding A will correctly rebuild everything. However A will not be able to use classes in C. To allow that, either A has to declare C in its deps, or B can make it easier for A (and anything that may depend on A) by declaring C in its (B's) exports attribute.

The closure of exported libraries is available to all direct parent rules. Take a slightly different example: A depends on B, B depends on C and D, and also exports C but not D. Now A has access to C but not to D. Now, if C and D exported some libraries, C' and D' respectively, A could only access C' but not D'.

Important: an exported rule is not a regular dependency. Sticking to the previous example, if B exports C and wants to also use C, it has to also list it in its own deps.

""", ), "exported_plugins": attr.label_list( providers = [JavaPluginInfo], cfg = "exec", doc = """ The list of java_plugins (e.g. annotation processors) to export to libraries that directly depend on this library.

The specified list of java_plugins will be applied to any library which directly depends on this library, just as if that library had explicitly declared these labels in plugins.

""", ), "bootclasspath": attr.label( providers = [BootClassPathInfo], flags = ["SKIP_CONSTRAINTS_OVERRIDE"], doc = """Restricted API, do not use!""", ), "javabuilder_jvm_flags": attr.string_list(doc = """Restricted API, do not use!"""), "javacopts": attr.string_list( doc = """ Extra compiler options for this library. Subject to "Make variable" substitution and Bourne shell tokenization.

These compiler options are passed to javac after the global compiler options.

""", ), "neverlink": attr.bool( doc = """ Whether this library should only be used for compilation and not at runtime. Useful if the library will be provided by the runtime environment during execution. Examples of such libraries are the IDE APIs for IDE plug-ins or tools.jar for anything running on a standard JDK.

Note that neverlink = True does not prevent the compiler from inlining material from this library into compilation targets that depend on it, as permitted by the Java Language Specification (e.g., static final constants of String or of primitive types). The preferred use case is therefore when the runtime library is identical to the compilation library.

If the runtime library differs from the compilation library then you must ensure that it differs only in places that the JLS forbids compilers to inline (and that must hold for all future versions of the JLS).

""", ), "resource_strip_prefix": attr.string( doc = """ The path prefix to strip from Java resources.

If specified, this path prefix is stripped from every file in the resources attribute. It is an error for a resource file not to be under this directory. If not specified (the default), the path of resource file is determined according to the same logic as the Java package of source files. For example, a source file at stuff/java/foo/bar/a.txt will be located at foo/bar/a.txt.

""", ), "proguard_specs": attr.label_list( allow_files = True, doc = """ Files to be used as Proguard specification. These will describe the set of specifications to be used by Proguard. If specified, they will be added to any android_binary target depending on this library. The files included here must only have idempotent rules, namely -dontnote, -dontwarn, assumenosideeffects, and rules that start with -keep. Other options can only appear in android_binary's proguard_specs, to ensure non-tautological merges. """, ), "add_exports": attr.string_list( doc = """ Allow this library to access the given module or package.

This corresponds to the javac and JVM --add-exports= flags. """, ), "add_opens": attr.string_list( doc = """ Allow this library to reflectively access the given module or package.

This corresponds to the javac and JVM --add-opens= flags. """, ), "licenses": attr.license() if hasattr(attr, "license") else attr.string_list(), "_java_toolchain_type": attr.label(default = semantics.JAVA_TOOLCHAIN_TYPE), }, )