Home | History | Annotate | Download | only in cmd
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef AAPT2_LINK_H
     18 #define AAPT2_LINK_H
     19 
     20 #include <regex>
     21 
     22 #include "Command.h"
     23 #include "Diagnostics.h"
     24 #include "Resource.h"
     25 #include "split/TableSplitter.h"
     26 #include "format/binary/TableFlattener.h"
     27 #include "link/ManifestFixer.h"
     28 #include "trace/TraceBuffer.h"
     29 
     30 namespace aapt {
     31 
     32 enum class OutputFormat {
     33   kApk,
     34   kProto,
     35 };
     36 
     37 struct LinkOptions {
     38   std::string output_path;
     39   std::string manifest_path;
     40   std::vector<std::string> include_paths;
     41   std::vector<std::string> overlay_files;
     42   std::vector<std::string> assets_dirs;
     43   bool output_to_directory = false;
     44   bool auto_add_overlay = false;
     45   OutputFormat output_format = OutputFormat::kApk;
     46 
     47   // Java/Proguard options.
     48   Maybe<std::string> generate_java_class_path;
     49   Maybe<std::string> custom_java_package;
     50   std::set<std::string> extra_java_packages;
     51   Maybe<std::string> generate_text_symbols_path;
     52   Maybe<std::string> generate_proguard_rules_path;
     53   Maybe<std::string> generate_main_dex_proguard_rules_path;
     54   bool generate_conditional_proguard_rules = false;
     55   bool generate_minimal_proguard_rules = false;
     56   bool generate_non_final_ids = false;
     57   std::vector<std::string> javadoc_annotations;
     58   Maybe<std::string> private_symbols;
     59 
     60   // Optimizations/features.
     61   bool no_auto_version = false;
     62   bool no_version_vectors = false;
     63   bool no_version_transitions = false;
     64   bool no_resource_deduping = false;
     65   bool no_resource_removal = false;
     66   bool no_xml_namespaces = false;
     67   bool do_not_compress_anything = false;
     68   std::unordered_set<std::string> extensions_to_not_compress;
     69   Maybe<std::regex> regex_to_not_compress;
     70 
     71   // Static lib options.
     72   bool no_static_lib_packages = false;
     73 
     74   // AndroidManifest.xml massaging options.
     75   ManifestFixerOptions manifest_fixer_options;
     76 
     77   // Products to use/filter on.
     78   std::unordered_set<std::string> products;
     79 
     80   // Flattening options.
     81   TableFlattenerOptions table_flattener_options;
     82   bool keep_raw_values = false;
     83 
     84   // Split APK options.
     85   TableSplitterOptions table_splitter_options;
     86   std::vector<SplitConstraints> split_constraints;
     87   std::vector<std::string> split_paths;
     88 
     89   // Configurations to exclude
     90   std::vector<std::string> exclude_configs_;
     91 
     92   // Stable ID options.
     93   std::unordered_map<ResourceName, ResourceId> stable_id_map;
     94   Maybe<std::string> resource_id_map_path;
     95 
     96   // When 'true', allow reserved package IDs to be used for applications. Pre-O, the platform
     97   // treats negative resource IDs [those with a package ID of 0x80 or higher] as invalid.
     98   // In order to work around this limitation, we allow the use of traditionally reserved
     99   // resource IDs [those between 0x02 and 0x7E].
    100   bool allow_reserved_package_id = false;
    101 
    102   // Whether we should fail on definitions of a resource with conflicting visibility.
    103   bool strict_visibility = false;
    104 };
    105 
    106 class LinkCommand : public Command {
    107  public:
    108   explicit LinkCommand(IDiagnostics* diag) : Command("link", "l"),
    109                                              diag_(diag) {
    110     SetDescription("Links resources into an apk.");
    111     AddRequiredFlag("-o", "Output path.", &options_.output_path, Command::kPath);
    112     AddRequiredFlag("--manifest", "Path to the Android manifest to build.",
    113         &options_.manifest_path, Command::kPath);
    114     AddOptionalFlagList("-I", "Adds an Android APK to link against.", &options_.include_paths,
    115          Command::kPath);
    116     AddOptionalFlagList("-A", "An assets directory to include in the APK. These are unprocessed.",
    117         &options_.assets_dirs, Command::kPath);
    118     AddOptionalFlagList("-R", "Compilation unit to link, using `overlay` semantics.\n"
    119         "The last conflicting resource given takes precedence.", &overlay_arg_list_,
    120         Command::kPath);
    121     AddOptionalFlag("--package-id",
    122         "Specify the package ID to use for this app. Must be greater or equal to\n"
    123             "0x7f and can't be used with --static-lib or --shared-lib.", &package_id_);
    124     AddOptionalFlag("--java", "Directory in which to generate R.java.",
    125         &options_.generate_java_class_path, Command::kPath);
    126     AddOptionalFlag("--proguard", "Output file for generated Proguard rules.",
    127         &options_.generate_proguard_rules_path, Command::kPath);
    128     AddOptionalFlag("--proguard-main-dex",
    129         "Output file for generated Proguard rules for the main dex.",
    130         &options_.generate_main_dex_proguard_rules_path, Command::kPath);
    131     AddOptionalSwitch("--proguard-conditional-keep-rules",
    132         "Generate conditional Proguard keep rules.",
    133         &options_.generate_conditional_proguard_rules);
    134     AddOptionalSwitch("--proguard-minimal-keep-rules",
    135         "Generate a minimal set of Proguard keep rules.",
    136         &options_.generate_minimal_proguard_rules);
    137     AddOptionalSwitch("--no-auto-version", "Disables automatic style and layout SDK versioning.",
    138         &options_.no_auto_version);
    139     AddOptionalSwitch("--no-version-vectors",
    140         "Disables automatic versioning of vector drawables. Use this only\n"
    141             "when building with vector drawable support library.",
    142         &options_.no_version_vectors);
    143     AddOptionalSwitch("--no-version-transitions",
    144         "Disables automatic versioning of transition resources. Use this only\n"
    145             "when building with transition support library.",
    146         &options_.no_version_transitions);
    147     AddOptionalSwitch("--no-resource-deduping", "Disables automatic deduping of resources with\n"
    148             "identical values across compatible configurations.",
    149         &options_.no_resource_deduping);
    150     AddOptionalSwitch("--no-resource-removal", "Disables automatic removal of resources without\n"
    151             "defaults. Use this only when building runtime resource overlay packages.",
    152         &options_.no_resource_removal);
    153     AddOptionalSwitch("--enable-sparse-encoding",
    154         "This decreases APK size at the cost of resource retrieval performance.",
    155         &options_.table_flattener_options.use_sparse_entries);
    156     AddOptionalSwitch("-x", "Legacy flag that specifies to use the package identifier 0x01.",
    157         &legacy_x_flag_);
    158     AddOptionalSwitch("-z", "Require localization of strings marked 'suggested'.",
    159         &require_localization_);
    160     AddOptionalFlagList("-c",
    161         "Comma separated list of configurations to include. The default\n"
    162             "is all configurations.", &configs_);
    163     AddOptionalFlag("--preferred-density",
    164         "Selects the closest matching density and strips out all others.",
    165         &preferred_density_);
    166     AddOptionalFlag("--product", "Comma separated list of product names to keep", &product_list_);
    167     AddOptionalSwitch("--output-to-dir", "Outputs the APK contents to a directory specified by -o.",
    168         &options_.output_to_directory);
    169     AddOptionalSwitch("--no-xml-namespaces", "Removes XML namespace prefix and URI information\n"
    170             "from AndroidManifest.xml and XML binaries in res/*.",
    171         &options_.no_xml_namespaces);
    172     AddOptionalFlag("--min-sdk-version",
    173         "Default minimum SDK version to use for AndroidManifest.xml.",
    174         &options_.manifest_fixer_options.min_sdk_version_default);
    175     AddOptionalFlag("--target-sdk-version",
    176         "Default target SDK version to use for AndroidManifest.xml.",
    177         &options_.manifest_fixer_options.target_sdk_version_default);
    178     AddOptionalFlag("--version-code",
    179         "Version code (integer) to inject into the AndroidManifest.xml if none is\n"
    180             "present.", &options_.manifest_fixer_options.version_code_default);
    181     AddOptionalFlag("--version-code-major",
    182         "Version code major (integer) to inject into the AndroidManifest.xml if none is\n"
    183             "present.", &options_.manifest_fixer_options.version_code_major_default);
    184     AddOptionalFlag("--version-name",
    185         "Version name to inject into the AndroidManifest.xml if none is present.",
    186         &options_.manifest_fixer_options.version_name_default);
    187     AddOptionalSwitch("--replace-version",
    188         "If --version-code and/or --version-name are specified, these\n"
    189             "values will replace any value already in the manifest. By\n"
    190             "default, nothing is changed if the manifest already defines\n"
    191             "these attributes.",
    192         &options_.manifest_fixer_options.replace_version);
    193     AddOptionalFlag("--compile-sdk-version-code",
    194         "Version code (integer) to inject into the AndroidManifest.xml if none is\n"
    195             "present.",
    196         &options_.manifest_fixer_options.compile_sdk_version);
    197     AddOptionalFlag("--compile-sdk-version-name",
    198         "Version name to inject into the AndroidManifest.xml if none is present.",
    199         &options_.manifest_fixer_options.compile_sdk_version_codename);
    200     AddOptionalSwitch("--shared-lib", "Generates a shared Android runtime library.",
    201         &shared_lib_);
    202     AddOptionalSwitch("--static-lib", "Generate a static Android library.", &static_lib_);
    203     AddOptionalSwitch("--proto-format",
    204         "Generates compiled resources in Protobuf format.\n"
    205             "Suitable as input to the bundle tool for generating an App Bundle.",
    206         &proto_format_);
    207     AddOptionalSwitch("--no-static-lib-packages",
    208         "Merge all library resources under the app's package.",
    209         &options_.no_static_lib_packages);
    210     AddOptionalSwitch("--non-final-ids",
    211         "Generates R.java without the final modifier. This is implied when\n"
    212             "--static-lib is specified.",
    213         &options_.generate_non_final_ids);
    214     AddOptionalFlag("--stable-ids", "File containing a list of name to ID mapping.",
    215         &stable_id_file_path_);
    216     AddOptionalFlag("--emit-ids",
    217         "Emit a file at the given path with a list of name to ID mappings,\n"
    218             "suitable for use with --stable-ids.",
    219         &options_.resource_id_map_path);
    220     AddOptionalFlag("--private-symbols",
    221         "Package name to use when generating R.java for private symbols.\n"
    222             "If not specified, public and private symbols will use the application's\n"
    223             "package name.",
    224         &options_.private_symbols);
    225     AddOptionalFlag("--custom-package", "Custom Java package under which to generate R.java.",
    226         &options_.custom_java_package);
    227     AddOptionalFlagList("--extra-packages",
    228         "Generate the same R.java but with different package names.",
    229         &extra_java_packages_);
    230     AddOptionalFlagList("--add-javadoc-annotation",
    231         "Adds a JavaDoc annotation to all generated Java classes.",
    232         &options_.javadoc_annotations);
    233     AddOptionalFlag("--output-text-symbols",
    234         "Generates a text file containing the resource symbols of the R class in\n"
    235             "the specified folder.",
    236         &options_.generate_text_symbols_path);
    237     AddOptionalSwitch("--allow-reserved-package-id",
    238         "Allows the use of a reserved package ID. This should on be used for\n"
    239             "packages with a pre-O min-sdk\n",
    240         &options_.allow_reserved_package_id);
    241     AddOptionalSwitch("--auto-add-overlay",
    242         "Allows the addition of new resources in overlays without\n"
    243             "<add-resource> tags.",
    244         &options_.auto_add_overlay);
    245     AddOptionalFlag("--rename-manifest-package", "Renames the package in AndroidManifest.xml.",
    246         &options_.manifest_fixer_options.rename_manifest_package);
    247     AddOptionalFlag("--rename-instrumentation-target-package",
    248         "Changes the name of the target package for instrumentation. Most useful\n"
    249             "when used in conjunction with --rename-manifest-package.",
    250         &options_.manifest_fixer_options.rename_instrumentation_target_package);
    251     AddOptionalFlagList("-0", "File extensions not to compress.",
    252         &options_.extensions_to_not_compress);
    253     AddOptionalSwitch("--no-compress", "Do not compress any resources.",
    254         &options_.do_not_compress_anything);
    255     AddOptionalSwitch("--keep-raw-values", "Preserve raw attribute values in xml files.",
    256         &options_.keep_raw_values);
    257     AddOptionalFlag("--no-compress-regex",
    258         "Do not compress extensions matching the regular expression. Remember to\n"
    259             " use the '$' symbol for end of line. Uses a non case-sensitive\n"
    260             " ECMAScript regular expression grammar.",
    261         &no_compress_regex);
    262     AddOptionalSwitch("--warn-manifest-validation",
    263         "Treat manifest validation errors as warnings.",
    264         &options_.manifest_fixer_options.warn_validation);
    265     AddOptionalFlagList("--split",
    266         "Split resources matching a set of configs out to a Split APK.\n"
    267             "Syntax: path/to/output.apk:<config>[,<config>[...]].\n"
    268             "On Windows, use a semicolon ';' separator instead.",
    269         &split_args_);
    270     AddOptionalFlagList("--exclude-configs",
    271         "Excludes values of resources whose configs contain the specified qualifiers.",
    272         &options_.exclude_configs_);
    273     AddOptionalSwitch("--debug-mode",
    274         "Inserts android:debuggable=\"true\" in to the application node of the\n"
    275             "manifest, making the application debuggable even on production devices.",
    276         &options_.manifest_fixer_options.debug_mode);
    277     AddOptionalSwitch("--strict-visibility",
    278         "Do not allow overlays with different visibility levels.",
    279         &options_.strict_visibility);
    280     AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_);
    281     AddOptionalFlag("--trace-folder", "Generate systrace json trace fragment to specified folder.",
    282                     &trace_folder_);
    283   }
    284 
    285   int Action(const std::vector<std::string>& args) override;
    286 
    287  private:
    288   IDiagnostics* diag_;
    289   LinkOptions options_;
    290 
    291   std::vector<std::string> overlay_arg_list_;
    292   std::vector<std::string> extra_java_packages_;
    293   Maybe<std::string> package_id_;
    294   std::vector<std::string> configs_;
    295   Maybe<std::string> preferred_density_;
    296   Maybe<std::string> product_list_;
    297   Maybe<std::string> no_compress_regex;
    298   bool legacy_x_flag_ = false;
    299   bool require_localization_ = false;
    300   bool verbose_ = false;
    301   bool shared_lib_ = false;
    302   bool static_lib_ = false;
    303   bool proto_format_ = false;
    304   Maybe<std::string> stable_id_file_path_;
    305   std::vector<std::string> split_args_;
    306   Maybe<std::string> trace_folder_;
    307 };
    308 
    309 }// namespace aapt
    310 
    311 #endif //AAPT2_LINK_H
    312