| # Copyright 2022 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("//build/bazel/bazel_inputs.gni") |
| import("//build/bazel/bazel_workspace.gni") |
| import("//build/bazel/legacy_ninja_build_outputs.gni") |
| import("//build/images/vbmeta.gni") |
| import("//build/product.gni") |
| import("//build/toolchain/rbe.gni") |
| |
| assert( |
| current_toolchain == default_toolchain, |
| "This BUILD.gn file should only be parsed in the default toolchain, to prevent generating Bazel workspace multiple times.") |
| |
| # A GN target used to generate at GN-gen time a bazel inputs manifest file |
| # under the following path which is hard-coded in toplevel.WORKSPACE.bazel: |
| # |
| # $BUILD_DIR/gen/build/bazel/legacy_ninja_build_outputs.inputs_manifest.json |
| # |
| # See bazel_inputs.gni comments for details on the manifest file format, |
| # and repository_rules.bzl:bazel_inputs_repository() to see how it is parsed |
| # to generate an external repository for the Bazel project. |
| # |
| # It is possible to build this target to ensure that all Ninja outputs seen |
| # by the Bazel workspace are properly generated, as in: |
| # |
| # fx build build/bazel:legacy_ninja_build_outputs |
| # |
| # IMPORTANT: Nothing in the GN graph should depend on this directly, but this |
| # BUILD.gn file must be reachable from //:* to ensure that it is parsed and |
| # that this file is generated at `gn gen` time. |
| # |
| # Doing so allows breaking the testonly boundary, as required to allow |
| # non-testonly bazel_build_action() targets to depend on |
| # :generate_main_workspace below, without depending on this target. |
| # |
| bazel_inputs_manifest("legacy_ninja_build_outputs") { |
| testonly = true |
| |
| output = bazel_inputs_manifest |
| |
| # IMPORTANT: All bazel_input_xxx() targets must be reachable from this |
| # dependencies list! |
| inputs_deps = gn_labels_for_bazel_inputs + extra_gn_labels_for_bazel_inputs |
| } |
| |
| # Used by bazel_build_action() to only allow one concurrent `bazel build` |
| # action at a time during the build, since doing so modifies the workspace, |
| # in particular the `bazel-bin` symlink that is used to copy the Bazel outputs |
| # to the Ninja output directory. |
| if (current_toolchain == default_toolchain) { |
| pool("build_action_pool") { |
| depth = 1 |
| } |
| } |
| |
| action("generate_main_workspace") { |
| assert( |
| bazel_top_dir == target_gen_dir, |
| "Bazel workspace generation action was moved, please update " + |
| "//build/bazel/bazel_workspace.gni$0x0aOld bazel_top_dir location " + |
| "[${bazel_top_dir}] new location [${target_gen_dir}") |
| |
| script = "//build/bazel/scripts/update_workspace.py" |
| |
| # The update script tracks the file and directory entries of FUCHSIA_DIR |
| # and will update the workspace if they change (i.e. if a file or |
| # directory is added to / removed from FUCHSIA_DIR itself). However, |
| # there is no way for Ninja to track these changes, and thus no way |
| # to enforce the action to be run when this happens, even though these |
| # are rare occurences, that could happen in the following cases: |
| # |
| # - A developer manually adds or removes a file to/from FUCHSIA_DIR. |
| # In this case, manually calling the script is needed, and this |
| # can be done by invoking any `fx bazel ...` command (even |
| # `fx bazel version`) or `fx build bazel_workspace`. |
| # |
| # - A `jiri update` modifies the content of FUCHSIA_DIR. Depend on |
| # the top-level //.git/index file to detect this. Note that the |
| # script will not necessarily update the workspace in this case, |
| # this simply ensures that it is run to do its checks. |
| # |
| # - A manual `git checkout HEAD^ -- .` command will modify the local |
| # workspace without modifying the index, so also depend on |
| # //.git/HEAD to detect this. |
| # |
| inputs = [ |
| "//.git/index", |
| "//.git/HEAD", |
| |
| # The bazel prebuilt is an implicit input for the script. |
| "//prebuilt/third_party/bazel/${host_os}-${host_cpu}/bazel", |
| |
| # The script expands these templates |
| "//build/bazel/templates/template.WORKSPACE.bazel", |
| "//build/bazel/templates/template.bazel.sh", |
| "//build/bazel/templates/template.bazelrc", |
| "//build/bazel/templates/template.fuchsia_build_config.bzl", |
| |
| # The script reads RBE configs |
| rbe_config_file, |
| ] |
| |
| deps = [ |
| # This dependency is required to properly populate @fuchsia_sdk and |
| # @internal_sdk for |
| # @rules_fuchsia//:fuchsia/workspace/fuchsia_sdk_repository.bzl |
| "//sdk:core", |
| "//sdk:platform", |
| ] |
| |
| outputs = [ |
| "$target_gen_dir/bazel", |
| "$target_gen_dir/download_config_file", |
| "$target_gen_dir/generated-info.json", |
| "$target_gen_dir/workspace/.bazelrc", |
| "$target_gen_dir/workspace/WORKSPACE.bazel", |
| "$target_gen_dir/workspace/fuchsia_build_config.bzl", |
| ] |
| |
| args = [ |
| "--gn_output_dir", |
| rebase_path(root_build_dir, root_build_dir), |
| "--target_arch", |
| target_cpu, |
| ] |
| |
| # The generated wrapper includes the absolute path of the Ninja output |
| # directory, which will be read by Bazel repository rules during workspace |
| # setup. |
| no_output_dir_leaks = false |
| } |
| |
| # Generate a symlink to the @fuchsia_sdk repository, after ensuring it was |
| # properly populated by Bazel. The symlink has a stable path of |
| # gen/build/bazel/fuchsia_sdk while the actual location of the repository |
| # depends on Bazel internals (e.g. whether BzlMod is enabled or not). |
| action("generate_fuchsia_sdk_repository") { |
| script = "//build/bazel/scripts/generate-fuchsia-sdk-symlink.py" |
| outputs = [ "$target_gen_dir/fuchsia_sdk" ] |
| deps = [ |
| ":generate_main_workspace", |
| "//sdk:core", |
| "//sdk:platform", |
| ] |
| inputs = get_target_outputs(deps[0]) |
| args = [ |
| "--bazel-launcher", |
| rebase_path(inputs[0], root_build_dir), |
| "--output-symlink", |
| rebase_path(outputs[0], root_build_dir), |
| ] |
| metadata = { |
| # Used by the //:bazel_sdk_info build API module target. |
| bazel_sdk_info = [ |
| { |
| location = rebase_path(outputs[0], root_build_dir) |
| }, |
| ] |
| } |
| |
| # This cannot be hermetic as well since it creates a ton of |
| # files in the output base that cannot be listed in advance. |
| hermetic_deps = false |
| } |
| |
| # Generate a build_args.bzl file that contains Bazel-specific constant |
| # declarations that match the current build configuration found in args.gn. |
| # |
| # Note that another way to pass configuration information is to add |
| # specific lines to the project's auto-generated .bazelrc file, or even |
| # to set specific options in the Bazel launcher script. |
| # |
| _build_args_bzl_output = "${target_out_dir}/build_args.bzl" |
| _build_args_bzl_target = "build_args.bzl.generated" |
| generated_file(_build_args_bzl_target) { |
| output_conversion = "list lines" |
| contents = [ "# Auto-generated - DO NOT EDIT" ] |
| |
| # Export use_vbmeta boolean flag. |
| # Boolean values are capitalized differently in GN and Bazel ... |
| if (use_vbmeta) { |
| contents += [ "use_vbmeta = True" ] |
| } else { |
| contents += [ "use_vbmeta = False" ] |
| } |
| outputs = [ _build_args_bzl_output ] |
| } |
| |
| bazel_input_resource("build_args_bazel_inputs") { |
| sources = [ _build_args_bzl_output ] |
| outputs = [ "build_args.bzl" ] |
| deps = [ ":${_build_args_bzl_target}" ] |
| } |
| |
| group("tests") { |
| testonly = true |
| deps = [ "scripts:tests" ] |
| } |