tree: d94aab16cef003767e6fc304c27429a463e1e3a1 [path history] [tgz]
  1. meta/
  2. plasa/
  3. tests/
  4. tools/
  5. BUILD.gn
  6. build_final_idk.py
  7. compute_atom_api.py
  8. config.gni
  9. create_atom_manifest.py
  10. create_molecule_manifest.py
  11. export_sdk.py
  12. filter_host_tools_from_sdk_api.py
  13. generate_archive_manifest.py
  14. generate_final_idk.gni
  15. generate_meta.py
  16. manifest_schema.json
  17. merged_sdk.gni
  18. METADATA.textproto
  19. OWNERS
  20. physical_device.gni
  21. product_bundle.gni
  22. product_bundle_transfer_manifest.gni
  23. product_metadata.gni
  24. README.md
  25. sdk.gni
  26. sdk_alias.gni
  27. sdk_atom.gni
  28. sdk_atom_alias.gni
  29. sdk_collection.gni
  30. sdk_common.py
  31. sdk_common_unittest.py
  32. sdk_component_manifests.gni
  33. sdk_data.gni
  34. sdk_documentation.gni
  35. sdk_host_tool.gni
  36. sdk_molecule.gni
  37. sdk_noop_atom.gni
  38. sdk_prebuilt_executable.gni
  39. verify_sdk_api.py
  40. virtual_device.gni
build/sdk/README.md

SDK build tools

This directory contains templates and scripts used to build and consume IDKs in the Fuchsia GN build.

Note: Fuchsia SDKs, like the GN SDK, or the Bazel SDK, are generated by processing the content of an IDK archive. This process is out of scope for this document, which only describes how an IDK is assembled.

Overview

The build output of “an IDK build” is a tarball containing files collected from the source tree and the output directory, augmented with metadata files.

Metadata includes the nature of an element (e.g. programming language(s), runtime type), its relationship with other elements (e.g. dependencies, supporting tools), the context in which the element was constructed (e.g. target architecture, high-level compilation options), etc...

As described by the IDK standard layout specification, a single $IDK/meta/manifest.json file lists all SDK elements, with references to individual meta.json files for each one of them.

Schemas for the various types of SDK elements are available under //build/sdk/meta/, and provide an external contract for SDK-generating tools outside the Fuchsia build.

Implementation

Individual elements are declared using the sdk_atom template. It should be rare for a developer to directly use that template though: in most instances its use should be wrapped by another higher-level template, such as language-based templates (e.g. sdk_source_set() for C++).

Each atom has an id, a unique identifier for the element within the SDK, such as sdk://pkg/foo, which determines its output location in the final IDK archive. It also has a category, to restrict its availability outside of the Fuchsia team. In particular only atoms in the public or partner category should be part of an IDK distributed to third-party teams. Apart from that, categories are internal to the Fuchsia build system (i.e. they do not appear in SDK metadata files).

Groups of atoms are declared with the sdk_molecule template. A molecule can also depend on other molecules. Molecules are a great way to provide hierarchy to SDK atoms, but they do not have an id, as they are only used as a grouping mechanism within the Fuchsia build.

The sdk_collection template is used to declare a group of atoms (or molecules), while verifying that its content matches a given API/ABI. It will also create an “export directory” that follows the standard IDK layout for all its elements, under $OUTPUT_DIR/sdk/exported/<name>.

The [generate_final_idk][generate_final_idk] template is used to generate the final IDK archive, by merging the content of one or more collections. It also ensures that all prebuilt binaries are provided for all supported target CPU architectures (achieved by performing specific sub-builds of the same collections), that are all stored in the same compressed archive output.

It is possible to see an SDK collection as a “partial IDK” since it only contains a subset of atoms that go into the final IDK, but only provides prebuilts for the current build configuration's target_cpu, and for the current SDK API level / build variant.

Declaring SDK elements

There are a few GN templates developers should use to enable the inclusion of their code in an SDK:

Some language-specific targets are also SDK-ready:

In order to add documentation to an SDK, use the sdk_documentation template.

Component manifest shards being added to the SDK should use the sdk_component_manifest template.

Other static data (e.g. configuration or LICENSE files) being added to the SDK should use the sdk_data template.

A target //foo/bar declared with one of these templates will yield an additional target //foo/bar:bar_sdk which is an atom ready to be included as an sdk_molecule() or sdk_collection() dependency.

Outputs

Each SDK atom target (e.g. foo_sdk) generates two manifest files:

  • A meta.json file that follows one of the standard schemas available under //sdk/meta/, which will be included in the final IDK output.

  • An internal JSON manifest file, under gen/.../foo.sdk which describes the atom and all its transitive dependencies. Unlike the meta.json file, this file should not be used outside of a Fuchsia checkout, and its content / schema may change at any time.

Each sdk_collection("foo") target also generates sibling targets that other parts of the build system (and sometimes internal scripts) rely on:

  • foo_final_manifest: Creates a internal JSON manifest at $OUTPUT_DIR/sdk/manifest/<name>. This is seldom used by other parts of the build systems, or tools like fx or ffx when it runs from a Fuchsia checkout.

  • foo_export: Creates the collection's export directory under $OUTPUT_DIR/sdk/exported/<name>. This contains files that follow the standard IDK layout, including a top-level meta/manifest.json file describing all elements available from the collection.

    These export directories are seldom used by other parts of the build system, but should not be considered as official distribution artifacts.

  • foo_archive: Creates a compressed archive from the content of the collection under $OUTPUT_DIR/sdk/archive/<name>.tar.gz.

By default, target foo only depends on foo_final_manifest and foo_export. They can depend optionally on foo_archive though this is not the default.

Note that sdk collection archives only contain binaries for the current target_cpu value, and current API level. In theory they should not exist, nor distributed outside of the Fuchsia tree, though they currently are for historical reasons.

They are nonetheless deprecated. Generating archives should ideally only be done using the generate_final_idk() GN template instead.

Creating a custom IDK

Once elements have been set up for inclusion in an IDK, declaring such an IDK only takes a few steps:

  1. Identify the collections needed in the IDK. Create a new collection, or add atoms to an existing one if needed.

  2. Create a final_fuchsia_idk("my_idk") target under //sdk/BUILD.gn.

  3. If this new IDK only contains public or partner atoms, add its collections to the _fuchsia_sdk_deps list defined in //sdk/BUILD.gn to ensure its archives will be built and uploaded to cloud storage by the Fuchsia SDK CI builders.

  4. Alternatively, or if this is not possible (e.g. if this new IDK is defined in //vendor/.., which cannot be referenced from //sdk/BUILD.gn), add it to the sdk_archive_labels list in your args.gn file.

From there, the archive can be built locally with fx build my_idk and will be available as $OUTPUT_DIR/sdk/archive/my_idk.tar.gz.

Using a custom SDK in the build

Any IDK or sdk_collection target creates an “export” directory following the standard IDK layout, under $OUTPUT_DIR/sdk/exported/<name>/. This can be used to build certain third-party code which otherwise relies on an official IDK.

GN build arguments

build_sdk_archives

Setting the deprecated build_sdk_archives build argument to true in args.gn will force the generation by default of a compressed archive for a few collections defined in //sdk/BUILD.gn.

It will appear under $OUTPUT_DIR/sdk/archive/<name>.tar.gz. This is disabled by default since it is time-consuming and is only needed for a few legacy cases. Once all these use cases have been updated, this feature will be removed.

For consistency reasons, IDK archives should be used instead whenever something needs to be distributed outside of the Fuchsia team.

warn_on_sdk_changes

For each element in the SDK, a reference file representing its API is checked into the source tree. If the API is modified but the reference file is not updated, the build will fail. Set this argument to true in order to turn the errors into mere warnings.