Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 46 additions & 45 deletions haskell/compile.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def _modules_by_name(ctx: AnalysisContext, *, sources: list[Artifact], link_styl

return modules

def _dynamic_target_metadata_impl(actions, artifacts, dynamic_values, outputs, arg):
def _dynamic_target_metadata_impl(actions, output, arg, pkg_deps) -> list[Provider]:
# Add -package-db and -package/-expose-package flags for each Haskell
# library dependency.

Expand All @@ -185,7 +185,7 @@ def _dynamic_target_metadata_impl(actions, artifacts, dynamic_values, outputs, a
enable_profiling = False,
use_empty_lib = True,
for_deps = True,
resolved = dynamic_values,
pkg_deps = pkg_deps,
)
package_flag = _package_flag(arg.haskell_toolchain)
ghc_args = cmd_args()
Expand All @@ -210,13 +210,20 @@ def _dynamic_target_metadata_impl(actions, artifacts, dynamic_values, outputs, a
md_args.add(
arg.lib_package_name_and_prefix,
)
md_args.add("--output", outputs[arg.md_file].as_output())
md_args.add("--output", output)

actions.run(md_args, category = "haskell_metadata", identifier = arg.suffix if arg.suffix else None)

return []

_dynamic_target_metadata = dynamic_actions(impl = _dynamic_target_metadata_impl)
_dynamic_target_metadata = dynamic_actions(
impl = _dynamic_target_metadata_impl,
attrs = {
"output": dynattrs.output(),
"arg": dynattrs.value(typing.Any),
"pkg_deps": dynattrs.option(dynattrs.dynamic_value()),
},
)

def target_metadata(
ctx: AnalysisContext,
Expand Down Expand Up @@ -245,17 +252,15 @@ def target_metadata(
# (module X.Y.Z must be defined in a file at X/Y/Z.hs)

ctx.actions.dynamic_output_new(_dynamic_target_metadata(
dynamic = [],
dynamic_values = [haskell_toolchain.packages.dynamic] if haskell_toolchain.packages else [],
outputs = [md_file.as_output()],
pkg_deps = haskell_toolchain.packages.dynamic if haskell_toolchain.packages else None,
output = md_file.as_output(),
arg = struct(
compiler_flags = ctx.attrs.compiler_flags,
deps = ctx.attrs.deps,
direct_deps_link_info = attr_deps_haskell_link_infos(ctx),
haskell_direct_deps_lib_infos = haskell_direct_deps_lib_infos,
haskell_toolchain = haskell_toolchain,
lib_package_name_and_prefix =_attr_deps_haskell_lib_package_name_and_prefix(ctx),
md_file = md_file,
md_gen = md_gen,
sources = sources,
strip_prefix = _strip_prefix(str(ctx.label.cell_root), str(ctx.label.path)),
Expand Down Expand Up @@ -313,7 +318,7 @@ def get_packages_info(
specify_pkg_version = specify_pkg_version,
enable_profiling = enable_profiling,
use_empty_lib = use_empty_lib,
resolved = {},
pkg_deps = None,
)

def get_packages_info2(
Expand All @@ -326,7 +331,7 @@ def get_packages_info2(
specify_pkg_version: bool,
enable_profiling: bool,
use_empty_lib: bool,
resolved: dict[DynamicValue, ResolvedDynamicValue],
pkg_deps: ResolvedDynamicValue | None,
for_deps: bool = False) -> PackagesInfo:

# Collect library dependencies. Note that these don't need to be in a
Expand Down Expand Up @@ -363,8 +368,7 @@ def get_packages_info2(
])
exposed_package_args.add(hidden_args)

if resolved:
pkg_deps = resolved[haskell_toolchain.packages.dynamic]
if pkg_deps:
package_db = pkg_deps.providers[DynamicHaskellPackageDbInfo].packages
else:
package_db = {}
Expand Down Expand Up @@ -418,7 +422,7 @@ def _common_compile_module_args(
compiler_flags: list[ArgLike],
ghc_wrapper: RunInfo,
haskell_toolchain: HaskellToolchainInfo,
resolved: dict[DynamicValue, ResolvedDynamicValue],
pkg_deps: ResolvedDynamicValue | None,
enable_haddock: bool,
enable_profiling: bool,
link_style: LinkStyle,
Expand Down Expand Up @@ -493,7 +497,6 @@ def _common_compile_module_args(
toolchain_libs = direct_toolchain_libs + libs.reduce("packages")

if haskell_toolchain.packages:
pkg_deps = resolved[haskell_toolchain.packages.dynamic]
package_db = pkg_deps.providers[DynamicHaskellPackageDbInfo].packages
else:
package_db = []
Expand Down Expand Up @@ -563,7 +566,7 @@ def _compile_module(
md_file: Artifact,
graph: dict[str, list[str]],
package_deps: dict[str, list[str]],
outputs: dict[Artifact, Artifact],
outputs: dict[Artifact, OutputArtifact],
artifact_suffix: str,
direct_deps_by_name: dict[str, typing.Any],
toolchain_deps_by_name: dict[str, None],
Expand All @@ -590,8 +593,8 @@ def _compile_module(
objects = [outputs[obj] for obj in module.objects]
his = [outputs[hi] for hi in module.interfaces]

compile_args_for_file.add("-o", objects[0].as_output())
compile_args_for_file.add("-ohi", his[0].as_output())
compile_args_for_file.add("-o", objects[0])
compile_args_for_file.add("-ohi", his[0])

# Set the output directories. We do not use the -outputdir flag, but set the directories individually.
# Note, the -outputdir option is shorthand for the combination of -odir, -hidir, -hiedir, -stubdir and -dumpdir.
Expand All @@ -603,12 +606,12 @@ def _compile_module(
)
if module.stub_dir != None:
stubs = outputs[module.stub_dir]
compile_args_for_file.add("-stubdir", stubs.as_output())
compile_args_for_file.add("-stubdir", stubs)

if link_style in [LinkStyle("static_pic"), LinkStyle("static")]:
compile_args_for_file.add("-dynamic-too")
compile_args_for_file.add("-dyno", objects[1].as_output())
compile_args_for_file.add("-dynohi", his[1].as_output())
compile_args_for_file.add("-dyno", objects[1])
compile_args_for_file.add("-dynohi", his[1])

compile_args_for_file.add(module.source)

Expand All @@ -623,9 +626,9 @@ def _compile_module(
toolchain_deps.append(dep_pkgname)
elif dep_pkgname in direct_deps_by_name:
library_deps.append(dep_pkgname)
exposed_package_dbs.append(direct_deps_by_name[dep_pkgname].package_db)
exposed_package_dbs.append(direct_deps_by_name[dep_pkgname][0])
for dep_modname in dep_modules:
exposed_package_modules.append(direct_deps_by_name[dep_pkgname].modules[dep_modname])
exposed_package_modules.append(direct_deps_by_name[dep_pkgname][1].providers[DynamicCompileResultInfo].modules[dep_modname])
else:
fail("Unknown library dependency '{}'. Add the library to the `deps` attribute".format(dep_pkgname))

Expand Down Expand Up @@ -698,7 +701,7 @@ def _compile_module(
tagged_dep_file = abi_tag.tag_artifacts(dep_file)

compile_cmd.add("--buck2-dep", tagged_dep_file)
compile_cmd.add("--abi-out", outputs[module.hash].as_output())
compile_cmd.add("--abi-out", outputs[module.hash])

actions.run(
compile_cmd, category = "haskell_compile_" + artifact_suffix.replace("-", "_"), identifier = module_name,
Expand All @@ -720,14 +723,7 @@ def _compile_module(

return module_tset

def _dynamic_do_compile_impl(actions, artifacts, dynamic_values, outputs, arg):
direct_deps_by_name = {
info.value.name: struct(
package_db = info.value.empty_db,
modules = dynamic_values[info.value.dynamic[arg.enable_profiling]].providers[DynamicCompileResultInfo].modules,
)
for info in arg.direct_deps_info
}
def _dynamic_do_compile_impl(actions, md_file, pkg_deps, arg, direct_deps_by_name, outputs):
common_args = _common_compile_module_args(
actions,
compiler_flags = arg.compiler_flags,
Expand All @@ -737,7 +733,7 @@ def _dynamic_do_compile_impl(actions, artifacts, dynamic_values, outputs, arg):
haskell_toolchain = arg.haskell_toolchain,
label = arg.label,
main = arg.main,
resolved = dynamic_values,
pkg_deps = pkg_deps,
sources = arg.sources,
enable_haddock = arg.enable_haddock,
enable_profiling = arg.enable_profiling,
Expand All @@ -746,7 +742,7 @@ def _dynamic_do_compile_impl(actions, artifacts, dynamic_values, outputs, arg):
pkgname = arg.pkgname,
)

md = artifacts[arg.md_file].read_json()
md = md_file.read_json()
th_modules = md["th_modules"]
module_map = md["module_mapping"]
graph = md["module_graph"]
Expand Down Expand Up @@ -785,7 +781,16 @@ def _dynamic_do_compile_impl(actions, artifacts, dynamic_values, outputs, arg):



_dynamic_do_compile = dynamic_actions(impl = _dynamic_do_compile_impl)
_dynamic_do_compile = dynamic_actions(
impl = _dynamic_do_compile_impl,
attrs = {
"md_file" : dynattrs.artifact_value(),
"arg" : dynattrs.value(typing.Any),
"pkg_deps": dynattrs.option(dynattrs.dynamic_value()),
"outputs": dynattrs.dict(Artifact, dynattrs.output()),
"direct_deps_by_name": dynattrs.dict(str, dynattrs.tuple(dynattrs.value(Artifact), dynattrs.dynamic_value())),
},
)

# Compile all the context's sources.
def compile(
Expand Down Expand Up @@ -822,17 +827,13 @@ def compile(
]

dyn_module_tsets = ctx.actions.dynamic_output_new(_dynamic_do_compile(
dynamic = [md_file],
dynamic_values = [
info.value.dynamic[enable_profiling]
for lib in attr_deps_haskell_link_infos(ctx)
for info in [
lib.prof_info[link_style]
if enable_profiling else
lib.info[link_style]
]
] + ([ haskell_toolchain.packages.dynamic ] if haskell_toolchain.packages else [ ]),
outputs = [o.as_output() for o in interfaces + objects + stub_dirs + abi_hashes],
md_file = md_file,
pkg_deps = haskell_toolchain.packages.dynamic if haskell_toolchain.packages else None,
outputs = {o: o.as_output() for o in interfaces + objects + stub_dirs + abi_hashes},
direct_deps_by_name = {
info.value.name: (info.value.empty_db, info.value.dynamic[enable_profiling])
for info in direct_deps_info
},
arg = struct(
artifact_suffix = artifact_suffix,
compiler_flags = ctx.attrs.compiler_flags,
Expand Down
49 changes: 34 additions & 15 deletions haskell/haskell.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ def haskell_prebuilt_library_impl(ctx: AnalysisContext) -> list[Provider]:
hlibinfo = HaskellLibraryInfo(
name = ctx.attrs.name,
db = ctx.attrs.db,
empty_db = None,
deps_db = None,
objects = {},
dependencies = [],
import_dirs = {},
stub_dirs = [],
id = ctx.attrs.id,
Expand All @@ -255,6 +259,10 @@ def haskell_prebuilt_library_impl(ctx: AnalysisContext) -> list[Provider]:
prof_hlibinfo = HaskellLibraryInfo(
name = ctx.attrs.name,
db = ctx.attrs.db,
empty_db = None,
deps_db = None,
objects = {},
dependencies = [],
import_dirs = {},
stub_dirs = [],
id = ctx.attrs.id,
Expand Down Expand Up @@ -549,8 +557,7 @@ def _get_haskell_shared_library_name_linker_flags(
else:
fail("Unknown linker type '{}'.".format(linker_type))

def _dynamic_link_shared_impl(actions, artifacts, dynamic_values, outputs, arg):
pkg_deps = dynamic_values[arg.haskell_toolchain.packages.dynamic]
def _dynamic_link_shared_impl(actions, pkg_deps, lib, arg):
package_db = pkg_deps.providers[DynamicHaskellPackageDbInfo].packages

package_db_tset = actions.tset(
Expand Down Expand Up @@ -591,7 +598,7 @@ def _dynamic_link_shared_impl(actions, artifacts, dynamic_values, outputs, arg):
link_cmd_args.append(link_args)

link_cmd = cmd_args(link_cmd_args, hidden = link_cmd_hidden)
link_cmd.add("-o", outputs[arg.lib].as_output())
link_cmd.add("-o", lib)

actions.run(
link_cmd,
Expand All @@ -600,7 +607,14 @@ def _dynamic_link_shared_impl(actions, artifacts, dynamic_values, outputs, arg):

return []

_dynamic_link_shared = dynamic_actions(impl = _dynamic_link_shared_impl)
_dynamic_link_shared = dynamic_actions(
impl = _dynamic_link_shared_impl,
attrs = {
"arg": dynattrs.value(typing.Any),
"lib": dynattrs.output(),
"pkg_deps": dynattrs.dynamic_value(),
},
)

def _build_haskell_lib(
ctx,
Expand Down Expand Up @@ -664,9 +678,8 @@ def _build_haskell_lib(
)

ctx.actions.dynamic_output_new(_dynamic_link_shared(
dynamic = [],
dynamic_values = [haskell_toolchain.packages.dynamic],
outputs = [lib.as_output()],
pkg_deps = haskell_toolchain.packages.dynamic,
lib = lib.as_output(),
arg = struct(
artifact_suffix = artifact_suffix,
haskell_toolchain = haskell_toolchain,
Expand Down Expand Up @@ -979,6 +992,7 @@ def haskell_library_impl(ctx: AnalysisContext) -> list[Provider]:
cmd_args(
haskell_toolchain.haddock,
"--gen-index",
"--optghc=-package-env=-",
"-o", cmd_args(styles[0].as_output(), parent=1),
hidden=[file.as_output() for file in styles]
),
Expand Down Expand Up @@ -1124,7 +1138,7 @@ def _make_link_package(

return db

def _dynamic_link_binary_impl(actions, artifacts, dynamic_values, outputs, arg):
def _dynamic_link_binary_impl(actions, pkg_deps, output, arg):
link_cmd = arg.link.copy() # link is already frozen, make a copy

# Add -package-db and -package/-expose-package flags for each Haskell
Expand All @@ -1136,7 +1150,7 @@ def _dynamic_link_binary_impl(actions, artifacts, dynamic_values, outputs, arg):
haskell_toolchain = arg.haskell_toolchain,
haskell_direct_deps_lib_infos = arg.haskell_direct_deps_lib_infos,
link_style = arg.link_style,
resolved = dynamic_values,
pkg_deps = pkg_deps,
specify_pkg_version = False,
enable_profiling = arg.enable_profiling,
use_empty_lib = False,
Expand All @@ -1149,13 +1163,20 @@ def _dynamic_link_binary_impl(actions, artifacts, dynamic_values, outputs, arg):
link_cmd.add(arg.haskell_toolchain.linker_flags)
link_cmd.add(arg.linker_flags)

link_cmd.add("-o", outputs[arg.output].as_output())
link_cmd.add("-o", output)

actions.run(link_cmd, category = "haskell_link")

return []

_dynamic_link_binary = dynamic_actions(impl = _dynamic_link_binary_impl)
_dynamic_link_binary = dynamic_actions(
impl = _dynamic_link_binary_impl,
attrs = {
"arg": dynattrs.value(typing.Any),
"pkg_deps": dynattrs.option(dynattrs.dynamic_value()),
"output": dynattrs.output(),
},
)

def haskell_binary_impl(ctx: AnalysisContext) -> list[Provider]:
enable_profiling = ctx.attrs.enable_profiling
Expand Down Expand Up @@ -1377,9 +1398,8 @@ def haskell_binary_impl(ctx: AnalysisContext) -> list[Provider]:
)

ctx.actions.dynamic_output_new(_dynamic_link_binary(
dynamic = [],
dynamic_values = [haskell_toolchain.packages.dynamic] if haskell_toolchain.packages else [ ],
outputs = [output.as_output()],
pkg_deps = haskell_toolchain.packages.dynamic if haskell_toolchain.packages else None,
output = output.as_output(),
arg = struct(
deps = ctx.attrs.deps,
direct_deps_link_info = attr_deps_haskell_link_infos(ctx),
Expand All @@ -1389,7 +1409,6 @@ def haskell_binary_impl(ctx: AnalysisContext) -> list[Provider]:
link = link,
link_style = link_style,
linker_flags = ctx.attrs.linker_flags,
output = output,
toolchain_libs = toolchain_libs,
),
))
Expand Down
Loading