fwd/vendor/cxx/tools/buck/prelude/python/python.bzl
John Doty 9c435dc440 Vendor dependencies
Let's see how I like this workflow.
2022-12-19 08:38:22 -08:00

127 lines
5.1 KiB
Python

# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.
load("@prelude//cxx:cxx_toolchain_types.bzl", "CxxPlatformInfo")
load("@prelude//linking:shared_libraries.bzl", "traverse_shared_library_info")
load("@prelude//utils:utils.bzl", "flatten")
load(":interface.bzl", "PythonLibraryInterface", "PythonLibraryManifestsInterface")
load(":manifest.bzl", "ManifestInfo")
load(":toolchain.bzl", "PythonPlatformInfo", "get_platform_attr")
PythonLibraryManifests = record(
label = field("label"),
srcs = field([ManifestInfo.type, None]),
src_types = field([ManifestInfo.type, None], None),
resources = field([(ManifestInfo.type, ["_arglike"]), None]),
bytecode = field([ManifestInfo.type, None]),
# A map of module name to to source artifact for Python extensions.
extensions = field([{str.type: "_a"}, None]),
)
def _bytecode_artifacts(value: PythonLibraryManifests.type):
if value.bytecode == None:
return []
return value.bytecode.artifacts
def _bytecode_manifests(value: PythonLibraryManifests.type):
if value.bytecode == None:
return []
return value.bytecode.manifest
def _hidden_resources(value: PythonLibraryManifests.type):
if value.resources == None:
return []
return value.resources[1]
def _has_hidden_resources(children: [bool.type], value: [PythonLibraryManifests.type, None]):
if value:
if value.resources and len(value.resources[1]) > 0:
return True
return any(children)
def _resource_manifests(value: PythonLibraryManifests.type):
if value.resources == None:
return []
return value.resources[0].manifest
def _resource_artifacts(value: PythonLibraryManifests.type):
if value.resources == None:
return []
return value.resources[0].artifacts
def _source_manifests(value: PythonLibraryManifests.type):
if value.srcs == None:
return []
return value.srcs.manifest
def _source_artifacts(value: PythonLibraryManifests.type):
if value.srcs == None:
return []
return value.srcs.artifacts
def _source_type_manifests(value: PythonLibraryManifests.type):
if value.src_types == None:
return []
return value.src_types.manifest
def _source_type_artifacts(value: PythonLibraryManifests.type):
if value.src_types == None:
return []
return value.src_types.artifacts
PythonLibraryManifestsTSet = transitive_set(
args_projections = {
"bytecode_artifacts": _bytecode_artifacts,
"bytecode_manifests": _bytecode_manifests,
"hidden_resources": _hidden_resources,
"resource_artifacts": _resource_artifacts,
"resource_manifests": _resource_manifests,
"source_artifacts": _source_artifacts,
"source_manifests": _source_manifests,
"source_type_artifacts": _source_type_artifacts,
"source_type_manifests": _source_type_manifests,
},
reductions = {
"has_hidden_resources": _has_hidden_resources,
},
)
# Information about a python library and its dependencies.
# TODO(nmj): Resources in general, and mapping of resources to new paths too.
PythonLibraryInfo = provider(fields = [
"manifests", # PythonLibraryManifestsTSet
"shared_libraries", # "SharedLibraryInfo"
])
def info_to_interface(info: PythonLibraryInfo.type) -> PythonLibraryInterface.type:
return PythonLibraryInterface(
shared_libraries = lambda: traverse_shared_library_info(info.shared_libraries),
iter_manifests = lambda: info.manifests.traverse(),
manifests = lambda: manifests_to_interface(info.manifests),
has_hidden_resources = lambda: info.manifests.reduce("has_hidden_resources"),
hidden_resources = lambda: [info.manifests.project_as_args("hidden_resources")],
)
def manifests_to_interface(manifests: PythonLibraryManifestsTSet.type) -> PythonLibraryManifestsInterface.type:
return PythonLibraryManifestsInterface(
src_manifests = lambda: [manifests.project_as_args("source_manifests")],
src_artifacts = lambda: [manifests.project_as_args("source_artifacts")],
src_type_manifests = lambda: [manifests.project_as_args("source_manifests")],
src_type_artifacts = lambda: [manifests.project_as_args("source_artifacts")],
bytecode_manifests = lambda: [manifests.project_as_args("bytecode_manifests")],
bytecode_artifacts = lambda: [manifests.project_as_args("bytecode_artifacts")],
resource_manifests = lambda: [manifests.project_as_args("resource_manifests")],
resource_artifacts = lambda: [manifests.project_as_args("resource_artifacts")],
)
def get_python_deps(ctx: "context"):
python_platform = ctx.attrs._python_toolchain[PythonPlatformInfo]
cxx_platform = ctx.attrs._cxx_toolchain[CxxPlatformInfo]
return flatten(
[ctx.attrs.deps] +
get_platform_attr(python_platform, cxx_platform, ctx.attrs.platform_deps),
)