blob: 4981d0a65084bd4902e88668841dfee447c3d07c [file] [log] [blame]
Andrew Grieve7dd4aaf2021-04-27 21:47:081#!/usr/bin/env python3
Ingemar Ådahl6ada47b2017-07-10 17:14:012
3# Copyright 2017 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Merges dependency Android manifests into a root manifest."""
8
9import argparse
10import contextlib
11import os
12import sys
13import tempfile
Eric Stevenson80458272019-02-04 20:57:5814import xml.etree.ElementTree as ElementTree
Ingemar Ådahl6ada47b2017-07-10 17:14:0115
16from util import build_utils
Tibor Goldschwendt228bd4c2019-06-17 20:32:0217from util import manifest_utils
Ingemar Ådahl6ada47b2017-07-10 17:14:0118
Eric Stevenson80458272019-02-04 20:57:5819_MANIFEST_MERGER_MAIN_CLASS = 'com.android.manifmerger.Merger'
20_MANIFEST_MERGER_JARS = [
Sam Maier226aef92020-02-07 22:39:4021 os.path.join('build-system', 'manifest-merger.jar'),
22 os.path.join('common', 'common.jar'),
23 os.path.join('sdk-common', 'sdk-common.jar'),
24 os.path.join('sdklib', 'sdklib.jar'),
Peter Wen059f2e42021-09-20 18:05:3025 os.path.join('external', 'com', 'google', 'guava', 'guava', '30.1-jre',
26 'guava-30.1-jre.jar'),
Sam Maier226aef92020-02-07 22:39:4027 os.path.join('external', 'kotlin-plugin-ij', 'Kotlin', 'kotlinc', 'lib',
28 'kotlin-stdlib.jar'),
Torne (Richard Coles)ff4b3822021-07-22 20:09:5529 os.path.join('external', 'com', 'google', 'code', 'gson', 'gson', '2.8.6',
30 'gson-2.8.6.jar'),
Ingemar Ådahl6ada47b2017-07-10 17:14:0131]
32
Ingemar Ådahl6ada47b2017-07-10 17:14:0133
34@contextlib.contextmanager
Tibor Goldschwendtfda15942019-06-24 21:57:4735def _ProcessManifest(manifest_path, min_sdk_version, target_sdk_version,
Tibor Goldschwendt17604402019-07-11 14:44:1036 max_sdk_version, manifest_package):
Sam Maier5e585302020-01-29 15:54:2137 """Patches an Android manifest's package and performs assertions to ensure
38 correctness for the manifest.
Ingemar Ådahl6ada47b2017-07-10 17:14:0139 """
Tibor Goldschwendt228bd4c2019-06-17 20:32:0240 doc, manifest, _ = manifest_utils.ParseManifest(manifest_path)
Tibor Goldschwendt17604402019-07-11 14:44:1041 manifest_utils.AssertUsesSdk(manifest, min_sdk_version, target_sdk_version,
42 max_sdk_version)
Tibor Goldschwendtfda15942019-06-24 21:57:4743 assert manifest_utils.GetPackage(manifest) or manifest_package, \
44 'Must set manifest package in GN or in AndroidManifest.xml'
45 manifest_utils.AssertPackage(manifest, manifest_package)
46 if manifest_package:
47 manifest.set('package', manifest_package)
Ingemar Ådahl6ada47b2017-07-10 17:14:0148 tmp_prefix = os.path.basename(manifest_path)
49 with tempfile.NamedTemporaryFile(prefix=tmp_prefix) as patched_manifest:
Tibor Goldschwendt228bd4c2019-06-17 20:32:0250 manifest_utils.SaveManifest(doc, patched_manifest.name)
Tibor Goldschwendtfda15942019-06-24 21:57:4751 yield patched_manifest.name, manifest_utils.GetPackage(manifest)
Ingemar Ådahl6ada47b2017-07-10 17:14:0152
53
Sam Maier9760d5b2022-04-22 21:04:0554@contextlib.contextmanager
55def _SetTargetApi(manifest_path, target_sdk_version):
56 """Patches an Android manifest's TargetApi if not set.
57
58 We do this to avoid the manifest merger assuming we have a targetSdkVersion
59 of 1 and inserting unnecessary permission requests into our merged manifests.
60 See b/222331337 for more details.
61 """
62 doc, manifest, _ = manifest_utils.ParseManifest(manifest_path)
63 manifest_utils.SetTargetApiIfUnset(manifest, target_sdk_version)
64 tmp_prefix = os.path.basename(manifest_path)
65 with tempfile.NamedTemporaryFile(prefix=tmp_prefix) as patched_manifest:
66 manifest_utils.SaveManifest(doc, patched_manifest.name)
67 yield patched_manifest.name
68
69
Sam Maier226aef92020-02-07 22:39:4070def _BuildManifestMergerClasspath(android_sdk_cmdline_tools):
Ingemar Ådahl6ada47b2017-07-10 17:14:0171 return ':'.join([
Sam Maier226aef92020-02-07 22:39:4072 os.path.join(android_sdk_cmdline_tools, 'lib', jar)
Eric Stevenson80458272019-02-04 20:57:5873 for jar in _MANIFEST_MERGER_JARS
Ingemar Ådahl6ada47b2017-07-10 17:14:0174 ])
75
76
77def main(argv):
78 argv = build_utils.ExpandFileArgs(argv)
79 parser = argparse.ArgumentParser(description=__doc__)
Andrew Grieve9ce44b92017-07-25 02:43:0580 build_utils.AddDepfileOption(parser)
Sam Maierd7e900a2020-01-30 16:37:3481 parser.add_argument(
Sam Maier226aef92020-02-07 22:39:4082 '--android-sdk-cmdline-tools',
83 help='Path to SDK\'s cmdline-tools folder.',
Sam Maierd7e900a2020-01-30 16:37:3484 required=True)
Ingemar Ådahl6ada47b2017-07-10 17:14:0185 parser.add_argument('--root-manifest',
86 help='Root manifest which to merge into',
87 required=True)
88 parser.add_argument('--output', help='Output manifest path', required=True)
89 parser.add_argument('--extras',
90 help='GN list of additional manifest to merge')
Tibor Goldschwendt228bd4c2019-06-17 20:32:0291 parser.add_argument(
92 '--min-sdk-version',
93 required=True,
94 help='android:minSdkVersion for merging.')
95 parser.add_argument(
96 '--target-sdk-version',
97 required=True,
98 help='android:targetSdkVersion for merging.')
Tibor Goldschwendtfda15942019-06-24 21:57:4799 parser.add_argument(
Tibor Goldschwendt17604402019-07-11 14:44:10100 '--max-sdk-version', help='android:maxSdkVersion for merging.')
101 parser.add_argument(
Tibor Goldschwendtfda15942019-06-24 21:57:47102 '--manifest-package',
103 help='Package name of the merged AndroidManifest.xml.')
Andrew Grievee9cae1e2020-08-21 18:34:16104 parser.add_argument('--warnings-as-errors',
105 action='store_true',
106 help='Treat all warnings as errors.')
Ingemar Ådahl6ada47b2017-07-10 17:14:01107 args = parser.parse_args(argv)
108
Sam Maier226aef92020-02-07 22:39:40109 classpath = _BuildManifestMergerClasspath(args.android_sdk_cmdline_tools)
Ingemar Ådahl6ada47b2017-07-10 17:14:01110
Eric Stevenson80458272019-02-04 20:57:58111 with build_utils.AtomicOutput(args.output) as output:
Andrew Grievee9cae1e2020-08-21 18:34:16112 cmd = build_utils.JavaCmd(args.warnings_as_errors) + [
Eric Stevenson80458272019-02-04 20:57:58113 '-cp',
114 classpath,
115 _MANIFEST_MERGER_MAIN_CLASS,
116 '--out',
117 output.name,
Tibor Goldschwendt17604402019-07-11 14:44:10118 '--property',
119 'MIN_SDK_VERSION=' + args.min_sdk_version,
120 '--property',
121 'TARGET_SDK_VERSION=' + args.target_sdk_version,
Takuto Ikuta61fee732018-07-06 05:44:45122 ]
Ingemar Ådahl6ada47b2017-07-10 17:14:01123
Tibor Goldschwendt17604402019-07-11 14:44:10124 if args.max_sdk_version:
125 cmd += [
126 '--property',
127 'MAX_SDK_VERSION=' + args.max_sdk_version,
128 ]
129
Takuto Ikuta61fee732018-07-06 05:44:45130 extras = build_utils.ParseGnList(args.extras)
Takuto Ikuta61fee732018-07-06 05:44:45131
Sam Maier9760d5b2022-04-22 21:04:05132 with contextlib.ExitStack() as stack:
133 root_manifest, package = stack.enter_context(
134 _ProcessManifest(args.root_manifest, args.min_sdk_version,
135 args.target_sdk_version, args.max_sdk_version,
136 args.manifest_package))
137 if extras:
138 extras_processed = [
139 stack.enter_context(_SetTargetApi(e, args.target_sdk_version))
140 for e in extras
141 ]
142 cmd += ['--libs', ':'.join(extras_processed)]
Tibor Goldschwendt228bd4c2019-06-17 20:32:02143 cmd += [
144 '--main',
145 root_manifest,
146 '--property',
147 'PACKAGE=' + package,
Mohamed Heikal9ec8d822021-05-11 19:18:20148 '--remove-tools-declarations',
Tibor Goldschwendt228bd4c2019-06-17 20:32:02149 ]
Andrew Grievee9cae1e2020-08-21 18:34:16150 build_utils.CheckOutput(
151 cmd,
152 # https://issuetracker.google.com/issues/63514300:
153 # The merger doesn't set a nonzero exit code for failures.
154 fail_func=lambda returncode, stderr: returncode != 0 or build_utils.
155 IsTimeStale(output.name, [root_manifest] + extras),
156 fail_on_output=args.warnings_as_errors)
Eric Stevenson59bf3c62019-01-23 23:30:49157
Tibor Goldschwendt520e1a42019-06-24 21:45:33158 # Check for correct output.
159 _, manifest, _ = manifest_utils.ParseManifest(output.name)
160 manifest_utils.AssertUsesSdk(manifest, args.min_sdk_version,
161 args.target_sdk_version)
Tibor Goldschwendtfda15942019-06-24 21:57:47162 manifest_utils.AssertPackage(manifest, package)
Eric Stevenson59bf3c62019-01-23 23:30:49163
Andrew Grieve9ce44b92017-07-25 02:43:05164 if args.depfile:
165 inputs = extras + classpath.split(':')
Andrew Grieve85822952020-06-25 18:06:00166 build_utils.WriteDepfile(args.depfile, args.output, inputs=inputs)
Ingemar Ådahl6ada47b2017-07-10 17:14:01167
168
169if __name__ == '__main__':
170 main(sys.argv[1:])