com.android.builder.core.DexProcessBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of builder Show documentation
Show all versions of builder Show documentation
Library to build Android applications.
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.builder.core;
import static com.google.common.base.Preconditions.checkState;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.process.JavaProcessInfo;
import com.android.ide.common.process.ProcessEnvBuilder;
import com.android.ide.common.process.ProcessException;
import com.android.ide.common.process.ProcessInfoBuilder;
import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.repository.FullRevision;
import com.google.common.base.Charsets;
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
/**
* A builder to create a dex-specific ProcessInfoBuilder
*/
public class DexProcessBuilder extends ProcessEnvBuilder {
private static final FullRevision MIN_BUILD_TOOLS_REVISION_FOR_DEX_INPUT_LIST = new FullRevision(21, 0, 0);
private static final FullRevision MIN_MULTIDEX_BUILD_TOOLS_REV = new FullRevision(21, 0, 0);
private static final FullRevision MIN_MULTI_THREADED_DEX_BUILD_TOOLS_REV = new FullRevision(22, 0, 2);
@NonNull
private final File mOutputFile;
private boolean mVerbose = false;
private boolean mIncremental = false;
private boolean mNoOptimize = false;
private boolean mMultiDex = false;
private File mMainDexList = null;
private Set mInputs = Sets.newHashSet();
private File mTempInputFolder = null;
private List mAdditionalParams = null;
public DexProcessBuilder(@NonNull File outputFile) {
mOutputFile = outputFile;
}
@NonNull
public DexProcessBuilder setVerbose(boolean verbose) {
mVerbose = verbose;
return this;
}
@NonNull
public DexProcessBuilder setIncremental(boolean incremental) {
mIncremental = incremental;
return this;
}
@NonNull
public DexProcessBuilder setNoOptimize(boolean noOptimize) {
mNoOptimize = noOptimize;
return this;
}
@NonNull
public DexProcessBuilder setMultiDex(boolean multiDex) {
mMultiDex = multiDex;
return this;
}
@NonNull
public DexProcessBuilder setMainDexList(File mainDexList) {
mMainDexList = mainDexList;
return this;
}
@NonNull
public DexProcessBuilder addInput(File input) {
mInputs.add(input);
return this;
}
@NonNull
public DexProcessBuilder addInputs(@NonNull Collection inputs) {
mInputs.addAll(inputs);
return this;
}
@NonNull
public DexProcessBuilder setTempInputFolder(File tempInputFolder) {
mTempInputFolder = tempInputFolder;
return this;
}
@NonNull
public DexProcessBuilder additionalParameters(@NonNull List params) {
if (mAdditionalParams == null) {
mAdditionalParams = Lists.newArrayListWithExpectedSize(params.size());
}
mAdditionalParams.addAll(params);
return this;
}
@NonNull
public JavaProcessInfo build(
@NonNull BuildToolInfo buildToolInfo,
@NonNull DexOptions dexOptions) throws ProcessException {
checkState(
!mMultiDex
|| buildToolInfo.getRevision().compareTo(MIN_MULTIDEX_BUILD_TOOLS_REV) >= 0,
"Multi dex requires Build Tools " +
MIN_MULTIDEX_BUILD_TOOLS_REV.toString() +
" / Current: " +
buildToolInfo.getRevision().toShortString());
ProcessInfoBuilder builder = new ProcessInfoBuilder();
builder.addEnvironments(mEnvironment);
String dx = buildToolInfo.getPath(BuildToolInfo.PathId.DX_JAR);
if (dx == null || !new File(dx).isFile()) {
throw new IllegalStateException("dx.jar is missing");
}
builder.setClasspath(dx);
builder.setMain("com.android.dx.command.Main");
if (dexOptions.getJavaMaxHeapSize() != null) {
builder.addJvmArg("-Xmx" + dexOptions.getJavaMaxHeapSize());
} else {
builder.addJvmArg("-Xmx1024M");
}
builder.addArgs("--dex");
if (mVerbose) {
builder.addArgs("--verbose");
}
if (dexOptions.getJumboMode()) {
builder.addArgs("--force-jumbo");
}
if (mIncremental) {
builder.addArgs("--incremental", "--no-strict");
}
if (mNoOptimize) {
builder.addArgs("--no-optimize");
}
// only change thread count is build tools is 22.0.2+
if (buildToolInfo.getRevision().compareTo(MIN_MULTI_THREADED_DEX_BUILD_TOOLS_REV) >= 0) {
Integer threadCount = dexOptions.getThreadCount();
if (threadCount == null) {
builder.addArgs("--num-threads=4");
} else {
builder.addArgs("--num-threads=" + threadCount);
}
}
if (mMultiDex) {
builder.addArgs("--multi-dex");
if (mMainDexList != null ) {
builder.addArgs("--main-dex-list", mMainDexList.getAbsolutePath());
}
}
if (mAdditionalParams != null) {
for (String arg : mAdditionalParams) {
builder.addArgs(arg);
}
}
builder.addArgs("--output", mOutputFile.getAbsolutePath());
// input
builder.addArgs(getFilesToAdd(buildToolInfo));
return builder.createJavaProcess();
}
@NonNull
private List getFilesToAdd(@NonNull BuildToolInfo buildToolInfo) throws
ProcessException {
// remove non-existing files.
Set existingFiles = Sets.filter(mInputs, new Predicate() {
@Override
public boolean apply(@Nullable File input) {
return input != null && input.exists();
}
});
if (existingFiles.isEmpty()) {
throw new ProcessException("No files to pass to dex.");
}
// sort the inputs
List sortedList = Lists.newArrayList(existingFiles);
Collections.sort(sortedList, new Comparator() {
@Override
public int compare(File file, File file2) {
boolean file2IsDir = file2.isDirectory();
if (file.isDirectory()) {
return file2IsDir ? 0 : -1;
} else if (file2IsDir) {
return 1;
}
long diff = file.length() - file2.length();
return diff > 0 ? 1 : (diff < 0 ? -1 : 0);
}
});
// convert to String-based paths.
List filePathList = Lists.newArrayListWithCapacity(sortedList.size());
for (File f : sortedList) {
filePathList.add(f.getAbsolutePath());
}
if (mTempInputFolder != null && buildToolInfo.getRevision()
.compareTo(MIN_BUILD_TOOLS_REVISION_FOR_DEX_INPUT_LIST) >= 0) {
File inputListFile = new File(mTempInputFolder, "inputList.txt");
// Write each library line by line to file
try {
Files.asCharSink(inputListFile, Charsets.UTF_8).writeLines(filePathList);
} catch (IOException e) {
throw new ProcessException(e);
}
return Collections.singletonList("--input-list=" + inputListFile.getAbsolutePath());
} else {
return filePathList;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy