feat(third_party/bazel): Check in rules_haskell from Tweag
This commit is contained in:
parent
2eb1dc26e4
commit
f723b8b878
479 changed files with 51484 additions and 0 deletions
175
third_party/bazel/rules_haskell/haskell/private/actions/repl.bzl
vendored
Normal file
175
third_party/bazel/rules_haskell/haskell/private/actions/repl.bzl
vendored
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
"""GHCi REPL support"""
|
||||
|
||||
load(":private/context.bzl", "render_env")
|
||||
load(":private/packages.bzl", "expose_packages", "pkg_info_to_compile_flags")
|
||||
load(
|
||||
":private/path_utils.bzl",
|
||||
"get_lib_name",
|
||||
"is_shared_library",
|
||||
"link_libraries",
|
||||
"ln",
|
||||
"target_unique_name",
|
||||
)
|
||||
load(":providers.bzl", "get_libs_for_ghc_linker")
|
||||
load(
|
||||
":private/set.bzl",
|
||||
"set",
|
||||
)
|
||||
load("@bazel_skylib//lib:paths.bzl", "paths")
|
||||
load("@bazel_skylib//lib:shell.bzl", "shell")
|
||||
|
||||
def build_haskell_repl(
|
||||
hs,
|
||||
ghci_script,
|
||||
ghci_repl_wrapper,
|
||||
user_compile_flags,
|
||||
repl_ghci_args,
|
||||
hs_info,
|
||||
output,
|
||||
package_databases,
|
||||
version,
|
||||
lib_info = None):
|
||||
"""Build REPL script.
|
||||
|
||||
Args:
|
||||
hs: Haskell context.
|
||||
hs_info: HaskellInfo.
|
||||
|
||||
package_databases: package caches excluding the cache file of the package
|
||||
we're creating a REPL for.
|
||||
lib_info: If we're building REPL for a library target, pass
|
||||
HaskellLibraryInfo here, otherwise it should be None.
|
||||
|
||||
Returns:
|
||||
None.
|
||||
"""
|
||||
|
||||
# The base and directory packages are necessary for the GHCi script we use
|
||||
# (loads source files and brings in scope the corresponding modules).
|
||||
args = ["-package", "base", "-package", "directory"]
|
||||
|
||||
pkg_ghc_info = expose_packages(
|
||||
hs_info,
|
||||
lib_info,
|
||||
use_direct = False,
|
||||
use_my_pkg_id = None,
|
||||
custom_package_databases = package_databases,
|
||||
version = version,
|
||||
)
|
||||
args += pkg_info_to_compile_flags(pkg_ghc_info)
|
||||
|
||||
lib_imports = []
|
||||
if lib_info != None:
|
||||
for idir in set.to_list(hs_info.import_dirs):
|
||||
args += ["-i{0}".format(idir)]
|
||||
lib_imports.append(idir)
|
||||
|
||||
link_ctx = hs_info.cc_dependencies.dynamic_linking
|
||||
libs_to_link = link_ctx.dynamic_libraries_for_runtime.to_list()
|
||||
|
||||
# External C libraries that we need to make available to the REPL.
|
||||
libraries = link_libraries(libs_to_link, args)
|
||||
|
||||
# Transitive library dependencies to have in runfiles.
|
||||
(library_deps, ld_library_deps, ghc_env) = get_libs_for_ghc_linker(
|
||||
hs,
|
||||
hs_info.transitive_cc_dependencies,
|
||||
path_prefix = "$RULES_HASKELL_EXEC_ROOT",
|
||||
)
|
||||
library_path = [paths.dirname(lib.path) for lib in library_deps]
|
||||
ld_library_path = [paths.dirname(lib.path) for lib in ld_library_deps]
|
||||
|
||||
repl_file = hs.actions.declare_file(target_unique_name(hs, "repl"))
|
||||
|
||||
add_sources = ["*" + f.path for f in set.to_list(hs_info.source_files)]
|
||||
|
||||
ghci_repl_script = hs.actions.declare_file(
|
||||
target_unique_name(hs, "ghci-repl-script"),
|
||||
)
|
||||
hs.actions.expand_template(
|
||||
template = ghci_script,
|
||||
output = ghci_repl_script,
|
||||
substitutions = {
|
||||
"{ADD_SOURCES}": " ".join(add_sources),
|
||||
"{COMMANDS}": "",
|
||||
},
|
||||
)
|
||||
|
||||
# Extra arguments.
|
||||
# `compiler flags` is the default set of arguments for the repl,
|
||||
# augmented by `repl_ghci_args`.
|
||||
# The ordering is important, first compiler flags (from toolchain
|
||||
# and local rule), then from `repl_ghci_args`. This way the more
|
||||
# specific arguments are listed last, and then have more priority in
|
||||
# GHC.
|
||||
# Note that most flags for GHCI do have their negative value, so a
|
||||
# negative flag in `repl_ghci_args` can disable a positive flag set
|
||||
# in `user_compile_flags`, such as `-XNoOverloadedStrings` will disable
|
||||
# `-XOverloadedStrings`.
|
||||
args += hs.toolchain.compiler_flags + user_compile_flags + hs.toolchain.repl_ghci_args + repl_ghci_args
|
||||
|
||||
hs.actions.expand_template(
|
||||
template = ghci_repl_wrapper,
|
||||
output = repl_file,
|
||||
substitutions = {
|
||||
"{ENV}": render_env(ghc_env),
|
||||
"{TOOL}": hs.tools.ghci.path,
|
||||
"{ARGS}": " ".join(
|
||||
[
|
||||
"-ghci-script",
|
||||
paths.join("$RULES_HASKELL_EXEC_ROOT", ghci_repl_script.path),
|
||||
] + [
|
||||
shell.quote(a)
|
||||
for a in args
|
||||
],
|
||||
),
|
||||
},
|
||||
is_executable = True,
|
||||
)
|
||||
|
||||
ghc_info = struct(
|
||||
has_version = pkg_ghc_info.has_version,
|
||||
library_path = library_path,
|
||||
ld_library_path = ld_library_path,
|
||||
packages = pkg_ghc_info.packages,
|
||||
package_ids = pkg_ghc_info.package_ids,
|
||||
package_dbs = pkg_ghc_info.package_dbs,
|
||||
lib_imports = lib_imports,
|
||||
libraries = libraries,
|
||||
execs = struct(
|
||||
ghc = hs.tools.ghc.path,
|
||||
ghci = hs.tools.ghci.path,
|
||||
runghc = hs.tools.runghc.path,
|
||||
),
|
||||
flags = struct(
|
||||
compiler = user_compile_flags,
|
||||
toolchain_compiler = hs.toolchain.compiler_flags,
|
||||
repl = repl_ghci_args,
|
||||
toolchain_repl = hs.toolchain.repl_ghci_args,
|
||||
),
|
||||
)
|
||||
ghc_info_file = hs.actions.declare_file(
|
||||
target_unique_name(hs, "ghc-info"),
|
||||
)
|
||||
hs.actions.write(
|
||||
output = ghc_info_file,
|
||||
content = ghc_info.to_json(),
|
||||
)
|
||||
|
||||
# XXX We create a symlink here because we need to force
|
||||
# hs.tools.ghci and ghci_script and the best way to do that is
|
||||
# to use hs.actions.run. That action, in turn must produce
|
||||
# a result, so using ln seems to be the only sane choice.
|
||||
extra_inputs = depset(transitive = [
|
||||
depset([
|
||||
hs.tools.ghci,
|
||||
ghci_repl_script,
|
||||
repl_file,
|
||||
ghc_info_file,
|
||||
]),
|
||||
set.to_depset(package_databases),
|
||||
depset(library_deps),
|
||||
depset(ld_library_deps),
|
||||
set.to_depset(hs_info.source_files),
|
||||
])
|
||||
ln(hs, repl_file, output, extra_inputs)
|
||||
Loading…
Add table
Add a link
Reference in a new issue