Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 418763ff authored by Adam Lesinski's avatar Adam Lesinski
Browse files

AAPT2: Generate R.txt

In order to support a staged rollout of support for AAPT2,
libraries being built the old way (merged into a single resource
directory) still need to make use of the generated R.txt AAPT
emitted. Do the same as AAPT.

Test: manual
Change-Id: Iaac1e824ddbd67e4efbab7692cddc1e4aa052f5a
parent ec8f3536
Loading
Loading
Loading
Loading
+25 −7
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ struct LinkOptions {
  Maybe<std::string> generate_java_class_path;
  Maybe<std::string> custom_java_package;
  std::set<std::string> extra_java_packages;
  Maybe<std::string> generate_text_symbols_path;
  Maybe<std::string> generate_proguard_rules_path;
  Maybe<std::string> generate_main_dex_proguard_rules_path;
  bool generate_non_final_ids = false;
@@ -837,8 +838,8 @@ class LinkCommand {
  }

  bool WriteJavaFile(ResourceTable* table, const StringPiece& package_name_to_generate,
                     const StringPiece& out_package,
                     const JavaClassGeneratorOptions& java_options) {
                     const StringPiece& out_package, const JavaClassGeneratorOptions& java_options,
                     const Maybe<std::string> out_text_symbols_path = {}) {
    if (!options_.generate_java_class_path) {
      return true;
    }
@@ -861,8 +862,20 @@ class LinkCommand {
      return false;
    }

    std::unique_ptr<std::ofstream> fout_text;
    if (out_text_symbols_path) {
      fout_text =
          util::make_unique<std::ofstream>(out_text_symbols_path.value(), std::ofstream::binary);
      if (!*fout_text) {
        context_->GetDiagnostics()->Error(
            DiagMessage() << "failed writing to '" << out_text_symbols_path.value()
                          << "': " << android::base::SystemErrorCodeToString(errno));
        return false;
      }
    }

    JavaClassGenerator generator(context_, table, java_options);
    if (!generator.Generate(package_name_to_generate, out_package, &fout)) {
    if (!generator.Generate(package_name_to_generate, out_package, &fout, fout_text.get())) {
      context_->GetDiagnostics()->Error(DiagMessage(out_path) << generator.getError());
      return false;
    }
@@ -1683,7 +1696,8 @@ class LinkCommand {
            std::move(packages_to_callback);
      }

      if (!WriteJavaFile(&final_table_, actual_package, output_package, options)) {
      if (!WriteJavaFile(&final_table_, actual_package, output_package, options,
                         options_.generate_text_symbols_path)) {
        return 1;
      }
    }
@@ -1841,6 +1855,10 @@ int Link(const std::vector<StringPiece>& args) {
          .OptionalFlagList("--add-javadoc-annotation",
                            "Adds a JavaDoc annotation to all generated Java classes.",
                            &options.javadoc_annotations)
          .OptionalFlag("--output-text-symbols",
                        "Generates a text file containing the resource symbols of the R class in\n"
                        "the specified folder.",
                        &options.generate_text_symbols_path)
          .OptionalSwitch("--auto-add-overlay",
                          "Allows the addition of new resources in overlays without\n"
                          "<add-resource> tags.",
+52 −12
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <sstream>
#include <tuple>

#include "android-base/errors.h"
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
#include "androidfw/StringPiece.h"
@@ -227,7 +228,8 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res
                                          const Styleable& styleable,
                                          const StringPiece& package_name_to_generate,
                                          ClassDefinition* out_class_def,
                                          MethodDefinition* out_rewrite_method) {
                                          MethodDefinition* out_rewrite_method,
                                          std::ostream* out_r_txt) {
  const std::string array_field_name = TransformToFieldName(name.entry);
  std::unique_ptr<ResourceArrayMember> array_def =
      util::make_unique<ResourceArrayMember>(array_field_name);
@@ -328,10 +330,25 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res
    array_def->GetCommentBuilder()->AppendComment(styleable_comment.str());
  }

  if (out_r_txt != nullptr) {
    *out_r_txt << "int[] styleable " << array_field_name << " {";
  }

  // Add the ResourceIds to the array member.
  for (const StyleableAttr& styleable_attr : sorted_attributes) {
    const ResourceId id = styleable_attr.attr_ref->id.value_or_default(ResourceId(0));
  for (size_t i = 0; i < attr_count; i++) {
    const ResourceId id = sorted_attributes[i].attr_ref->id.value_or_default(ResourceId(0));
    array_def->AddElement(id);

    if (out_r_txt != nullptr) {
      if (i != 0) {
        *out_r_txt << ",";
      }
      *out_r_txt << " " << id;
    }
  }

  if (out_r_txt != nullptr) {
    *out_r_txt << " }\n";
  }

  // Add the Styleable array to the Styleable class.
@@ -386,6 +403,11 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res
    attr_processor->AppendComment(
        StringPrintf("@attr name %s:%s", package_name.data(), attr_name.entry.data()));

    if (out_r_txt != nullptr) {
      *out_r_txt << StringPrintf("int styleable %s %d\n", sorted_attributes[i].field_name.data(),
                                 (int)i);
    }

    out_class_def->AddMember(std::move(index_member));
  }

@@ -406,7 +428,8 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res

void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const ResourceId& id,
                                         const ResourceEntry& entry, ClassDefinition* out_class_def,
                                         MethodDefinition* out_rewrite_method) {
                                         MethodDefinition* out_rewrite_method,
                                         std::ostream* out_r_txt) {
  const std::string field_name = TransformToFieldName(name.entry);
  std::unique_ptr<ResourceMember> resource_member =
      util::make_unique<ResourceMember>(field_name, id);
@@ -434,6 +457,10 @@ void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const Reso

  out_class_def->AddMember(std::move(resource_member));

  if (out_r_txt != nullptr) {
    *out_r_txt << "int " << name.type << " " << field_name << " " << id << "\n";
  }

  if (out_rewrite_method != nullptr) {
    const StringPiece& type_str = ToString(name.type);
    out_rewrite_method->AppendStatement(StringPrintf("%s.%s = (%s.%s & 0x00ffffff) | (p << 24);",
@@ -470,7 +497,8 @@ bool JavaClassGenerator::ProcessType(const StringPiece& package_name_to_generate
                                     const ResourceTablePackage& package,
                                     const ResourceTableType& type,
                                     ClassDefinition* out_type_class_def,
                                     MethodDefinition* out_rewrite_method_def) {
                                     MethodDefinition* out_rewrite_method_def,
                                     std::ostream* out_r_txt) {
  for (const auto& entry : type.entries) {
    const Maybe<std::string> unmangled_name =
        UnmangleResource(package.name, package_name_to_generate, *entry);
@@ -505,15 +533,17 @@ bool JavaClassGenerator::ProcessType(const StringPiece& package_name_to_generate
          static_cast<const Styleable*>(entry->values.front()->value.get());

      ProcessStyleable(resource_name, id, *styleable, package_name_to_generate, out_type_class_def,
                       out_rewrite_method_def);
                       out_rewrite_method_def, out_r_txt);
    } else {
      ProcessResource(resource_name, id, *entry, out_type_class_def, out_rewrite_method_def);
      ProcessResource(resource_name, id, *entry, out_type_class_def, out_rewrite_method_def,
                      out_r_txt);
    }
  }
  return true;
}

bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, std::ostream* out) {
bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, std::ostream* out,
                                  std::ostream* out_r_txt) {
  return Generate(package_name_to_generate, package_name_to_generate, out);
}

@@ -527,8 +557,8 @@ static void AppendJavaDocAnnotations(const std::vector<std::string>& annotations
}

bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
                                  const StringPiece& out_package_name,
                                  std::ostream* out) {
                                  const StringPiece& out_package_name, std::ostream* out,
                                  std::ostream* out_r_txt) {
  ClassDefinition r_class("R", ClassQualifier::kNone, true);
  std::unique_ptr<MethodDefinition> rewrite_method;

@@ -558,7 +588,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
      std::unique_ptr<ClassDefinition> class_def = util::make_unique<ClassDefinition>(
          ToString(type->type), ClassQualifier::kStatic, force_creation_if_empty);
      if (!ProcessType(package_name_to_generate, *package, *type, class_def.get(),
                       rewrite_method.get())) {
                       rewrite_method.get(), out_r_txt)) {
        return false;
      }

@@ -567,7 +597,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
        const ResourceTableType* priv_type = package->FindType(ResourceType::kAttrPrivate);
        if (priv_type) {
          if (!ProcessType(package_name_to_generate, *package, *priv_type, class_def.get(),
                           rewrite_method.get())) {
                           rewrite_method.get(), out_r_txt)) {
            return false;
          }
        }
@@ -597,6 +627,16 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
  }

  out->flush();

  if (out_r_txt != nullptr) {
    out_r_txt->flush();

    if (!*out_r_txt) {
      error_ = android::base::SystemErrorCodeToString(errno);
      return false;
    }
  }

  return true;
}

+10 −6
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ struct JavaClassGeneratorOptions {
  std::vector<std::string> javadoc_annotations;
};

// Generates the R.java file for a resource table.
// Generates the R.java file for a resource table and optionally an R.txt file.
class JavaClassGenerator {
 public:
  JavaClassGenerator(IAaptContext* context, ResourceTable* table,
@@ -69,10 +69,12 @@ class JavaClassGenerator {
  // All symbols technically belong to a single package, but linked libraries will
  // have their names mangled, denoting that they came from a different package.
  // We need to generate these symbols in a separate file. Returns true on success.
  bool Generate(const android::StringPiece& package_name_to_generate, std::ostream* out);
  bool Generate(const android::StringPiece& package_name_to_generate, std::ostream* out,
                std::ostream* out_r_txt = nullptr);

  bool Generate(const android::StringPiece& package_name_to_generate,
                const android::StringPiece& output_package_name, std::ostream* out);
                const android::StringPiece& output_package_name, std::ostream* out,
                std::ostream* out_r_txt = nullptr);

  const std::string& getError() const;

@@ -88,13 +90,14 @@ class JavaClassGenerator {

  bool ProcessType(const android::StringPiece& package_name_to_generate,
                   const ResourceTablePackage& package, const ResourceTableType& type,
                   ClassDefinition* out_type_class_def, MethodDefinition* out_rewrite_method_def);
                   ClassDefinition* out_type_class_def, MethodDefinition* out_rewrite_method_def,
                   std::ostream* out_r_txt);

  // Writes a resource to the R.java file, optionally writing out a rewrite rule for its package
  // ID if `out_rewrite_method` is not nullptr.
  void ProcessResource(const ResourceNameRef& name, const ResourceId& id,
                       const ResourceEntry& entry, ClassDefinition* out_class_def,
                       MethodDefinition* out_rewrite_method);
                       MethodDefinition* out_rewrite_method, std::ostream* out_r_txt);

  // Writes a styleable resource to the R.java file, optionally writing out a rewrite rule for
  // its package ID if `out_rewrite_method` is not nullptr.
@@ -102,7 +105,8 @@ class JavaClassGenerator {
  void ProcessStyleable(const ResourceNameRef& name, const ResourceId& id,
                        const Styleable& styleable,
                        const android::StringPiece& package_name_to_generate,
                        ClassDefinition* out_class_def, MethodDefinition* out_rewrite_method);
                        ClassDefinition* out_class_def, MethodDefinition* out_rewrite_method,
                        std::ostream* out_r_txt);

  IAaptContext* context_;
  ResourceTable* table_;