Skip to main content
Glama
cxx_library_utility.bzl7.55 kB
# 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//:artifacts.bzl", "ArtifactOutputs", # @unused Used as a type "single_artifact", ) load("@prelude//:paths.bzl", "paths") load( "@prelude//linking:link_info.bzl", "DepMetadata", "LinkStrategy", "LinkStyle", "LinkerFlags", "MergedLinkInfo", ) load("@prelude//linking:types.bzl", "Linkage") load( "@prelude//utils:utils.bzl", "flatten", "from_named_set", ) load(":cxx_context.bzl", "get_cxx_platform_info", "get_cxx_toolchain_info") load( ":cxx_toolchain_types.bzl", "LinkerType", "ShlibInterfacesMode", ) load( ":headers.bzl", "cxx_attr_header_namespace", ) load(":platform.bzl", "cxx_by_platform") OBJECTS_SUBTARGET = "objects" # The dependencies def cxx_attr_deps(ctx: AnalysisContext) -> list[Dependency]: return ( ctx.attrs.deps + flatten(cxx_by_platform(ctx, getattr(ctx.attrs, "platform_deps", []))) + (getattr(ctx.attrs, "deps_query", []) or []) ) def cxx_attr_exported_deps(ctx: AnalysisContext) -> list[Dependency]: return getattr(ctx.attrs, "exported_deps", []) + flatten(cxx_by_platform(ctx, ctx.attrs.exported_platform_deps)) def cxx_attr_linker_flags_all(ctx: AnalysisContext) -> LinkerFlags: flags = ( cxx_attr_linker_flags(ctx) + (ctx.attrs.local_linker_script_flags if hasattr(ctx.attrs, "local_linker_script_flags") else []) ) post_flags = ( (ctx.attrs.post_linker_flags if hasattr(ctx.attrs, "post_linker_flags") else []) + (flatten(cxx_by_platform(ctx, ctx.attrs.post_platform_linker_flags)) if hasattr(ctx.attrs, "post_platform_linker_flags") else []) ) exported_flags = cxx_attr_exported_linker_flags(ctx) exported_post_flags = cxx_attr_exported_post_linker_flags(ctx) return LinkerFlags( flags = flags, post_flags = post_flags, exported_flags = exported_flags, exported_post_flags = exported_post_flags, ) def cxx_attr_exported_linker_flags(ctx: AnalysisContext) -> list[typing.Any]: return ( ctx.attrs.exported_linker_flags + (flatten(cxx_by_platform(ctx, ctx.attrs.exported_platform_linker_flags)) if hasattr(ctx.attrs, "exported_platform_linker_flags") else []) ) def cxx_attr_exported_post_linker_flags(ctx: AnalysisContext) -> list[typing.Any]: return ( ctx.attrs.exported_post_linker_flags + (flatten(cxx_by_platform(ctx, ctx.attrs.exported_post_platform_linker_flags)) if hasattr(ctx.attrs, "exported_post_platform_linker_flags") else []) ) def cxx_inherited_link_info(first_order_deps: list[Dependency]) -> list[MergedLinkInfo]: """ Returns the list of MergedLinkInfo from the dependencies, filtering out those without a MergedLinkInfo """ # We filter out nones because some non-cxx rule without such providers could be a dependency, for example # cxx_binary "fbcode//one_world/cli/util/process_wrapper:process_wrapper" depends on # python_library "fbcode//third-party-buck/$platform/build/glibc:__project__" return filter(None, [x.get(MergedLinkInfo) for x in first_order_deps]) # Linker flags def cxx_attr_linker_flags(ctx: AnalysisContext) -> list[typing.Any]: return ( ctx.attrs.linker_flags + (flatten(cxx_by_platform(ctx, ctx.attrs.platform_linker_flags)) if hasattr(ctx.attrs, "platform_linker_flags") else []) ) # Even though we're returning the shared library links, we must still # respect the `link_style` attribute of the target which controls how # all deps get linked. For example, you could be building the shared # output of a library which has `link_style = "static"`. # # The fallback equivalent code in Buck v1 is in CxxLibraryFactor::createBuildRule() # where link style is determined using the `linkableDepType` variable. # Note if `static` link style is requested, we assume `static_pic` # instead, so that code in the shared library can be correctly # loaded in the address space of any process at any address. def cxx_attr_link_strategy(attrs: typing.Any) -> LinkStrategy: value = attrs.link_style if attrs.link_style != None else "shared" if value == "static": value = "static_pic" return LinkStrategy(value) def cxx_attr_link_style(ctx: AnalysisContext) -> LinkStyle: if ctx.attrs.link_style != None: return LinkStyle(ctx.attrs.link_style) if ctx.attrs.defaults != None: # v1 equivalent code is in CxxConstructorArg::getDefaultFlavors and ParserWithConfigurableAttributes::applyDefaultFlavors # Only values in the map are used by v1 as flavors, copy this behavior and return the first value which is compatible with link style. v1_flavors = ctx.attrs.defaults.values() for s in [LinkStyle("static"), LinkStyle("static_pic"), LinkStyle("shared")]: if s.value in v1_flavors: return s return get_cxx_toolchain_info(ctx).linker_info.link_style def cxx_attr_preferred_linkage(ctx: AnalysisContext) -> Linkage: preferred_linkage = ctx.attrs.preferred_linkage # force_static is deprecated, but it has precedence over preferred_linkage if getattr(ctx.attrs, "force_static", False): preferred_linkage = "static" return Linkage(preferred_linkage) def cxx_attr_resources(ctx: AnalysisContext) -> dict[str, ArtifactOutputs]: """ Return the resources provided by this rule, as a map of resource name to a tuple of the resource artifact and any "other" outputs exposed by it. """ resources = {} namespace = cxx_attr_header_namespace(ctx) # Use getattr, as apple rules don't have a `resources` parameter. for name, resource in from_named_set(getattr(ctx.attrs, "resources", {})).items(): resources[paths.join(namespace, name)] = single_artifact(resource) return resources def cxx_is_gnu(ctx: AnalysisContext) -> bool: return get_cxx_toolchain_info(ctx).linker_info.type == LinkerType("gnu") def cxx_use_shlib_intfs(ctx: AnalysisContext) -> bool: """ Return whether we should use shared library interfaces for linking. """ # Per-rule opt-out. if not getattr(ctx.attrs, "supports_shlib_interfaces", True): return False linker_info = get_cxx_toolchain_info(ctx).linker_info return linker_info.shlib_interfaces != ShlibInterfacesMode("disabled") def cxx_use_shlib_intfs_mode(ctx: AnalysisContext, mode: ShlibInterfacesMode) -> bool: """ Verify we are using a specific shared library interface mode. """ return cxx_use_shlib_intfs(ctx) and get_cxx_toolchain_info(ctx).linker_info.shlib_interfaces == mode def cxx_platform_supported(ctx: AnalysisContext) -> bool: """ Return whether this rule's `supported_platforms_regex` matches the current platform name. """ if ctx.attrs.supported_platforms_regex == None: return True return regex_match( ctx.attrs.supported_platforms_regex, get_cxx_platform_info(ctx).name, ) def cxx_attr_dep_metadata(ctx: AnalysisContext) -> list[DepMetadata]: """ Return a `DepMetadata` structure with a meaningful version identifier. """ if not getattr(ctx.attrs, "version", None): return [] return [DepMetadata(version = ctx.attrs.version)]

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server