#!/usr/bin/env python3 # Copyright (c) 2023-2024 Arm Limited. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. import argparse import os from jinja2 import Template import datetime # Paths to exclude excluded_paths = ["build", "compute_kernel_writer/", "src/dynamic_fusion/runtime/gpu/cl/ckw_driver/", "src/dynamic_fusion/sketch/gpu/ckw_driver/", "docs/", "documentation/", "examples/", "opencl-1.2-stubs/", "release_repository/", "opengles-3.1-stubs/", "scripts/", "tests/", "/GLES_COMPUTE/", "/graph/", "/sve/", "/SVE/", "/sve2/", "/SVE2/", "/sme/", "/sme2/", ] excluded_files = ["TracePoint.cpp"] # Android bp template to render year = datetime.datetime.now().year bp_tm = Template( """// // Copyright © 2020-""" + str(year) + """ Arm Ltd. All rights reserved. // SPDX-License-Identifier: MIT // // OpenCL sources are NOT required by ArmNN or its Android NNAPI driver and are used for CI purposes only. opencl_srcs = [ {% for cl_src in cl_srcs -%} "{{ cl_src }}", {% endfor %} ] bootstrap_go_package { name: "arm_compute_library_nn_driver", pkgPath: "arm_compute_library_nn_driver", deps: [ "blueprint", "blueprint-pathtools", "blueprint-proptools", "soong", "soong-android", "soong-cc", ], srcs: [ "scripts/arm_compute_library_nn_driver.go", ], pluginFor: [ "soong_build" ], } arm_compute_library_defaults { name: "acl-default-cppflags", cppflags: [ "-std=c++14", "-fexceptions", "-DBOOST_NO_AUTO_PTR", "-DEMBEDDED_KERNELS", "-DARM_COMPUTE_ASSERTS_ENABLED", "-DARM_COMPUTE_CPP_SCHEDULER", "-DENABLE_NEON", "-DARM_COMPUTE_ENABLE_NEON", "-Wno-unused-parameter", "-DNO_DOT_IN_TOOLCHAIN", "-Wno-implicit-fallthrough", "-fPIC" ], rtti: true, } cc_library_static { name: "arm_compute_library", defaults: ["acl-default-cppflags"], proprietary: true, local_include_dirs: ["build/android-arm64v8a/src/core", "build/android-arm64v8a/src/core/CL", "compute_kernel_writer/include", "src/core/common", "src/core/helpers", "src/core/NEON/kernels/arm_gemm", "src/core/NEON/kernels/assembly", "src/core/NEON/kernels/convolution/common", "src/core/NEON/kernels/convolution/winograd", "src/cpu/kernels/assembly"], export_include_dirs: [".", "./include"], srcs: [ {% for src in srcs -%} "{{ src }}", {% endfor %} ], arch: { arm: { srcs: [ {% for arm_src in arm_srcs -%} "{{ arm_src }}", {% endfor %} ], }, arm64: { srcs: [ {% for arm64_src in arm64_srcs -%} "{{ arm64_src }}", {% endfor %} ], }, }, rtti: true, } """) def generate_bp_file(cpp_files, opencl_files): arm_files = [f for f in cpp_files if "a32_" in f] arm64_files = [f for f in cpp_files if any(a64 in f for a64 in ["a64_", "sve_", 'sme_', 'sme2_'])] gen_files = [x for x in cpp_files if x not in arm_files + arm64_files] arm_files.sort() arm64_files.sort() gen_files.sort() opencl_files.sort() bp_file = bp_tm.render(srcs=gen_files, arm_srcs=arm_files, arm64_srcs=arm64_files, cl_srcs=opencl_files) return bp_file def list_all_files(repo_path): """ Gets the list of files to include to the Android.bp :param repo_path: Path of the repository :return: The filtered list of useful filess """ if not repo_path.endswith('/'): repo_path = repo_path + "/" # Get cpp files cpp_files = [] cl_files = [] for path, subdirs, files in os.walk(repo_path): for file in files: if file.endswith(".cpp"): cpp_files.append(os.path.join(path, file)) elif file.endswith(".cl"): cl_files.append(os.path.join(path, file)) # Include CL headers if "src/core/CL/cl_kernels" in path and file.endswith(".h"): cl_files.append(os.path.join(path, file)) # Filter out unused cpp files filtered_cpp_files = [] for cpp_file in cpp_files: if any(ep in cpp_file for ep in excluded_paths) or any(ef in cpp_file for ef in excluded_files): continue filtered_cpp_files.append(cpp_file.replace(repo_path, "")) # Filter out unused cl files filtered_cl_files = [] for cl_file in cl_files: if any(ep in cl_file for ep in excluded_paths): continue filtered_cl_files.append(cl_file.replace(repo_path, "")) return filtered_cpp_files, filtered_cl_files if __name__ == "__main__": # Parse arguments parser = argparse.ArgumentParser('Generate Android.bp file for ComputeLibrary') parser.add_argument('--folder', default=".", metavar="folder", dest='folder', type=str, required=False, help='Compute Library source path') parser.add_argument('--output_file', metavar="output_file", default='Android.bp', type=str, required=False, help='Specify Android bp output file') args = parser.parse_args() cpp_files, opencl_files = list_all_files(args.folder) bp_file = generate_bp_file(cpp_files, opencl_files) with open(args.output_file, 'w') as f: f.write(bp_file)