This document describes how the Fuchsia IDKs and Bazel SDKs are generated by the platform build, the role of each instance and their relationships. This information is crucial for the rest of the migration to Bazel, and will be updated accordingly.
The GN //sdk:final_fuchsia_idk
target is used to build [^1] and validate the Fuchsia IDK (formerly known as the “core” or “partner” IDK), which is the official archive distributed to third-party SDK developers. It contains all atoms in the “partner” category, as well as prebuilt binaries for all combinations of supported CPU architectures and API levels.
Currently, this is built directly from Ninja (no Bazel required) as the shape of the Fuchsia IDK (i.e. which atoms it includes) it entirely defined in the GN build graph (in //sdk/BUILD.gn
).
Note that building the Fuchsia IDK takes a long time [^2][^3] due to the high number of (cpu, api_level)
combinations that must be built. Thus, this target is only built by a few dedicated builder configurations (e.g. sdk-core-linux
).
[^1]: //sdk:final_fuchsia_idk.exported
is the GN target for the IDK. //sdk:final_fuchsia_idk
wraps it along with its validation and archive targets.
[^2]: Because these sub-builds are rarely built, the remote cache is rarely helpful. As a result, each sub-build takes approximately 5 to 8 minutes. Due to sub-build mechanics, the sub-builds cannot start until the contents of the IDK have already been built once and thus start late in the build. Also, sub-build parallelism is limited for performance reasons, so there will be effectively multiple rounds of sub-builds.
[^3]: For local builds, the build time can be significantly reduced by setting the idk_buildable_cpus
and idk_buildable_api_levels
GN args.
The GN //sdk:final_fuchsia_sdk
target is used to build (but not validate or generate the archive) the official Fuchsia Bazel SDK distributed to third-party developers. It augments the Fuchsia IDK with our set of Bazel-specific build rules and target declarations.
Its content is directly usable by third-party Bazel projects, which can include it with a simple local_repository()
directive in their WORKSPACE.bazel
file, such as:
local_repository( name = "fuchsia_sdk", path = "/path/to/fuchsia_sdk", )
Just like the Fuchsia IDK, the Fuchsia Bazel SDK is built directly from GN, without using any Bazel workspace, and building it takes so long that this is only done on a few dedicated builder configurations (e.g. sdk-bazel-linux
).
The GN //sdk:bazel_in_tree_idk
target is used to build an IDK (actually an IDK collection) that has the same set of atoms as the Fuchsia IDK, but which only provides prebuilt binaries for the current target_cpu
architecture, and the HEAD
API level (using artifacts from the main PLATFORM
build). It is only intended to be used to populate the @fuchsia_sdk
and @fuchsia_in_tree_idk
repositories (described below).
The GN //sdk:bazel_internal_only_idk
target groups atoms with an unstable API and that are not ready to be moved to the “partner” category. This should only be used to populate the @internal_sdk
repository of the in-tree Bazel workspace. These atoms should never be used outside of the platform build.
It only contains prebuilt binaries for the current target_cpu
architecture, and the HEAD
API level (also from the PLATFORM
build)).
Nothing in the GN graph should depend on this.
As previously mentioned, building the Fuchsia IDK and Fuchsia Bazel SDK can take a long time. As a mitigation for platform developers working with these targets or needing to locally build an SDK to test with a specific target, there are a small number of GN targets that generate the IDK or SDK with support for targeting a subset of API levels and/or CPU architectures. These can be used like the publishable IDK and SDK, respectively.
The following subsets are currently supported:
HEAD
and default target CPU architecture://sdk:final_fuchsia_idk_head_only
//sdk:final_fuchsia_sdk_head_only
The platform build's internal Bazel workspace also uses a number of external repositories that are related to the IDK and the Bazel SDK:
@fuchsia_in_tree_idk
repository:This repository currently wraps the Ninja-generated in-tree IDK as a Bazel repository. A key difference though is that its metadata files contain Bazel target labels, instead of file paths, for any buildable artifacts (i.e. not source files), for example, pkg/fdio/meta.json
looks like:
{ "binaries": { "x64": { "debug": "@fuchsia_in_tree_idk//.build-id:15/646fc64e58e6bc964d5781afec10233689ab08.debug", "dist": "@fuchsia_in_tree_idk//arch/x64:dist/libfdio.so", "dist_path": "lib/libfdio.so", # <-- configuration string "link": "@fuchsia_in_tree_idk//arch/x64:lib/libfdio.so" # <-- ninja artifact } }, "deps": [], "format": "shared", "headers": [ "pkg/fdio/include/lib/fdio/directory.h", # <-- symlink to source file "pkg/fdio/include/lib/fdio/fd.h", # <-- symlink to source file ... ], "ifs": "fdio.ifs", "include_dir": "pkg/fdio/include", "name": "fdio", "root": "pkg/fdio", "type": "cc_prebuilt_library" }
In the current implementation, the labels point to simple symlinks that go into the Ninja build directory. But this extra level of indirection will allow, in the future, building said artifacts directly with Bazel.
Note that this does not comply with the official IDK layout, so its content cannot be used or distributed outside of the platform build's Bazel workspace.
@fuchsia_sdk
repository:This repository exposes the same set of atoms and binaries as the in-tree IDK, augmented with Bazel SDK rule definitions and Bazel targets for each atom.
It is used by the BUILD.bazel
files inside of fuchsia.git
, to use SDK atom targets and our set of Bazel rules to develop Fuchsia packages with them.
It is populated by parsing the content of the @fuchsia_in_tree_idk
repository.
Note that its content cannot be used directly in external Bazel workspaces.
@fuchsia_internal_only_idk
repository:This is similar to @fuchsia_in_tree_idk
, but wraps the content of the //sdk:bazel_internal_only_idk
instead.
@internal_sdk
repository:This repository exposes SDK atoms and binaries from the in-tree internal IDK to the platform build's Bazel workspace. This means that only prebuilts for the current target_cpu
architecture and HEAD
API levels are available there.
It is populated by parsing the content of the @fuchsia_internal_only_idk
repository.
The following diagram illustrates the dependencies between the items described above. The notation [foo()]
denotes a repository rule invocation, which occurs when Bazel sets up external repositories, while [[bar()]]
denotes a regular build rule invoked through an explcitit bazel build
command.
GN Build Graph | Bazel Workspace | | Fuchsia IDK | | //sdk:final_fuchsia_idk | | | [fuchsia_sdk_repository() in Python] | | | v | Fuchsia Bazel SDK | //sdk:final_fuchsia_sdk | | | Bazel In-Tree IDK | //sdk:bazel_in_tree_idk | | | @fuchsia_in_tree_idk ---[fuchsia_sdk_repository()]---> @fuchsia_sdk | | Bazel In-Tree Internal IDK | //sdk:bazel_internal_only_idk | | | `----------[fuchsia_idk_repository()]--> @fuchsia_internal_only_idk | | | | | [fuchsia_sdk_repository()] | | | v | @internal_sdk |
The IDK and SDK subsets are entirely within GN:
GN Build Graph | Bazel Workspace | | Fuchsia HEAD-only IDK | | //sdk:final_fuchsia_idk_head_only | | | [fuchsia_sdk_repository() in Python] | | | v | Fuchsia HEAD-only Bazel SDK | //sdk:final_fuchsia_sdk_head_only | |
fuchsia_idk_repository()
functionThis function takes an IDK as input, and populates a Bazel repository, with it, changing the content of its metadata files to include Bazel targets for buildable artifacts, plus adding the necessary BUILD.bazel
files that they reference.
Note that the output repository‘s content does not follow the official IDK layout anymore, and should never be used outside of the platform build’s Bazel workspace.
fuchsia_sdk_repository()
functionThis function takes an IDK as input, and generates a Bazel SDK directory or repository as output.
Its logic is written in a special way to allow it to run either in a Starlark environment (i.e. as a Bazel repository rule), or in a Python one (i.e. as a build action, either from Ninja or Bazel).
Currently, it is used as Python at build time to generate the Fuchsia Bazel SDK from the Fuchsia IDK, as a Ninja action, and the final Fuchsia in-tree SDK, as a Bazel action.
It is also used as Starlark in the Bazel repository rules that generate the @fuchsia_sdk
and @internal_sdk
repositories.