Skip to content

Commit 15ad309

Browse files
authored
Merge pull request #2232 from tweag/mp/bazel-7-cc_shared_library
support Bazel 7 cc_shared_library
2 parents 96e2314 + 46a752d commit 15ad309

File tree

11 files changed

+153
-25
lines changed

11 files changed

+153
-25
lines changed

haskell/cc.bzl

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ load(
1212
load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain")
1313
load(
1414
"//haskell:providers.bzl",
15-
"GhcPluginInfo",
1615
"HaskellInfo",
1716
)
1817
load(":private/cc_libraries.bzl", "deps_HaskellCcLibrariesInfo", "get_cc_libraries")
@@ -156,6 +155,11 @@ def cc_interop_info(ctx, override_cc_toolchain = None):
156155
cc_libraries_info = deps_HaskellCcLibrariesInfo(
157156
ctx.attr.deps + getattr(ctx.attr, "plugins", []) + getattr(ctx.attr, "setup_deps", []),
158157
)
158+
159+
transitive_libraries = _transitive_libraries_from_attr(ctx, "deps")
160+
plugin_libraries = _transitive_libraries_from_attr(ctx, "plugins")
161+
setup_libraries = _transitive_libraries_from_attr(ctx, "setup_deps")
162+
159163
return CcInteropInfo(
160164
tools = struct(**tools),
161165
env = env,
@@ -171,22 +175,9 @@ def cc_interop_info(ctx, override_cc_toolchain = None):
171175
linker_flags = linker_flags,
172176
cc_libraries_info = cc_libraries_info,
173177
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]),
174-
transitive_libraries = [lib for li in cc_common.merge_cc_infos(cc_infos = [
175-
dep[CcInfo]
176-
for dep in ctx.attr.deps
177-
if CcInfo in dep
178-
]).linking_context.linker_inputs.to_list() for lib in li.libraries],
179-
plugin_libraries = [lib for li in cc_common.merge_cc_infos(cc_infos = [
180-
dep[CcInfo]
181-
for plugin in getattr(ctx.attr, "plugins", [])
182-
for dep in plugin[GhcPluginInfo].deps
183-
if CcInfo in dep
184-
]).linking_context.linker_inputs.to_list() for lib in li.libraries],
185-
setup_libraries = [lib for li in cc_common.merge_cc_infos(cc_infos = [
186-
dep[CcInfo]
187-
for dep in getattr(ctx.attr, "setup_deps", [])
188-
if CcInfo in dep
189-
]).linking_context.linker_inputs.to_list() for lib in li.libraries],
178+
transitive_libraries = transitive_libraries,
179+
plugin_libraries = plugin_libraries,
180+
setup_libraries = setup_libraries,
190181
)
191182

192183
def ghc_cc_program_args(hs, cc, ld):
@@ -237,3 +228,17 @@ def ghc_cc_program_args(hs, cc, ld):
237228
"-r",
238229
])
239230
return args
231+
232+
def _transitive_libraries_from_attr(ctx, attr_name):
233+
cc_infos = [
234+
input[CcInfo]
235+
for input in getattr(ctx.attr, attr_name, [])
236+
if CcInfo in input
237+
]
238+
cc_shared_library_infos = [
239+
input[CcSharedLibraryInfo]
240+
for input in getattr(ctx.attr, attr_name, [])
241+
if CcSharedLibraryInfo in input
242+
]
243+
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]
244+
return [lib for li in linker_inputs for lib in li.libraries]

haskell/private/cc_libraries.bzl

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ def extend_HaskellCcLibrariesInfo(
290290
ctx,
291291
cc_libraries_info,
292292
cc_info,
293+
cc_shared_info,
293294
is_haskell):
294295
"""Adapt new LibraryToLink and add to HaskellCcLibrariesInfo.
295296
@@ -301,6 +302,7 @@ def extend_HaskellCcLibrariesInfo(
301302
ctx: Aspect or rule context.
302303
cc_libraries_info: HaskellCcLibrariesInfo of all dependencies.
303304
cc_info: CcInfo of the current target.
305+
cc_shared_info: CcSharedLibraryInfo of the current target.
304306
is_haskell: Bool, whether the current target is a Haskell library.
305307
306308
Returns:
@@ -309,7 +311,11 @@ def extend_HaskellCcLibrariesInfo(
309311
posix = ctx.toolchains["@rules_sh//sh/posix:toolchain_type"]
310312
libraries = dict(cc_libraries_info.libraries)
311313

312-
for li in cc_info.linking_context.linker_inputs.to_list():
314+
linker_inputs = cc_info.linking_context.linker_inputs.to_list() if cc_info else []
315+
if cc_shared_info:
316+
linker_inputs.append(cc_shared_info.linker_input)
317+
318+
for li in linker_inputs:
313319
for lib_to_link in li.libraries:
314320
key = cc_library_key(lib_to_link)
315321
if key in libraries:
@@ -343,7 +349,7 @@ def extend_HaskellCcLibrariesInfo(
343349

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

364-
if CcInfo in target:
370+
cc_info = target[CcInfo] if CcInfo in target else None
371+
cc_shared_info = target[CcSharedLibraryInfo] if CcSharedLibraryInfo in target else None
372+
if cc_info or cc_shared_info:
365373
cc_libraries_info = extend_HaskellCcLibrariesInfo(
366374
ctx = ctx,
367375
cc_libraries_info = cc_libraries_info,
368-
cc_info = target[CcInfo],
376+
cc_info = cc_info,
377+
cc_shared_info = cc_shared_info,
369378
is_haskell = HaskellInfo in target,
370379
)
371380

@@ -386,3 +395,40 @@ haskell_cc_libraries_aspect = aspect(
386395
Create a symbolic link for each static library whose name doesn't match the
387396
mangled name of the corresponding dynamic library.
388397
"""
398+
399+
def merge_cc_shared_library_infos(owner, cc_shared_library_infos):
400+
"""Similar to cc_common.merge_cc_infos but for CcSharedLibraryInfo
401+
402+
Args:
403+
owner: The label of the target that produced all files used in this input.
404+
cc_shared_library_infos: CcSharedLibraryInfo providers to be merged.
405+
406+
Returns:
407+
CcSharedLibraryInfo
408+
"""
409+
dynamic_deps = []
410+
exports = []
411+
link_once_static_libs = {}
412+
transitive_dynamic_deps = []
413+
libraries_to_link = []
414+
for cc_shared_library_info in cc_shared_library_infos:
415+
dynamic_dep_entry = struct(
416+
exports = cc_shared_library_info.exports,
417+
linker_input = cc_shared_library_info.linker_input,
418+
link_once_static_libs = cc_shared_library_info.link_once_static_libs,
419+
)
420+
dynamic_deps.append(dynamic_dep_entry)
421+
transitive_dynamic_deps.append(cc_shared_library_info.dynamic_deps)
422+
libraries_to_link.extend(cc_shared_library_info.linker_input.libraries)
423+
link_once_static_libs.update(pairs = cc_shared_library_info.link_once_static_libs)
424+
exports.extend(cc_shared_library_info.exports)
425+
426+
return CcSharedLibraryInfo(
427+
dynamic_deps = depset(direct = dynamic_deps, transitive = transitive_dynamic_deps, order = "topological"),
428+
exports = exports,
429+
link_once_static_libs = link_once_static_libs,
430+
linker_input = cc_common.create_linker_input(
431+
owner = owner,
432+
libraries = depset(libraries_to_link),
433+
),
434+
)

haskell/private/haskell_impl.bzl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ load(
2323
)
2424
load(":private/actions/package.bzl", "package")
2525
load(":private/actions/runghc.bzl", "build_haskell_runghc")
26+
load(":private/cc_libraries.bzl", "merge_cc_shared_library_infos")
2627
load(":private/context.bzl", "haskell_context")
2728
load(":private/dependencies.bzl", "gather_dep_info")
2829
load(":private/expansions.bzl", "haskell_library_expand_make_variables")
@@ -710,10 +711,15 @@ def haskell_library_impl(ctx):
710711
),
711712
] + [dep[CcInfo] for dep in deps if CcInfo in dep],
712713
)
714+
out_cc_shared_library_info = merge_cc_shared_library_infos(
715+
owner = ctx.label,
716+
cc_shared_library_infos = [dep[CcSharedLibraryInfo] for dep in deps if CcSharedLibraryInfo in dep],
717+
)
713718

714719
return [
715720
hs_info,
716721
out_cc_info,
722+
out_cc_shared_library_info,
717723
coverage_info,
718724
default_info,
719725
lib_info,

haskell/private/versions.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ SUPPORTED_BAZEL_VERSIONS = [
1717
"6.0.0",
1818
"6.3.2",
1919
"6.5.0",
20+
"7.1.0",
2021
]
2122

2223
SUPPORTED_NIXPKGS_BAZEL_PACKAGES = [
2324
"bazel_6",
25+
"bazel_7",
2426
]
2527

2628
def _parse_version_chunk(version_chunk):

haskell/protobuf.bzl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ def _haskell_proto_aspect_impl(target, ctx):
215215
# TODO this pattern match is very brittle. Let's not do this. The
216216
# order should match the order in the return value expression in
217217
# haskell_library_impl().
218-
[hs_info, cc_info, _coverage_info, default_info, library_info, output_groups] = _haskell_library_impl(patched_ctx)
218+
[hs_info, cc_info, cc_shared_library_info, _coverage_info, default_info, library_info, output_groups] = _haskell_library_impl(patched_ctx)
219219

220220
# Build haddock informations
221221
transitive_html = {}
@@ -255,11 +255,13 @@ def _haskell_proto_aspect_impl(target, ctx):
255255
for dep in getattr(ctx.rule.attr, attr, [])
256256
]),
257257
cc_info = cc_info,
258+
cc_shared_info = cc_shared_library_info,
258259
is_haskell = True,
259260
)
260261

261262
return [
262263
cc_info, # CcInfo
264+
cc_shared_library_info, # CcSharedLibraryInfo
263265
hs_info, # HaskellInfo
264266
library_info, # HaskellLibraryInfo
265267
# We can't return DefaultInfo here because target already provides that.

haskell/repl.bzl

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ load(
1414
"haskell_cc_libraries_aspect",
1515
"link_libraries",
1616
"merge_HaskellCcLibrariesInfo",
17+
"merge_cc_shared_library_infos",
1718
)
1819
load(":private/context.bzl", "haskell_context", "render_env")
1920
load(":private/expansions.bzl", "expand_make_variables")
@@ -48,6 +49,7 @@ HaskellReplLoadInfo = provider(
4849
"import_dirs": "Depset of Haskell import directories.",
4950
"cc_libraries_info": "HaskellCcLibrariesInfo of transitive C dependencies.",
5051
"cc_info": "CcInfo of transitive C dependencies.",
52+
"cc_shared_library_infos": "CcSharedLibraryInfo providers of transitive C dependencies.",
5153
"compiler_flags": "Flags to pass to the Haskell compiler.",
5254
"repl_ghci_args": "Arbitrary extra arguments to pass to GHCi. This extends `compiler_flags` and `repl_ghci_args` from the toolchain",
5355
"data_runfiles": "Runtime data dependencies of this target, i.e. the files and runfiles of the `data` attribute.",
@@ -68,6 +70,7 @@ HaskellReplDepInfo = provider(
6870
"interface_dirs": "Set of interface dirs for all the dependencies",
6971
"cc_libraries_info": "HaskellCcLibrariesInfo of transitive C dependencies.",
7072
"cc_info": "CcInfo of the package itself (includes its transitive dependencies).",
73+
"cc_shared_library_infos": "CcSharedLibraryInfo providers of transitive C dependencies.",
7174
"runfiles": "Runfiles of this target.",
7275
},
7376
)
@@ -146,6 +149,7 @@ def _merge_HaskellReplLoadInfo(load_infos):
146149
import_dirs = depset()
147150
cc_libraries_infos = []
148151
cc_infos = []
152+
cc_shared_library_infos = []
149153
compiler_flags = []
150154
repl_ghci_args = []
151155
data_runfiles = []
@@ -158,6 +162,7 @@ def _merge_HaskellReplLoadInfo(load_infos):
158162
import_dirs = depset(transitive = [import_dirs, load_info.import_dirs])
159163
cc_libraries_infos.append(load_info.cc_libraries_info)
160164
cc_infos.append(load_info.cc_info)
165+
cc_shared_library_infos.extend(load_info.cc_shared_library_infos)
161166
compiler_flags += load_info.compiler_flags
162167
repl_ghci_args += load_info.repl_ghci_args
163168
data_runfiles.append(load_info.data_runfiles)
@@ -171,6 +176,7 @@ def _merge_HaskellReplLoadInfo(load_infos):
171176
import_dirs = import_dirs,
172177
cc_libraries_info = merge_HaskellCcLibrariesInfo(infos = cc_libraries_infos),
173178
cc_info = cc_common.merge_cc_infos(cc_infos = cc_infos),
179+
cc_shared_library_infos = cc_shared_library_infos,
174180
compiler_flags = compiler_flags,
175181
repl_ghci_args = repl_ghci_args,
176182
data_runfiles = _merge_runfiles(data_runfiles),
@@ -180,11 +186,13 @@ def _merge_HaskellReplLoadInfo(load_infos):
180186
def _merge_HaskellReplLoadInfoMulti(root_info, load_infos):
181187
cc_libraries_infos = []
182188
cc_infos = []
189+
cc_shared_library_infos = []
183190
data_runfiles = []
184191
java_deps = []
185192
for load_info in load_infos:
186193
cc_libraries_infos.append(load_info.cc_libraries_info)
187194
cc_infos.append(load_info.cc_info)
195+
cc_shared_library_infos.extend(load_info.cc_shared_library_infos)
188196
data_runfiles.append(load_info.data_runfiles)
189197
java_deps.append(load_info.java_deps)
190198

@@ -197,6 +205,7 @@ def _merge_HaskellReplLoadInfoMulti(root_info, load_infos):
197205
import_dirs = root_info.import_dirs,
198206
cc_libraries_info = merge_HaskellCcLibrariesInfo(infos = cc_libraries_infos),
199207
cc_info = cc_common.merge_cc_infos(cc_infos = cc_infos),
208+
cc_shared_library_infos = cc_shared_library_infos,
200209
compiler_flags = root_info.compiler_flags,
201210
repl_ghci_args = root_info.repl_ghci_args,
202211
data_runfiles = _merge_runfiles(data_runfiles),
@@ -209,6 +218,7 @@ def _merge_HaskellReplDepInfo(dep_infos, dep_infos_for_package_dbs = []):
209218
interface_dirs = depset()
210219
cc_libraries_infos = []
211220
cc_infos = []
221+
cc_shared_library_infos = []
212222
runfiles = []
213223

214224
for dep_info in dep_infos:
@@ -217,6 +227,7 @@ def _merge_HaskellReplDepInfo(dep_infos, dep_infos_for_package_dbs = []):
217227
interface_dirs = depset(transitive = [interface_dirs, dep_info.interface_dirs])
218228
cc_libraries_infos.append(dep_info.cc_libraries_info)
219229
cc_infos.append(dep_info.cc_info)
230+
cc_shared_library_infos.extend(dep_info.cc_shared_library_infos)
220231
runfiles.append(dep_info.runfiles)
221232

222233
for dep_info in dep_infos_for_package_dbs:
@@ -229,6 +240,7 @@ def _merge_HaskellReplDepInfo(dep_infos, dep_infos_for_package_dbs = []):
229240
interface_dirs = interface_dirs,
230241
cc_libraries_info = merge_HaskellCcLibrariesInfo(infos = cc_libraries_infos),
231242
cc_info = cc_common.merge_cc_infos(cc_infos = cc_infos),
243+
cc_shared_library_infos = cc_shared_library_infos,
232244
runfiles = _merge_runfiles(runfiles),
233245
)
234246

@@ -260,6 +272,11 @@ def _create_HaskellReplCollectInfo(target, dep_labels, dep_package_ids, dep_pack
260272
for dep in getattr(ctx.rule.attr, "deps", []) + getattr(ctx.rule.attr, "narrowed_deps", [])
261273
if CcInfo in dep and not HaskellInfo in dep
262274
]
275+
ccSharedLibraryInfoDeps = [
276+
dep
277+
for dep in getattr(ctx.rule.attr, "deps", []) + getattr(ctx.rule.attr, "narrowed_deps", [])
278+
if CcSharedLibraryInfo in dep and not HaskellInfo in dep
279+
]
263280
if HaskellLibraryInfo in target:
264281
package_id = target[HaskellLibraryInfo].package_id
265282
load_info = HaskellReplLoadInfo(
@@ -269,12 +286,19 @@ def _create_HaskellReplCollectInfo(target, dep_labels, dep_package_ids, dep_pack
269286
boot_files = hs_info.boot_files,
270287
module_names = hs_info.module_names,
271288
import_dirs = set.to_depset(hs_info.import_dirs),
272-
cc_libraries_info = deps_HaskellCcLibrariesInfo(ccInfoDeps),
289+
cc_libraries_info = deps_HaskellCcLibrariesInfo(ccInfoDeps + ccSharedLibraryInfoDeps),
273290
cc_info = cc_common.merge_cc_infos(cc_infos = [
274291
# Collect pure C library dependencies, no Haskell dependencies.
275292
dep[CcInfo]
276293
for dep in ccInfoDeps
277294
]),
295+
cc_shared_library_infos = [merge_cc_shared_library_infos(
296+
owner = ctx.label,
297+
cc_shared_library_infos = [
298+
dep[CcSharedLibraryInfo]
299+
for dep in ccSharedLibraryInfoDeps
300+
],
301+
)],
278302
compiler_flags = hs_info.user_compile_flags,
279303
repl_ghci_args = hs_info.user_repl_flags,
280304
data_runfiles = _data_runfiles(ctx, ctx.rule, "data"),
@@ -290,6 +314,7 @@ def _create_HaskellReplCollectInfo(target, dep_labels, dep_package_ids, dep_pack
290314
interface_dirs = hs_info.interface_dirs,
291315
cc_libraries_info = target[HaskellCcLibrariesInfo],
292316
cc_info = target[CcInfo],
317+
cc_shared_library_infos = [target[CcSharedLibraryInfo]] if CcSharedLibraryInfo in target else [],
293318
runfiles = target[DefaultInfo].default_runfiles,
294319
)
295320
dep_infos[target.label] = dep_info
@@ -492,7 +517,9 @@ def _compiler_flags_and_inputs(hs, cc, repl_info, get_dirname, static = False, i
492517
repl_info.load_info.cc_info,
493518
repl_info.dep_info.cc_info,
494519
])
495-
all_libraries = [lib for li in cc_info.linking_context.linker_inputs.to_list() for lib in li.libraries]
520+
cc_shared_library_infos = repl_info.load_info.cc_shared_library_infos + repl_info.dep_info.cc_shared_library_infos
521+
linker_inputs = cc_info.linking_context.linker_inputs.to_list() + [info.linker_input for info in cc_shared_library_infos]
522+
all_libraries = [lib for li in linker_inputs for lib in li.libraries]
496523
cc_libraries = get_cc_libraries(cc_libraries_info, all_libraries)
497524
if static:
498525
cc_library_files = _concat(get_library_files(hs, cc_libraries_info, cc_libraries))

rules_haskell_tests/MODULE.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,11 @@ use_repo(
113113
non_modules_deps_1,
114114
"asterius_bundle_linux_amd64",
115115
"bazel_6",
116+
"bazel_7",
116117
"build_bazel_bazel_6_0_0",
117118
"build_bazel_bazel_6_3_2",
118119
"build_bazel_bazel_6_5_0",
120+
"build_bazel_bazel_7_1_0",
119121
"glibc_locales",
120122
"linux_amd64_asterius-toolchain",
121123
"nixpkgs_config_cc",

rules_haskell_tests/tests/recompilation/recompilation_workspace/WORKSPACE

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,10 @@ haskell_register_ghc_nixpkgs(
2121
load("@rules_haskell//haskell:toolchain.bzl", "rules_haskell_toolchains")
2222

2323
rules_haskell_toolchains(version = "8.10.7")
24+
25+
load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_cc_configure")
26+
27+
nixpkgs_cc_configure(
28+
name = "nixpkgs_config_cc",
29+
repository = "@rules_haskell//nixpkgs:default.nix",
30+
)

0 commit comments

Comments
 (0)