229 lines
8.3 KiB
Python
229 lines
8.3 KiB
Python
# Copyright 2018 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.
|
|
|
|
"""android_library rule."""
|
|
|
|
load("//rules:acls.bzl", "acls")
|
|
load(":attrs.bzl", _ATTRS = "ATTRS")
|
|
load(":impl.bzl", _impl = "impl")
|
|
load(
|
|
"//rules:attrs.bzl",
|
|
_attrs = "attrs",
|
|
)
|
|
|
|
_RULE_DOC = """
|
|
#### Examples
|
|
|
|
The following example shows how to use android libraries with resources.
|
|
<pre><code>android_library(
|
|
name = "hellobazellib",
|
|
srcs = glob(["*.java"]),
|
|
resource_files = glob(["res/**/*"]),
|
|
manifest = "AndroidManifest.xml",
|
|
deps = [
|
|
"//java/bazel/hellobazellib/activities",
|
|
"//java/bazel/hellobazellib/common",
|
|
"//java/bazel/hellobazellib/math",
|
|
"//java/bazel/hellobazellib/service",
|
|
],
|
|
)</code></pre>
|
|
|
|
The following example shows how to set `idl_import_root`. Let //java/bazel/helloandroid/BUILD contain:
|
|
<pre><code>android_library(
|
|
name = "parcelable",
|
|
srcs = ["MyParcelable.java"], # bazel.helloandroid.MyParcelable
|
|
# MyParcelable.aidl will be used as import for other .aidl
|
|
# files that depend on it, but will not be compiled.
|
|
idl_parcelables = ["MyParcelable.aidl"] # bazel.helloandroid.MyParcelable
|
|
# We don't need to specify idl_import_root since the aidl file
|
|
# which declares bazel.helloandroid.MyParcelable
|
|
# is present at java/bazel/helloandroid/MyParcelable.aidl
|
|
# underneath a java root (java/).
|
|
)
|
|
android_library(
|
|
name = "foreign_parcelable",
|
|
srcs = ["src/android/helloandroid/OtherParcelable.java"], # android.helloandroid.OtherParcelable
|
|
idl_parcelables = [
|
|
"src/android/helloandroid/OtherParcelable.aidl" # android.helloandroid.OtherParcelable
|
|
],
|
|
# We need to specify idl_import_root because the aidl file which
|
|
# declares android.helloandroid.OtherParcelable is not positioned
|
|
# at android/helloandroid/OtherParcelable.aidl under a normal java root.
|
|
# Setting idl_import_root to "src" in //java/bazel/helloandroid
|
|
# adds java/bazel/helloandroid/src to the list of roots
|
|
# the aidl compiler will search for imported types.
|
|
idl_import_root = "src",
|
|
)
|
|
\\# Here, OtherInterface.aidl has an "import android.helloandroid.CallbackInterface;" statement.
|
|
android_library(
|
|
name = "foreign_interface",
|
|
idl_srcs = [
|
|
"src/android/helloandroid/OtherInterface.aidl" # android.helloandroid.OtherInterface
|
|
"src/android/helloandroid/CallbackInterface.aidl" # android.helloandroid.CallbackInterface
|
|
],
|
|
# As above, idl_srcs which are not correctly positioned under a java root
|
|
# must have idl_import_root set. Otherwise, OtherInterface (or any other
|
|
# interface in a library which depends on this one) will not be able
|
|
# to find CallbackInterface when it is imported.
|
|
idl_import_root = "src",
|
|
)
|
|
\\# MyParcelable.aidl is imported by MyInterface.aidl, so the generated
|
|
\\# MyInterface.java requires MyParcelable.class at compile time.
|
|
\\# Depending on :parcelable ensures that aidl compilation of MyInterface.aidl
|
|
\\# specifies the correct import roots and can access MyParcelable.aidl, and
|
|
\\# makes MyParcelable.class available to Java compilation of MyInterface.java
|
|
\\# as usual.
|
|
android_library(
|
|
name = "idl",
|
|
idl_srcs = ["MyInterface.aidl"],
|
|
deps = [":parcelable"],
|
|
)
|
|
\\# Here, ServiceParcelable uses and thus depends on ParcelableService,
|
|
\\# when it's compiled, but ParcelableService also uses ServiceParcelable,
|
|
\\# which creates a circular dependency.
|
|
\\# As a result, these files must be compiled together, in the same android_library.
|
|
android_library(
|
|
name = "circular_dependencies",
|
|
srcs = ["ServiceParcelable.java"],
|
|
idl_srcs = ["ParcelableService.aidl"],
|
|
idl_parcelables = ["ServiceParcelable.aidl"],
|
|
)</code></pre>
|
|
"""
|
|
|
|
def _outputs(name, _package_name, _defined_local_resources):
|
|
outputs = dict(
|
|
lib_jar = "lib%{name}.jar",
|
|
lib_src_jar = "lib%{name}-src.jar",
|
|
aar = "%{name}.aar",
|
|
)
|
|
|
|
if _defined_local_resources:
|
|
# TODO(b/177261846): resource-related predeclared outputs need to be re-pointed at the
|
|
# corresponding artifacts in the Starlark pipeline.
|
|
label = "//" + _package_name + ":" + name
|
|
if acls.in_android_library_starlark_resource_outputs_rollout(label):
|
|
path_prefix = "_migrated/"
|
|
else:
|
|
path_prefix = ""
|
|
outputs.update(
|
|
dict(
|
|
resources_src_jar = path_prefix + "%{name}.srcjar",
|
|
resources_txt = path_prefix + "%{name}_symbols/R.txt",
|
|
resources_jar = path_prefix + "%{name}_resources.jar",
|
|
),
|
|
)
|
|
|
|
return outputs
|
|
|
|
def make_rule(
|
|
attrs = _ATTRS,
|
|
implementation = _impl,
|
|
outputs = _outputs,
|
|
additional_toolchains = []):
|
|
"""Makes the rule.
|
|
|
|
Args:
|
|
attrs: A dict. The attributes for the rule.
|
|
implementation: A function. The rule's implementation method.
|
|
outputs: A dict, function, or None. The rule's outputs.
|
|
additional_toolchains: A list. Additional toolchains passed to pass to rule(toolchains).
|
|
|
|
Returns:
|
|
A rule.
|
|
"""
|
|
return rule(
|
|
attrs = attrs,
|
|
fragments = [
|
|
"android",
|
|
"java",
|
|
],
|
|
implementation = implementation,
|
|
doc = _RULE_DOC,
|
|
provides = [
|
|
AndroidCcLinkParamsInfo,
|
|
AndroidIdeInfo,
|
|
AndroidIdlInfo,
|
|
AndroidLibraryResourceClassJarProvider,
|
|
AndroidNativeLibsInfo,
|
|
JavaInfo,
|
|
],
|
|
outputs = outputs,
|
|
toolchains = [
|
|
"//toolchains/android:toolchain_type",
|
|
"//toolchains/android_sdk:toolchain_type",
|
|
] + additional_toolchains,
|
|
_skylark_testable = True,
|
|
)
|
|
|
|
android_library = make_rule()
|
|
|
|
def _is_defined(name, attrs):
|
|
return name in attrs and attrs[name] != None
|
|
|
|
def attrs_metadata(attrs):
|
|
"""Adds additional metadata for specific android_library attrs.
|
|
|
|
Bazel native rules have additional capabilities when inspecting attrs that
|
|
are not available in Starlark. For example, native rules are able to
|
|
determine if an attribute was set by a user and make decisions based on this
|
|
knowledge - sometimes the behavior may differ if the user specifies the
|
|
default value of the attribute. As such the Starlark android_library uses
|
|
this shim to provide similar capabilities.
|
|
|
|
Args:
|
|
attrs: The attributes passed to the android_library rule.
|
|
|
|
Returns:
|
|
A dictionary containing attr values with additional metadata.
|
|
"""
|
|
|
|
# Required for the outputs.
|
|
attrs["$defined_local_resources"] = bool(
|
|
attrs.get("assets") or
|
|
attrs.get("assets_dir") or
|
|
attrs.get("assets_dir") == "" or
|
|
attrs.get("export_manifest") or
|
|
attrs.get("manifest") or
|
|
attrs.get("resource_files"),
|
|
)
|
|
|
|
# TODO(b/116691720): Remove normalization when bug is fixed.
|
|
if _is_defined("exports_manifest", attrs):
|
|
attrs["exports_manifest"] = _attrs.tristate.normalize(
|
|
attrs.get("exports_manifest"),
|
|
)
|
|
|
|
# TODO(b/127517031): Remove these entries once fixed.
|
|
attrs["$defined_assets"] = _is_defined("assets", attrs)
|
|
attrs["$defined_assets_dir"] = _is_defined("assets_dir", attrs)
|
|
attrs["$defined_idl_import_root"] = _is_defined("idl_import_root", attrs)
|
|
attrs["$defined_idl_parcelables"] = _is_defined("idl_parcelables", attrs)
|
|
attrs["$defined_idl_srcs"] = _is_defined("idl_srcs", attrs)
|
|
|
|
# Required for ACLs check in _outputs(), since the callback can't access
|
|
# the native module.
|
|
attrs["$package_name"] = native.package_name()
|
|
|
|
return attrs
|
|
|
|
def android_library_macro(**attrs):
|
|
"""Bazel android_library rule.
|
|
|
|
https://docs.bazel.build/versions/master/be/android.html#android_library
|
|
|
|
Args:
|
|
**attrs: Rule attributes
|
|
"""
|
|
android_library(**attrs_metadata(attrs))
|