Skip to content

Commit

Permalink
Write start.ghci file
Browse files Browse the repository at this point in the history
Summary:
## This stack
This stack is what I have so far for the native `haskell_ghci` buck2 rule implementation.
On D44449945 I published an initial RFC with what I had so far, but there were still a lot of things I didn't know.

Now, I think I'm much closer to getting to finishing, but there are still a few things I don't know that could be causing the errors that I'm getting...
I'll try to aggregate everything in an Help section...

My goal now is to
1. Generate scripts that are equivalent (e.g. only differences are in directory paths)
2. Generate all the necessary artifacts (e.g. SOs, scripts), which I'll compare using `tree -lv BUCK_OUT` of buck1 and buck2 output.
3. Run haxlsh and successfully load and run an endpoint.

I'm very close to #1. The only thing that's different is that I'm not creating an omnibus SO and I'm passing all the dependencies explicitly.

## This diff
As title.

Reviewed By: pepeiborra

Differential Revision: D46476480

fbshipit-source-id: aa9eea0bd0ed9b65b94156f27adda16fd69afe7e
  • Loading branch information
gustavoavena authored and facebook-github-bot committed Jun 15, 2023
1 parent a00a673 commit 4381f8b
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 2 deletions.
6 changes: 6 additions & 0 deletions prelude/haskell/haskell.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ HaskellLibraryInfo = record(
# at compile time. The real library flags are propagated up the
# dependency graph via MergedLinkInfo.
libs = field(["artifact"], []),
# Package version, used to specify the full package when exposing it,
# e.g. filepath-1.4.2.1, deepseq-1.4.4.0.
# Internal packages default to 1.0.0, e.g. `fbcode-dsi-logger-hs-types-1.0.0`.
version = str.type,
)

# --
Expand Down Expand Up @@ -247,6 +251,7 @@ def haskell_prebuilt_library_impl(ctx: "context") -> ["provider"]:
stub_dirs = [],
id = ctx.attrs.id,
libs = libs,
version = ctx.attrs.version,
)

def archive_linkable(lib):
Expand Down Expand Up @@ -660,6 +665,7 @@ def haskell_library_impl(ctx: "context") -> ["provider"]:
import_dirs = [compiled.hi],
stub_dirs = [compiled.stubs],
libs = libs,
version = "1.0.0",
)
hlib_infos[link_style] = hlib
hlink_infos[link_style] = [hlib]
Expand Down
68 changes: 66 additions & 2 deletions prelude/haskell/haskell_ghci.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,69 @@
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.

def haskell_ghci_impl(_ctx: "context") -> ["provider"]:
return [DefaultInfo()]
load("@prelude//haskell:haskell.bzl", "HaskellLibraryProvider")
load("@prelude//utils:utils.bzl", "flatten")

def _first_order_haskell_deps(ctx: "context") -> ["HaskellLibraryInfo"]:
return dedupe(
flatten(
[
dep[HaskellLibraryProvider].lib.values()
for dep in ctx.attrs.deps
if HaskellLibraryProvider in dep
],
),
)

# Creates the start.ghci script used to load the packages during startup
def _write_start_ghci(ctx: "context", script_file: "artifact"):
start_cmd = cmd_args()

# Reason for unsetting `LD_PRELOAD` env var obtained from D6255224:
# "Certain libraries (like allocators) cannot be loaded after the process
# has started. When needing to use these libraries, send them to a
# user-supplied script for handling them appropriately. Running the real
# iserv with these libraries under LD_PRELOAD accomplishes this.
# To ensure the LD_PRELOAD env doesn't make it to subsequently forked
# processes, the very first action of start.ghci is to unset the variable."
start_cmd.add("System.Environment.unsetEnv \"LD_PRELOAD\"")

set_cmd = cmd_args(":set", delimiter = " ")
first_order_deps = list(map(
lambda dep: dep.name + "-" + dep.version,
_first_order_haskell_deps(ctx),
))
deduped_deps = {pkg: 1 for pkg in first_order_deps}.keys()
package_list = cmd_args(
deduped_deps,
format = "-package {}",
delimiter = " ",
)
set_cmd.add(package_list)
set_cmd.add("\n")
start_cmd.add(set_cmd)

header_ghci = ctx.actions.declare_output("header.ghci")

ctx.actions.write(header_ghci.as_output(), start_cmd)

if ctx.attrs.ghci_init:
append_ghci_init = cmd_args()
append_ghci_init.add(
["sh", "-c", 'cat "$1" "$2" > "$3"', "--", header_ghci, ctx.attrs.ghci_init, script_file.as_output()],
)
ctx.actions.run(append_ghci_init, category = "append_ghci_init")
else:
ctx.actions.copy_file(script_file, header_ghci)

def haskell_ghci_impl(ctx: "context") -> ["provider"]:
start_ghci_file = ctx.actions.declare_output("start.ghci")
_write_start_ghci(ctx, start_ghci_file)

outputs = [
start_ghci_file,
]

return [
DefaultInfo(default_outputs = outputs),
]

0 comments on commit 4381f8b

Please sign in to comment.