Skip to content

Commit

Permalink
Merge pull request #2104 from tweag/cb/toolchain-transition
Browse files Browse the repository at this point in the history
Remove `haskell_toolchain_libraries` rule
  • Loading branch information
mergify[bot] authored Jan 8, 2024
2 parents 69f2427 + e33cb9f commit 0039f48
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 166 deletions.
8 changes: 0 additions & 8 deletions haskell/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("@rules_python//python:defs.bzl", "py_binary", "py_library")
load(
"@rules_haskell//haskell:private/haskell_impl.bzl",
"haskell_toolchain_libraries",
)
load(
"@rules_haskell//haskell:private/cc_wrapper.bzl",
"cc_wrapper",
Expand Down Expand Up @@ -167,10 +163,6 @@ toolchain_type(
# implemented, yet. See
# https://github.com/bazelbuild/proposals/blob/master/designs/2019-02-12-toolchain-transitions.md
# This will need to be revisited once that proposal is implemented.
haskell_toolchain_libraries(
name = "toolchain-libraries",
visibility = ["//visibility:public"],
)

config_setting(
name = "use_worker",
Expand Down
3 changes: 0 additions & 3 deletions haskell/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -670,9 +670,6 @@ haskell_toolchain_library = rule(
package = attr.string(
doc = "The name of a GHC package not built by Bazel. Defaults to the name of the rule.",
),
_toolchain_libraries = attr.label(
default = Label("@rules_haskell//haskell:toolchain-libraries"),
),
),
toolchains = [
"@rules_haskell//haskell:toolchain",
Expand Down
154 changes: 2 additions & 152 deletions haskell/private/haskell_impl.bzl
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""Implementation of core Haskell rules"""

load("@bazel_skylib//lib:dicts.bzl", "dicts")
load("@rules_cc//cc:find_cc_toolchain.bzl", "use_cc_toolchain")
load(
":providers.bzl",
"C2hsLibraryInfo",
Expand Down Expand Up @@ -35,9 +34,7 @@ load(":private/mode.bzl", "is_profiling_enabled")
load(
":private/path_utils.bzl",
"determine_module_names",
"get_dynamic_hs_lib_name",
"get_lib_extension",
"get_static_hs_lib_name",
"infer_main_module",
"match_label",
"parse_pattern",
Expand Down Expand Up @@ -795,7 +792,8 @@ def haskell_toolchain_library_impl(ctx):
else:
package = ctx.label.name

libraries = ctx.attr._toolchain_libraries[HaskellToolchainLibraries].libraries
libraries = hs.toolchain.new_libraries.libraries

target = libraries.get(package)

if not target:
Expand Down Expand Up @@ -823,154 +821,6 @@ The following toolchain libraries are available:
)),
]

def _toolchain_library_symlink(dynamic_library):
prefix = dynamic_library.owner.workspace_root.replace("_", "_U").replace("/", "_S")
basename = dynamic_library.basename
return paths.join(prefix, basename)

def haskell_toolchain_libraries_impl(ctx):
hs = haskell_context(ctx)
with_profiling = is_profiling_enabled(hs)
with_threaded = "-threaded" in hs.toolchain.ghcopts

cc_toolchain = find_cc_toolchain(ctx)
feature_configuration = cc_common.configure_features(
ctx = ctx,
cc_toolchain = cc_toolchain,
requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)

libraries = hs.toolchain.libraries

# List of library in left-to-right post-ordering
# Meaning, if package B depends on package A, then A will appear before B.
ordered = depset(transitive = [
target[HaskellImportHack].transitive_depends
for target in hs.toolchain.libraries.values()
])

library_dict = {}
for package in ordered.to_list():
target = libraries[package]

# Construct CcInfo
if with_profiling:
# GHC does not provide dynamic profiling mode libraries. The dynamic
# libraries that are available are missing profiling symbols, that
# other profiling mode build results will reference. Therefore, we
# don't import dynamic libraries in profiling mode.
libs = {
get_static_hs_lib_name(hs.toolchain.version, lib): {"static": lib}
for lib in target[HaskellImportHack].static_profiling_libraries.to_list()
}
else:
# Workaround for https://github.com/tweag/rules_haskell/issues/881
# Static and dynamic libraries don't necessarily pair up 1 to 1.
# E.g. the rts package in the Unix GHC bindist contains the
# dynamic libHSrts and the static libCffi and libHSrts.
libs = {}
for lib in target[HaskellImportHack].dynamic_libraries.to_list():
libname = get_dynamic_hs_lib_name(hs.toolchain.version, lib)
if libname == "ffi" and libname in libs:
# Make sure that the file of libffi matching its soname
# ends up in target runfiles. Otherwise, execution will
# fail with "cannot open shared object file" errors.
# On Linux libffi comes in three shapes:
# libffi.so, libffi.so.7, libffi.so.7.1.0
# (version numbers may vary)
# The soname is then libffi.so.7, meaning, at runtime the
# dynamic linker will look for libffi.so.7. So, that file
# should be the LibraryToLink.dynamic_library.
ext_components = get_lib_extension(lib).split(".")
if len(ext_components) == 2 and ext_components[0] == "so":
libs[libname]["dynamic"] = lib
else:
libs[libname] = {"dynamic": lib}
for lib in target[HaskellImportHack].static_libraries.to_list():
name = get_static_hs_lib_name(with_profiling, lib)
entry = libs.get(name, {})
entry["static"] = lib
libs[name] = entry

# Avoid duplicate runtime and ffi libraries. These libraries come
# in threaded and non-threaded flavors. Depending on the
# compilation mode we want to forward only one or the other.
# XXX: Threaded mode should be a per-target property. Use Bazel
# build configurations and transitions to select the threaded or
# non-threaded runtime and ffi on a per-target basis.
if "HSrts_thr" in libs:
if with_threaded:
libs["HSrts"] = libs["HSrts_thr"]
libs.pop("HSrts_thr")
if "Cffi_thr" in libs:
if with_threaded:
libs["ffi"]["static"] = libs["Cffi_thr"]["static"]
libs.pop("Cffi_thr")
linker_inputs = [
cc_common.create_linker_input(
owner = ctx.label,
libraries = depset(direct = [
cc_common.create_library_to_link(
actions = ctx.actions,
feature_configuration = feature_configuration,
dynamic_library = lib.get("dynamic", None),
dynamic_library_symlink_path =
_toolchain_library_symlink(lib["dynamic"]) if lib.get("dynamic") else "",
static_library = lib.get("static", None),
cc_toolchain = cc_toolchain,
)
for lib in libs.values()
]),
user_link_flags = depset(direct = target[HaskellImportHack].linkopts),
),
]
compilation_context = cc_common.create_compilation_context(
headers = target[HaskellImportHack].headers,
includes = target[HaskellImportHack].includes,
)
linking_context = cc_common.create_linking_context(
linker_inputs = depset(direct = linker_inputs),
)
cc_info = CcInfo(
compilation_context = compilation_context,
linking_context = linking_context,
)
library_dict[package] = struct(
default_info = target[DefaultInfo],
hs_info = target[HaskellInfo],
hs_lib_info = target[HaskellLibraryInfo],
cc_info = cc_common.merge_cc_infos(cc_infos = [cc_info] + [
library_dict[dep].cc_info
for dep in target[HaskellImportHack].depends
]),
haddock_info = target[HaddockInfo],
)

return [HaskellToolchainLibraries(libraries = library_dict)]

haskell_toolchain_libraries = rule(
haskell_toolchain_libraries_impl,
attrs = {
"_cc_toolchain": attr.label(
default = Label("@rules_cc//cc:current_cc_toolchain"),
),
},
toolchains = use_cc_toolchain() + [
"@rules_haskell//haskell:toolchain",
],
fragments = ["cpp"],
)
"""Generate Haskell toolchain libraries.
This is an internal rule and should not be user facing.
This rule is a work-around for toolchain transitions not being implemented,
yet. See
https://github.com/bazelbuild/proposals/blob/master/designs/2019-02-12-toolchain-transitions.md
This will need to be revisited once that proposal is implemented.
"""

def haskell_import_impl(ctx):
# The `allow_files` attribute of `rule` cannot define patterns of accepted
# file extensions like `.so.*`. Instead, we check for the correct file
Expand Down
Loading

0 comments on commit 0039f48

Please sign in to comment.