Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support Bazel 7 cc_shared_library #2232

Merged
merged 9 commits into from
Aug 30, 2024
Prev Previous commit
Next Next commit
support cc_shared_library as dep in haskell rules
Adds support for CcSharedLibraryInfo provider
malt3 committed Aug 28, 2024
commit 62bdb6211ec0120590d47b4f0a0cebe4fc145d23
38 changes: 22 additions & 16 deletions haskell/cc.bzl
Original file line number Diff line number Diff line change
@@ -156,6 +156,11 @@ def cc_interop_info(ctx, override_cc_toolchain = None):
cc_libraries_info = deps_HaskellCcLibrariesInfo(
ctx.attr.deps + getattr(ctx.attr, "plugins", []) + getattr(ctx.attr, "setup_deps", []),
)

transitive_libraries = _transitive_libraries_from_attr(ctx, "deps")
plugin_libraries = _transitive_libraries_from_attr(ctx, "plugins")
setup_libraries = _transitive_libraries_from_attr(ctx, "setup_deps")

return CcInteropInfo(
tools = struct(**tools),
env = env,
@@ -171,22 +176,9 @@ def cc_interop_info(ctx, override_cc_toolchain = None):
linker_flags = linker_flags,
cc_libraries_info = cc_libraries_info,
cc_libraries = get_cc_libraries(cc_libraries_info, [lib for li in cc_common.merge_cc_infos(cc_infos = ccs).linking_context.linker_inputs.to_list() for lib in li.libraries]),
transitive_libraries = [lib for li in cc_common.merge_cc_infos(cc_infos = [
dep[CcInfo]
for dep in ctx.attr.deps
if CcInfo in dep
]).linking_context.linker_inputs.to_list() for lib in li.libraries],
plugin_libraries = [lib for li in cc_common.merge_cc_infos(cc_infos = [
dep[CcInfo]
for plugin in getattr(ctx.attr, "plugins", [])
for dep in plugin[GhcPluginInfo].deps
if CcInfo in dep
]).linking_context.linker_inputs.to_list() for lib in li.libraries],
setup_libraries = [lib for li in cc_common.merge_cc_infos(cc_infos = [
dep[CcInfo]
for dep in getattr(ctx.attr, "setup_deps", [])
if CcInfo in dep
]).linking_context.linker_inputs.to_list() for lib in li.libraries],
transitive_libraries = transitive_libraries,
plugin_libraries = plugin_libraries,
setup_libraries = setup_libraries,
)

def ghc_cc_program_args(hs, cc, ld):
@@ -237,3 +229,17 @@ def ghc_cc_program_args(hs, cc, ld):
"-r",
])
return args

def _transitive_libraries_from_attr(ctx, attr_name):
cc_infos = [
input[CcInfo]
for input in getattr(ctx.attr, attr_name, [])
if CcInfo in input
]
cc_shared_library_infos = [
input[CcSharedLibraryInfo]
for input in getattr(ctx.attr, attr_name, [])
if CcSharedLibraryInfo in input
]
linker_inputs = cc_common.merge_cc_infos(cc_infos = cc_infos).linking_context.linker_inputs.to_list() + [info.linker_input for info in cc_shared_library_infos]
return [lib for li in linker_inputs for lib in li.libraries]
54 changes: 50 additions & 4 deletions haskell/private/cc_libraries.bzl
Original file line number Diff line number Diff line change
@@ -290,6 +290,7 @@ def extend_HaskellCcLibrariesInfo(
ctx,
cc_libraries_info,
cc_info,
cc_shared_info,
is_haskell):
"""Adapt new LibraryToLink and add to HaskellCcLibrariesInfo.

@@ -301,6 +302,7 @@ def extend_HaskellCcLibrariesInfo(
ctx: Aspect or rule context.
cc_libraries_info: HaskellCcLibrariesInfo of all dependencies.
cc_info: CcInfo of the current target.
cc_shared_info: CcSharedLibraryInfo of the current target.
is_haskell: Bool, whether the current target is a Haskell library.

Returns:
@@ -309,7 +311,11 @@ def extend_HaskellCcLibrariesInfo(
posix = ctx.toolchains["@rules_sh//sh/posix:toolchain_type"]
libraries = dict(cc_libraries_info.libraries)

for li in cc_info.linking_context.linker_inputs.to_list():
linker_inputs = cc_info.linking_context.linker_inputs.to_list() if cc_info else []
if cc_shared_info:
linker_inputs.append(cc_shared_info.linker_input)

for li in linker_inputs:
for lib_to_link in li.libraries:
key = cc_library_key(lib_to_link)
if key in libraries:
@@ -343,7 +349,7 @@ def extend_HaskellCcLibrariesInfo(

def _haskell_cc_libraries_aspect_impl(target, ctx):
if HaskellProtobufInfo in target:
# haskell_cc_libraries_aspect depends on the CcInfo and optionally
# haskell_cc_libraries_aspect depends on the CcInfo, CcSharedLibraryInfo and optionally
# HaskellInfo providers of a target. In the case of proto_library
# targets these providers are returned by the _haskell_proto_aspect.
# That aspect in turn requires HaskellCcLibrariesInfo in all its
@@ -361,11 +367,14 @@ def _haskell_cc_libraries_aspect_impl(target, ctx):
if HaskellCcLibrariesInfo in dep
])

if CcInfo in target:
cc_info = target[CcInfo] if CcInfo in target else None
cc_shared_info = target[CcSharedLibraryInfo] if CcSharedLibraryInfo in target else None
if cc_info or cc_shared_info:
cc_libraries_info = extend_HaskellCcLibrariesInfo(
ctx = ctx,
cc_libraries_info = cc_libraries_info,
cc_info = target[CcInfo],
cc_info = cc_info,
cc_shared_info = cc_shared_info,
is_haskell = HaskellInfo in target,
)

@@ -386,3 +395,40 @@ haskell_cc_libraries_aspect = aspect(
Create a symbolic link for each static library whose name doesn't match the
mangled name of the corresponding dynamic library.
"""

def merge_cc_shared_library_infos(owner, cc_shared_library_infos):
"""Similar to cc_common.merge_cc_infos but for CcSharedLibraryInfo

Args:
owner: The label of the target that produced all files used in this input.
cc_shared_library_infos: CcSharedLibraryInfo providers to be merged.

Returns:
CcSharedLibraryInfo
"""
dynamic_deps = []
exports = []
link_once_static_libs = {}
transitive_dynamic_deps = []
libraries_to_link = []
for cc_shared_library_info in cc_shared_library_infos:
dynamic_dep_entry = struct(
exports = cc_shared_library_info.exports,
linker_input = cc_shared_library_info.linker_input,
link_once_static_libs = cc_shared_library_info.link_once_static_libs,
)
dynamic_deps.append(dynamic_dep_entry)
transitive_dynamic_deps.append(cc_shared_library_info.dynamic_deps)
libraries_to_link.extend(cc_shared_library_info.linker_input.libraries)
link_once_static_libs.update(pairs = cc_shared_library_info.link_once_static_libs)
exports.extend(cc_shared_library_info.exports)

return CcSharedLibraryInfo(
dynamic_deps = depset(direct = dynamic_deps, transitive = transitive_dynamic_deps, order = "topological"),
exports = exports,
link_once_static_libs = link_once_static_libs,
linker_input = cc_common.create_linker_input(
owner = owner,
libraries = depset(libraries_to_link),
),
)
6 changes: 6 additions & 0 deletions haskell/private/haskell_impl.bzl
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ load(
)
load(":private/actions/package.bzl", "package")
load(":private/actions/runghc.bzl", "build_haskell_runghc")
load(":private/cc_libraries.bzl", "merge_cc_shared_library_infos")
load(":private/context.bzl", "haskell_context")
load(":private/dependencies.bzl", "gather_dep_info")
load(":private/expansions.bzl", "haskell_library_expand_make_variables")
@@ -710,10 +711,15 @@ def haskell_library_impl(ctx):
),
] + [dep[CcInfo] for dep in deps if CcInfo in dep],
)
out_cc_shared_library_info = merge_cc_shared_library_infos(
owner = ctx.label,
cc_shared_library_infos = [dep[CcSharedLibraryInfo] for dep in deps if CcSharedLibraryInfo in dep],
)

return [
hs_info,
out_cc_info,
out_cc_shared_library_info,
coverage_info,
default_info,
lib_info,