diff options
Diffstat (limited to 'third_party/bazel/rules_haskell/haskell/private/actions/runghc.bzl')
-rw-r--r-- | third_party/bazel/rules_haskell/haskell/private/actions/runghc.bzl | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/third_party/bazel/rules_haskell/haskell/private/actions/runghc.bzl b/third_party/bazel/rules_haskell/haskell/private/actions/runghc.bzl new file mode 100644 index 000000000000..da855a3adb3c --- /dev/null +++ b/third_party/bazel/rules_haskell/haskell/private/actions/runghc.bzl @@ -0,0 +1,115 @@ +"""runghc 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( + ":private/set.bzl", + "set", +) +load(":providers.bzl", "get_libs_for_ghc_linker") +load("@bazel_skylib//lib:shell.bzl", "shell") + +def build_haskell_runghc( + hs, + runghc_wrapper, + user_compile_flags, + extra_args, + hs_info, + output, + package_databases, + version, + lib_info = None): + """Build runghc script. + + Args: + hs: Haskell context. + hs_info: HaskellInfo. + + package_databases: package caches excluding the cache file of the package + we're creating a runghc for. + lib_info: If we're building runghc for a library target, pass + HaskellLibraryInfo here, otherwise it should be None. + + Returns: + None. + """ + + args = pkg_info_to_compile_flags(expose_packages( + hs_info, + lib_info, + use_direct = False, + use_my_pkg_id = None, + custom_package_databases = package_databases, + version = version, + )) + + if lib_info != None: + for idir in set.to_list(hs_info.import_dirs): + args += ["-i{0}".format(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 runghc. + 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", + ) + + runghc_file = hs.actions.declare_file(target_unique_name(hs, "runghc")) + + # Extra arguments. + # `compiler flags` is the default set of arguments for runghc, + # augmented by `extra_args`. + # The ordering is important, first compiler flags (from toolchain + # and local rule), then from `extra_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 `extra_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 + + # ghc args need to be wrapped up in "--ghc-arg=" when passing to runghc + runcompile_flags = ["--ghc-arg=%s" % a for a in args] + runcompile_flags += extra_args + + hs.actions.expand_template( + template = runghc_wrapper, + output = runghc_file, + substitutions = { + "{ENV}": render_env(ghc_env), + "{TOOL}": hs.tools.runghc.path, + "{ARGS}": " ".join([shell.quote(a) for a in runcompile_flags]), + }, + is_executable = True, + ) + + # XXX We create a symlink here because we need to force + # hs.tools.runghc 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.runghc, + runghc_file, + ]), + set.to_depset(package_databases), + depset(library_deps), + depset(ld_library_deps), + set.to_depset(hs_info.source_files), + ]) + ln(hs, runghc_file, output, extra_inputs) |