1# Copyright (C) 2021 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15# A repository rule to run soong_ui --make-mode to provide the Bazel standalone 16# build with prebuilts from Make/Soong that Bazel can't build yet. 17def _impl(rctx): 18 target_product = rctx.os.environ.get("TARGET_PRODUCT", "aosp_arm") 19 target_build_variant = rctx.os.environ.get("TARGET_BUILD_VARIANT", "eng") 20 21 binaries = rctx.attr.binaries 22 target_modules = rctx.attr.target_module_files 23 24 build_dir = rctx.path(Label("//:WORKSPACE")).dirname 25 soong_ui_bash = str(build_dir) + "/build/soong/soong_ui.bash" 26 args = [ 27 soong_ui_bash, 28 "--make-mode", 29 "--skip-soong-tests", 30 ] 31 all_modules = target_modules.keys() + binaries 32 args += all_modules 33 34 rctx.report_progress("Building modules with Soong: %s" % str(all_modules)) 35 out_dir = str(build_dir.dirname) + "/make_injection" 36 exec_result = rctx.execute( 37 args, 38 environment = { 39 "OUT_DIR": out_dir, 40 "TARGET_PRODUCT": target_product, 41 "TARGET_BUILD_VARIANT": target_build_variant, 42 "TOP": str(build_dir.dirname.dirname.dirname), 43 }, 44 quiet = False, # stream stdout so it shows progress 45 timeout = 3600, # default of 600 seconds is not sufficient 46 ) 47 if exec_result.return_code != 0: 48 fail(exec_result.stderr) 49 50 # Get the explicit list of host binary paths to be exported 51 rctx.symlink(out_dir + "/host/linux-x86", "host/linux-x86") 52 binary_path_prefix = "host/linux-x86/bin" 53 binary_paths = ['"%s/%s"' % (binary_path_prefix, binary) for binary in binaries] 54 55 # Get the explicit list of target installed files to be exported 56 rctx.symlink(out_dir + "/target", "target") 57 target_path_prefix = "target/product/generic" 58 target_paths = [] 59 for paths in target_modules.values(): 60 target_paths.extend(['"%s/%s"' % (target_path_prefix, path) for path in paths]) 61 62 exports_files = """exports_files([ 63 %s 64]) 65""" % ",\n ".join(binary_paths + target_paths) 66 rctx.file("BUILD", exports_files) 67 68make_injection_repository = repository_rule( 69 implementation = _impl, 70 doc = """This rule exposes Soong prebuilts for migrating the build to Bazel. 71 72This rule allows the Bazel build (i.e. b build //bionic/...) to depend on prebuilts from 73Soong. A use case is to allow the Bazel build to use prebuilt host tools in the 74Bazel rules toolchains without first converting them to Bazel.""", 75 attrs = { 76 "binaries": attr.string_list(default = [], doc = "A list of host binary modules built for linux-x86."), 77 "target_module_files": attr.string_list_dict(default = {}, doc = "A dict of modules to the target files that should be exported."), 78 # See b/210399979 79 "watch_android_bp_files": attr.label_list(allow_files = [".bp"], default = [], doc = "A list of Android.bp files to watch for changes to invalidate this repository rule."), 80 }, 81 environ = ["TARGET_PRODUCT", "TARGET_BUILD_VARIANT"], 82) 83