summaryrefslogtreecommitdiff
path: root/tools/aapt2/cmd/Link.h
blob: dc18b1ccda6003b6ce0c3f32ccab15982edd2254 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef AAPT2_LINK_H
#define AAPT2_LINK_H

#include <optional>
#include <regex>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "Command.h"
#include "Resource.h"
#include "androidfw/IDiagnostics.h"
#include "cmd/Util.h"
#include "format/binary/TableFlattener.h"
#include "format/proto/ProtoSerialize.h"
#include "link/ManifestFixer.h"
#include "split/TableSplitter.h"
#include "trace/TraceBuffer.h"

namespace aapt {

enum class OutputFormat {
  kApk,
  kProto,
};

struct LinkOptions {
  std::string output_path;
  std::string manifest_path;
  std::vector<std::string> include_paths;
  std::vector<std::string> overlay_files;
  std::vector<std::string> assets_dirs;
  bool output_to_directory = false;
  bool auto_add_overlay = false;
  bool override_styles_instead_of_overlaying = false;
  OutputFormat output_format = OutputFormat::kApk;
  std::optional<std::string> rename_resources_package;

  // Java/Proguard options.
  std::optional<std::string> generate_java_class_path;
  std::optional<std::string> custom_java_package;
  std::set<std::string> extra_java_packages;
  std::optional<std::string> generate_text_symbols_path;
  std::optional<std::string> generate_proguard_rules_path;
  std::optional<std::string> generate_main_dex_proguard_rules_path;
  bool generate_conditional_proguard_rules = false;
  bool generate_minimal_proguard_rules = false;
  bool generate_non_final_ids = false;
  bool no_proguard_location_reference = false;
  std::vector<std::string> javadoc_annotations;
  std::optional<std::string> private_symbols;

  // Optimizations/features.
  bool no_auto_version = false;
  bool no_version_vectors = false;
  bool no_version_transitions = false;
  bool no_resource_deduping = false;
  bool no_resource_removal = false;
  bool no_xml_namespaces = false;
  bool do_not_compress_anything = false;
  bool use_sparse_encoding = false;
  std::unordered_set<std::string> extensions_to_not_compress;
  std::optional<std::regex> regex_to_not_compress;
  FeatureFlagValues feature_flag_values;

  // Static lib options.
  bool no_static_lib_packages = false;
  bool merge_only = false;

  // AndroidManifest.xml massaging options.
  ManifestFixerOptions manifest_fixer_options;

  // Products to use/filter on.
  std::unordered_set<std::string> products;

  // Flattening options.
  TableFlattenerOptions table_flattener_options;
  SerializeTableOptions proto_table_flattener_options;
  bool keep_raw_values = false;

  // Split APK options.
  TableSplitterOptions table_splitter_options;
  std::vector<SplitConstraints> split_constraints;
  std::vector<std::string> split_paths;

  // Configurations to exclude
  std::vector<std::string> exclude_configs_;

  // Stable ID options.
  std::unordered_map<ResourceName, ResourceId> stable_id_map;
  std::optional<std::string> resource_id_map_path;

  // When 'true', allow reserved package IDs to be used for applications. Pre-O, the platform
  // treats negative resource IDs [those with a package ID of 0x80 or higher] as invalid.
  // In order to work around this limitation, we allow the use of traditionally reserved
  // resource IDs [those between 0x02 and 0x7E].
  bool allow_reserved_package_id = false;

  // Whether we should fail on definitions of a resource with conflicting visibility.
  bool strict_visibility = false;
};

class LinkCommand : public Command {
 public:
  explicit LinkCommand(android::IDiagnostics* diag) : Command("link", "l"), diag_(diag) {
    SetDescription("Links resources into an apk.");
    AddRequiredFlag("-o", "Output path.", &options_.output_path, Command::kPath);
    AddRequiredFlag("--manifest", "Path to the Android manifest to build.",
        &options_.manifest_path, Command::kPath);
    AddOptionalFlagList("-I", "Adds an Android APK to link against.", &options_.include_paths,
         Command::kPath);
    AddOptionalFlagList("-A", "An assets directory to include in the APK. These are unprocessed.",
        &options_.assets_dirs, Command::kPath);
    AddOptionalFlagList("-R", "Compilation unit to link, using `overlay` semantics.\n"
        "The last conflicting resource given takes precedence.", &overlay_arg_list_,
        Command::kPath);
    AddOptionalFlag("--package-id",
        "Specify the package ID to use for this app. Must be greater or equal to\n"
            "0x7f and can't be used with --static-lib or --shared-lib.", &package_id_);
    AddOptionalFlag("--java", "Directory in which to generate R.java.",
        &options_.generate_java_class_path, Command::kPath);
    AddOptionalFlag("--proguard", "Output file for generated Proguard rules.",
        &options_.generate_proguard_rules_path, Command::kPath);
    AddOptionalFlag("--proguard-main-dex",
        "Output file for generated Proguard rules for the main dex.",
        &options_.generate_main_dex_proguard_rules_path, Command::kPath);
    AddOptionalSwitch("--proguard-conditional-keep-rules",
        "Generate conditional Proguard keep rules.",
        &options_.generate_conditional_proguard_rules);
    AddOptionalSwitch("--proguard-minimal-keep-rules",
        "Generate a minimal set of Proguard keep rules.",
        &options_.generate_minimal_proguard_rules);
    AddOptionalSwitch("--no-auto-version", "Disables automatic style and layout SDK versioning.",
        &options_.no_auto_version);
    AddOptionalSwitch("--no-version-vectors",
        "Disables automatic versioning of vector drawables. Use this only\n"
            "when building with vector drawable support library.",
        &options_.no_version_vectors);
    AddOptionalSwitch("--no-version-transitions",
        "Disables automatic versioning of transition resources. Use this only\n"
            "when building with transition support library.",
        &options_.no_version_transitions);
    AddOptionalSwitch("--no-resource-deduping", "Disables automatic deduping of resources with\n"
            "identical values across compatible configurations.",
        &options_.no_resource_deduping);
    AddOptionalSwitch("--no-resource-removal", "Disables automatic removal of resources without\n"
            "defaults. Use this only when building runtime resource overlay packages.",
        &options_.no_resource_removal);
    AddOptionalSwitch("--enable-sparse-encoding",
                      "This decreases APK size at the cost of resource retrieval performance.",
                      &options_.use_sparse_encoding);
    AddOptionalSwitch("--enable-compact-entries",
        "This decreases APK size by using compact resource entries for simple data types.",
        &options_.table_flattener_options.use_compact_entries);
    AddOptionalSwitch("-x", "Legacy flag that specifies to use the package identifier 0x01.",
        &legacy_x_flag_);
    AddOptionalSwitch("-z", "Require localization of strings marked 'suggested'.",
        &require_localization_);
    AddOptionalFlagList("-c",
        "Comma separated list of configurations to include. The default\n"
            "is all configurations.", &configs_);
    AddOptionalFlag("--preferred-density",
        "Selects the closest matching density and strips out all others.",
        &preferred_density_);
    AddOptionalFlag("--product", "Comma separated list of product names to keep", &product_list_);
    AddOptionalSwitch("--output-to-dir", "Outputs the APK contents to a directory specified by -o.",
        &options_.output_to_directory);
    AddOptionalSwitch("--no-xml-namespaces", "Removes XML namespace prefix and URI information\n"
            "from AndroidManifest.xml and XML binaries in res/*.",
        &options_.no_xml_namespaces);
    AddOptionalFlag("--min-sdk-version",
        "Default minimum SDK version to use for AndroidManifest.xml.",
        &options_.manifest_fixer_options.min_sdk_version_default);
    AddOptionalFlag("--target-sdk-version",
        "Default target SDK version to use for AndroidManifest.xml.",
        &options_.manifest_fixer_options.target_sdk_version_default);
    AddOptionalFlag("--version-code",
        "Version code (integer) to inject into the AndroidManifest.xml if none is\n"
            "present.", &options_.manifest_fixer_options.version_code_default);
    AddOptionalFlag("--version-code-major",
        "Version code major (integer) to inject into the AndroidManifest.xml if none is\n"
            "present.", &options_.manifest_fixer_options.version_code_major_default);
    AddOptionalFlag("--version-name",
        "Version name to inject into the AndroidManifest.xml if none is present.",
        &options_.manifest_fixer_options.version_name_default);
    AddOptionalFlag("--revision-code",
        "Revision code (integer) to inject into the AndroidManifest.xml if none is\n"
            "present.", &options_.manifest_fixer_options.revision_code_default);
    AddOptionalSwitch("--replace-version",
        "If --version-code, --version-name, and/or --revision-code are specified, these\n"
            "values will replace any value already in the manifest. By\n"
            "default, nothing is changed if the manifest already defines\n"
            "these attributes.",
        &options_.manifest_fixer_options.replace_version);
    AddOptionalFlag("--compile-sdk-version-code",
        "Version code (integer) to inject into the AndroidManifest.xml if none is\n"
            "present.",
        &options_.manifest_fixer_options.compile_sdk_version);
    AddOptionalFlag("--compile-sdk-version-name",
        "Version name to inject into the AndroidManifest.xml if none is present.",
        &options_.manifest_fixer_options.compile_sdk_version_codename);
    AddOptionalSwitch(
        "--no-compile-sdk-metadata",
        "Suppresses output of compile SDK-related attributes in AndroidManifest.xml,\n"
        "including android:compileSdkVersion and platformBuildVersion.",
        &options_.manifest_fixer_options.no_compile_sdk_metadata);
    AddOptionalFlagList("--fingerprint-prefix", "Fingerprint prefix to add to install constraints.",
                        &options_.manifest_fixer_options.fingerprint_prefixes);
    AddOptionalSwitch("--shared-lib", "Generates a shared Android runtime library.",
        &shared_lib_);
    AddOptionalSwitch("--static-lib", "Generate a static Android library.", &static_lib_);
    AddOptionalSwitch("--proto-format",
        "Generates compiled resources in Protobuf format.\n"
            "Suitable as input to the bundle tool for generating an App Bundle.",
        &proto_format_);
    AddOptionalSwitch("--no-static-lib-packages",
        "Merge all library resources under the app's package.",
        &options_.no_static_lib_packages);
    AddOptionalSwitch("--non-final-ids",
        "Generates R.java without the final modifier. This is implied when\n"
            "--static-lib is specified.",
        &options_.generate_non_final_ids);
    AddOptionalSwitch("--no-proguard-location-reference",
        "Keep proguard rules files from having a reference to the source file",
        &options_.no_proguard_location_reference);
    AddOptionalFlag("--stable-ids", "File containing a list of name to ID mapping.",
        &stable_id_file_path_);
    AddOptionalFlag("--emit-ids",
        "Emit a file at the given path with a list of name to ID mappings,\n"
            "suitable for use with --stable-ids.",
        &options_.resource_id_map_path);
    AddOptionalFlag("--private-symbols",
        "Package name to use when generating R.java for private symbols.\n"
            "If not specified, public and private symbols will use the application's\n"
            "package name.",
        &options_.private_symbols);
    AddOptionalFlag("--custom-package", "Custom Java package under which to generate R.java.",
        &options_.custom_java_package);
    AddOptionalFlagList("--extra-packages",
        "Generate the same R.java but with different package names.",
        &extra_java_packages_);
    AddOptionalFlagList("--add-javadoc-annotation",
        "Adds a JavaDoc annotation to all generated Java classes.",
        &options_.javadoc_annotations);
    AddOptionalFlag("--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);
    AddOptionalSwitch("--allow-reserved-package-id",
        "Allows the use of a reserved package ID. This should on be used for\n"
            "packages with a pre-O min-sdk\n",
        &options_.allow_reserved_package_id);
    AddOptionalSwitch("--auto-add-overlay",
        "Allows the addition of new resources in overlays without\n"
            "<add-resource> tags.",
        &options_.auto_add_overlay);
    AddOptionalSwitch("--override-styles-instead-of-overlaying",
        "Causes styles defined in -R resources to replace previous definitions\n"
            "instead of merging into them\n",
        &options_.override_styles_instead_of_overlaying);
    AddOptionalFlag("--rename-manifest-package", "Renames the package in AndroidManifest.xml.",
        &options_.manifest_fixer_options.rename_manifest_package);
    AddOptionalFlag("--rename-resources-package", "Renames the package in resources table",
        &options_.rename_resources_package);
    AddOptionalFlag("--rename-instrumentation-target-package",
        "Changes the name of the target package for instrumentation. Most useful\n"
            "when used in conjunction with --rename-manifest-package.",
        &options_.manifest_fixer_options.rename_instrumentation_target_package);
    AddOptionalFlag("--rename-overlay-target-package",
        "Changes the name of the target package for overlay. Most useful\n"
            "when used in conjunction with --rename-manifest-package.",
        &options_.manifest_fixer_options.rename_overlay_target_package);
    AddOptionalFlag("--rename-overlay-category", "Changes the category for the overlay.",
                    &options_.manifest_fixer_options.rename_overlay_category);
    AddOptionalFlagList("-0", "File suffix not to compress.",
        &options_.extensions_to_not_compress);
    AddOptionalSwitch("--no-compress", "Do not compress any resources.",
        &options_.do_not_compress_anything);
    AddOptionalSwitch("--keep-raw-values", "Preserve raw attribute values in xml files.",
        &options_.keep_raw_values);
    AddOptionalFlag("--no-compress-regex",
        "Do not compress extensions matching the regular expression. Remember to\n"
            "use the '$' symbol for end of line. Uses a case-sensitive ECMAScript"
            "regular expression grammar.",
        &no_compress_regex);
    AddOptionalSwitch("--warn-manifest-validation",
        "Treat manifest validation errors as warnings.",
        &options_.manifest_fixer_options.warn_validation);
    AddOptionalFlagList("--split",
        "Split resources matching a set of configs out to a Split APK.\n"
            "Syntax: path/to/output.apk:<config>[,<config>[...]].\n"
            "On Windows, use a semicolon ';' separator instead.",
        &split_args_);
    AddOptionalFlagList("--exclude-configs",
        "Excludes values of resources whose configs contain the specified qualifiers.",
        &options_.exclude_configs_);
    AddOptionalSwitch("--debug-mode",
        "Inserts android:debuggable=\"true\" in to the application node of the\n"
            "manifest, making the application debuggable even on production devices.",
        &options_.manifest_fixer_options.debug_mode);
    AddOptionalSwitch("--strict-visibility",
        "Do not allow overlays with different visibility levels.",
        &options_.strict_visibility);
    AddOptionalSwitch("--exclude-sources",
        "Do not serialize source file information when generating resources in\n"
            "Protobuf format.",
        &options_.proto_table_flattener_options.exclude_sources);
    AddOptionalFlag("--trace-folder",
        "Generate systrace json trace fragment to specified folder.",
        &trace_folder_);
    AddOptionalSwitch("--merge-only",
        "Only merge the resources, without verifying resource references. This flag\n"
            "should only be used together with the --static-lib flag.",
        &options_.merge_only);
    AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_);
    AddOptionalFlagList("--feature-flags",
                        "Specify the values of feature flags. The pairs in the argument\n"
                        "are separated by ',' and the name is separated from the value by '='.\n"
                        "Example: \"flag1=true,flag2=false,flag3=\" (flag3 has no given value).",
                        &feature_flags_args_);
  }

  int Action(const std::vector<std::string>& args) override;

 private:
  android::IDiagnostics* diag_;
  LinkOptions options_;

  std::vector<std::string> overlay_arg_list_;
  std::vector<std::string> extra_java_packages_;
  std::optional<std::string> package_id_;
  std::vector<std::string> configs_;
  std::optional<std::string> preferred_density_;
  std::optional<std::string> product_list_;
  std::optional<std::string> no_compress_regex;
  bool legacy_x_flag_ = false;
  bool require_localization_ = false;
  bool verbose_ = false;
  bool shared_lib_ = false;
  bool static_lib_ = false;
  bool proto_format_ = false;
  std::optional<std::string> stable_id_file_path_;
  std::vector<std::string> split_args_;
  std::optional<std::string> trace_folder_;
  std::vector<std::string> feature_flags_args_;
};

}// namespace aapt

#endif //AAPT2_LINK_H