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 <optional> 21 #include <regex> 22 #include <string> 23 #include <unordered_map> 24 #include <unordered_set> 25 #include <vector> 26 27 #include "Command.h" 28 #include "Resource.h" 29 #include "androidfw/IDiagnostics.h" 30 #include "cmd/Util.h" 31 #include "format/binary/TableFlattener.h" 32 #include "format/proto/ProtoSerialize.h" 33 #include "link/ManifestFixer.h" 34 #include "split/TableSplitter.h" 35 #include "trace/TraceBuffer.h" 36 37 namespace aapt { 38 39 enum class OutputFormat { 40 kApk, 41 kProto, 42 }; 43 44 struct LinkOptions { 45 std::string output_path; 46 std::string manifest_path; 47 std::vector<std::string> include_paths; 48 std::vector<std::string> overlay_files; 49 std::vector<std::string> assets_dirs; 50 bool output_to_directory = false; 51 bool auto_add_overlay = false; 52 bool override_styles_instead_of_overlaying = false; 53 OutputFormat output_format = OutputFormat::kApk; 54 std::optional<std::string> rename_resources_package; 55 56 // Java/Proguard options. 57 std::optional<std::string> generate_java_class_path; 58 std::optional<std::string> custom_java_package; 59 std::set<std::string> extra_java_packages; 60 std::optional<std::string> generate_text_symbols_path; 61 std::optional<std::string> generate_proguard_rules_path; 62 std::optional<std::string> generate_main_dex_proguard_rules_path; 63 bool generate_conditional_proguard_rules = false; 64 bool generate_minimal_proguard_rules = false; 65 bool generate_non_final_ids = false; 66 bool no_proguard_location_reference = false; 67 std::vector<std::string> javadoc_annotations; 68 std::optional<std::string> private_symbols; 69 70 // Optimizations/features. 71 bool no_auto_version = false; 72 bool no_version_vectors = false; 73 bool no_version_transitions = false; 74 bool no_resource_deduping = false; 75 bool no_resource_removal = false; 76 bool no_xml_namespaces = false; 77 bool do_not_compress_anything = false; 78 bool use_sparse_encoding = false; 79 std::unordered_set<std::string> extensions_to_not_compress; 80 std::optional<std::regex> regex_to_not_compress; 81 bool no_compress_fonts = false; 82 FeatureFlagValues feature_flag_values; 83 84 // Static lib options. 85 bool no_static_lib_packages = false; 86 bool merge_only = false; 87 88 // AndroidManifest.xml massaging options. 89 ManifestFixerOptions manifest_fixer_options; 90 91 // Products to use/filter on. 92 std::unordered_set<std::string> products; 93 94 // Flattening options. 95 TableFlattenerOptions table_flattener_options; 96 SerializeTableOptions proto_table_flattener_options; 97 bool keep_raw_values = false; 98 99 // Split APK options. 100 TableSplitterOptions table_splitter_options; 101 std::vector<SplitConstraints> split_constraints; 102 std::vector<std::string> split_paths; 103 104 // Configurations to exclude 105 std::vector<std::string> exclude_configs_; 106 107 // Stable ID options. 108 std::unordered_map<ResourceName, ResourceId> stable_id_map; 109 std::optional<std::string> resource_id_map_path; 110 111 // When 'true', allow reserved package IDs to be used for applications. Pre-O, the platform 112 // treats negative resource IDs [those with a package ID of 0x80 or higher] as invalid. 113 // In order to work around this limitation, we allow the use of traditionally reserved 114 // resource IDs [those between 0x02 and 0x7E]. 115 bool allow_reserved_package_id = false; 116 117 // Whether we should fail on definitions of a resource with conflicting visibility. 118 bool strict_visibility = false; 119 }; 120 121 class LinkCommand : public Command { 122 public: LinkCommand(android::IDiagnostics * diag)123 explicit LinkCommand(android::IDiagnostics* diag) : Command("link", "l"), diag_(diag) { 124 SetDescription("Links resources into an apk."); 125 AddRequiredFlag("-o", "Output path.", &options_.output_path, Command::kPath); 126 AddRequiredFlag("--manifest", "Path to the Android manifest to build.", 127 &options_.manifest_path, Command::kPath); 128 AddOptionalFlagList("-I", "Adds an Android APK to link against.", &options_.include_paths, 129 Command::kPath); 130 AddOptionalFlagList("-A", "An assets directory to include in the APK. These are unprocessed.", 131 &options_.assets_dirs, Command::kPath); 132 AddOptionalFlagList("-R", "Compilation unit to link, using `overlay` semantics.\n" 133 "The last conflicting resource given takes precedence.", &overlay_arg_list_, 134 Command::kPath); 135 AddOptionalFlag("--package-id", 136 "Specify the package ID to use for this app. Must be greater or equal to\n" 137 "0x7f and can't be used with --static-lib or --shared-lib.", &package_id_); 138 AddOptionalFlag("--java", "Directory in which to generate R.java.", 139 &options_.generate_java_class_path, Command::kPath); 140 AddOptionalFlag("--proguard", "Output file for generated Proguard rules.", 141 &options_.generate_proguard_rules_path, Command::kPath); 142 AddOptionalFlag("--proguard-main-dex", 143 "Output file for generated Proguard rules for the main dex.", 144 &options_.generate_main_dex_proguard_rules_path, Command::kPath); 145 AddOptionalSwitch("--proguard-conditional-keep-rules", 146 "Generate conditional Proguard keep rules.", 147 &options_.generate_conditional_proguard_rules); 148 AddOptionalSwitch("--proguard-minimal-keep-rules", 149 "Generate a minimal set of Proguard keep rules.", 150 &options_.generate_minimal_proguard_rules); 151 AddOptionalSwitch("--no-auto-version", "Disables automatic style and layout SDK versioning.", 152 &options_.no_auto_version); 153 AddOptionalSwitch("--no-version-vectors", 154 "Disables automatic versioning of vector drawables. Use this only\n" 155 "when building with vector drawable support library.", 156 &options_.no_version_vectors); 157 AddOptionalSwitch("--no-version-transitions", 158 "Disables automatic versioning of transition resources. Use this only\n" 159 "when building with transition support library.", 160 &options_.no_version_transitions); 161 AddOptionalSwitch("--no-resource-deduping", "Disables automatic deduping of resources with\n" 162 "identical values across compatible configurations.", 163 &options_.no_resource_deduping); 164 AddOptionalSwitch("--no-resource-removal", "Disables automatic removal of resources without\n" 165 "defaults. Use this only when building runtime resource overlay packages.", 166 &options_.no_resource_removal); 167 AddOptionalSwitch( 168 "--enable-sparse-encoding", 169 "Enables encoding sparse entries using a binary search tree.\n" 170 "This decreases APK size at the cost of resource retrieval performance.\n" 171 "Only applies sparse encoding if minSdk of the APK is >= 32", 172 &options_.use_sparse_encoding); 173 AddOptionalSwitch("--enable-compact-entries", 174 "This decreases APK size by using compact resource entries for simple data types.", 175 &options_.table_flattener_options.use_compact_entries); 176 AddOptionalSwitch("-x", "Legacy flag that specifies to use the package identifier 0x01.", 177 &legacy_x_flag_); 178 AddOptionalSwitch("-z", "Require localization of strings marked 'suggested'.", 179 &require_localization_); 180 AddOptionalFlagList("-c", 181 "Comma separated list of configurations to include. The default\n" 182 "is all configurations.", &configs_); 183 AddOptionalFlag("--preferred-density", 184 "Selects the closest matching density and strips out all others.", 185 &preferred_density_); 186 AddOptionalFlag("--product", "Comma separated list of product names to keep", &product_list_); 187 AddOptionalSwitch("--output-to-dir", "Outputs the APK contents to a directory specified by -o.", 188 &options_.output_to_directory); 189 AddOptionalSwitch("--no-xml-namespaces", "Removes XML namespace prefix and URI information\n" 190 "from AndroidManifest.xml and XML binaries in res/*.", 191 &options_.no_xml_namespaces); 192 AddOptionalFlag("--min-sdk-version", 193 "Default minimum SDK version to use for AndroidManifest.xml.", 194 &options_.manifest_fixer_options.min_sdk_version_default); 195 AddOptionalFlag("--target-sdk-version", 196 "Default target SDK version to use for AndroidManifest.xml.", 197 &options_.manifest_fixer_options.target_sdk_version_default); 198 AddOptionalFlag("--version-code", 199 "Version code (integer) to inject into the AndroidManifest.xml if none is\n" 200 "present.", &options_.manifest_fixer_options.version_code_default); 201 AddOptionalFlag("--version-code-major", 202 "Version code major (integer) to inject into the AndroidManifest.xml if none is\n" 203 "present.", &options_.manifest_fixer_options.version_code_major_default); 204 AddOptionalFlag("--version-name", 205 "Version name to inject into the AndroidManifest.xml if none is present.", 206 &options_.manifest_fixer_options.version_name_default); 207 AddOptionalFlag("--revision-code", 208 "Revision code (integer) to inject into the AndroidManifest.xml if none is\n" 209 "present.", &options_.manifest_fixer_options.revision_code_default); 210 AddOptionalSwitch("--replace-version", 211 "If --version-code, --version-name, and/or --revision-code are specified, these\n" 212 "values will replace any value already in the manifest. By\n" 213 "default, nothing is changed if the manifest already defines\n" 214 "these attributes.", 215 &options_.manifest_fixer_options.replace_version); 216 AddOptionalFlag("--compile-sdk-version-code", 217 "Version code (integer) to inject into the AndroidManifest.xml if none is\n" 218 "present.", 219 &options_.manifest_fixer_options.compile_sdk_version); 220 AddOptionalFlag("--compile-sdk-version-name", 221 "Version name to inject into the AndroidManifest.xml if none is present.", 222 &options_.manifest_fixer_options.compile_sdk_version_codename); 223 AddOptionalSwitch( 224 "--no-compile-sdk-metadata", 225 "Suppresses output of compile SDK-related attributes in AndroidManifest.xml,\n" 226 "including android:compileSdkVersion and platformBuildVersion.", 227 &options_.manifest_fixer_options.no_compile_sdk_metadata); 228 AddOptionalFlagList("--fingerprint-prefix", "Fingerprint prefix to add to install constraints.", 229 &options_.manifest_fixer_options.fingerprint_prefixes); 230 AddOptionalSwitch("--shared-lib", "Generates a shared Android runtime library.", 231 &shared_lib_); 232 AddOptionalSwitch("--static-lib", "Generate a static Android library.", &static_lib_); 233 AddOptionalSwitch("--proto-format", 234 "Generates compiled resources in Protobuf format.\n" 235 "Suitable as input to the bundle tool for generating an App Bundle.", 236 &proto_format_); 237 AddOptionalSwitch("--no-static-lib-packages", 238 "Merge all library resources under the app's package.", 239 &options_.no_static_lib_packages); 240 AddOptionalSwitch("--non-final-ids", 241 "Generates R.java without the final modifier. This is implied when\n" 242 "--static-lib is specified.", 243 &options_.generate_non_final_ids); 244 AddOptionalSwitch("--no-proguard-location-reference", 245 "Keep proguard rules files from having a reference to the source file", 246 &options_.no_proguard_location_reference); 247 AddOptionalFlag("--stable-ids", "File containing a list of name to ID mapping.", 248 &stable_id_file_path_); 249 AddOptionalFlag("--emit-ids", 250 "Emit a file at the given path with a list of name to ID mappings,\n" 251 "suitable for use with --stable-ids.", 252 &options_.resource_id_map_path); 253 AddOptionalFlag("--private-symbols", 254 "Package name to use when generating R.java for private symbols.\n" 255 "If not specified, public and private symbols will use the application's\n" 256 "package name.", 257 &options_.private_symbols); 258 AddOptionalFlag("--custom-package", "Custom Java package under which to generate R.java.", 259 &options_.custom_java_package); 260 AddOptionalFlagList("--extra-packages", 261 "Generate the same R.java but with different package names.", 262 &extra_java_packages_); 263 AddOptionalFlagList("--add-javadoc-annotation", 264 "Adds a JavaDoc annotation to all generated Java classes.", 265 &options_.javadoc_annotations); 266 AddOptionalFlag("--output-text-symbols", 267 "Generates a text file containing the resource symbols of the R class in\n" 268 "the specified folder.", 269 &options_.generate_text_symbols_path); 270 AddOptionalSwitch("--allow-reserved-package-id", 271 "Allows the use of a reserved package ID. This should on be used for\n" 272 "packages with a pre-O min-sdk\n", 273 &options_.allow_reserved_package_id); 274 AddOptionalSwitch("--auto-add-overlay", 275 "Allows the addition of new resources in overlays without\n" 276 "<add-resource> tags.", 277 &options_.auto_add_overlay); 278 AddOptionalSwitch("--override-styles-instead-of-overlaying", 279 "Causes styles defined in -R resources to replace previous definitions\n" 280 "instead of merging into them\n", 281 &options_.override_styles_instead_of_overlaying); 282 AddOptionalFlag("--rename-manifest-package", "Renames the package in AndroidManifest.xml.", 283 &options_.manifest_fixer_options.rename_manifest_package); 284 AddOptionalFlag("--rename-resources-package", "Renames the package in resources table", 285 &options_.rename_resources_package); 286 AddOptionalFlag("--rename-instrumentation-target-package", 287 "Changes the name of the target package for instrumentation. Most useful\n" 288 "when used in conjunction with --rename-manifest-package.", 289 &options_.manifest_fixer_options.rename_instrumentation_target_package); 290 AddOptionalFlag("--rename-overlay-target-package", 291 "Changes the name of the target package for overlay. Most useful\n" 292 "when used in conjunction with --rename-manifest-package.", 293 &options_.manifest_fixer_options.rename_overlay_target_package); 294 AddOptionalFlag("--rename-overlay-category", "Changes the category for the overlay.", 295 &options_.manifest_fixer_options.rename_overlay_category); 296 AddOptionalFlagList("-0", "File suffix not to compress.", 297 &options_.extensions_to_not_compress); 298 AddOptionalSwitch("--no-compress", "Do not compress any resources.", 299 &options_.do_not_compress_anything); 300 AddOptionalSwitch("--keep-raw-values", "Preserve raw attribute values in xml files.", 301 &options_.keep_raw_values); 302 AddOptionalFlag("--no-compress-regex", 303 "Do not compress extensions matching the regular expression. Remember to\n" 304 "use the '$' symbol for end of line. Uses a case-sensitive ECMAScript" 305 "regular expression grammar.", 306 &no_compress_regex); 307 AddOptionalSwitch("--no-compress-fonts", 308 "Do not compress files with common extensions for fonts.\n" 309 "This allows loading fonts directly from the APK, without needing to\n" 310 "decompress them first. Loading fonts will be faster and use less memory.\n" 311 "The downside is that the APK will be larger.\n" 312 "Passing this flag is functionally equivalent to passing the following flags:\n" 313 "-0 .ttf -0 .otf -0 .ttc", 314 &options_.no_compress_fonts); 315 AddOptionalSwitch("--warn-manifest-validation", 316 "Treat manifest validation errors as warnings.", 317 &options_.manifest_fixer_options.warn_validation); 318 AddOptionalFlagList("--split", 319 "Split resources matching a set of configs out to a Split APK.\n" 320 "Syntax: path/to/output.apk:<config>[,<config>[...]].\n" 321 "On Windows, use a semicolon ';' separator instead.", 322 &split_args_); 323 AddOptionalFlagList("--exclude-configs", 324 "Excludes values of resources whose configs contain the specified qualifiers.", 325 &options_.exclude_configs_); 326 AddOptionalSwitch("--debug-mode", 327 "Inserts android:debuggable=\"true\" in to the application node of the\n" 328 "manifest, making the application debuggable even on production devices.", 329 &options_.manifest_fixer_options.debug_mode); 330 AddOptionalSwitch("--strict-visibility", 331 "Do not allow overlays with different visibility levels.", 332 &options_.strict_visibility); 333 AddOptionalSwitch("--exclude-sources", 334 "Do not serialize source file information when generating resources in\n" 335 "Protobuf format.", 336 &options_.proto_table_flattener_options.exclude_sources); 337 AddOptionalFlag("--trace-folder", 338 "Generate systrace json trace fragment to specified folder.", 339 &trace_folder_); 340 AddOptionalSwitch("--merge-only", 341 "Only merge the resources, without verifying resource references. This flag\n" 342 "should only be used together with the --static-lib flag.", 343 &options_.merge_only); 344 AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_); 345 AddOptionalFlagList("--feature-flags", 346 "Specify the values of feature flags. The pairs in the argument\n" 347 "are separated by ',' the name is separated from the value by '='.\n" 348 "The name can have a suffix of ':ro' to indicate it is read only." 349 "Example: \"flag1=true,flag2:ro=false,flag3=\" (flag3 has no given value).", 350 &feature_flags_args_); 351 AddOptionalSwitch("--non-updatable-system", 352 "Mark the app as a non-updatable system app. This inserts\n" 353 "updatableSystem=\"false\" to the root manifest node, overwriting any\n" 354 "existing attribute. This is ignored if the manifest has a versionCode.", 355 &options_.manifest_fixer_options.non_updatable_system); 356 } 357 358 int Action(const std::vector<std::string>& args) override; 359 360 private: 361 android::IDiagnostics* diag_; 362 LinkOptions options_; 363 364 std::vector<std::string> overlay_arg_list_; 365 std::vector<std::string> extra_java_packages_; 366 std::optional<std::string> package_id_; 367 std::vector<std::string> configs_; 368 std::optional<std::string> preferred_density_; 369 std::optional<std::string> product_list_; 370 std::optional<std::string> no_compress_regex; 371 bool legacy_x_flag_ = false; 372 bool require_localization_ = false; 373 bool verbose_ = false; 374 bool shared_lib_ = false; 375 bool static_lib_ = false; 376 bool proto_format_ = false; 377 std::optional<std::string> stable_id_file_path_; 378 std::vector<std::string> split_args_; 379 std::optional<std::string> trace_folder_; 380 std::vector<std::string> feature_flags_args_; 381 }; 382 383 }// namespace aapt 384 385 #endif //AAPT2_LINK_H 386