Skip to content

Commit

Permalink
Support --output_library_merged_assets
Browse files Browse the repository at this point in the history
  • Loading branch information
Bencodes committed Apr 26, 2021
1 parent 492b865 commit 8973c51
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,14 @@ ParsedAndroidAssets parse(AndroidDataContext dataContext) throws InterruptedExce
/** Convenience method to do all of asset processing - parsing and merging. */
public MergedAndroidAssets process(AndroidDataContext dataContext, AssetDependencies assetDeps)
throws InterruptedException {
return parse(dataContext).merge(dataContext, assetDeps);
ParsedAndroidAssets parsedAssets = parse(dataContext);

boolean mergeAssets = dataContext.getAndroidConfig().outputLibraryMergedAssets()
|| dataContext.throwOnResourceConflict();

return mergeAssets ?
parsedAssets.merge(dataContext, assetDeps) :
MergedAndroidAssets.of(parsedAssets, null, assetDeps);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,14 @@ public static class Options extends FragmentOptions {
+ " instead of declarations plus all dependency references.")
public boolean namespacedRClass;

@Option(
name = "output_library_merged_assets",
defaultValue = "true",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.UNKNOWN},
help = "If disabled, does not produce merged asset.zip outputs for library targets")
public boolean outputLibraryMergedAssets;

@Option(
name = "legacy_main_dex_list_generator",
// TODO(b/147692286): Update this default value to R8's GenerateMainDexList binary after
Expand Down Expand Up @@ -1012,6 +1020,7 @@ public FragmentOptions getHost() {
private final boolean useRTxtFromMergedResources;
private final boolean linkLibraryResources;
private final boolean namespacedRClass;
private final boolean outputLibraryMergedAssets;
private final Label legacyMainDexListGenerator;
private final boolean disableInstrumentationManifestMerging;
private final boolean incompatibleUseToolchainResolution;
Expand Down Expand Up @@ -1072,6 +1081,7 @@ public AndroidConfiguration(BuildOptions buildOptions) throws InvalidConfigurati
this.useRTxtFromMergedResources = options.useRTxtFromMergedResources;
this.linkLibraryResources = options.linkLibraryResources;
this.namespacedRClass = options.namespacedRClass;
this.outputLibraryMergedAssets = options.outputLibraryMergedAssets;
this.legacyMainDexListGenerator = options.legacyMainDexListGenerator;
this.disableInstrumentationManifestMerging = options.disableInstrumentationManifestMerging;
this.incompatibleUseToolchainResolution = options.incompatibleUseToolchainResolution;
Expand Down Expand Up @@ -1349,6 +1359,10 @@ public boolean disableInstrumentationManifestMerging() {
return disableInstrumentationManifestMerging;
}

boolean outputLibraryMergedAssets() {
return outputLibraryMergedAssets;
}

/** Returns the label provided with --legacy_main_dex_list_generator, if any. */
// TODO(b/147692286): Move R8's main dex list tool into tool repository.
@StarlarkConfigurationField(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ static MergedAndroidAssets mergeFrom(
AndroidDataContext dataContext, ParsedAndroidAssets parsed, AssetDependencies deps)
throws InterruptedException {

Artifact mergedAssets =
dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_ASSETS_ZIP);
Artifact mergedAssets = dataContext.getAndroidConfig().outputLibraryMergedAssets() ?
dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_ASSETS_ZIP) : null;

BusyBoxActionBuilder builder = BusyBoxActionBuilder.create(dataContext, "MERGE_ASSETS");
if (dataContext.throwOnResourceConflict()) {
builder.addFlag("--throwOnAssetConflict");
}

builder
.addOutput("--assetsOutput", mergedAssets)
.maybeAddOutput("--assetsOutput", mergedAssets)
.addInput(
"--primaryData",
AndroidDataConverter.PARSED_ASSET_CONVERTER.map(parsed),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
// limitations under the License.
package com.google.devtools.build.android;

import com.android.builder.core.VariantType;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.devtools.build.android.AndroidDataMerger.ContentComparingChecker;
import com.google.devtools.build.android.Converters.PathConverter;
import com.google.devtools.build.android.Converters.SerializedAndroidDataConverter;
import com.google.devtools.build.android.Converters.SerializedAndroidDataListConverter;
Expand Down Expand Up @@ -133,30 +133,46 @@ void run(Path tmp, ExecutorServiceCloser executorService) throws Exception {

Preconditions.checkNotNull(options.primary);

MergedAndroidData mergedData =
AndroidResourceMerger.mergeDataAndWrite(
options.primary,
/* primaryManifest = */ null,
options.directData,
options.transitiveData,
/* resourcesOut = */ ignored,
mergedAssets,
/* cruncher = */ null,
VariantType.LIBRARY,
/* symbolsOut = */ null,
/* rclassWriter = */ null,
options.throwOnAssetConflict,
executorService);
final ParsedAndroidData.Builder primaryBuilder = ParsedAndroidData.Builder.newBuilder();
final AndroidParsedDataDeserializer deserializer = AndroidParsedDataDeserializer.create();
options.primary.deserialize(
DependencyInfo.DependencyType.PRIMARY, deserializer, primaryBuilder.consumers());
ParsedAndroidData primaryData = primaryBuilder.build();

UnwrittenMergedAndroidData unwrittenMergedData = AndroidResourceMerger.mergeData(
executorService,
options.transitiveData,
options.directData,
primaryData,
/* primaryManifest = */ null,
/* allowPrimaryOverrideAll = */ false,
deserializer,
options.throwOnAssetConflict,
ContentComparingChecker.create());

logCompletion("Merging");

Preconditions.checkState(
!Files.exists(ignored),
"The asset merging action should not produce non-asset merge results!");

ResourcesZip.from(ignored, mergedData.getAssetDir())
.writeTo(options.assetsOutput, /* compress= */ true);
logCompletion("Create assets zip");
if (options.assetsOutput != null) {
MergedAndroidData writtenMergedData =
AndroidResourceMerger.writeMergedData(
ignored,
mergedAssets,
/* cruncher = */ null,
/* symbolsOut = */ null,
/* rclassWriter = */ null,
executorService,
unwrittenMergedData);

logCompletion("Writing");

Preconditions.checkState(
!Files.exists(ignored),
"The asset merging action should not produce non-asset merge results!");

ResourcesZip.from(ignored, writtenMergedData.getAssetDir())
.writeTo(options.assetsOutput, /* compress= */ true);
logCompletion("Create assets zip");
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ static MergingException withMessage(String message) {
* Merges all secondary resources with the primary resources, given that the primary resources
* have not yet been parsed and serialized.
*/
public static MergedAndroidData mergeDataAndWrite(
static MergedAndroidData mergeDataAndWrite(
final UnvalidatedAndroidData primary,
final List<? extends SerializedAndroidData> direct,
final List<? extends SerializedAndroidData> transitive,
Expand All @@ -99,91 +99,39 @@ public static MergedAndroidData mergeDataAndWrite(
boolean throwOnResourceConflict) {
try (ExecutorServiceCloser executorService = ExecutorServiceCloser.createWithFixedPoolOf(15)) {
final ParsedAndroidData parsedPrimary = ParsedAndroidData.from(primary);
return mergeDataAndWrite(
parsedPrimary,
primary.getManifest(),
direct,
transitive,
return writeMergedData(
resourcesOut,
assetsOut,
cruncher,
type,
symbolsOut,
/* rclassWriter= */ null,
AndroidParsedDataDeserializer.withFilteredResources(filteredResources),
throwOnResourceConflict,
executorService);
executorService,
mergeData(
executorService,
transitive,
direct,
parsedPrimary,
primary.getManifest(),
type != VariantType.LIBRARY,
AndroidParsedDataDeserializer.withFilteredResources(filteredResources),
throwOnResourceConflict,
ContentComparingChecker.create()));
} catch (IOException e) {
throw MergingException.wrapException(e);
}
}

/**
* Merges all secondary resources with the primary resources, given that the primary resources
* have been separately parsed and serialized.
*/
public static MergedAndroidData mergeDataAndWrite(
final SerializedAndroidData primary,
final Path primaryManifest,
final List<? extends SerializedAndroidData> direct,
final List<? extends SerializedAndroidData> transitive,
/** Writes out merged data. */
static MergedAndroidData writeMergedData(
final Path resourcesOut,
final Path assetsOut,
@Nullable final PngCruncher cruncher,
final VariantType type,
@Nullable final Path symbolsOut,
@Nullable final AndroidResourceClassWriter rclassWriter,
boolean throwOnResourceConflict,
ListeningExecutorService executorService) {
final ParsedAndroidData.Builder primaryBuilder = ParsedAndroidData.Builder.newBuilder();
final AndroidParsedDataDeserializer deserializer = AndroidParsedDataDeserializer.create();
primary.deserialize(
DependencyInfo.DependencyType.PRIMARY, deserializer, primaryBuilder.consumers());
ParsedAndroidData primaryData = primaryBuilder.build();
return mergeDataAndWrite(
primaryData,
primaryManifest,
direct,
transitive,
resourcesOut,
assetsOut,
cruncher,
type,
symbolsOut,
rclassWriter,
deserializer,
throwOnResourceConflict,
executorService);
}

/** Merges all secondary resources with the primary resources. */
private static MergedAndroidData mergeDataAndWrite(
final ParsedAndroidData primary,
final Path primaryManifest,
final List<? extends SerializedAndroidData> direct,
final List<? extends SerializedAndroidData> transitive,
final Path resourcesOut,
final Path assetsOut,
@Nullable final PngCruncher cruncher,
final VariantType type,
@Nullable final Path symbolsOut,
@Nullable AndroidResourceClassWriter rclassWriter,
AndroidParsedDataDeserializer deserializer,
boolean throwOnResourceConflict,
ListeningExecutorService executorService) {
ListeningExecutorService executorService,
UnwrittenMergedAndroidData merged) {
Stopwatch timer = Stopwatch.createStarted();
try {
UnwrittenMergedAndroidData merged =
mergeData(
executorService,
transitive,
direct,
primary,
primaryManifest,
type != VariantType.LIBRARY,
deserializer,
throwOnResourceConflict,
ContentComparingChecker.create());
timer.reset().start();
if (symbolsOut != null) {
AndroidDataSerializer serializer = AndroidDataSerializer.create();
Expand Down Expand Up @@ -212,7 +160,7 @@ private static MergedAndroidData mergeDataAndWrite(
}
}

private static UnwrittenMergedAndroidData mergeData(
static UnwrittenMergedAndroidData mergeData(
ListeningExecutorService executorService,
List<? extends SerializedAndroidData> transitive,
List<? extends SerializedAndroidData> direct,
Expand Down

0 comments on commit 8973c51

Please sign in to comment.