1*115816f9SAndroid Build Coastguard Worker#!/usr/bin/env -S python3 -u 2*115816f9SAndroid Build Coastguard Worker# Copyright (C) 2024 The Android Open Source Project 3*115816f9SAndroid Build Coastguard Worker# 4*115816f9SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*115816f9SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*115816f9SAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*115816f9SAndroid Build Coastguard Worker# 8*115816f9SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*115816f9SAndroid Build Coastguard Worker# 10*115816f9SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*115816f9SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 12*115816f9SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*115816f9SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*115816f9SAndroid Build Coastguard Worker# limitations under the License. 15*115816f9SAndroid Build Coastguard Worker 16*115816f9SAndroid Build Coastguard Workerimport argparse 17*115816f9SAndroid Build Coastguard Workerimport os 18*115816f9SAndroid Build Coastguard Workerfrom pathlib import Path 19*115816f9SAndroid Build Coastguard Workerimport shutil 20*115816f9SAndroid Build Coastguard Workerimport subprocess 21*115816f9SAndroid Build Coastguard Workerimport sys 22*115816f9SAndroid Build Coastguard Worker 23*115816f9SAndroid Build Coastguard Worker# Formatted using: pyformat -s 4 --force_quote_type double -i scripts/gather-android-metalava-artifacts.py 24*115816f9SAndroid Build Coastguard Worker 25*115816f9SAndroid Build Coastguard Worker 26*115816f9SAndroid Build Coastguard Workerdef parse_command_line_args(args): 27*115816f9SAndroid Build Coastguard Worker """Define the command line options and the parse the command line arguments with them. 28*115816f9SAndroid Build Coastguard Worker 29*115816f9SAndroid Build Coastguard Worker :param args: the command line arguments :return: Return the result of 30*115816f9SAndroid Build Coastguard Worker parsing the command line arguments. 31*115816f9SAndroid Build Coastguard Worker """ 32*115816f9SAndroid Build Coastguard Worker args_parser = argparse.ArgumentParser( 33*115816f9SAndroid Build Coastguard Worker description=( 34*115816f9SAndroid Build Coastguard Worker "Gather Android artifacts created by Metalava. This will build and" 35*115816f9SAndroid Build Coastguard Worker " then copy a set of targets to the output directory. If no custom" 36*115816f9SAndroid Build Coastguard Worker " targets are provided then a set of default ones will be provided" 37*115816f9SAndroid Build Coastguard Worker " that covers stub generation, signature to JDiff conversion and" 38*115816f9SAndroid Build Coastguard Worker " api-versions.xml file generation. The intent is that this would" 39*115816f9SAndroid Build Coastguard Worker " be run this before and after making the change to build and copy" 40*115816f9SAndroid Build Coastguard Worker " the artifacts into two separate directories that can then be" 41*115816f9SAndroid Build Coastguard Worker " compared to see what, if any, changes have happened. This does" 42*115816f9SAndroid Build Coastguard Worker " not check signature file generation as that can be easily checked" 43*115816f9SAndroid Build Coastguard Worker " by running `m checkapi`." 44*115816f9SAndroid Build Coastguard Worker ), 45*115816f9SAndroid Build Coastguard Worker ) 46*115816f9SAndroid Build Coastguard Worker args_parser.add_argument( 47*115816f9SAndroid Build Coastguard Worker "directory", 48*115816f9SAndroid Build Coastguard Worker help="Output directory into which artifacts will be copied.", 49*115816f9SAndroid Build Coastguard Worker ) 50*115816f9SAndroid Build Coastguard Worker args_parser.add_argument( 51*115816f9SAndroid Build Coastguard Worker "--stub-src-jar", 52*115816f9SAndroid Build Coastguard Worker action="append", 53*115816f9SAndroid Build Coastguard Worker help="Additional stub jar to gather", 54*115816f9SAndroid Build Coastguard Worker ) 55*115816f9SAndroid Build Coastguard Worker 56*115816f9SAndroid Build Coastguard Worker return args_parser.parse_args(args) 57*115816f9SAndroid Build Coastguard Worker 58*115816f9SAndroid Build Coastguard Worker 59*115816f9SAndroid Build Coastguard Workerdef default_stub_files(): 60*115816f9SAndroid Build Coastguard Worker """:return: A representative sample list of stub source jars generated by the Android build using Metalava""" 61*115816f9SAndroid Build Coastguard Worker return [ 62*115816f9SAndroid Build Coastguard Worker f"out/target/common/docs/{x}-stubs.srcjar" 63*115816f9SAndroid Build Coastguard Worker for x in [ 64*115816f9SAndroid Build Coastguard Worker "api-stubs-docs-non-updatable", 65*115816f9SAndroid Build Coastguard Worker "system-api-stubs-docs-non-updatable", 66*115816f9SAndroid Build Coastguard Worker "test-api-stubs-docs-non-updatable", 67*115816f9SAndroid Build Coastguard Worker "module-lib-api-stubs-docs-non-updatable", 68*115816f9SAndroid Build Coastguard Worker ] 69*115816f9SAndroid Build Coastguard Worker ] 70*115816f9SAndroid Build Coastguard Worker 71*115816f9SAndroid Build Coastguard Worker 72*115816f9SAndroid Build Coastguard Workerdef default_doc_stub_files(): 73*115816f9SAndroid Build Coastguard Worker """:return: A representative sample list of doc stub source jars generated by the Android build using Metalava""" 74*115816f9SAndroid Build Coastguard Worker return [ 75*115816f9SAndroid Build Coastguard Worker "out/target/common/docs/framework-doc-stubs-stubs.srcjar", 76*115816f9SAndroid Build Coastguard Worker "out/target/common/docs/framework-doc-system-stubs-stubs.srcjar", 77*115816f9SAndroid Build Coastguard Worker ] 78*115816f9SAndroid Build Coastguard Worker 79*115816f9SAndroid Build Coastguard Worker 80*115816f9SAndroid Build Coastguard Workerdef default_api_version_files(): 81*115816f9SAndroid Build Coastguard Worker """:return: A representative sample list of `api-versions.xml` files generated by the Android build using 82*115816f9SAndroid Build Coastguard Worker 83*115816f9SAndroid Build Coastguard Worker Metalava. 84*115816f9SAndroid Build Coastguard Worker """ 85*115816f9SAndroid Build Coastguard Worker return [ 86*115816f9SAndroid Build Coastguard Worker "out/soong/lint/api_versions_public.xml", 87*115816f9SAndroid Build Coastguard Worker "out/soong/lint/api_versions_system.xml", 88*115816f9SAndroid Build Coastguard Worker "out/soong/lint/api_versions_module_lib.xml", 89*115816f9SAndroid Build Coastguard Worker "out/soong/lint/api_versions_system_server.xml", 90*115816f9SAndroid Build Coastguard Worker "out/target/common/obj/PACKAGING/api_versions_module_lib_complete_generated-api-versions.xml", 91*115816f9SAndroid Build Coastguard Worker "out/target/common/obj/PACKAGING/api_versions_system_server_complete_generated-api-versions.xml", 92*115816f9SAndroid Build Coastguard Worker ] 93*115816f9SAndroid Build Coastguard Worker 94*115816f9SAndroid Build Coastguard Worker 95*115816f9SAndroid Build Coastguard Workerdef default_jdiff_files(): 96*115816f9SAndroid Build Coastguard Worker """:return: A representative sample list of JDiff files created by the Android build using Metalava.""" 97*115816f9SAndroid Build Coastguard Worker return [ 98*115816f9SAndroid Build Coastguard Worker # JDiff files generated from jar files. 99*115816f9SAndroid Build Coastguard Worker "out/target/common/obj/api.xml", 100*115816f9SAndroid Build Coastguard Worker "out/target/common/obj/system-api.xml", 101*115816f9SAndroid Build Coastguard Worker "out/target/common/obj/module-lib-api.xml", 102*115816f9SAndroid Build Coastguard Worker "out/target/common/obj/system-server-api.xml", 103*115816f9SAndroid Build Coastguard Worker "out/target/common/obj/test-api.xml", 104*115816f9SAndroid Build Coastguard Worker # JDiff files generated from txt files. 105*115816f9SAndroid Build Coastguard Worker "out/soong/.intermediates/packages/services/Car/car-lib/android.car-test-stubs-jdiff/gen/car-test-api.xml", 106*115816f9SAndroid Build Coastguard Worker "out/soong/.intermediates/packages/services/Car/car-lib/android.car-stubs-jdiff/gen/car-api.xml", 107*115816f9SAndroid Build Coastguard Worker "out/soong/.intermediates/packages/services/Car/car-lib/android.car-system-stubs-jdiff/gen/car-system-api.xml", 108*115816f9SAndroid Build Coastguard Worker ""# JDiff files generated from txt files and then compressed using gzip.. 109*115816f9SAndroid Build Coastguard Worker "out/soong/.intermediates/cts/tests/signature/api/cts-android-test-base-current-api-gz/gen/android-test-base-current.api.gz", 110*115816f9SAndroid Build Coastguard Worker "out/soong/.intermediates/cts/tests/signature/api/cts-android-test-mock-current-api-gz/gen/android-test-mock-current.api.gz", 111*115816f9SAndroid Build Coastguard Worker "out/soong/.intermediates/cts/tests/signature/api/cts-android-test-runner-current-api-gz/gen/android-test-runner-current.api.gz", 112*115816f9SAndroid Build Coastguard Worker "out/soong/.intermediates/cts/tests/signature/api/cts-apache-http-legacy-current-api-gz/gen/apache-http-legacy-current.api.gz", 113*115816f9SAndroid Build Coastguard Worker "out/soong/.intermediates/cts/tests/signature/api/cts-car-system-current-api-gz/gen/car-system-current.api.gz", 114*115816f9SAndroid Build Coastguard Worker "out/soong/.intermediates/cts/tests/signature/api/cts-current-api-gz/android_common/gen/current.api.gz", 115*115816f9SAndroid Build Coastguard Worker "out/soong/.intermediates/cts/tests/signature/api/cts-system-current-api-gz/android_common/gen/system-current.api.gz", 116*115816f9SAndroid Build Coastguard Worker "out/soong/.intermediates/cts/tests/signature/api/cts-system-removed-api-gz/android_common/gen/system-removed.api.gz", 117*115816f9SAndroid Build Coastguard Worker 118*115816f9SAndroid Build Coastguard Worker ] 119*115816f9SAndroid Build Coastguard Worker 120*115816f9SAndroid Build Coastguard Worker 121*115816f9SAndroid Build Coastguard Workerdef default_dex_writer_files(): 122*115816f9SAndroid Build Coastguard Worker """:return: A representative sample list of dex writer related files created by the Android build using Metalava.""" 123*115816f9SAndroid Build Coastguard Worker return [ 124*115816f9SAndroid Build Coastguard Worker # This is not actually a dex writer file but it contains information derived from lots of dex writer files so 125*115816f9SAndroid Build Coastguard Worker # any differences in the dex writer files will affect this file. 126*115816f9SAndroid Build Coastguard Worker "out/soong/hiddenapi/hiddenapi-flags.csv", 127*115816f9SAndroid Build Coastguard Worker ] 128*115816f9SAndroid Build Coastguard Worker 129*115816f9SAndroid Build Coastguard Worker 130*115816f9SAndroid Build Coastguard Workerdef default_custom_files(top): 131*115816f9SAndroid Build Coastguard Worker """Returns a representative sample list of custom files created by the Android build using a custom tool based, at 132*115816f9SAndroid Build Coastguard Worker 133*115816f9SAndroid Build Coastguard Worker least in part, on Metalava. 134*115816f9SAndroid Build Coastguard Worker :return: A list of custom files. 135*115816f9SAndroid Build Coastguard Worker """ 136*115816f9SAndroid Build Coastguard Worker product_out = Path(os.environ.get("ANDROID_PRODUCT_OUT")).relative_to(top) 137*115816f9SAndroid Build Coastguard Worker return [ 138*115816f9SAndroid Build Coastguard Worker f"{product_out}/obj/ETC/flag-api-mapping-{surface}_intermediates/flag-api-mapping-{surface}" 139*115816f9SAndroid Build Coastguard Worker for surface in [ 140*115816f9SAndroid Build Coastguard Worker "PublicApi", 141*115816f9SAndroid Build Coastguard Worker "SystemApi", 142*115816f9SAndroid Build Coastguard Worker "ModuleLibApi", 143*115816f9SAndroid Build Coastguard Worker "SystemServerApi", 144*115816f9SAndroid Build Coastguard Worker ] 145*115816f9SAndroid Build Coastguard Worker ] 146*115816f9SAndroid Build Coastguard Worker 147*115816f9SAndroid Build Coastguard Worker 148*115816f9SAndroid Build Coastguard Workerdef construct_target_list(args, top): 149*115816f9SAndroid Build Coastguard Worker """Generate a list of targets from the supplied arguments 150*115816f9SAndroid Build Coastguard Worker 151*115816f9SAndroid Build Coastguard Worker :param args: the command line arguments. 152*115816f9SAndroid Build Coastguard Worker :return: a non-empty list of targets to build. 153*115816f9SAndroid Build Coastguard Worker """ 154*115816f9SAndroid Build Coastguard Worker targets = [] 155*115816f9SAndroid Build Coastguard Worker # If any custom options have been provided then build them. 156*115816f9SAndroid Build Coastguard Worker if args.stub_src_jar: 157*115816f9SAndroid Build Coastguard Worker targets += args.stub_src_jar 158*115816f9SAndroid Build Coastguard Worker # If no custom targets have been provided then use the default targets. 159*115816f9SAndroid Build Coastguard Worker if not targets: 160*115816f9SAndroid Build Coastguard Worker targets += default_stub_files() 161*115816f9SAndroid Build Coastguard Worker targets += default_doc_stub_files() 162*115816f9SAndroid Build Coastguard Worker targets += default_jdiff_files() 163*115816f9SAndroid Build Coastguard Worker targets += default_api_version_files() 164*115816f9SAndroid Build Coastguard Worker targets += default_dex_writer_files() 165*115816f9SAndroid Build Coastguard Worker targets += default_custom_files(top) 166*115816f9SAndroid Build Coastguard Worker return targets 167*115816f9SAndroid Build Coastguard Worker 168*115816f9SAndroid Build Coastguard Worker 169*115816f9SAndroid Build Coastguard Workerdef main(args): 170*115816f9SAndroid Build Coastguard Worker top = os.environ.get("ANDROID_BUILD_TOP") 171*115816f9SAndroid Build Coastguard Worker if not top: 172*115816f9SAndroid Build Coastguard Worker raise Exception("ANDROID_BUILD_TOP not specified") 173*115816f9SAndroid Build Coastguard Worker os.chdir(top) 174*115816f9SAndroid Build Coastguard Worker 175*115816f9SAndroid Build Coastguard Worker # Parse command line arguments. 176*115816f9SAndroid Build Coastguard Worker args = parse_command_line_args(args) 177*115816f9SAndroid Build Coastguard Worker 178*115816f9SAndroid Build Coastguard Worker # Make sure that the output directory does not already exist. 179*115816f9SAndroid Build Coastguard Worker output_dir = Path(args.directory) 180*115816f9SAndroid Build Coastguard Worker if output_dir.exists(): 181*115816f9SAndroid Build Coastguard Worker raise Exception(f"{output_dir} exists, please delete or change") 182*115816f9SAndroid Build Coastguard Worker 183*115816f9SAndroid Build Coastguard Worker # Construct the list of targets to build, using defaults where required. 184*115816f9SAndroid Build Coastguard Worker targets = construct_target_list(args, top) 185*115816f9SAndroid Build Coastguard Worker 186*115816f9SAndroid Build Coastguard Worker # Build the targets. 187*115816f9SAndroid Build Coastguard Worker build_targets(targets) 188*115816f9SAndroid Build Coastguard Worker 189*115816f9SAndroid Build Coastguard Worker # Create the output directory and copy the targets into it. 190*115816f9SAndroid Build Coastguard Worker copy_targets(output_dir, targets) 191*115816f9SAndroid Build Coastguard Worker 192*115816f9SAndroid Build Coastguard Worker 193*115816f9SAndroid Build Coastguard Workerdef copy_targets(output_dir, targets): 194*115816f9SAndroid Build Coastguard Worker print(f"Making output directory: '{output_dir}'") 195*115816f9SAndroid Build Coastguard Worker os.mkdir(output_dir) 196*115816f9SAndroid Build Coastguard Worker print() 197*115816f9SAndroid Build Coastguard Worker print(f"Copying the following targets into '{output_dir}':") 198*115816f9SAndroid Build Coastguard Worker for t in targets: 199*115816f9SAndroid Build Coastguard Worker print(f" {t}") 200*115816f9SAndroid Build Coastguard Worker shutil.copy(t, output_dir) 201*115816f9SAndroid Build Coastguard Worker print() 202*115816f9SAndroid Build Coastguard Worker 203*115816f9SAndroid Build Coastguard Worker 204*115816f9SAndroid Build Coastguard Workerdef build_targets(targets): 205*115816f9SAndroid Build Coastguard Worker print() 206*115816f9SAndroid Build Coastguard Worker print("Building the following targets:") 207*115816f9SAndroid Build Coastguard Worker for t in targets: 208*115816f9SAndroid Build Coastguard Worker print(f" {t}") 209*115816f9SAndroid Build Coastguard Worker print() 210*115816f9SAndroid Build Coastguard Worker subprocess.run( 211*115816f9SAndroid Build Coastguard Worker ["build/soong/soong_ui.bash", "--make-mode"] + targets, check=True 212*115816f9SAndroid Build Coastguard Worker ) 213*115816f9SAndroid Build Coastguard Worker print() 214*115816f9SAndroid Build Coastguard Worker 215*115816f9SAndroid Build Coastguard Worker 216*115816f9SAndroid Build Coastguard Workerif __name__ == "__main__": 217*115816f9SAndroid Build Coastguard Worker main(sys.argv[1:]) 218