@Override
  public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
    return builder
        .requiresConfigurationFragments(PythonConfiguration.class)
        /* <!-- #BLAZE_RULE(py_library).ATTRIBUTE(deps) -->
        The list of other libraries to be linked in to the library target.
        ${SYNOPSIS}
        See general comments about <code>deps</code> at
        <a href="common-definitions.html#common-attributes">
        Attributes common to all build rules</a>.
        In practice, these arguments are treated like those in <code>srcs</code>;
        you may move items between these lists willy-nilly.  It's probably more
        readable to keep your <code>.py</code> files in your <code>srcs</code>.
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */

        /* <!-- #BLAZE_RULE(py_library).ATTRIBUTE(data) -->
        The list of files needed by this library at runtime.
        ${SYNOPSIS}
        See general comments about <code>data</code> at
        <a href="common-definitions.html#common-attributes">
        Attributes common to all build rules</a>.
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */

        /* <!-- #BLAZE_RULE(py_library).ATTRIBUTE(srcs) -->
        The list of source files that are processed to create the target.
        ${SYNOPSIS}
        This includes all your checked-in code and any generated source files.
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(
            attr("srcs", LABEL_LIST)
                .direct_compile_time_input()
                .allowedFileTypes(BazelPyRuleClasses.PYTHON_SOURCE))
        .build();
  }
示例#2
0
 @Override
 public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
   return builder
       .setUndocumented()
       /* <!-- #BLAZE_RULE($android_resource_support).ATTRIBUTE(manifest) -->
       The name of the Android manifest file, normally <code>AndroidManifest.xml</code>.
       Must be defined if resource_files or assets are defined.
       <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
       .add(attr("manifest", LABEL).legacyAllowAnyFileType())
       /* <!-- #BLAZE_RULE($android_resource_support).ATTRIBUTE(exports_manifest) -->
       Whether to export manifest entries to <code>android_binary</code> targets
       that depend on this target. <code>uses-permissions</code> attributes are never exported.
       <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
       .add(attr("exports_manifest", BOOLEAN).value(false))
       /* <!-- #BLAZE_RULE($android_resource_support).ATTRIBUTE(resource_files) -->
       The list of resources to be packaged.
       This is typically a <code>glob</code> of all files under the
       <code>res</code> directory.
       <br/>
       Generated files (from genrules) can be referenced by
       <a href="../build-ref.html#labels">Label</a> here as well. The only restriction is that
       the generated outputs must be under the same "<code>res</code>" directory as any other
       resource files that are included.
       <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
       .add(attr("resource_files", LABEL_LIST).legacyAllowAnyFileType())
       /* <!-- #BLAZE_RULE($android_resource_support).ATTRIBUTE(assets_dir) -->
       The string giving the path to the files in <code>assets</code>.
       The pair <code>assets</code> and <code>assets_dir</code> describe packaged
       assets and either both attributes should be provided or none of them.
       <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
       .add(attr("assets_dir", STRING))
       /* <!-- #BLAZE_RULE($android_resource_support).ATTRIBUTE(assets) -->
       The list of assets to be packaged.
       This is typically a <code>glob</code> of all files under the
       <code>assets</code> directory. You can also reference other rules (any rule that produces
       files) or exported files in the other packages, as long as all those files are under the
       <code>assets_dir</code> directory in the corresponding package.
       <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
       .add(attr("assets", LABEL_LIST).legacyAllowAnyFileType())
       /* <!-- #BLAZE_RULE($android_resource_support).ATTRIBUTE(inline_constants) -->
       Let the compiler inline the constants defined in the generated java sources.
       This attribute must be set to 0 for all <code>android_library</code> rules
       used directly by an <code>android_binary</code>,
       and for any <code>android_binary</code> that has an <code>android_library</code>
       in its transitive closure.
       <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
       .add(attr("inline_constants", BOOLEAN).value(false))
       /* <!-- #BLAZE_RULE($android_resource_support).ATTRIBUTE(custom_package) -->
       Java package for which java sources will be generated.
       By default the package is inferred from the directory where the BUILD file
       containing the rule is. You can specify a different package but this is
       highly discouraged since it can introduce classpath conflicts with other
       libraries that will only be detected at runtime.
       <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
       .add(attr("custom_package", STRING))
       .build();
 }
示例#3
0
 @Override
 public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
   return builder
       .add(
           attr("foo", LABEL_LIST)
               .legacyAllowAnyFileType()
               .aspect(AspectWithEmptyLateBoundAttribute.class))
       .build();
 }
示例#4
0
 @Override
 public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
   return builder
       .add(
           attr("foo", LABEL_LIST)
               .legacyAllowAnyFileType()
               .aspect(AspectThatRegistersAction.class))
       .add(attr(":action_listener", LABEL_LIST).cfg(HOST).value(ACTION_LISTENER))
       .build();
 }
示例#5
0
 /** Share common attributes across both base and Skylark base rules. */
 public static RuleClass.Builder commonCoreAndSkylarkAttributes(RuleClass.Builder builder) {
   return builder
       // The visibility attribute is special: it is a nodep label, and loading the
       // necessary package groups is handled by {@link LabelVisitor#visitTargetVisibility}.
       // Package groups always have the null configuration so that they are not duplicated
       // needlessly.
       .add(
           attr("visibility", NODEP_LABEL_LIST)
               .orderIndependent()
               .cfg(HOST)
               .nonconfigurable(
                   "special attribute integrated more deeply into Bazel's core logic"))
       .add(
           attr("deprecation", STRING)
               .value(deprecationDefault)
               .nonconfigurable("Used in core loading phase logic with no access to configs"))
       .add(
           attr("tags", STRING_LIST)
               .orderIndependent()
               .taggable()
               .nonconfigurable("low-level attribute, used in TargetUtils without configurations"))
       .add(
           attr("generator_name", STRING)
               .undocumented("internal")
               .nonconfigurable("static structure of a rule"))
       .add(
           attr("generator_function", STRING)
               .undocumented("internal")
               .nonconfigurable("static structure of a rule"))
       .add(
           attr("generator_location", STRING)
               .undocumented("internal")
               .nonconfigurable("static structure of a rule"))
       .add(
           attr("testonly", BOOLEAN)
               .value(testonlyDefault)
               .nonconfigurable("policy decision: rules testability should be consistent"))
       .add(attr("features", STRING_LIST).orderIndependent())
       .add(attr(":action_listener", LABEL_LIST).cfg(HOST).value(ACTION_LISTENER))
       .add(
           attr(RuleClass.COMPATIBLE_ENVIRONMENT_ATTR, LABEL_LIST)
               .allowedRuleClasses(EnvironmentRule.RULE_NAME)
               .cfg(Attribute.ConfigurationTransition.HOST)
               .allowedFileTypes(FileTypeSet.NO_FILE)
               .nonconfigurable(
                   "special logic for constraints and select: see ConstraintSemantics"))
       .add(
           attr(RuleClass.RESTRICTED_ENVIRONMENT_ATTR, LABEL_LIST)
               .allowedRuleClasses(EnvironmentRule.RULE_NAME)
               .cfg(Attribute.ConfigurationTransition.HOST)
               .allowedFileTypes(FileTypeSet.NO_FILE)
               .nonconfigurable(
                   "special logic for constraints and select: see ConstraintSemantics"));
 }
示例#6
0
 @Override
 public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
   return builder
       .add(
           attr("$android_resources_processor", LABEL)
               .cfg(HOST)
               .exec()
               .value(AndroidRuleClasses.DEFAULT_RESOURCES_PROCESSOR))
       .add(
           attr("$android_aar_generator", LABEL)
               .cfg(HOST)
               .exec()
               .value(AndroidRuleClasses.DEFAULT_AAR_GENERATOR))
       .build();
 }
示例#7
0
 @Override
 public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
   return builder
       .add(
           attr(":android_sdk", LABEL)
               .allowedRuleClasses("android_sdk", "filegroup")
               .value(new AndroidSdkLabel(env.getToolsLabel(AndroidRuleClasses.DEFAULT_SDK))))
       /* <!-- #BLAZE_RULE($android_base).ATTRIBUTE(plugins) -->
       Java compiler plugins to run at compile-time.
       Every <code>java_plugin</code> specified in
       the plugins attribute will be run whenever
       this target is built.  Resources generated by
       the plugin will be included in the result jar of
       the target.
       <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
       .add(
           attr("plugins", LABEL_LIST)
               .cfg(HOST)
               .allowedRuleClasses("java_plugin")
               .legacyAllowAnyFileType())
       .add(
           attr(":java_plugins", LABEL_LIST)
               .cfg(HOST)
               .allowedRuleClasses("java_plugin")
               .silentRuleClassFilter()
               .value(JavaSemantics.JAVA_PLUGINS))
       /* <!-- #BLAZE_RULE($android_base).ATTRIBUTE(javacopts) -->
       Extra compiler options for this target.
       Subject to <a href="${link make-variables}">"Make variable"</a> substitution and
       <a href="${link common-definitions#sh-tokenization}">Bourne shell tokenization</a>.
       <p>
       These compiler options are passed to javac after the global compiler options.</p>
       <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
       .add(attr("javacopts", STRING_LIST))
       // TODO(ahumesky): It would be better to put this dependency in //tools/android somehow
       // like all the rest of android tools.
       .add(
           attr("$jarjar_bin", LABEL)
               .cfg(HOST)
               .exec()
               .value(env.getToolsLabel("//third_party/java/jarjar:jarjar_bin")))
       .add(
           attr("$idlclass", LABEL)
               .cfg(HOST)
               .exec()
               .value(env.getToolsLabel("//tools/android:IdlClass")))
       .build();
 }
示例#8
0
    @Override
    public RuleClass build(RuleClass.Builder builder, final RuleDefinitionEnvironment env) {
      return builder
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(srcs) -->
          The list of source files that are processed to create the target.
          <p><code>srcs</code> files of type <code>.java</code> are compiled.
          <em>For readability's sake</em>, it is not good to put the name of a
          generated <code>.java</code> source file into the <code>srcs</code>.
          Instead, put the depended-on rule name in the <code>srcs</code>, as
          described below.
          </p>
          <p><code>srcs</code> files of type <code>.srcjar</code> are unpacked and
          compiled. (This is useful if you need to generate a set of .java files with
          a genrule or build extension.)
          </p>
          <p>This rule currently forces source and class compatibility with Java 6.
          </p>
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("srcs", LABEL_LIST)
                  .direct_compile_time_input()
                  .allowedFileTypes(JavaSemantics.JAVA_SOURCE, JavaSemantics.SOURCE_JAR))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(deps) -->
          The list of other libraries to be linked in to the binary target.
          Permitted library types are: <code>android_library</code>,
          <code>java_library</code> with <code>android</code> constraint and
          <code>cc_library</code> wrapping or producing <code>.so</code> native libraries for the
          Android target platform.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .override(
              builder
                  .copy("deps")
                  .cfg(ANDROID_SPLIT_TRANSITION)
                  .allowedRuleClasses(ALLOWED_DEPENDENCIES)
                  .allowedFileTypes()
                  .aspect(androidNeverlinkAspect)
                  .aspect(dexArchiveAspect, DexArchiveAspect.PARAM_EXTRACTOR)
                  .aspect(jackAspect))
          // Proguard rule specifying master list of classes to keep during legacy multidexing.
          .add(
              attr("$build_incremental_dexmanifest", LABEL)
                  .cfg(HOST)
                  .exec()
                  .value(env.getToolsLabel(BUILD_INCREMENTAL_DEXMANIFEST_LABEL)))
          .add(
              attr("$stubify_manifest", LABEL)
                  .cfg(HOST)
                  .exec()
                  .value(env.getToolsLabel(STUBIFY_MANIFEST_LABEL)))
          .add(
              attr("$shuffle_jars", LABEL)
                  .cfg(HOST)
                  .exec()
                  .value(env.getToolsLabel("//tools/android:shuffle_jars")))
          .add(
              attr("$dexbuilder", LABEL)
                  .cfg(HOST)
                  .exec()
                  .value(env.getToolsLabel("//tools/android:dexbuilder")))
          .add(
              attr("$dexmerger", LABEL)
                  .cfg(HOST)
                  .exec()
                  .value(env.getToolsLabel("//tools/android:dexmerger")))
          .add(
              attr("$merge_dexzips", LABEL)
                  .cfg(HOST)
                  .exec()
                  .value(env.getToolsLabel("//tools/android:merge_dexzips")))
          .add(
              attr("$incremental_install", LABEL)
                  .cfg(HOST)
                  .exec()
                  .value(env.getToolsLabel(INCREMENTAL_INSTALL_LABEL)))
          .add(
              attr("$build_split_manifest", LABEL)
                  .cfg(HOST)
                  .exec()
                  .value(env.getToolsLabel(BUILD_SPLIT_MANIFEST_LABEL)))
          .add(
              attr("$strip_resources", LABEL)
                  .cfg(HOST)
                  .exec()
                  .value(env.getToolsLabel(STRIP_RESOURCES_LABEL)))
          .add(
              attr("$incremental_stub_application", LABEL)
                  .value(env.getToolsLabel(DEFAULT_INCREMENTAL_STUB_APPLICATION)))
          .add(
              attr("$incremental_split_stub_application", LABEL)
                  .value(env.getToolsLabel(DEFAULT_INCREMENTAL_SPLIT_STUB_APPLICATION)))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(dexopts) -->
          Additional command-line flags for the dx tool when generating classes.dex.
          Subject to <a href="${link make-variables}">"Make variable"</a> substitution and
          <a href="${link common-definitions#sh-tokenization}">Bourne shell tokenization</a>.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("dexopts", STRING_LIST))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(dex_shards) -->
          Number of shards dexing should be decomposed into.
          This is makes dexing much faster at the expense of app installation and startup time. The
          larger the binary, the more shards should be used. 25 is a good value to start
          experimenting with.
          <p>
          Note that each shard will result in at least one dex in the final app. For this reason,
          setting this to more than 1 is not recommended for release binaries.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("dex_shards", INTEGER).value(1))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(incremental_dexing) -->
          Force the target to be built with or without incremental dexing, overriding defaults and
          --incremental_dexing flag. Users should set this attribute to 0 for release binaries
          (e.g., to avoid accidental usage of --incremental_dexing), since incremental dexing can
          produce slightly larger artifacts than dx. It is an error to set this attribute to 1 for
          android_binary and android_test rules that have Proguard enabled, as well as for
          android_test rules with binary_under_test set. We are working on addressing these
          shortcomings so please check with us if you run into these limitations.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("incremental_dexing", TRISTATE)
                  // Read by DexArchiveAspect's attribute extractor
                  .nonconfigurable("AspectParameters don't support configurations."))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(main_dex_list_opts) -->
          Command line options to pass to the main dex list builder.
          Use this option to affect the classes included in the main dex list.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("main_dex_list_opts", STRING_LIST))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(main_dex_list) -->

                    A text file contains a list of class file names. Classes defined by those class files are
                    put in the primary classes.dex. e.g.:<pre class="code">
          android/support/multidex/MultiDex$V19.class
          android/support/multidex/MultiDex.class
          android/support/multidex/MultiDexApplication.class
          com/google/common/base/Objects.class
                    </pre>
                    Must be used with <code>multidex="manual_main_dex"</code>.
                    <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("main_dex_list", LABEL).legacyAllowAnyFileType())
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(main_dex_proguard_specs) -->
          Files to be used as the Proguard specifications to determine classes that must be kept in
          the main dex.
          Only allowed if the <code>multidex</code> attribute is set to <code>legacy</code>.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("main_dex_proguard_specs", LABEL_LIST).legacyAllowAnyFileType())
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(proguard_specs) -->
          Files to be used as Proguard specification.
          This file will describe the set of specifications to be used by Proguard.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("proguard_specs", LABEL_LIST).legacyAllowAnyFileType())
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(proguard_generate_mapping) -->
          Whether to generate Proguard mapping file.
          The mapping file will be generated only if <code>proguard_specs</code> is
          specified. This file will list the mapping between the original and
          obfuscated class, method, and field names.
          <p><em class="harmful">WARNING: If this attribute is used, the Proguard
          specification should contain neither <code>-dontobfuscate</code> nor
          <code>-printmapping</code>.</em></p>
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(
              attr("proguard_generate_mapping", BOOLEAN)
                  .value(false)
                  .nonconfigurable("value is referenced in an ImplicitOutputsFunction"))
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(proguard_apply_mapping) -->
          File to be used as a mapping for proguard.
          A mapping file generated by <code>proguard_generate_mapping</code> to be
          re-used to apply the same mapping to a new build.
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("proguard_apply_mapping", LABEL).legacyAllowAnyFileType())
          /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(legacy_native_support) -->
          Enables legacy native support, where pre-compiled native libraries are copied
          directly into the APK.
          Possible values:
          <ul>
              <li><code>legacy_native_support = 1</code>: Pre-built .so files found in the
                dependencies of cc_libraries in the transitive closure will be copied into
                the APK without being modified in any way. All cc_libraries in the transitive
                closure of this rule must wrap .so files. (<em class="harmful">deprecated</em> -
                legacy_native_support = 0 will become the default and this attribute will be
                removed in a future Blaze release.)</li>
              <li><code>legacy_native_support = 0</code>: Native dependencies in the transitive
                closure will be linked together into a single lib[ruleName].so
                before being placed in the APK. This ensures that, e.g., only one copy of
                //base will be loaded into memory. This lib[ruleName].so can be loaded
                via System.loadLibrary as normal.</li>
              <li><code>legacy_native_support = -1</code>: Linking is controlled by the
                <a href="../blaze-user-manual.html#flag--legacy_android_native_support">
                --[no]legacy_android_native_support</a> Blaze flag.</li>
            </ul>
          <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
          .add(attr("legacy_native_support", TRISTATE).value(TriState.AUTO))
          .add(attr(":extra_proguard_specs", LABEL_LIST).value(JavaSemantics.EXTRA_PROGUARD_SPECS))
          .advertiseProvider(JavaCompilationArgsProvider.class)
          .build();
    }
示例#9
0
  @Override
  public RuleClass build(RuleClass.Builder builder, final RuleDefinitionEnvironment env) {
    return builder
        //       /* <!-- #BLAZE_RULE(android_binary).ATTRIBUTE(application_id) -->
        //       A full Java-language-style package name for the application. The name should be
        // unique.
        //       The name may contain uppercase or lowercase letters ('A' through 'Z'), numbers, and
        //       underscores ('_'). However, individual package name parts may only start with
        // letters.
        //       The package name serves as a unique identifier for the application. It's also the
        // default
        //       name for the application process (see the &lt;application&gt; element's process
        // attribute)
        //       and the default task affinity of an activity.
        //
        //       This overrides the value declared in the manifest.
        //       <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("application_id", STRING).undocumented("not ready for production use"))
        //       /* <!-- #BLAZE_RULE(android_binary).ATTRIBUTE(version_code) -->
        //       An internal version number. This number is used only to determine whether one
        // version is
        //       more recent than another, with higher numbers indicating more recent versions. This
        // is not
        //       the version number shown to users; that number is set by the version_name
        // attribute.
        //       The value must be set as an integer, such as "100". Each successive version must
        // have a
        //       higher number.
        //       This overrides the value declared in the manifest.
        //
        //       Subject to <a href="make-variables.html">"Make" variable</a> substitution.
        //       Suggested practice is to declare a varrdef and reference it here so that a
        // particular build
        //       invocation will be used to generate apks for release.
        //       <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("version_code", STRING).undocumented("not ready for production use"))
        //       /* <!-- #BLAZE_RULE(android_binary).ATTRIBUTE(version_name) -->
        //       The version number shown to users. The string has no other purpose than to be
        // displayed to
        //       users. The version_code attribute holds the significant version number used
        // internally.
        //       This overrides the value declared in the manifest.
        //
        //       Subject to <a href="make-variables.html">"Make" variable</a> substitution.
        //       Suggested practice is to declare a varrdef and reference it here so that a
        // particular build
        //       invocation will be used to generate apks for release.
        //       <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("version_name", STRING).undocumented("not ready for production use"))
        /* <!-- #BLAZE_RULE(android_binary).ATTRIBUTE(nocompress_extensions) -->
        A list of file extension to leave uncompressed in apk.
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("nocompress_extensions", STRING_LIST))
        /* <!-- #BLAZE_RULE(android_binary).ATTRIBUTE(resource_configuration_filters) -->
        A list of resource configuration filters, such 'en' that will limit the resources in the
        apk to only the ones in the 'en' configuration.
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("resource_configuration_filters", STRING_LIST))
        /* <!-- #BLAZE_RULE(android_binary).ATTRIBUTE(densities) -->
        Densities to filter for when building the apk.
        This will strip out raster drawable resources that would not be loaded by a device with
        the specified screen densities, to reduce APK size. A corresponding compatible-screens
        section will also be added to the manifest if it does not already contain a superset
        listing.
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(attr("densities", STRING_LIST))
        .add(
            attr("$android_manifest_merge_tool", LABEL)
                .cfg(HOST)
                .exec()
                .value(env.getToolsLabel(AndroidRuleClasses.MANIFEST_MERGE_TOOL_LABEL)))

        /* <!-- #BLAZE_RULE(android_binary).ATTRIBUTE(multidex) -->
        Whether to split code into multiple dex files.
        Possible values:
        <ul>
          <li><code>native</code>: Split code into multiple dex files when the
            dex 64K index limit is exceeded.
            Assumes native platform support for loading multidex classes at
            runtime. <em class="harmful">This only works with Android L and
            newer</em>.</li>
          <li><code>legacy</code>: Split code into multiple dex files when the
            dex 64K index limit is exceeded. Assumes multidex classes are
            loaded through application code (i.e. no platform support).</li>
          <li><code>manual_main_dex</code>: Split code into multiple dex files when the
            dex 64K index limit is exceeded. The content of the main dex file
            needs to be specified by providing a list of classes in a text file
            using the <a href="#android_binary.main_dex_list">main_dex_list</a>.</li>
          <li><code>off</code>: Compile all code to a single dex file, even if
            if exceeds the index limit.</li>
        </ul>
        <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
        .add(
            attr("multidex", STRING)
                .allowedValues(new AllowedValueSet(MultidexMode.getValidValues()))
                .value(MultidexMode.OFF.getAttributeValue()))
        .removeAttribute("data")
        .build();
  }