Search in sources :

Example 41 with OptionsParser

use of com.google.devtools.common.options.OptionsParser in project bazel by bazelbuild.

the class AndroidResourceProcessingAction method main.

public static void main(String[] args) throws Exception {
    final Stopwatch timer = Stopwatch.createStarted();
    OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class, AaptConfigOptions.class);
    optionsParser.enableParamsFileSupport(FileSystems.getDefault());
    optionsParser.parseAndExitUponError(args);
    aaptConfigOptions = optionsParser.getOptions(AaptConfigOptions.class);
    options = optionsParser.getOptions(Options.class);
    final AndroidResourceProcessor resourceProcessor = new AndroidResourceProcessor(STD_LOGGER);
    try (ScopedTemporaryDirectory scopedTmp = new ScopedTemporaryDirectory("android_resources_tmp")) {
        final Path tmp = scopedTmp.getPath();
        final Path mergedAssets = tmp.resolve("merged_assets");
        final Path mergedResources = tmp.resolve("merged_resources");
        final Path filteredResources = tmp.resolve("resources-filtered");
        final Path densityManifest = tmp.resolve("manifest-filtered/AndroidManifest.xml");
        final Path processedManifest = tmp.resolve("manifest-processed/AndroidManifest.xml");
        final Path dummyManifest = tmp.resolve("manifest-aapt-dummy/AndroidManifest.xml");
        Path generatedSources = null;
        if (options.srcJarOutput != null || options.rOutput != null || options.symbolsOut != null) {
            generatedSources = tmp.resolve("generated_resources");
        }
        logger.fine(String.format("Setup finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
        List<DependencyAndroidData> data = ImmutableSet.<DependencyAndroidData>builder().addAll(options.directData).addAll(options.transitiveData).build().asList();
        final MergedAndroidData mergedData = AndroidResourceMerger.mergeData(options.primaryData, options.directData, options.transitiveData, mergedResources, mergedAssets, selectPngCruncher(), options.packageType, options.symbolsOut);
        logger.fine(String.format("Merging finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
        final DensityFilteredAndroidData filteredData = mergedData.filter(new DensitySpecificResourceFilter(options.densities, filteredResources, mergedResources), new DensitySpecificManifestProcessor(options.densities, densityManifest));
        logger.fine(String.format("Density filtering finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
        MergedAndroidData processedData = AndroidManifestProcessor.with(STD_LOGGER).processManifest(options.packageType, options.packageForR, options.applicationId, options.versionCode, options.versionName, filteredData, processedManifest);
        // Write manifestOutput now before the dummy manifest is created.
        if (options.manifestOutput != null) {
            AndroidResourceOutputs.copyManifestToOutput(processedData, options.manifestOutput);
        }
        if (options.packageType == VariantType.LIBRARY) {
            resourceProcessor.writeDummyManifestForAapt(dummyManifest, options.packageForR);
            processedData = new MergedAndroidData(processedData.getResourceDir(), processedData.getAssetDir(), dummyManifest);
        }
        resourceProcessor.processResources(aaptConfigOptions.aapt, aaptConfigOptions.androidJar, aaptConfigOptions.buildToolsVersion, options.packageType, aaptConfigOptions.debug, options.packageForR, new FlagAaptOptions(aaptConfigOptions), aaptConfigOptions.resourceConfigs, aaptConfigOptions.splits, processedData, data, generatedSources, options.packagePath, options.proguardOutput, options.mainDexProguardOutput, options.resourcesOutput != null ? processedData.getResourceDir().resolve("values").resolve("public.xml") : null, options.dataBindingInfoOut);
        logger.fine(String.format("aapt finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
        if (options.srcJarOutput != null) {
            AndroidResourceOutputs.createSrcJar(generatedSources, options.srcJarOutput, VariantType.LIBRARY == options.packageType);
        }
        if (options.rOutput != null) {
            AndroidResourceOutputs.copyRToOutput(generatedSources, options.rOutput, VariantType.LIBRARY == options.packageType);
        }
        if (options.resourcesOutput != null) {
            AndroidResourceOutputs.createResourcesZip(processedData.getResourceDir(), processedData.getAssetDir(), options.resourcesOutput, false);
        }
        logger.fine(String.format("Packaging finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
    } catch (MergingException e) {
        logger.log(java.util.logging.Level.SEVERE, "Error during merging resources", e);
        throw e;
    } catch (IOException | InterruptedException | LoggedErrorException | UnrecognizedSplitsException e) {
        logger.log(java.util.logging.Level.SEVERE, "Error during processing resources", e);
        throw e;
    } catch (Exception e) {
        logger.log(java.util.logging.Level.SEVERE, "Unexpected", e);
        throw e;
    } finally {
        resourceProcessor.shutdown();
    }
    logger.fine(String.format("Resources processed in %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
}
Also used : Path(java.nio.file.Path) AaptConfigOptions(com.google.devtools.build.android.AndroidResourceProcessor.AaptConfigOptions) FlagAaptOptions(com.google.devtools.build.android.AndroidResourceProcessor.FlagAaptOptions) FlagAaptOptions(com.google.devtools.build.android.AndroidResourceProcessor.FlagAaptOptions) UnrecognizedSplitsException(com.google.devtools.build.android.SplitConfigurationFilter.UnrecognizedSplitsException) MergingException(com.android.ide.common.res2.MergingException) Stopwatch(com.google.common.base.Stopwatch) IOException(java.io.IOException) OptionsParser(com.google.devtools.common.options.OptionsParser) UnrecognizedSplitsException(com.google.devtools.build.android.SplitConfigurationFilter.UnrecognizedSplitsException) LoggedErrorException(com.android.ide.common.internal.LoggedErrorException) MergingException(com.android.ide.common.res2.MergingException) IOException(java.io.IOException) LoggedErrorException(com.android.ide.common.internal.LoggedErrorException) AaptConfigOptions(com.google.devtools.build.android.AndroidResourceProcessor.AaptConfigOptions)

Example 42 with OptionsParser

use of com.google.devtools.common.options.OptionsParser in project bazel by bazelbuild.

the class AndroidResourceValidatorAction method main.

public static void main(String[] args) throws Exception {
    final Stopwatch timer = Stopwatch.createStarted();
    OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class, AaptConfigOptions.class);
    optionsParser.enableParamsFileSupport(FileSystems.getDefault());
    optionsParser.parseAndExitUponError(args);
    AaptConfigOptions aaptConfigOptions = optionsParser.getOptions(AaptConfigOptions.class);
    Options options = optionsParser.getOptions(Options.class);
    final AndroidResourceProcessor resourceProcessor = new AndroidResourceProcessor(stdLogger);
    VariantType packageType = VariantType.LIBRARY;
    Preconditions.checkNotNull(options.rOutput);
    Preconditions.checkNotNull(options.srcJarOutput);
    try (ScopedTemporaryDirectory scopedTmp = new ScopedTemporaryDirectory("resource_validator_tmp")) {
        Path tmp = scopedTmp.getPath();
        Path expandedOut = tmp.resolve("tmp-expanded");
        Path resources = expandedOut.resolve("res");
        Path assets = expandedOut.resolve("assets");
        Path generatedSources = tmp.resolve("generated_resources");
        Path dummyManifest = tmp.resolve("manifest-aapt-dummy/AndroidManifest.xml");
        unpackZip(options.mergedResources, expandedOut);
        logger.fine(String.format("unpacked zip at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
        // We need to make the manifest aapt safe (w.r.t., placeholders). For now, just stub it out.
        resourceProcessor.writeDummyManifestForAapt(dummyManifest, options.packageForR);
        resourceProcessor.runAapt(aaptConfigOptions.aapt, aaptConfigOptions.androidJar, aaptConfigOptions.buildToolsVersion, packageType, aaptConfigOptions.debug, options.packageForR, new FlagAaptOptions(aaptConfigOptions), aaptConfigOptions.resourceConfigs, ImmutableList.<String>of(), dummyManifest, resources, assets, generatedSources, null, /* packageOut */
        null, /* proguardOut */
        null, /* mainDexProguardOut */
        null);
        logger.fine(String.format("aapt finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
        AndroidResourceOutputs.copyRToOutput(generatedSources, options.rOutput, VariantType.LIBRARY == packageType);
        AndroidResourceOutputs.createSrcJar(generatedSources, options.srcJarOutput, VariantType.LIBRARY == packageType);
    } catch (Exception e) {
        logger.log(java.util.logging.Level.SEVERE, "Unexpected", e);
        throw e;
    } finally {
        resourceProcessor.shutdown();
    }
    logger.fine(String.format("Resources merged in %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
}
Also used : Path(java.nio.file.Path) AaptConfigOptions(com.google.devtools.build.android.AndroidResourceProcessor.AaptConfigOptions) FlagAaptOptions(com.google.devtools.build.android.AndroidResourceProcessor.FlagAaptOptions) FlagAaptOptions(com.google.devtools.build.android.AndroidResourceProcessor.FlagAaptOptions) VariantType(com.android.builder.core.VariantType) Stopwatch(com.google.common.base.Stopwatch) OptionsParser(com.google.devtools.common.options.OptionsParser) IOException(java.io.IOException) AaptConfigOptions(com.google.devtools.build.android.AndroidResourceProcessor.AaptConfigOptions)

Example 43 with OptionsParser

use of com.google.devtools.common.options.OptionsParser in project bazel by bazelbuild.

the class DexBuilder method main.

public static void main(String[] args) throws Exception {
    if (args.length == 1 && args[0].startsWith("@")) {
        args = Files.readAllLines(Paths.get(args[0].substring(1)), ISO_8859_1).toArray(new String[0]);
    }
    OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class, DexingOptions.class);
    optionsParser.parseAndExitUponError(args);
    Options options = optionsParser.getOptions(Options.class);
    if (options.persistentWorker) {
        runPersistentWorker();
    } else {
        buildDexArchive(options, optionsParser.getOptions(DexingOptions.class));
    }
}
Also used : DexingOptions(com.google.devtools.build.android.dexer.Dexing.DexingOptions) DexingOptions(com.google.devtools.build.android.dexer.Dexing.DexingOptions) OptionsParser(com.google.devtools.common.options.OptionsParser)

Example 44 with OptionsParser

use of com.google.devtools.common.options.OptionsParser in project bazel by bazelbuild.

the class Desugar method main.

public static void main(String[] args) throws Exception {
    // LambdaClassMaker generates lambda classes for us, but it does so by essentially simulating
    // the call to LambdaMetafactory that the JVM would make when encountering an invokedynamic.
    // LambdaMetafactory is in the JDK and its implementation has a property to write out ("dump")
    // generated classes, which we take advantage of here.  Set property before doing anything else
    // since the property is read in the static initializer; if this breaks we can investigate
    // setting the property when calling the tool.
    Path dumpDirectory = Files.createTempDirectory("lambdas");
    System.setProperty(LambdaClassMaker.LAMBDA_METAFACTORY_DUMPER_PROPERTY, dumpDirectory.toString());
    deleteTreeOnExit(dumpDirectory);
    if (args.length == 1 && args[0].startsWith("@")) {
        args = Files.readAllLines(Paths.get(args[0].substring(1)), ISO_8859_1).toArray(new String[0]);
    }
    OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class);
    optionsParser.setAllowResidue(false);
    optionsParser.parseAndExitUponError(args);
    Options options = optionsParser.getOptions(Options.class);
    checkState(!options.inputJars.isEmpty(), "--input is required");
    checkState(options.inputJars.size() == options.outputJars.size(), "Desugar requires the same number of inputs and outputs to pair them");
    checkState(!options.bootclasspath.isEmpty() || options.allowEmptyBootclasspath, "At least one --bootclasspath_entry is required");
    if (options.verbose) {
        System.out.printf("Lambda classes will be written under %s%n", dumpDirectory);
    }
    CoreLibraryRewriter rewriter = new CoreLibraryRewriter(options.coreLibrary ? "__desugar__/" : "");
    boolean allowDefaultMethods = options.minSdkVersion >= 24;
    boolean allowCallsToObjectsNonNull = options.minSdkVersion >= 19;
    LambdaClassMaker lambdas = new LambdaClassMaker(dumpDirectory);
    // Process each input separately
    for (InputOutputPair inputOutputPair : toInputOutputPairs(options)) {
        Path inputJar = inputOutputPair.getInput();
        IndexedJars appIndexedJar = new IndexedJars(ImmutableList.of(inputJar));
        IndexedJars appAndClasspathIndexedJars = new IndexedJars(options.classpath, appIndexedJar);
        ClassLoader loader = createClassLoader(rewriter, options.bootclasspath, appAndClasspathIndexedJars);
        try (ZipFile in = new ZipFile(inputJar.toFile());
            ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(Files.newOutputStream(inputOutputPair.getOutput())))) {
            ClassReaderFactory readerFactory = new ClassReaderFactory((options.copyBridgesFromClasspath && !allowDefaultMethods) ? appAndClasspathIndexedJars : appIndexedJar, rewriter);
            ImmutableSet.Builder<String> interfaceLambdaMethodCollector = ImmutableSet.builder();
            // Process input Jar, desugaring as we go
            for (Enumeration<? extends ZipEntry> entries = in.entries(); entries.hasMoreElements(); ) {
                ZipEntry entry = entries.nextElement();
                try (InputStream content = in.getInputStream(entry)) {
                    // danger of accidentally uncompressed resources ending up in an .apk.
                    if (entry.getName().endsWith(".class")) {
                        ClassReader reader = rewriter.reader(content);
                        CoreLibraryRewriter.UnprefixingClassWriter writer = rewriter.writer(ClassWriter.COMPUTE_MAXS);
                        ClassVisitor visitor = writer;
                        if (!options.onlyDesugarJavac9ForLint) {
                            if (!allowDefaultMethods) {
                                visitor = new Java7Compatibility(visitor, readerFactory);
                            }
                            visitor = new LambdaDesugaring(visitor, loader, lambdas, interfaceLambdaMethodCollector, allowDefaultMethods);
                        }
                        if (!allowCallsToObjectsNonNull) {
                            visitor = new ObjectsRequireNonNullMethodInliner(visitor);
                        }
                        reader.accept(visitor, 0);
                        writeStoredEntry(out, entry.getName(), writer.toByteArray());
                    } else {
                        // TODO(bazel-team): Avoid de- and re-compressing resource files
                        ZipEntry destEntry = new ZipEntry(entry);
                        destEntry.setCompressedSize(-1);
                        out.putNextEntry(destEntry);
                        ByteStreams.copy(content, out);
                        out.closeEntry();
                    }
                }
            }
            ImmutableSet<String> interfaceLambdaMethods = interfaceLambdaMethodCollector.build();
            checkState(!allowDefaultMethods || interfaceLambdaMethods.isEmpty(), "Desugaring with default methods enabled moved interface lambdas");
            // Write out the lambda classes we generated along the way
            ImmutableMap<Path, LambdaInfo> lambdaClasses = lambdas.drain();
            checkState(!options.onlyDesugarJavac9ForLint || lambdaClasses.isEmpty(), "There should be no lambda classes generated: %s", lambdaClasses.keySet());
            for (Map.Entry<Path, LambdaInfo> lambdaClass : lambdaClasses.entrySet()) {
                try (InputStream bytecode = Files.newInputStream(dumpDirectory.resolve(lambdaClass.getKey()))) {
                    ClassReader reader = rewriter.reader(bytecode);
                    CoreLibraryRewriter.UnprefixingClassWriter writer = rewriter.writer(ClassWriter.COMPUTE_MAXS);
                    ClassVisitor visitor = writer;
                    if (!allowDefaultMethods) {
                        // null ClassReaderFactory b/c we don't expect to need it for lambda classes
                        visitor = new Java7Compatibility(visitor, (ClassReaderFactory) null);
                    }
                    visitor = new LambdaClassFixer(visitor, lambdaClass.getValue(), readerFactory, interfaceLambdaMethods, allowDefaultMethods);
                    // Send lambda classes through desugaring to make sure there's no invokedynamic
                    // instructions in generated lambda classes (checkState below will fail)
                    visitor = new LambdaDesugaring(visitor, loader, lambdas, null, allowDefaultMethods);
                    if (!allowCallsToObjectsNonNull) {
                        // Not sure whether there will be implicit null check emitted by javac, so we rerun
                        // the inliner again
                        visitor = new ObjectsRequireNonNullMethodInliner(visitor);
                    }
                    reader.accept(visitor, 0);
                    String filename = rewriter.unprefix(lambdaClass.getValue().desiredInternalName()) + ".class";
                    writeStoredEntry(out, filename, writer.toByteArray());
                }
            }
            Map<Path, LambdaInfo> leftBehind = lambdas.drain();
            checkState(leftBehind.isEmpty(), "Didn't process %s", leftBehind);
        }
    }
}
Also used : ZipEntry(java.util.zip.ZipEntry) ClassVisitor(org.objectweb.asm.ClassVisitor) ImmutableSet(com.google.common.collect.ImmutableSet) BufferedOutputStream(java.io.BufferedOutputStream) Path(java.nio.file.Path) InputStream(java.io.InputStream) OptionsParser(com.google.devtools.common.options.OptionsParser) ZipFile(java.util.zip.ZipFile) ZipOutputStream(java.util.zip.ZipOutputStream) ClassReader(org.objectweb.asm.ClassReader) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 45 with OptionsParser

use of com.google.devtools.common.options.OptionsParser in project bazel by bazelbuild.

the class ManifestMergerAction method main.

public static void main(String[] args) throws Exception {
    OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class);
    optionsParser.parseAndExitUponError(args);
    options = optionsParser.getOptions(Options.class);
    try {
        Path mergedManifest;
        AndroidManifestProcessor manifestProcessor = AndroidManifestProcessor.with(stdLogger);
        if (options.mergeType == MergeType.APPLICATION) {
            // Remove uses-permission tags from mergees before the merge.
            Path tmp = Files.createTempDirectory("manifest_merge_tmp");
            tmp.toFile().deleteOnExit();
            ImmutableMap.Builder<Path, String> mergeeManifests = ImmutableMap.builder();
            for (Entry<Path, String> mergeeManifest : options.mergeeManifests.entrySet()) {
                mergeeManifests.put(removePermissions(mergeeManifest.getKey(), tmp), mergeeManifest.getValue());
            }
            // Ignore custom package at the binary level.
            mergedManifest = manifestProcessor.mergeManifest(options.manifest, mergeeManifests.build(), options.mergeType, options.manifestValues, options.manifestOutput, options.log);
        } else {
            // Only need to stamp custom package into the library level.
            mergedManifest = manifestProcessor.writeManifestPackage(options.manifest, options.customPackage, options.manifestOutput);
        }
        if (!mergedManifest.equals(options.manifestOutput)) {
            Files.copy(options.manifest, options.manifestOutput, StandardCopyOption.REPLACE_EXISTING);
        }
        // Set to the epoch for caching purposes.
        Files.setLastModifiedTime(options.manifestOutput, FileTime.fromMillis(0L));
    } catch (IOException e) {
        logger.log(SEVERE, "Error during merging manifests", e);
        throw e;
    }
}
Also used : Path(java.nio.file.Path) IOException(java.io.IOException) OptionsParser(com.google.devtools.common.options.OptionsParser) ImmutableMap(com.google.common.collect.ImmutableMap)

Aggregations

OptionsParser (com.google.devtools.common.options.OptionsParser)50 Path (java.nio.file.Path)11 IOException (java.io.IOException)10 Stopwatch (com.google.common.base.Stopwatch)8 Test (org.junit.Test)7 InvocationPolicyEnforcer (com.google.devtools.build.lib.flags.InvocationPolicyEnforcer)6 OptionsParsingException (com.google.devtools.common.options.OptionsParsingException)6 AaptConfigOptions (com.google.devtools.build.android.AndroidResourceProcessor.AaptConfigOptions)5 OptionsBase (com.google.devtools.common.options.OptionsBase)5 MergingException (com.android.ide.common.res2.MergingException)4 Path (com.google.devtools.build.lib.vfs.Path)4 VisibleForTesting (com.google.common.annotations.VisibleForTesting)3 EventBus (com.google.common.eventbus.EventBus)3 FlagAaptOptions (com.google.devtools.build.android.AndroidResourceProcessor.FlagAaptOptions)3 InputStream (java.io.InputStream)3 ArrayList (java.util.ArrayList)3 VariantType (com.android.builder.core.VariantType)2 ImmutableMap (com.google.common.collect.ImmutableMap)2 DexingOptions (com.google.devtools.build.android.dexer.Dexing.DexingOptions)2 SpawnActionContext (com.google.devtools.build.lib.actions.SpawnActionContext)2