#!/usr/bin/env python3
# Copyright 2024 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import sys
import tempfile
import argparse
from typing import List, Set
REPOSITORY_ROOT = os.path.abspath(
os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir))
sys.path.insert(0, REPOSITORY_ROOT)
import components.cronet.tools.utils as cronet_utils # pylint: disable=wrong-import-position
import build.android.gyp.util.build_utils as build_utils # pylint: disable=wrong-import-position
_ARCHS = ["x86", "x64", "arm", "arm64"]
_GN2BP_SCRIPT_PATH = os.path.join(REPOSITORY_ROOT,
"components/cronet/gn2bp/gen_android_bp.py")
_OUT_DIR = os.path.join(REPOSITORY_ROOT, "out")
_EXTRA_GN_ARGS = ("is_cronet_for_aosp_build=true"),
_GN_PATH = os.path.join(REPOSITORY_ROOT, 'buildtools/linux64/gn')
def _run_gn2bp(desc_files: Set[tempfile.NamedTemporaryFile]) -> int:
with tempfile.NamedTemporaryFile(mode="w+", encoding='utf-8') as android_bp:
base_cmd = ["python3", _GN2BP_SCRIPT_PATH, "--out", android_bp.name]
for desc_file in desc_files:
# desc_file.name represents the absolute path.
base_cmd += ["--desc", desc_file.name]
return cronet_utils.run(base_cmd)
def _get_args_for_aosp(arch: str) -> List[str]:
default_args = cronet_utils.get_android_gn_args(True, arch)
default_args += _EXTRA_GN_ARGS
return ' '.join(cronet_utils.filter_gn_args(default_args,
["use_remoteexec"]))
def _write_desc_json(gn_out_dir: str,
temp_file: tempfile.NamedTemporaryFile) -> int:
return cronet_utils.run([
_GN_PATH, "desc", gn_out_dir, "--format=json", "--all-toolchains", "//*"
],
stdout=temp_file)
def _main():
parser = argparse.ArgumentParser()
parser.add_argument('--stamp',
type=str,
help='Path to touch on success',
required=True)
args = parser.parse_args()
try:
# Create empty temp file for each architecture.
arch_to_temp_desc_file = {
arch: tempfile.NamedTemporaryFile(mode="w+", encoding='utf-8')
for arch in _ARCHS
}
for (arch, temp_file) in arch_to_temp_desc_file.items():
# gn desc behaves completely differently when the output
# directory is outside of chromium/src, some paths will
# stop having // in the beginning of their labels
# eg (//A/B will become A/B), this mostly apply to files
# that are generated through actions and not targets.
#
# This is why the temporary directory has to be generated
# beneath the repository root until gn2bp is tweaked to
# deal with this small differences.
with tempfile.TemporaryDirectory(dir=_OUT_DIR) as gn_out_dir:
cronet_utils.gn(gn_out_dir, _get_args_for_aosp(arch))
if _write_desc_json(gn_out_dir, temp_file) != 0:
# Close the files and exit if we failed to generate any
# of the desc.json files.
print(f"Failed to generate desc file for arch: {arch}")
for file in arch_to_temp_desc_file.values():
# Close the temporary files so they can be deleted.
file.close()
sys.exit(-1)
res = _run_gn2bp(arch_to_temp_desc_file.values())
finally:
for file in arch_to_temp_desc_file.values():
# Close the temporary files so they can be deleted.
file.close()
if res != 0:
print("Failed to execute gn2bp!")
sys.exit(-1)
else:
build_utils.Touch(args.stamp)
return 0
if __name__ == '__main__':
sys.exit(_main())