AAPT2: Proguard rules generation added.
Change-Id: Ifbe79516cd9a1ade471e211a259301c63b62ac67
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index de2dafc..41c229d 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -28,6 +28,7 @@
#include "ManifestValidator.h"
#include "NameMangler.h"
#include "Png.h"
+#include "ProguardRules.h"
#include "ResourceParser.h"
#include "ResourceTable.h"
#include "ResourceTableResolver.h"
@@ -300,6 +301,9 @@
// Directory to in which to generate R.java.
Maybe<Source> generateJavaClass;
+ // File in which to produce proguard rules.
+ Maybe<Source> generateProguardRules;
+
// Whether to output verbose details about
// compilation.
bool verbose = false;
@@ -417,7 +421,8 @@
bool linkXml(const AaptOptions& options, const std::shared_ptr<ResourceTable>& table,
const std::shared_ptr<IResolver>& resolver, const LinkItem& item,
- const void* data, size_t dataLen, ZipFile* outApk, std::queue<LinkItem>* outQueue) {
+ const void* data, size_t dataLen, ZipFile* outApk, std::queue<LinkItem>* outQueue,
+ proguard::KeepSet* keepSet) {
SourceLogger logger(item.source);
std::unique_ptr<xml::Node> root = xml::inflate(data, dataLen, &logger);
if (!root) {
@@ -435,6 +440,10 @@
xmlOptions.maxSdkAttribute = item.config.sdkVersion ? item.config.sdkVersion : 1;
}
+ if (options.generateProguardRules) {
+ proguard::collectProguardRules(item.name.type, item.source, root.get(), keepSet);
+ }
+
BigBuffer outBuffer(1024);
Maybe<size_t> minStrippedSdk = xml::flattenAndLink(item.source, root.get(),
item.originalPackage, resolver,
@@ -509,7 +518,7 @@
bool compileManifest(const AaptOptions& options, const std::shared_ptr<IResolver>& resolver,
const std::map<std::shared_ptr<ResourceTable>, StaticLibraryData>& libApks,
- const android::ResTable& table, ZipFile* outApk) {
+ const android::ResTable& table, ZipFile* outApk, proguard::KeepSet* keepSet) {
if (options.verbose) {
Logger::note(options.manifest) << "compiling AndroidManifest.xml." << std::endl;
}
@@ -557,6 +566,11 @@
}
}
+ if (options.generateProguardRules) {
+ proguard::collectProguardRulesForManifest(options.manifest, merger.getMergedXml(),
+ keepSet);
+ }
+
BigBuffer outBuffer(1024);
if (!xml::flattenAndLink(options.manifest, merger.getMergedXml(), options.appInfo.package,
resolver, {}, &outBuffer)) {
@@ -805,8 +819,10 @@
return false;
}
+ proguard::KeepSet keepSet;
+
android::ResTable binTable;
- if (!compileManifest(options, resolver, apkFiles, binTable, &outApk)) {
+ if (!compileManifest(options, resolver, apkFiles, binTable, &outApk, &keepSet)) {
return false;
}
@@ -826,7 +842,7 @@
assert(uncompressedData);
if (!linkXml(options, outTable, resolver, item, uncompressedData,
- entry->getUncompressedLen(), &outApk, &linkQueue)) {
+ entry->getUncompressedLen(), &outApk, &linkQueue, &keepSet)) {
Logger::error(options.output) << "failed to link '" << item.originalPath << "'."
<< std::endl;
return false;
@@ -883,6 +899,26 @@
}
}
+ // Generate the Proguard rules file.
+ if (options.generateProguardRules) {
+ const Source& outPath = options.generateProguardRules.value();
+
+ if (options.verbose) {
+ Logger::note(outPath) << "writing proguard rules." << std::endl;
+ }
+
+ std::ofstream fout(outPath.path);
+ if (!fout) {
+ Logger::error(outPath) << strerror(errno) << std::endl;
+ return false;
+ }
+
+ if (!proguard::writeKeepSet(&fout, keepSet)) {
+ Logger::error(outPath) << "failed to write proguard rules." << std::endl;
+ return false;
+ }
+ }
+
outTable->getValueStringPool().prune();
outTable->getValueStringPool().sort(
[](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
@@ -1072,6 +1108,11 @@
options.generateJavaClass = Source{ arg.toString() };
});
+ flag::optionalFlag("--proguard", "file in which to output proguard rules",
+ [&options](const StringPiece& arg) {
+ options.generateProguardRules = Source{ arg.toString() };
+ });
+
flag::optionalSwitch("--static-lib", "generate a static Android library", true,
&isStaticLib);