Skip to content
This repository was archived by the owner on Nov 10, 2023. It is now read-only.

Commit 9af214b

Browse files
IanChildsfacebook-github-bot
authored andcommitted
Move D8Command construction to generic class
Summary: Extracting out so that we can use it in a separate executable in the next diff. Reviewed By: jiawei-lyu fbshipit-source-id: 2fd4587b506761665344a8fa50a621d92c9e7dc1
1 parent cc57bb7 commit 9af214b

3 files changed

Lines changed: 139 additions & 83 deletions

File tree

src/com/facebook/buck/android/D8Step.java

Lines changed: 19 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,10 @@
1717
package com.facebook.buck.android;
1818

1919
import com.android.tools.r8.CompilationFailedException;
20-
import com.android.tools.r8.CompilationMode;
21-
import com.android.tools.r8.D8Command;
2220
import com.android.tools.r8.Diagnostic;
23-
import com.android.tools.r8.DiagnosticsHandler;
24-
import com.android.tools.r8.OutputMode;
2521
import com.android.tools.r8.utils.AbortException;
26-
import com.android.tools.r8.utils.InternalOptions;
2722
import com.facebook.buck.android.dex.D8Options;
23+
import com.facebook.buck.android.dex.D8Utils;
2824
import com.facebook.buck.android.toolchain.AndroidPlatformTarget;
2925
import com.facebook.buck.core.build.execution.context.IsolatedExecutionContext;
3026
import com.facebook.buck.event.ConsoleEvent;
@@ -36,19 +32,13 @@
3632
import com.google.common.collect.ImmutableList;
3733
import com.google.common.collect.ImmutableSet;
3834
import com.google.common.collect.Sets;
39-
import java.io.File;
4035
import java.io.IOException;
41-
import java.nio.file.Files;
4236
import java.nio.file.Path;
43-
import java.nio.file.StandardCopyOption;
44-
import java.util.ArrayList;
4537
import java.util.Collection;
4638
import java.util.EnumSet;
47-
import java.util.HashSet;
48-
import java.util.List;
4939
import java.util.Optional;
5040
import java.util.Set;
51-
import java.util.stream.Stream;
41+
import java.util.stream.Collectors;
5242
import javax.annotation.Nullable;
5343

5444
/** Runs d8. */
@@ -137,65 +127,24 @@ public StepExecutionResult executeIsolatedStep(IsolatedExecutionContext context)
137127
}
138128

139129
private int executeInProcess(IsolatedExecutionContext context) throws IOException {
140-
D8DiagnosticsHandler diagnosticsHandler = new D8DiagnosticsHandler();
130+
D8Utils.D8DiagnosticsHandler diagnosticsHandler = new D8Utils.D8DiagnosticsHandler();
141131
try {
142-
Set<Path> inputs = new HashSet<>();
143-
for (Path rawFile : filesToDex) {
144-
Path toDex = filesystem.resolve(rawFile);
145-
if (Files.isRegularFile(toDex)) {
146-
inputs.add(toDex);
147-
} else {
148-
try (Stream<Path> paths = Files.walk(toDex)) {
149-
paths.filter(path -> path.toFile().isFile()).forEach(inputs::add);
150-
}
151-
}
152-
}
153-
154-
// D8 only outputs to dex if the output path is a directory. So we output to a temporary dir
155-
// and move it over to the final location
156-
boolean outputToDex = outputDexFile.getFileName().toString().endsWith(".dex");
157-
Path output = outputToDex ? Files.createTempDirectory("buck-d8") : outputDexFile;
158-
159-
D8Command.Builder builder =
160-
D8Command.builder(diagnosticsHandler)
161-
.addProgramFiles(inputs)
162-
.setIntermediate(options.contains(D8Options.INTERMEDIATE))
163-
.addLibraryFiles(androidPlatformTarget.getAndroidJar())
164-
.setMode(
165-
options.contains(D8Options.NO_OPTIMIZE)
166-
? CompilationMode.DEBUG
167-
: CompilationMode.RELEASE)
168-
.setOutput(output, OutputMode.DexIndexed)
169-
.setDisableDesugaring(options.contains(D8Options.NO_DESUGAR))
170-
.setInternalOptionsModifier(
171-
(InternalOptions opt) -> {
172-
opt.testing.forceJumboStringProcessing =
173-
options.contains(D8Options.FORCE_JUMBO);
174-
});
175-
176-
bucketId.ifPresent(builder::setBucketId);
177-
minSdkVersion.ifPresent(builder::setMinApiLevel);
178-
primaryDexClassNamesPath.ifPresent(builder::addMainDexListFiles);
132+
resourcesReferencedInCode =
133+
D8Utils.runD8Command(
134+
diagnosticsHandler,
135+
outputDexFile,
136+
filesToDex.stream().map(filesystem::resolve).collect(Collectors.toList()),
137+
options,
138+
primaryDexClassNamesPath,
139+
androidPlatformTarget.getAndroidJar(),
140+
classpathFiles == null
141+
? null
142+
: classpathFiles.stream()
143+
.map(filesystem::getPathForRelativeExistingPath)
144+
.collect(Collectors.toList()),
145+
bucketId,
146+
minSdkVersion);
179147

180-
if (classpathFiles != null && !classpathFiles.isEmpty()) {
181-
// classpathFiles is needed only for D8 java 8 desugar
182-
ImmutableSet.Builder<Path> absolutePaths = ImmutableSet.builder();
183-
for (Path classpathFile : classpathFiles) {
184-
absolutePaths.add(filesystem.getPathForRelativeExistingPath(classpathFile));
185-
}
186-
builder.addClasspathFiles(absolutePaths.build());
187-
}
188-
D8Command d8Command = builder.build();
189-
com.android.tools.r8.D8.run(d8Command);
190-
191-
if (outputToDex) {
192-
File[] outputs = output.toFile().listFiles();
193-
if (outputs != null && (outputs.length > 0)) {
194-
Files.move(outputs[0].toPath(), outputDexFile, StandardCopyOption.REPLACE_EXISTING);
195-
}
196-
}
197-
198-
resourcesReferencedInCode = d8Command.getDexItemFactory().computeReferencedResources();
199148
return SUCCESS_EXIT_CODE;
200149
} catch (CompilationFailedException e) {
201150
if (isOverloadedDexException(e)) {
@@ -222,7 +171,7 @@ private boolean isOverloadedDexException(CompilationFailedException e) {
222171
}
223172

224173
private void postCompilationFailureToConsole(
225-
IsolatedExecutionContext context, D8DiagnosticsHandler diagnosticsHandler) {
174+
IsolatedExecutionContext context, D8Utils.D8DiagnosticsHandler diagnosticsHandler) {
226175
context.postEvent(
227176
ConsoleEvent.severe(
228177
String.join(
@@ -292,19 +241,6 @@ Collection<String> getResourcesReferencedInCode() {
292241
return resourcesReferencedInCode;
293242
}
294243

295-
private static class D8DiagnosticsHandler implements DiagnosticsHandler {
296-
297-
private final List<Diagnostic> diagnostics = new ArrayList<>();
298-
299-
@Override
300-
public void warning(Diagnostic warning) {
301-
diagnostics.add(warning);
302-
}
303-
304-
@Override
305-
public void info(Diagnostic info) {}
306-
}
307-
308244
public Path getOutputDexFile() {
309245
return outputDexFile;
310246
}

src/com/facebook/buck/android/dex/BUCK

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ java_library(
55
"PUBLIC",
66
],
77
deps = [
8+
"//third-party/java/d8:d8",
89
],
910
)
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.facebook.buck.android.dex;
18+
19+
import com.android.tools.r8.CompilationFailedException;
20+
import com.android.tools.r8.CompilationMode;
21+
import com.android.tools.r8.D8Command;
22+
import com.android.tools.r8.Diagnostic;
23+
import com.android.tools.r8.DiagnosticsHandler;
24+
import com.android.tools.r8.OutputMode;
25+
import com.android.tools.r8.utils.InternalOptions;
26+
import java.io.File;
27+
import java.io.IOException;
28+
import java.nio.file.Files;
29+
import java.nio.file.Path;
30+
import java.nio.file.StandardCopyOption;
31+
import java.util.ArrayList;
32+
import java.util.Collection;
33+
import java.util.HashSet;
34+
import java.util.List;
35+
import java.util.Optional;
36+
import java.util.Set;
37+
import java.util.stream.Stream;
38+
39+
/** Runs d8. */
40+
public class D8Utils {
41+
42+
public static Collection<String> runD8Command(
43+
D8DiagnosticsHandler diagnosticsHandler,
44+
Path outputDexFile,
45+
Iterable<Path> filesToDex,
46+
Set<D8Options> options,
47+
Optional<Path> primaryDexClassNamesPath,
48+
Path androidJarPath,
49+
Collection<Path> classpathFiles,
50+
Optional<String> bucketId,
51+
Optional<Integer> minSdkVersion)
52+
throws CompilationFailedException, IOException {
53+
Set<Path> inputs = new HashSet<>();
54+
for (Path toDex : filesToDex) {
55+
if (Files.isRegularFile(toDex)) {
56+
inputs.add(toDex);
57+
} else {
58+
try (Stream<Path> paths = Files.walk(toDex)) {
59+
paths.filter(path -> path.toFile().isFile()).forEach(inputs::add);
60+
}
61+
}
62+
}
63+
64+
// D8 only outputs to dex if the output path is a directory. So we output to a temporary dir
65+
// and move it over to the final location
66+
boolean outputToDex = outputDexFile.getFileName().toString().endsWith(".dex");
67+
Path output = outputToDex ? Files.createTempDirectory("buck-d8") : outputDexFile;
68+
69+
D8Command.Builder builder =
70+
D8Command.builder(diagnosticsHandler)
71+
.addProgramFiles(inputs)
72+
.setIntermediate(options.contains(D8Options.INTERMEDIATE))
73+
.addLibraryFiles(androidJarPath)
74+
.setMode(
75+
options.contains(D8Options.NO_OPTIMIZE)
76+
? CompilationMode.DEBUG
77+
: CompilationMode.RELEASE)
78+
.setOutput(output, OutputMode.DexIndexed)
79+
.setDisableDesugaring(options.contains(D8Options.NO_DESUGAR))
80+
.setInternalOptionsModifier(
81+
(InternalOptions opt) -> {
82+
opt.testing.forceJumboStringProcessing = options.contains(D8Options.FORCE_JUMBO);
83+
});
84+
85+
bucketId.ifPresent(builder::setBucketId);
86+
minSdkVersion.ifPresent(builder::setMinApiLevel);
87+
primaryDexClassNamesPath.ifPresent(builder::addMainDexListFiles);
88+
89+
if (classpathFiles != null) {
90+
// classpathFiles is needed only for D8 Java 8 desugar
91+
builder.addClasspathFiles(classpathFiles);
92+
}
93+
94+
D8Command d8Command = builder.build();
95+
com.android.tools.r8.D8.run(d8Command);
96+
97+
if (outputToDex) {
98+
File[] outputs = output.toFile().listFiles();
99+
if (outputs != null && (outputs.length > 0)) {
100+
Files.move(outputs[0].toPath(), outputDexFile, StandardCopyOption.REPLACE_EXISTING);
101+
}
102+
}
103+
104+
return d8Command.getDexItemFactory().computeReferencedResources();
105+
}
106+
107+
public static class D8DiagnosticsHandler implements DiagnosticsHandler {
108+
109+
public final List<Diagnostic> diagnostics = new ArrayList<>();
110+
111+
@Override
112+
public void warning(Diagnostic warning) {
113+
diagnostics.add(warning);
114+
}
115+
116+
@Override
117+
public void info(Diagnostic info) {}
118+
}
119+
}

0 commit comments

Comments
 (0)