@Test public void findDepsFromParamsSetsUpDepsForFlavoredTarget() { // Create the thrift target and implicit dep. BuildTarget thriftTarget = BuildTargetFactory.newInstance("//bar:thrift_compiler"); FakeBuildRule implicitDep = createFakeBuildRule("//foo:implicit_dep", new SourcePathResolver(new BuildRuleResolver())); // Setup the default values returned by the language specific enhancer. String language = "fake"; Flavor flavor = ImmutableFlavor.of("fake"); ImmutableSet<String> options = ImmutableSet.of(); ImmutableSet<BuildTarget> implicitDeps = ImmutableSet.of(implicitDep.getBuildTarget()); BuildTarget unflavoredTarget = BuildTargetFactory.newInstance("//:thrift"); BuildTarget flavoredTarget = BuildTargets.createFlavoredBuildTarget(unflavoredTarget.checkUnflavored(), flavor); // Setup an empty thrift buck config and description. FakeBuckConfig buckConfig = new FakeBuckConfig( ImmutableMap.of("thrift", ImmutableMap.of("compiler", thriftTarget.toString()))); ThriftBuckConfig thriftBuckConfig = new ThriftBuckConfig(buckConfig); ThriftLanguageSpecificEnhancer enhancer = new FakeThriftLanguageSpecificEnhancer(language, flavor, implicitDeps, options); ThriftLibraryDescription desc = new ThriftLibraryDescription(thriftBuckConfig, ImmutableList.of(enhancer)); ThriftConstructorArg constructorArg = desc.createUnpopulatedConstructorArg(); constructorArg.deps = Optional.of(ImmutableSortedSet.<BuildTarget>of()); // Now call the find deps methods and verify it returns nothing. Iterable<BuildTarget> results = desc.findDepsForTargetFromConstructorArgs(flavoredTarget, constructorArg); assertEquals( ImmutableSet.<BuildTarget>builder() .add(unflavoredTarget) .add(thriftTarget) .addAll(implicitDeps) .build(), ImmutableSet.copyOf(results)); }
@Override public <A extends Arg> BuildRule createBuildRule( TargetGraph targetGraph, BuildRuleParams originalBuildRuleParams, BuildRuleResolver resolver, A args) { UnflavoredBuildTarget originalBuildTarget = originalBuildRuleParams.getBuildTarget().checkUnflavored(); SourcePathResolver pathResolver = new SourcePathResolver(resolver); ImmutableList.Builder<BuildRule> aarExtraDepsBuilder = ImmutableList.<BuildRule>builder().addAll(originalBuildRuleParams.getExtraDeps().get()); /* android_manifest */ AndroidManifestDescription.Arg androidManifestArgs = androidManifestDescription.createUnpopulatedConstructorArg(); androidManifestArgs.skeleton = args.manifestSkeleton; androidManifestArgs.deps = args.deps; BuildRuleParams androidManifestParams = originalBuildRuleParams.copyWithChanges( BuildTargets.createFlavoredBuildTarget( originalBuildTarget, AAR_ANDROID_MANIFEST_FLAVOR), originalBuildRuleParams.getDeclaredDeps(), originalBuildRuleParams.getExtraDeps()); AndroidManifest manifest = androidManifestDescription.createBuildRule( targetGraph, androidManifestParams, resolver, androidManifestArgs); aarExtraDepsBuilder.add(resolver.addToIndex(manifest)); /* assemble dirs */ AndroidPackageableCollector collector = new AndroidPackageableCollector( originalBuildRuleParams.getBuildTarget(), /* buildTargetsToExcludeFromDex */ ImmutableSet.<BuildTarget>of(), /* resourcesToExclude */ ImmutableSet.<BuildTarget>of()); collector.addPackageables( AndroidPackageableCollector.getPackageableRules(originalBuildRuleParams.getDeps())); AndroidPackageableCollection packageableCollection = collector.build(); ImmutableSortedSet<BuildRule> androidResourceDeclaredDeps = AndroidResourceHelper.androidResOnly(originalBuildRuleParams.getDeclaredDeps().get()); ImmutableSortedSet<BuildRule> androidResourceExtraDeps = AndroidResourceHelper.androidResOnly(originalBuildRuleParams.getExtraDeps().get()); BuildRuleParams assembleAssetsParams = originalBuildRuleParams.copyWithChanges( BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_ASSEMBLE_ASSETS_FLAVOR), Suppliers.ofInstance(androidResourceDeclaredDeps), Suppliers.ofInstance(androidResourceExtraDeps)); ImmutableCollection<SourcePath> assetsDirectories = packageableCollection.getAssetsDirectories(); AssembleDirectories assembleAssetsDirectories = new AssembleDirectories(assembleAssetsParams, pathResolver, assetsDirectories); aarExtraDepsBuilder.add(resolver.addToIndex(assembleAssetsDirectories)); BuildRuleParams assembleResourceParams = originalBuildRuleParams.copyWithChanges( BuildTargets.createFlavoredBuildTarget( originalBuildTarget, AAR_ASSEMBLE_RESOURCE_FLAVOR), Suppliers.ofInstance(androidResourceDeclaredDeps), Suppliers.ofInstance(androidResourceExtraDeps)); ImmutableCollection<SourcePath> resDirectories = packageableCollection.getResourceDetails().getResourceDirectories(); MergeAndroidResourceSources assembleResourceDirectories = new MergeAndroidResourceSources(assembleResourceParams, pathResolver, resDirectories); aarExtraDepsBuilder.add(resolver.addToIndex(assembleResourceDirectories)); /* android_resource */ BuildRuleParams androidResourceParams = originalBuildRuleParams.copyWithChanges( BuildTargets.createFlavoredBuildTarget( originalBuildTarget, AAR_ANDROID_RESOURCE_FLAVOR), Suppliers.ofInstance( ImmutableSortedSet.<BuildRule>of( manifest, assembleAssetsDirectories, assembleResourceDirectories)), Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of())); AndroidResource androidResource = new AndroidResource( androidResourceParams, pathResolver, /* deps */ ImmutableSortedSet.<BuildRule>naturalOrder() .add(assembleAssetsDirectories) .add(assembleResourceDirectories) .addAll(originalBuildRuleParams.getDeclaredDeps().get()) .build(), new BuildTargetSourcePath(assembleResourceDirectories.getBuildTarget()), /* resSrcs */ ImmutableSortedSet.<SourcePath>of(), Optional.<SourcePath>absent(), /* rDotJavaPackage */ null, new BuildTargetSourcePath(assembleAssetsDirectories.getBuildTarget()), /* assetsSrcs */ ImmutableSortedSet.<SourcePath>of(), Optional.<SourcePath>absent(), new BuildTargetSourcePath(manifest.getBuildTarget()), /* hasWhitelistedStrings */ false); aarExtraDepsBuilder.add(resolver.addToIndex(androidResource)); /* native_libraries */ AndroidNativeLibsPackageableGraphEnhancer packageableGraphEnhancer = new AndroidNativeLibsPackageableGraphEnhancer( resolver, originalBuildRuleParams, nativePlatforms, ImmutableSet.<NdkCxxPlatforms.TargetCpuType>of()); Optional<CopyNativeLibraries> nativeLibrariesOptional = packageableGraphEnhancer.getCopyNativeLibraries(targetGraph, packageableCollection); if (nativeLibrariesOptional.isPresent()) { aarExtraDepsBuilder.add(resolver.addToIndex(nativeLibrariesOptional.get())); } Optional<Path> assembledNativeLibsDir = nativeLibrariesOptional.transform( new Function<CopyNativeLibraries, Path>() { @Override public Path apply(CopyNativeLibraries input) { return input.getPathToNativeLibsDir(); } }); BuildRuleParams androidAarParams = originalBuildRuleParams.copyWithExtraDeps( Suppliers.ofInstance(ImmutableSortedSet.copyOf(aarExtraDepsBuilder.build()))); return new AndroidAar( androidAarParams, pathResolver, manifest, androidResource, assembleResourceDirectories.getPathToOutput(), assembleAssetsDirectories.getPathToOutput(), assembledNativeLibsDir, packageableCollection.getNativeLibAssetsDirectories()); }
@Test public void createThriftCompilerBuildRulesHasCorrectDeps() throws IOException { BuildRuleResolver resolver = new BuildRuleResolver(); SourcePathResolver pathResolver = new SourcePathResolver(resolver); FakeProjectFilesystem filesystem = new FakeProjectFilesystem(); String language = "fake"; Flavor flavor = ImmutableFlavor.of("fake"); ImmutableSet<String> options = ImmutableSet.of(); // Setup the default values returned by the language specific enhancer. BuildTarget unflavoredTarget = BuildTargetFactory.newInstance("//:thrift"); BuildRuleParams unflavoredParams = new FakeBuildRuleParamsBuilder(BuildTarget.builder(unflavoredTarget).build()) .setProjectFilesystem(filesystem) .build(); // Setup a thrift source file generated by a genrule. BuildTarget flavoredTarget = BuildTargets.createFlavoredBuildTarget(unflavoredTarget.checkUnflavored(), flavor); BuildRuleParams flavoredParams = new FakeBuildRuleParamsBuilder(flavoredTarget).setProjectFilesystem(filesystem).build(); // Create a path for the thrift compiler. Path thriftPath = Paths.get("thrift_path"); filesystem.touch(thriftPath); // Setup an thrift buck config, with the path to the thrift compiler set. FakeBuckConfig buckConfig = new FakeBuckConfig( ImmutableMap.of("thrift", ImmutableMap.of("compiler", thriftPath.toString())), filesystem); ThriftBuckConfig thriftBuckConfig = new ThriftBuckConfig(buckConfig); ThriftLibraryDescription desc = new ThriftLibraryDescription( thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of()); // Setup a simple thrift source. String sourceName = "test.thrift"; SourcePath sourcePath = new TestSourcePath(sourceName); // Generate these rules using no deps. ImmutableMap<String, ThriftCompiler> rules = desc.createThriftCompilerBuildRules( flavoredParams, resolver, ThriftLibraryDescription.CompilerType.THRIFT, ImmutableList.<String>of(), language, options, ImmutableMap.of(sourceName, sourcePath), ImmutableSortedSet.<ThriftLibrary>of()); // Now verify that the generated rule had no associated deps. assertSame(rules.size(), 1); ThriftCompiler rule = rules.get(sourceName); assertNotNull(rule); assertEquals(ImmutableSortedSet.<BuildRule>of(), rule.getDeps()); // Lets do this again, but pass in a ThriftLibrary deps, wrapping some includes we need. Path includeRoot = desc.getIncludeRoot(unflavoredTarget); HeaderSymlinkTree thriftIncludeSymlinkTree = createFakeSymlinkTree( desc.createThriftIncludeSymlinkTreeTarget(unflavoredTarget), pathResolver, includeRoot); ThriftLibrary lib = new ThriftLibrary( unflavoredParams, pathResolver, ImmutableSortedSet.<ThriftLibrary>of(), thriftIncludeSymlinkTree, ImmutableMap.<Path, SourcePath>of()); // Generate these rules using no deps. rules = desc.createThriftCompilerBuildRules( flavoredParams, resolver, ThriftLibraryDescription.CompilerType.THRIFT, ImmutableList.<String>of(), language, options, ImmutableMap.of(sourceName, sourcePath), ImmutableSortedSet.of(lib)); // Now verify that the generated rule has all the deps from the passed in thrift library. assertSame(rules.size(), 1); rule = rules.get(sourceName); assertNotNull(rule); assertEquals(ImmutableSortedSet.<BuildRule>of(thriftIncludeSymlinkTree), rule.getDeps()); // Setup a simple genrule that creates the thrift source and verify its dep is propagated. Genrule genrule = (Genrule) GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:genrule")) .setOut(sourceName) .build(resolver); SourcePath ruleSourcePath = new BuildTargetSourcePath(genrule.getBuildTarget()); // Generate these rules using no deps and the genrule generated source. rules = desc.createThriftCompilerBuildRules( flavoredParams, resolver, ThriftLibraryDescription.CompilerType.THRIFT, ImmutableList.<String>of(), language, options, ImmutableMap.of(sourceName, ruleSourcePath), ImmutableSortedSet.<ThriftLibrary>of()); // Now verify that the generated rule had no associated deps. assertSame(rules.size(), 1); rule = rules.get(sourceName); assertNotNull(rule); assertEquals(ImmutableSortedSet.<BuildRule>of(genrule), rule.getDeps()); // Create a build rule that represents the thrift rule. FakeBuildRule thriftRule = createFakeBuildRule("//thrift:target", pathResolver); resolver.addToIndex(thriftRule); filesystem.mkdirs(thriftRule.getBuildTarget().getBasePath()); filesystem.touch(thriftRule.getBuildTarget().getBasePath().resolve("BUCK")); // Setup an empty thrift buck config, and set compiler target. buckConfig = new FakeBuckConfig( ImmutableMap.of( "thrift", ImmutableMap.of("compiler", thriftRule.getBuildTarget().toString())), filesystem); thriftBuckConfig = new ThriftBuckConfig(buckConfig); desc = new ThriftLibraryDescription( thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of()); // Generate these rules using no deps with a compiler target. rules = desc.createThriftCompilerBuildRules( flavoredParams, resolver, ThriftLibraryDescription.CompilerType.THRIFT, ImmutableList.<String>of(), language, options, ImmutableMap.of(sourceName, sourcePath), ImmutableSortedSet.<ThriftLibrary>of()); // Now verify that the generated rule only has deps from the compiler target. assertSame(rules.size(), 1); rule = rules.get(sourceName); assertNotNull(rule); assertEquals(ImmutableSortedSet.<BuildRule>of(thriftRule), rule.getDeps()); }
@Test public void createBuildRuleWithFlavoredTargetCallsEnhancerCorrectly() throws IOException { BuildRuleResolver resolver = new BuildRuleResolver(); SourcePathResolver pathResolver = new SourcePathResolver(resolver); FakeProjectFilesystem filesystem = new FakeProjectFilesystem(); // Setup the default values returned by the language specific enhancer. String language = "fake"; Flavor flavor = ImmutableFlavor.of("fake"); final BuildRule implicitDep = createFakeBuildRule("//implicit:dep", pathResolver); resolver.addToIndex(implicitDep); filesystem.mkdirs(implicitDep.getBuildTarget().getBasePath()); filesystem.touch(implicitDep.getBuildTarget().getBasePath().resolve("BUCK")); ImmutableSet<BuildTarget> implicitDeps = ImmutableSet.of(implicitDep.getBuildTarget()); ImmutableSet<String> options = ImmutableSet.of(); // Create the build targets and params. BuildTarget unflavoredTarget = BuildTargetFactory.newInstance("//:thrift"); BuildRuleParams unflavoredParams = new FakeBuildRuleParamsBuilder(unflavoredTarget).setProjectFilesystem(filesystem).build(); BuildTarget flavoredTarget = BuildTargets.createFlavoredBuildTarget(unflavoredTarget.checkUnflavored(), flavor); BuildRuleParams flavoredParams = new FakeBuildRuleParamsBuilder(flavoredTarget).setProjectFilesystem(filesystem).build(); // Setup a thrift source file generated by a genrule. final String thriftSourceName1 = "foo.thrift"; BuildTarget genruleTarget = BuildTargetFactory.newInstance("//:genrule"); final Genrule genrule = (Genrule) GenruleBuilder.newGenruleBuilder(genruleTarget) .setOut(thriftSourceName1) .build(resolver); SourcePath thriftSource1 = new BuildTargetSourcePath(genrule.getBuildTarget()); final ImmutableList<String> thriftServices1 = ImmutableList.of(); // Setup a normal thrift source file. final String thriftSourceName2 = "bar.thrift"; SourcePath thriftSource2 = new TestSourcePath(thriftSourceName2); final ImmutableList<String> thriftServices2 = ImmutableList.of(); // Create a build rule that represents the thrift rule. final FakeBuildRule thriftRule = createFakeBuildRule("//thrift:target", pathResolver); resolver.addToIndex(thriftRule); filesystem.mkdirs(thriftRule.getBuildTarget().getBasePath()); filesystem.touch(thriftRule.getBuildTarget().getBasePath().resolve("BUCK")); // Setup a simple description with an empty config. FakeBuckConfig buckConfig = new FakeBuckConfig( ImmutableMap.of( "thrift", ImmutableMap.of("compiler", thriftRule.getBuildTarget().toString()))); ThriftBuckConfig thriftBuckConfig = new ThriftBuckConfig(buckConfig); ThriftLibraryDescription desc = new ThriftLibraryDescription( thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of()); // Setup the include rules. final BuildRule thriftIncludeSymlinkTree = createFakeBuildRule( desc.createThriftIncludeSymlinkTreeTarget(unflavoredTarget), pathResolver); // Setup our language enhancer FakeThriftLanguageSpecificEnhancer enhancer = new FakeThriftLanguageSpecificEnhancer(language, flavor, implicitDeps, options) { @Override public void checkCreateBuildRuleInputs( ImmutableMap<String, ThriftSource> sources, ImmutableSortedSet<BuildRule> deps) { // Verify both thrift sources are present in the list. assertEquals(2, sources.size()); ThriftSource src1 = sources.get(thriftSourceName1); assertNotNull(src1); ThriftSource src2 = sources.get(thriftSourceName2); assertNotNull(src2); // Verify the services are listed correctly for both sources. assertEquals(thriftServices1, src1.getServices()); assertEquals(thriftServices2, src2.getServices()); // Verify dependencies are setup correctly. assertEquals( ImmutableSortedSet.of(genrule, thriftRule, thriftIncludeSymlinkTree), src1.getCompileRule().getDeps()); assertEquals( ImmutableSortedSet.of(genrule, thriftRule, thriftIncludeSymlinkTree), src2.getCompileRule().getDeps()); // Verify the language specific implicit rules are added correctly. assertEquals( ImmutableSortedSet.<BuildRule>naturalOrder().add(implicitDep).build(), deps); } }; // Recreate the description with the enhancer we setup above. desc = new ThriftLibraryDescription( thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of(enhancer)); // Setup the internal structure indicating that the thrift target was set in the // buck config. // desc.setCompilerTarget(thriftRule.getBuildTarget()); // Setup the implicit deps for the flavored build target. // desc.setImplicitDeps(flavoredTarget, ImmutableList.of(implicitDep.getBuildTarget())); // Build up the constructor arg. ThriftConstructorArg arg = desc.createUnpopulatedConstructorArg(); arg.name = "thrift"; arg.srcs = ImmutableMap.of( thriftSource1, thriftServices1, thriftSource2, thriftServices2); arg.deps = Optional.absent(); arg.flags = Optional.absent(); // Setup the unflavored target, which should just produce a ThriftInclude, SymlinkTree, and // ThriftLibrary rule. BuildRule rule = desc.createBuildRule(TargetGraph.EMPTY, unflavoredParams, resolver, arg); resolver.addToIndex(rule); // Now attempt to create the flavored thrift library. desc.createBuildRule(TargetGraph.EMPTY, flavoredParams, resolver, arg); }
/** * Creates a rooted DAG of build rules: * * <ul> * <li>{@code unzip_aar} depends on the deps specified to the original {@code android_aar} * <li>{@code prebuilt_jar} depends on {@code unzip_aar} * <li>{@code android_resource} depends on {@code unzip_aar} * <li>{@code android_library} depends on {@code android_resource}, {@code prebuilt_jar}, and * {@code unzip_aar} * </ul> * * Therefore, the return value is an {link AndroidLibrary} with no {@code srcs}. */ static BuildRule enhance( BuildRuleParams originalBuildRuleParams, SourcePath aarFile, BuildRuleResolver ruleResolver) { // unzip_aar BuildTarget originalBuildTarget = originalBuildRuleParams.getBuildTarget(); BuildRuleParams unzipAarParams = originalBuildRuleParams.copyWithChanges( UNZIP_AAR_TYPE, BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_UNZIP_FLAVOR), originalBuildRuleParams.getDeclaredDeps(), originalBuildRuleParams.getExtraDeps()); UnzipAar unzipAar = new UnzipAar(unzipAarParams, aarFile); ruleResolver.addToIndex(unzipAar); // unzip_aar#aar_classes_jar BuildRuleParams classesJarParams = originalBuildRuleParams.copyWithChanges( OutputOnlyBuildRule.TYPE, BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_CLASSES_JAR_FLAVOR), /* declaredDeps */ ImmutableSortedSet.<BuildRule>of(unzipAar), /* extraDeps */ ImmutableSortedSet.<BuildRule>of()); OutputOnlyBuildRule classesJar = new OutputOnlyBuildRule(classesJarParams, unzipAar.getPathToClassesJar()); ruleResolver.addToIndex(classesJar); // prebuilt_jar BuildRuleParams prebuiltJarParams = originalBuildRuleParams.copyWithChanges( PrebuiltJarDescription.TYPE, BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_PREBUILT_JAR_FLAVOR), /* declaredDeps */ ImmutableSortedSet.<BuildRule>of(unzipAar), /* extraDeps */ ImmutableSortedSet.<BuildRule>of()); PrebuiltJar prebuiltJar = new PrebuiltJar( /* params */ prebuiltJarParams, new BuildRuleSourcePath(classesJar), /* sourceJar */ Optional.<SourcePath>absent(), /* gwtJar */ Optional.<SourcePath>absent(), /* javadocUrl */ Optional.<String>absent()); ruleResolver.addToIndex(prebuiltJar); // unzip_aar#aar_manifest BuildRuleParams manifestParams = originalBuildRuleParams.copyWithChanges( OutputOnlyBuildRule.TYPE, BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_MANIFEST), /* declaredDeps */ ImmutableSortedSet.<BuildRule>of(unzipAar), /* extraDeps */ ImmutableSortedSet.<BuildRule>of()); OutputOnlyBuildRule manifest = new OutputOnlyBuildRule(manifestParams, unzipAar.getAndroidManifest()); ruleResolver.addToIndex(manifest); // android_resource BuildRuleParams androidResourceParams = originalBuildRuleParams.copyWithChanges( AndroidResourceDescription.TYPE, BuildTargets.createFlavoredBuildTarget( originalBuildTarget, AAR_ANDROID_RESOURCE_FLAVOR), /* declaredDeps */ ImmutableSortedSet.<BuildRule>of(manifest), /* extraDeps */ ImmutableSortedSet.<BuildRule>of()); // Because all resources and assets are generated files, we specify them as empty collections. ImmutableSortedSet<Path> resSrcs = ImmutableSortedSet.of(); ImmutableSortedSet<Path> assetsSrcs = ImmutableSortedSet.of(); AndroidResource androidResource = new AndroidResource( androidResourceParams, /* deps */ ImmutableSortedSet.<BuildRule>of(unzipAar), unzipAar.getResDirectory(), resSrcs, /* rDotJavaPackage */ null, /* assets */ unzipAar.getAssetsDirectory(), assetsSrcs, new BuildRuleSourcePath(manifest), /* hasWhitelistedStrings */ false); ruleResolver.addToIndex(androidResource); // android_library BuildRuleParams androidLibraryParams = originalBuildRuleParams.copyWithChanges( AndroidLibraryDescription.TYPE, BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_ANDROID_LIBRARY_FLAVOR), /* declaredDeps */ ImmutableSortedSet.<BuildRule>of( androidResource, prebuiltJar, unzipAar), /* extraDeps */ ImmutableSortedSet.<BuildRule>of()); return new AndroidLibrary( androidLibraryParams, /* srcs */ ImmutableSortedSet.<SourcePath>of(), /* resources */ ImmutableSortedSet.<SourcePath>of(), Optional.of(unzipAar.getProguardConfig()), /* postprocessClassesCommands */ ImmutableList.<String>of(), /* exportedDeps */ ImmutableSortedSet.<BuildRule>of(prebuiltJar), /* providedDeps */ ImmutableSortedSet.<BuildRule>of(), /* additionalClasspathEntries */ ImmutableSet.<Path>of(), /* javacOptions */ JavacOptions.DEFAULTS, /* resourcesRoot */ Optional.<Path>absent(), /* manifestFile */ Optional.<SourcePath>absent(), /* isPrebuiltAar */ true); }