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