blob: 13a33eaac860a4c926a19fec9d4ec8cdb3adb54b [file] [log] [blame]
# Copyright 2021 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.
"""Defines a WORKSPACE rule for loading a version of the Fuchsia IDK."""
load("//fuchsia/private/sdk_templates:generate_sdk_build_rules.bzl", "generate_sdk_build_rules")
load("//fuchsia/private:utils.bzl", "normalize_os")
# Base URL for Fuchsia IDK archives.
_SDK_URL_TEMPLATE = "https://chrome-infra-packages.appspot.com/dl/fuchsia/sdk/{type}/{os}-amd64/+/{tag}"
# Environment variable used to set a local Fuchsia Platform tree build output directory
# If this variable is set, it should point to <FUCHSIA_DIR>/out/<BUILD_DIR> where "sdk"
# and optionally "sdk:ddk" target(s) are built. In particular we will look for
# <LOCAL_FUCHSIA_PLATFORM_BUILD>/sdk/exported/core
# and
# <LOCAL_FUCHSIA_PLATFORM_BUILD>/sdk/exported/ddk (if "use_experimental" is True)
# Those can be produced with a 'fx build sdk sdk:ddk' command in a Fuchsia Platform tree.
_LOCAL_FUCHSIA_PLATFORM_BUILD = "LOCAL_FUCHSIA_PLATFORM_BUILD"
_LOCAL_BUILD_SDK_PATH = "sdk/exported/core"
_LOCAL_BUILD_EXPERIMENTAL_PATH = "sdk/exported/ddk"
def _sdk_url(os, tag, type = "core"):
# Return the URL of the SDK given an Operating System string and
# a CIPD tag.
return _SDK_URL_TEMPLATE.format(os = os, tag = tag, type = type)
def _instantiate_local(ctx, manifests):
# Copies the SDK from a local Fuchsia platform build.
local_fuchsia_dir = ctx.os.environ[_LOCAL_FUCHSIA_PLATFORM_BUILD]
print("WARNING: using local SDK from %s" % local_fuchsia_dir)
ctx.report_progress("Copying local SDK from %s" % local_fuchsia_dir)
local_sdk = ctx.path("%s/%s" % (local_fuchsia_dir, _LOCAL_BUILD_SDK_PATH))
if not local_sdk.exists:
fail("Cannot find SDK in local Fuchsia build. Please build it with 'fx build sdk' or unset variable %s: %s" % (_LOCAL_FUCHSIA_PLATFORM_BUILD, local_sdk))
ctx.execute(["cp", "-r", "-L", "-f", "%s/." % local_sdk, "."], quiet = False)
if ctx.attr.use_experimental:
ctx.report_progress("Copying experimental SDK from %s" % local_fuchsia_dir)
local_exp = ctx.path("%s/%s" % (local_fuchsia_dir, _LOCAL_BUILD_EXPERIMENTAL_PATH))
if not local_exp.exists:
fail("Cannot find experimental SDK in local Fuchsia build. Please build it with 'fx build sdk:ddk' or unset variable %s: %s" % (_LOCAL_FUCHSIA_PLATFORM_BUILD, local_exp))
ctx.execute(["mkdir", "-p", "experimental"], quiet = False)
ctx.execute(["cp", "-r", "-L", "-f", "%s/." % local_exp, "experimental/."], quiet = False)
_merge_experimental_sdk(ctx, manifests)
def _merge_experimental_sdk(ctx, manifests):
# the manifest in the experimental sdk has the same name as the one in core. To avoid overwriting
# the core manifest while extracting, we extract to a separate directory (experimental/), rename
# the manifest and then copy (hardlink to avoid unnecessary use of space) to the same place as
# the core sdk.
experimental_manifest = "meta/experimental_manifest.json"
ctx.execute(["mv", "experimental/meta/manifest.json", "experimental/%s" % experimental_manifest], quiet = False)
ctx.execute(["cp", "-r", "-f", "-l", "experimental/.", "."], quiet = False)
manifests.append(experimental_manifest)
def _fuchsia_sdk_repository_impl(ctx):
ctx.file("WORKSPACE.bazel", content = "")
manifests = ["meta/manifest.json"]
normalized_os = normalize_os(ctx)
if _LOCAL_FUCHSIA_PLATFORM_BUILD in ctx.os.environ:
_instantiate_local(ctx, manifests)
elif ctx.attr.cipd_tag:
sha256 = ""
if ctx.attr.sha256:
sha256 = ctx.attr.sha256[normalized_os]
ctx.download_and_extract(
_sdk_url(normalized_os, ctx.attr.cipd_tag),
type = "zip",
sha256 = sha256,
)
if ctx.attr.use_experimental:
sha256 = ""
if ctx.attr.sha256:
sha256 = ctx.attr.sha256["%s_experimental" % normalized_os]
ctx.download_and_extract(
_sdk_url(normalized_os, ctx.attr.cipd_tag, "experimental"),
type = "zip",
sha256 = sha256,
output = "experimental",
)
_merge_experimental_sdk(ctx, manifests)
else:
fail("One of %s env variable or fuchsia_sdk_repository.cipd_tag needs to be set" % _LOCAL_FUCHSIA_PLATFORM_BUILD)
ctx.report_progress("Generating Bazel rules for the SDK")
ctx.template(
"BUILD.bazel",
ctx.attr._template,
substitutions = {
"{{has_ddk}}": "has_ddk" if ctx.attr.use_experimental else "no_ddk",
},
)
generate_sdk_build_rules(ctx, manifests)
fuchsia_sdk_repository = repository_rule(
doc = """
Loads a particular version of the Fuchsia IDK.
The environment variable BAZEL_FUCHSIA_SDK_ARCHIVE can optionally be set
to the path of a locally built SDK archive file to override the tag
parameter.
If cipd_tag is set, sha256 can optionally be set to verify the downloaded file and to
allow Bazel to cache the file.
If cipd_tag is not set, BAZEL_FUCHSIA_SDK_ARCHIVE must be set.
""",
implementation = _fuchsia_sdk_repository_impl,
environ = [_LOCAL_FUCHSIA_PLATFORM_BUILD],
configure = True,
attrs = {
"cipd_tag": attr.string(
doc = "CIPD tag for the version to load.",
),
"use_experimental": attr.bool(
doc = "Use the experimental SDK libraries and tools. Can only be used if a cipd_tag is present.",
default = False,
),
"sha256": attr.string_dict(
doc = "Optional SHA-256 hash of the SDK archive. Valid keys are: mac, linux, mac_experimental and linux_experimental",
),
"_template": attr.label(
default = "@rules_fuchsia//fuchsia/private:fuchsia_sdk_repository_template.BUILD",
allow_single_file = True,
),
"_template_directory": attr.label(
default = "@rules_fuchsia//fuchsia/private/sdk_templates:BUILD.bazel",
allow_single_file = True,
),
},
)