blob: eb8e6d059425be2e973ecbd961e627b74e0c3011 [file] [log] [blame]
// Copyright 2015 The Bazel Authors. All rights reserved.
//
// 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.google.devtools.build.android.ziputils;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.ShellQuotedParamsFilePreProcessor;
import java.nio.file.FileSystems;
import java.util.List;
/**
* Command-line entry point for dex mapper utility, that maps an applications classes (given in
* one or more input jar files), to one or more output jars, that may then be compiled separately.
* This class performs command line parsing and delegates to an {@link SplitZip} instance.
*
* <p>The result of compiling each output archive can be consolidated using the dex reducer utility.
*/
public class DexMapper {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
OptionsParser parser =
OptionsParser.builder()
.optionsClasses(DexMapperOptions.class)
.allowResidue(true)
.argsPreProcessor(new ShellQuotedParamsFilePreProcessor(FileSystems.getDefault()))
.build();
parser.parseAndExitUponError(args);
DexMapperOptions options = parser.getOptions(DexMapperOptions.class);
List<String> inputs = options.inputJars;
List<String> outputs = options.outputJars;
String filterFile = options.mainDexFilter;
String resourceFile = options.outputResources;
try {
// Always drop desugaring metadata, which we check elsewhere and don't want in final APKs
// (see b/65645388).
Predicate<String> inputFilter = Predicates.not(Predicates.equalTo("META-INF/desugar_deps"));
if (options.inclusionFilterJar != null) {
inputFilter =
Predicates.and(inputFilter, SplitZipFilters.entriesIn(options.inclusionFilterJar));
}
new SplitZip()
.setVerbose(false)
.useDefaultEntryDate()
.setSplitDexedClasses(options.splitDexedClasses)
.addInputs(inputs)
.addOutputs(outputs)
.setInputFilter(inputFilter)
.setMainClassListFile(filterFile)
.setResourceFile(resourceFile)
.run()
.close();
} catch (Exception ex) {
System.err.println("Caught exception" + ex.getMessage());
ex.printStackTrace(System.out);
System.exit(1);
}
}
/** Commandline options. */
public static class DexMapperOptions extends OptionsBase {
@Option(
name = "input_jar",
defaultValue = "null",
category = "input",
allowMultiple = true,
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
abbrev = 'i',
help =
"Input file to read classes and jars from. Classes in "
+ " earlier files override those in later ones."
)
public List<String> inputJars;
@Option(
name = "output_jar",
defaultValue = "null",
category = "output",
allowMultiple = true,
abbrev = 'o',
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
help =
"Output file to write. Each argument is one shard. "
+ "Output files are filled in the order specified."
)
public List<String> outputJars;
@Option(
name = "main_dex_filter",
defaultValue = "null",
category = "input",
abbrev = 'f',
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
help = "List of classes to include in the first output file."
)
public String mainDexFilter;
@Option(
name = "output_resources",
defaultValue = "null",
category = "output",
abbrev = 'r',
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
help = "File to write the Java resources to."
)
public String outputResources;
@Option(
name = "split_dexed_classes",
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
help = "Split X.class.dex like X.class if true. Treated as resources if false."
)
public boolean splitDexedClasses;
@Option(
name = "inclusion_filter_jar",
defaultValue = "null",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.UNKNOWN},
help =
"Only copy entries that are listed in the given Jar file. By default, all entries "
+ "are copied over."
)
public String inclusionFilterJar;
}
}