| # 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, |
| ), |
| }, |
| ) |