use of com.facebook.buck.dalvik.EstimateDexWeightStep in project buck by facebook.
the class DexProducedFromJavaLibrary method getBuildSteps.
@Override
public ImmutableList<Step> getBuildSteps(BuildContext context, final BuildableContext buildableContext) {
ImmutableList.Builder<Step> steps = ImmutableList.builder();
steps.add(new RmStep(getProjectFilesystem(), getPathToDex()));
// Make sure that the buck-out/gen/ directory exists for this.buildTarget.
steps.add(new MkdirStep(getProjectFilesystem(), getPathToDex().getParent()));
// If there are classes, run dx.
final ImmutableSortedMap<String, HashCode> classNamesToHashes = javaLibrary.getClassNamesToHashes();
final boolean hasClassesToDx = !classNamesToHashes.isEmpty();
final Supplier<Integer> weightEstimate;
@Nullable final DxStep dx;
if (hasClassesToDx) {
Path pathToOutputFile = context.getSourcePathResolver().getAbsolutePath(javaLibrarySourcePath);
EstimateDexWeightStep estimate = new EstimateDexWeightStep(getProjectFilesystem(), pathToOutputFile);
steps.add(estimate);
weightEstimate = estimate;
// To be conservative, use --force-jumbo for these intermediate .dex files so that they can be
// merged into a final classes.dex that uses jumbo instructions.
dx = new DxStep(getProjectFilesystem(), getPathToDex(), Collections.singleton(pathToOutputFile), EnumSet.of(DxStep.Option.USE_CUSTOM_DX_IF_AVAILABLE, DxStep.Option.RUN_IN_PROCESS, DxStep.Option.NO_OPTIMIZE, DxStep.Option.FORCE_JUMBO));
steps.add(dx);
// The `DxStep` delegates to android tools to build a ZIP with timestamps in it, making
// the output non-deterministic. So use an additional scrubbing step to zero these out.
steps.add(new ZipScrubberStep(getProjectFilesystem(), getPathToDex()));
} else {
dx = null;
weightEstimate = Suppliers.ofInstance(0);
}
// Run a step to record artifacts and metadata. The values recorded depend upon whether dx was
// run.
String stepName = hasClassesToDx ? "record_dx_success" : "record_empty_dx";
AbstractExecutionStep recordArtifactAndMetadataStep = new AbstractExecutionStep(stepName) {
@Override
public StepExecutionResult execute(ExecutionContext context) throws IOException {
if (hasClassesToDx) {
buildableContext.recordArtifact(getPathToDex());
@Nullable Collection<String> referencedResources = dx.getResourcesReferencedInCode();
if (referencedResources != null) {
buildableContext.addMetadata(REFERENCED_RESOURCES, Ordering.natural().immutableSortedCopy(referencedResources));
}
}
buildableContext.addMetadata(WEIGHT_ESTIMATE, String.valueOf(weightEstimate.get()));
// Record the classnames to hashes map.
buildableContext.addMetadata(CLASSNAMES_TO_HASHES, context.getObjectMapper().writeValueAsString(Maps.transformValues(classNamesToHashes, Object::toString)));
return StepExecutionResult.SUCCESS;
}
};
steps.add(recordArtifactAndMetadataStep);
return steps.build();
}
use of com.facebook.buck.dalvik.EstimateDexWeightStep in project buck by facebook.
the class DexProducedFromJavaLibraryThatContainsClassFilesTest method testGetBuildStepsWhenThereAreClassesToDex.
@Test
public void testGetBuildStepsWhenThereAreClassesToDex() throws IOException, InterruptedException {
ProjectFilesystem filesystem = FakeProjectFilesystem.createJavaOnlyFilesystem();
BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
SourcePathResolver pathResolver = new SourcePathResolver(new SourcePathRuleFinder(resolver));
FakeJavaLibrary javaLibraryRule = new FakeJavaLibrary(BuildTargetFactory.newInstance(filesystem.getRootPath(), "//foo:bar"), pathResolver, filesystem, ImmutableSortedSet.of()) {
@Override
public ImmutableSortedMap<String, HashCode> getClassNamesToHashes() {
return ImmutableSortedMap.of("com/example/Foo", HashCode.fromString("cafebabe"));
}
};
resolver.addToIndex(javaLibraryRule);
Path jarOutput = BuildTargets.getGenPath(filesystem, javaLibraryRule.getBuildTarget(), "%s.jar");
javaLibraryRule.setOutputFile(jarOutput.toString());
BuildContext context = FakeBuildContext.withSourcePathResolver(pathResolver);
FakeBuildableContext buildableContext = new FakeBuildableContext();
Path dexOutput = BuildTargets.getGenPath(filesystem, javaLibraryRule.getBuildTarget().withFlavors(AndroidBinaryGraphEnhancer.DEX_FLAVOR), "%s.dex.jar");
createFiles(filesystem, dexOutput.toString(), jarOutput.toString());
BuildTarget buildTarget = BuildTargetFactory.newInstance(filesystem.getRootPath(), "//foo:bar#dex");
BuildRuleParams params = new FakeBuildRuleParamsBuilder(buildTarget).setProjectFilesystem(filesystem).build();
DexProducedFromJavaLibrary preDex = new DexProducedFromJavaLibrary(params, javaLibraryRule);
List<Step> steps = preDex.getBuildSteps(context, buildableContext);
AndroidPlatformTarget androidPlatformTarget = createMock(AndroidPlatformTarget.class);
expect(androidPlatformTarget.getDxExecutable()).andStubReturn(Paths.get("/usr/bin/dx"));
EasyMock.replay(androidPlatformTarget);
ExecutionContext executionContext = TestExecutionContext.newBuilder().setAndroidPlatformTargetSupplier(Suppliers.ofInstance(androidPlatformTarget)).build();
String expectedDxCommand = String.format("%s --dex --no-optimize --force-jumbo --output %s %s", Paths.get("/usr/bin/dx"), filesystem.resolve(dexOutput), filesystem.resolve(jarOutput));
MoreAsserts.assertSteps("Generate bar.dex.jar.", ImmutableList.of(String.format("rm -f %s", filesystem.resolve(dexOutput)), String.format("mkdir -p %s", filesystem.resolve(dexOutput).getParent()), "estimate_dex_weight", "(cd " + filesystem.getRootPath() + " && " + expectedDxCommand + ")", String.format("zip-scrub %s", dexOutput), "record_dx_success"), steps, executionContext);
((EstimateDexWeightStep) steps.get(2)).setWeightEstimateForTesting(250);
Step recordArtifactAndMetadataStep = steps.get(5);
int exitCode = recordArtifactAndMetadataStep.execute(executionContext).getExitCode();
assertEquals(0, exitCode);
assertEquals("The generated .dex.jar file should be in the set of recorded artifacts.", ImmutableSet.of(BuildTargets.getGenPath(filesystem, buildTarget, "%s.dex.jar")), buildableContext.getRecordedArtifacts());
buildableContext.assertContainsMetadataMapping(DexProducedFromJavaLibrary.WEIGHT_ESTIMATE, "250");
}
Aggregations