136 lines
4.2 KiB
Python
136 lines
4.2 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Copyright (C) 2022 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.
|
|
"""Utility functions to produce module or module type dependency graphs using json-module-graph or queryview."""
|
|
|
|
import json
|
|
import os
|
|
import os.path
|
|
import subprocess
|
|
import xml.etree.ElementTree
|
|
|
|
# This list of module types are omitted from the report and graph
|
|
# for brevity and simplicity. Presence in this list doesn't mean
|
|
# that they shouldn't be converted, but that they are not that useful
|
|
# to be recorded in the graph or report currently.
|
|
IGNORED_KINDS = set([
|
|
"license_kind",
|
|
"license",
|
|
"cc_defaults",
|
|
"cc_prebuilt_object",
|
|
"cc_prebuilt_library_headers",
|
|
"cc_prebuilt_library_shared",
|
|
"cc_prebuilt_library_static",
|
|
"cc_prebuilt_library_static",
|
|
"cc_prebuilt_library",
|
|
"java_defaults",
|
|
"ndk_prebuilt_static_stl",
|
|
"ndk_library",
|
|
])
|
|
|
|
SRC_ROOT_DIR = os.path.abspath(__file__ + "/../../../../..")
|
|
|
|
|
|
def _build_with_soong(target):
|
|
subprocess.check_output(
|
|
[
|
|
"build/soong/soong_ui.bash",
|
|
"--make-mode",
|
|
"--skip-soong-tests",
|
|
target,
|
|
],
|
|
cwd=SRC_ROOT_DIR,
|
|
env={
|
|
# Use aosp_arm as the canonical target product.
|
|
"TARGET_PRODUCT": "aosp_arm",
|
|
"TARGET_BUILD_VARIANT": "userdebug",
|
|
},
|
|
)
|
|
|
|
|
|
def get_queryview_module_info(module):
|
|
"""Returns the list of transitive dependencies of input module as built by queryview."""
|
|
_build_with_soong("queryview")
|
|
|
|
result = subprocess.check_output(
|
|
[
|
|
"tools/bazel", "query", "--config=ci", "--config=queryview",
|
|
"--output=xml",
|
|
'deps(attr("soong_module_name", "^{}$", //...))'.format(module)
|
|
],
|
|
cwd=SRC_ROOT_DIR,
|
|
)
|
|
return xml.etree.ElementTree.fromstring(result)
|
|
|
|
|
|
def get_json_module_info(module):
|
|
"""Returns the list of transitive dependencies of input module as provided by Soong's json module graph."""
|
|
_build_with_soong("json-module-graph")
|
|
# Run query.sh on the module graph for the top level module
|
|
result = subprocess.check_output(
|
|
[
|
|
"build/bazel/json_module_graph/query.sh", "fullTransitiveDeps",
|
|
"out/soong/module-graph.json", module
|
|
],
|
|
cwd=SRC_ROOT_DIR,
|
|
)
|
|
return json.loads(result)
|
|
|
|
|
|
def get_bp2build_converted_modules():
|
|
""" Returns the list of modules that bp2build can currently convert. """
|
|
_build_with_soong("bp2build")
|
|
# Parse the list of converted module names from bp2build
|
|
with open(
|
|
os.path.join(
|
|
SRC_ROOT_DIR,
|
|
"out/soong/soong_injection/metrics/converted_modules.txt")) as f:
|
|
# Read line by line, excluding comments.
|
|
# Each line is a module name.
|
|
ret = [line.strip() for line in f.readlines() if not line.startswith("#")]
|
|
return set(ret)
|
|
|
|
|
|
def get_json_module_type_info(module_type):
|
|
"""Returns the combined transitive dependency closures of all modules of module_type."""
|
|
_build_with_soong("json-module-graph")
|
|
# Run query.sh on the module graph for the top level module type
|
|
result = subprocess.check_output(
|
|
[
|
|
"build/bazel/json_module_graph/query.sh",
|
|
"fullTransitiveModuleTypeDeps", "out/soong/module-graph.json",
|
|
module_type
|
|
],
|
|
cwd=SRC_ROOT_DIR,
|
|
)
|
|
return json.loads(result)
|
|
|
|
|
|
def is_windows_variation(module):
|
|
"""Returns True if input module's variant is Windows.
|
|
|
|
Args:
|
|
module: an entry parsed from Soong's json-module-graph
|
|
"""
|
|
dep_variations = module.get("Variations")
|
|
dep_variation_os = ""
|
|
if dep_variations != None:
|
|
dep_variation_os = dep_variations.get("os")
|
|
return dep_variation_os == "windows"
|
|
|
|
|
|
def ignore_kind(kind):
|
|
return kind in IGNORED_KINDS or "defaults" in kind
|