AAPT2: Few tweaks to get shared-libraries working
Test: manual (building shared support library demo)
Change-Id: I4730645aa92ba1893baf67ffe35fbd4aac0f8e46
diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp
index 4905216..dd8e14b 100644
--- a/tools/aapt2/link/Link.cpp
+++ b/tools/aapt2/link/Link.cpp
@@ -1097,18 +1097,15 @@
return false;
}
- std::unique_ptr<ResourceTable> table =
- LoadTablePbFromCollection(collection.get());
+ std::unique_ptr<ResourceTable> table = LoadTablePbFromCollection(collection.get());
if (!table) {
- context_->GetDiagnostics()->Error(DiagMessage(input)
- << "invalid static library");
+ context_->GetDiagnostics()->Error(DiagMessage(input) << "invalid static library");
return false;
}
ResourceTablePackage* pkg = table->FindPackageById(0x7f);
if (!pkg) {
- context_->GetDiagnostics()->Error(DiagMessage(input)
- << "static library has no package");
+ context_->GetDiagnostics()->Error(DiagMessage(input) << "static library has no package");
return false;
}
@@ -1125,11 +1122,9 @@
pkg->name = "";
if (override) {
- result = table_merger_->MergeOverlay(Source(input), table.get(),
- collection.get());
+ result = table_merger_->MergeOverlay(Source(input), table.get(), collection.get());
} else {
- result =
- table_merger_->Merge(Source(input), table.get(), collection.get());
+ result = table_merger_->Merge(Source(input), table.get(), collection.get());
}
} else {
@@ -1782,17 +1777,21 @@
}
if (options_.generate_java_class_path) {
- JavaClassGeneratorOptions options;
- options.types = JavaClassGeneratorOptions::SymbolTypes::kAll;
- options.javadoc_annotations = options_.javadoc_annotations;
+ // The set of packages whose R class to call in the main classes
+ // onResourcesLoaded callback.
+ std::vector<std::string> packages_to_callback;
+
+ JavaClassGeneratorOptions template_options;
+ template_options.types = JavaClassGeneratorOptions::SymbolTypes::kAll;
+ template_options.javadoc_annotations = options_.javadoc_annotations;
if (options_.package_type == PackageType::kStaticLib || options_.generate_non_final_ids) {
- options.use_final = false;
+ template_options.use_final = false;
}
if (options_.package_type == PackageType::kSharedLib) {
- options.use_final = false;
- options.generate_rewrite_callback = true;
+ template_options.use_final = false;
+ template_options.rewrite_callback_options = OnResourcesLoadedCallbackOptions{};
}
const StringPiece actual_package = context_->GetCompilationPackage();
@@ -1802,36 +1801,51 @@
output_package = options_.custom_java_package.value();
}
+ // Generate the private symbols if required.
if (options_.private_symbols) {
+ packages_to_callback.push_back(options_.private_symbols.value());
+
// If we defined a private symbols package, we only emit Public symbols
// to the original package, and private and public symbols to the
// private package.
-
- options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic;
- if (!WriteJavaFile(&final_table_, context_->GetCompilationPackage(),
- output_package, options)) {
- return 1;
- }
-
+ JavaClassGeneratorOptions options = template_options;
options.types = JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate;
- output_package = options_.private_symbols.value();
- }
-
- if (!WriteJavaFile(&final_table_, actual_package, output_package,
- options)) {
- return 1;
- }
-
- for (const std::string& extra_package : options_.extra_java_packages) {
- if (!WriteJavaFile(&final_table_, actual_package, extra_package,
+ if (!WriteJavaFile(&final_table_, actual_package, options_.private_symbols.value(),
options)) {
return 1;
}
}
+
+ // Generate all the symbols for all extra packages.
+ for (const std::string& extra_package : options_.extra_java_packages) {
+ packages_to_callback.push_back(extra_package);
+
+ JavaClassGeneratorOptions options = template_options;
+ options.types = JavaClassGeneratorOptions::SymbolTypes::kAll;
+ if (!WriteJavaFile(&final_table_, actual_package, extra_package, options)) {
+ return 1;
+ }
+ }
+
+ // Generate the main public R class.
+ JavaClassGeneratorOptions options = template_options;
+
+ // Only generate public symbols if we have a private package.
+ if (options_.private_symbols) {
+ options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic;
+ }
+
+ if (options.rewrite_callback_options) {
+ options.rewrite_callback_options.value().packages_to_callback =
+ std::move(packages_to_callback);
+ }
+
+ if (!WriteJavaFile(&final_table_, actual_package, output_package, options)) {
+ return 1;
+ }
}
- if (!WriteProguardFile(options_.generate_proguard_rules_path,
- proguard_keep_set)) {
+ if (!WriteProguardFile(options_.generate_proguard_rules_path, proguard_keep_set)) {
return 1;
}
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index d5c0dc4..313fe45 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -79,6 +79,17 @@
return false;
}
+static xml::XmlNodeAction::ActionFuncWithDiag RequiredAndroidAttribute(const std::string& attr) {
+ return [=](xml::Element* el, SourcePathDiagnostics* diag) -> bool {
+ if (el->FindAttribute(xml::kSchemaAndroid, attr) == nullptr) {
+ diag->Error(DiagMessage(el->line_number)
+ << "<" << el->name << "> is missing required attribute 'android:" << attr << "'");
+ return false;
+ }
+ return true;
+ };
+}
+
static bool VerifyManifest(xml::Element* el, SourcePathDiagnostics* diag) {
xml::Attribute* attr = el->FindAttribute({}, "package");
if (!attr) {
@@ -272,6 +283,16 @@
application_action["uses-library"].Action(RequiredNameIsJavaPackage);
application_action["library"].Action(RequiredNameIsJavaPackage);
+
+ xml::XmlNodeAction& static_library_action = application_action["static-library"];
+ static_library_action.Action(RequiredNameIsJavaPackage);
+ static_library_action.Action(RequiredAndroidAttribute("version"));
+
+ xml::XmlNodeAction& uses_static_library_action = application_action["uses-static-library"];
+ uses_static_library_action.Action(RequiredNameIsJavaPackage);
+ uses_static_library_action.Action(RequiredAndroidAttribute("version"));
+ uses_static_library_action.Action(RequiredAndroidAttribute("certDigest"));
+
application_action["meta-data"] = meta_data_action;
application_action["activity"] = component_action;
application_action["activity-alias"] = component_action;
diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp
index 4a42826..0331313 100644
--- a/tools/aapt2/link/ReferenceLinker.cpp
+++ b/tools/aapt2/link/ReferenceLinker.cpp
@@ -122,8 +122,7 @@
DiagMessage msg(entry.key.GetSource());
// Call the matches method again, this time with a DiagMessage so we
- // fill
- // in the actual error message.
+ // fill in the actual error message.
symbol->attribute->Matches(entry.value.get(), &msg);
context_->GetDiagnostics()->Error(msg);
error_ = true;
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index 7e7b9fb..9311091 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -39,14 +39,12 @@
bool TableMerger::Merge(const Source& src, ResourceTable* table,
io::IFileCollection* collection) {
- return MergeImpl(src, table, collection, false /* overlay */,
- true /* allow new */);
+ return MergeImpl(src, table, collection, false /* overlay */, true /* allow new */);
}
bool TableMerger::MergeOverlay(const Source& src, ResourceTable* table,
io::IFileCollection* collection) {
- return MergeImpl(src, table, collection, true /* overlay */,
- options_.auto_add_overlay);
+ return MergeImpl(src, table, collection, true /* overlay */, options_.auto_add_overlay);
}
/**
@@ -55,25 +53,13 @@
bool TableMerger::MergeImpl(const Source& src, ResourceTable* table,
io::IFileCollection* collection, bool overlay,
bool allow_new) {
- const uint8_t desired_package_id = context_->GetPackageId();
-
bool error = false;
for (auto& package : table->packages) {
- // Warn of packages with an unrelated ID.
- const Maybe<ResourceId>& id = package->id;
- if (id && id.value() != 0x0 && id.value() != desired_package_id) {
- context_->GetDiagnostics()->Warn(DiagMessage(src) << "ignoring package "
- << package->name);
- continue;
- }
-
// Only merge an empty package or the package we're building.
// Other packages may exist, which likely contain attribute definitions.
// This is because at compile time it is unknown if the attributes are
- // simply
- // uses of the attribute or definitions.
- if (package->name.empty() ||
- context_->GetCompilationPackage() == package->name) {
+ // simply uses of the attribute or definitions.
+ if (package->name.empty() || context_->GetCompilationPackage() == package->name) {
FileMergeCallback callback;
if (collection) {
callback = [&](const ResourceNameRef& name,
@@ -83,8 +69,7 @@
io::IFile* f = collection->FindFile(*old_file->path);
if (!f) {
context_->GetDiagnostics()->Error(DiagMessage(src)
- << "file '" << *old_file->path
- << "' not found");
+ << "file '" << *old_file->path << "' not found");
return false;
}