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