Skip to content

Commit 7a79c89

Browse files
authored
Merge pull request facebook#19 from MercuryTechnologies/avoid-library-catalog
Remove toolchain library catalog
2 parents af8ba19 + f967596 commit 7a79c89

File tree

6 files changed

+41
-218
lines changed

6 files changed

+41
-218
lines changed

decls/haskell_common.bzl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,6 @@ def _scripts_arg():
4949
providers = [RunInfo],
5050
default = "prelude//haskell/tools:generate_target_metadata",
5151
),
52-
"_generate_toolchain_library_catalog": attrs.dep(
53-
providers = [RunInfo],
54-
default = "prelude//haskell/tools:generate_toolchain_library_catalog",
55-
),
5652
"_ghc_wrapper": attrs.dep(
5753
providers = [RunInfo],
5854
default = "prelude//haskell/tools:ghc_wrapper",

haskell/compile.bzl

Lines changed: 23 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ load(
2727
"attr_deps",
2828
"attr_deps_haskell_lib_infos",
2929
"attr_deps_haskell_link_infos",
30+
"attr_deps_haskell_toolchain_libraries",
3031
"get_artifact_suffix",
3132
"is_haskell_src",
3233
"output_extensions",
@@ -178,38 +179,6 @@ def _modules_by_name(ctx: AnalysisContext, *, sources: list[Artifact], link_styl
178179

179180
return modules
180181

181-
def _toolchain_library_catalog_impl(ctx: AnalysisContext) -> list[Provider]:
182-
haskell_toolchain = ctx.attrs.toolchain[HaskellToolchainInfo]
183-
184-
ghc_pkg = haskell_toolchain.packager
185-
186-
catalog_gen = ctx.attrs.generate_toolchain_library_catalog[RunInfo]
187-
catalog = ctx.actions.declare_output("haskell_toolchain_libraries.json")
188-
189-
cmd = cmd_args(catalog_gen, "--ghc-pkg", ghc_pkg, "--output", catalog.as_output())
190-
191-
if haskell_toolchain.packages:
192-
cmd.add("--package-db", haskell_toolchain.packages.package_db)
193-
194-
ctx.actions.run(cmd, category = "haskell_toolchain_library_catalog")
195-
196-
return [DefaultInfo(default_output = catalog)]
197-
198-
_toolchain_library_catalog = anon_rule(
199-
impl = _toolchain_library_catalog_impl,
200-
attrs = {
201-
"toolchain": attrs.dep(
202-
providers = [HaskellToolchainInfo],
203-
),
204-
"generate_toolchain_library_catalog": attrs.dep(
205-
providers = [RunInfo],
206-
),
207-
},
208-
artifact_promise_mappings = {
209-
"catalog": lambda x: x[DefaultInfo].default_outputs[0],
210-
}
211-
)
212-
213182
def target_metadata(
214183
ctx: AnalysisContext,
215184
*,
@@ -226,11 +195,6 @@ def target_metadata(
226195
if HaskellToolchainLibrary in dep
227196
]
228197

229-
toolchain_libs_catalog = ctx.actions.anon_target(_toolchain_library_catalog, {
230-
"toolchain": ctx.attrs._haskell_toolchain,
231-
"generate_toolchain_library_catalog": ctx.attrs._generate_toolchain_library_catalog,
232-
})
233-
234198
# The object and interface file paths are depending on the real module name
235199
# as inferred by GHC, not the source file path; currently this requires the
236200
# module name to correspond to the source file path as otherwise GHC will
@@ -239,9 +203,7 @@ def target_metadata(
239203
#
240204
# (module X.Y.Z must be defined in a file at X/Y/Z.hs)
241205

242-
catalog = toolchain_libs_catalog.artifact("catalog")
243-
244-
def get_metadata(ctx, _artifacts, resolved, outputs, catalog=catalog):
206+
def get_metadata(ctx, _artifacts, resolved, outputs):
245207

246208
# Add -package-db and -package/-expose-package flags for each Haskell
247209
# library dependency.
@@ -266,7 +228,6 @@ def target_metadata(
266228

267229
md_args = cmd_args(md_gen)
268230
md_args.add(packages_info.bin_paths)
269-
md_args.add("--toolchain-libs", catalog)
270231
md_args.add("--ghc", haskell_toolchain.compiler)
271232
md_args.add(cmd_args(ghc_args, format="--ghc-arg={}"))
272233
md_args.add(
@@ -531,10 +492,10 @@ def _compile_module(
531492
md_file: Artifact,
532493
graph: dict[str, list[str]],
533494
package_deps: dict[str, list[str]],
534-
toolchain_deps: list[str],
535495
outputs: dict[Artifact, Artifact],
536496
artifact_suffix: str,
537497
direct_deps_by_name: dict[str, typing.Any],
498+
toolchain_deps_by_name: dict[str, None],
538499
) -> CompiledModuleTSet:
539500
compile_cmd = cmd_args(common_args.command)
540501
# These compiler arguments can be passed in a response file.
@@ -594,12 +555,20 @@ def _compile_module(
594555
)
595556
)
596557

558+
toolchain_deps = []
559+
library_deps = []
597560
exposed_package_modules = []
598561
exposed_package_dbs = []
599562
for dep_pkgname, dep_modules in package_deps.items():
600-
exposed_package_dbs.append(direct_deps_by_name[dep_pkgname].package_db)
601-
for dep_modname in dep_modules:
602-
exposed_package_modules.append(direct_deps_by_name[dep_pkgname].modules[dep_modname])
563+
if dep_pkgname in toolchain_deps_by_name:
564+
toolchain_deps.append(dep_pkgname)
565+
elif dep_pkgname in direct_deps_by_name:
566+
library_deps.append(dep_pkgname)
567+
exposed_package_dbs.append(direct_deps_by_name[dep_pkgname].package_db)
568+
for dep_modname in dep_modules:
569+
exposed_package_modules.append(direct_deps_by_name[dep_pkgname].modules[dep_modname])
570+
else:
571+
fail("Unknown library dependency '{}'. Add the library to the `deps` attribute".format(dep_pkgname))
603572

604573
# Transitive module dependencies from other packages.
605574
cross_package_modules = ctx.actions.tset(
@@ -617,8 +586,8 @@ def _compile_module(
617586
children = [cross_package_modules] + this_package_modules,
618587
)
619588

620-
compile_cmd.add(cmd_args(toolchain_deps, prepend = "-package-id"))
621-
compile_cmd.add(cmd_args(package_deps.keys(), prepend = "-package"))
589+
compile_cmd.add(cmd_args(library_deps, prepend = "-package"))
590+
compile_cmd.add(cmd_args(toolchain_deps, prepend = "-package"))
622591

623592
abi_tag = ctx.actions.artifact_tag()
624593

@@ -628,7 +597,7 @@ def _compile_module(
628597
compile_cmd.hidden(dependency_modules.project_as_args("objects"))
629598
compile_cmd.add(dependency_modules.project_as_args("dyn_objects_dot_o"))
630599
compile_cmd.add(cmd_args(dependency_modules.reduce("package_deps").keys(), prepend = "-package"))
631-
compile_cmd.add(cmd_args(dependency_modules.reduce("toolchain_deps").keys(), prepend = "-package-id"))
600+
compile_cmd.add(cmd_args(dependency_modules.reduce("toolchain_deps").keys(), prepend = "-package"))
632601

633602
compile_cmd.add(cmd_args(dependency_modules.reduce("packagedb_deps").keys(), prepend = "--buck2-package-db"))
634603

@@ -662,7 +631,7 @@ def _compile_module(
662631
interfaces = module.interfaces,
663632
objects = module.objects,
664633
dyn_object_dot_o = dyn_object_dot_o,
665-
package_deps = package_deps.keys(),
634+
package_deps = library_deps,
666635
toolchain_deps = toolchain_deps,
667636
db_deps = exposed_package_dbs,
668637
),
@@ -687,6 +656,10 @@ def compile(
687656
def do_compile(ctx, artifacts, resolved, outputs, md_file=md_file, modules=modules):
688657
# Collect library dependencies. Note that these don't need to be in a
689658
# particular order.
659+
toolchain_deps_by_name = {
660+
lib.name: None
661+
for lib in attr_deps_haskell_toolchain_libraries(ctx)
662+
}
690663
direct_deps_info = [
691664
lib.prof_info[link_style] if enable_profiling else lib.info[link_style]
692665
for lib in attr_deps_haskell_link_infos(ctx)
@@ -713,7 +686,6 @@ def compile(
713686
module_map = md["module_mapping"]
714687
graph = md["module_graph"]
715688
package_deps = md["package_deps"]
716-
toolchain_deps = md["toolchain_deps"]
717689

718690
mapped_modules = { module_map.get(k, k): v for k, v in modules.items() }
719691
module_tsets = {}
@@ -730,11 +702,11 @@ def compile(
730702
module_tsets = module_tsets,
731703
graph = graph,
732704
package_deps = package_deps.get(module_name, {}),
733-
toolchain_deps = toolchain_deps.get(module_name, []),
734705
outputs = outputs,
735706
md_file=md_file,
736707
artifact_suffix = artifact_suffix,
737708
direct_deps_by_name = direct_deps_by_name,
709+
toolchain_deps_by_name = toolchain_deps_by_name,
738710
)
739711

740712
return [DynamicCompileResultInfo(modules = module_tsets)]

haskell/tools/BUCK.v2

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@ prelude.python_bootstrap_binary(
1212
visibility = ["PUBLIC"],
1313
)
1414

15-
prelude.python_bootstrap_binary(
16-
name = "generate_toolchain_library_catalog",
17-
main = "generate_toolchain_library_catalog.py",
18-
visibility = ["PUBLIC"],
19-
)
20-
2115
prelude.python_bootstrap_binary(
2216
name = "ghc_wrapper",
2317
main = "ghc_wrapper.py",

haskell/tools/generate_target_metadata.py

Lines changed: 5 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
* `module_mapping`: Mapping from source inferred module name to actual module name, if different.
1313
* `module_graph`: Intra-package module dependencies, `dict[modname, list[modname]]`.
1414
* `package_deps`": Cross-package module dependencies, `dict[modname, dict[pkgname, list[modname]]`.
15-
* `toolchain_deps`": Toolchain library dependencies, `dict[modname, list[pkgid]]`.
1615
"""
1716

1817
import argparse
@@ -32,11 +31,6 @@ def main():
3231
required=True,
3332
type=argparse.FileType("w"),
3433
help="Write package metadata to this file in JSON format.")
35-
parser.add_argument(
36-
"--toolchain-libs",
37-
required=True,
38-
type=str,
39-
help="Path to the toolchain libraries catalog file.")
4034
parser.add_argument(
4135
"--ghc",
4236
required=True,
@@ -87,21 +81,18 @@ def json_default_handler(o):
8781

8882

8983
def obtain_target_metadata(args):
90-
toolchain_packages = load_toolchain_packages(args.toolchain_libs)
91-
ghc_args = fix_ghc_args(args.ghc_arg, toolchain_packages)
9284
paths = [str(binpath) for binpath in args.bin_path if binpath.is_dir()]
93-
ghc_depends = run_ghc_depends(args.ghc, ghc_args, args.source, paths)
85+
ghc_depends = run_ghc_depends(args.ghc, args.ghc_arg, args.source, paths)
9486
th_modules = determine_th_modules(ghc_depends)
9587
module_mapping = determine_module_mapping(ghc_depends, args.source_prefix)
9688
# TODO(ah) handle .hi-boot dependencies
9789
module_graph = determine_module_graph(ghc_depends)
98-
package_deps, toolchain_deps = determine_package_deps(ghc_depends, toolchain_packages)
90+
package_deps = determine_package_deps(ghc_depends)
9991
return {
10092
"th_modules": th_modules,
10193
"module_mapping": module_mapping,
10294
"module_graph": module_graph,
10395
"package_deps": package_deps,
104-
"toolchain_deps": toolchain_deps,
10596
}
10697

10798

@@ -150,61 +141,15 @@ def determine_module_graph(ghc_depends):
150141
}
151142

152143

153-
def determine_package_deps(ghc_depends, toolchain_packages):
154-
toolchain_by_name = toolchain_packages["by-package-name"]
144+
def determine_package_deps(ghc_depends):
155145
package_deps = {}
156-
toolchain_deps = {}
157146

158147
for modname, description in ghc_depends.items():
159148
for pkgdep in description.get("packages", {}):
160149
pkgname = pkgdep.get("name")
161-
pkgid = pkgdep.get("id")
162-
163-
if pkgname in toolchain_by_name:
164-
if pkgid == toolchain_by_name[pkgname]:
165-
toolchain_deps.setdefault(modname, []).append(pkgid)
166-
elif pkgid == pkgname:
167-
# TODO(ah) why is base's package-id cropped to `base`?
168-
toolchain_deps.setdefault(modname, []).append(toolchain_by_name.get(pkgid, pkgid))
169-
# TODO(ah) is this an error?
170-
else:
171-
package_deps.setdefault(modname, {})[pkgname] = pkgdep.get("modules", [])
172-
173-
return package_deps, toolchain_deps
174-
175-
176-
def fix_ghc_args(ghc_args, toolchain_packages):
177-
"""Replaces -package flags by -package-id where applicable.
150+
package_deps.setdefault(modname, {})[pkgname] = pkgdep.get("modules", [])
178151

179-
Packages that have hidden internal packages cause failures of the form:
180-
181-
Could not load module ‘Data.Attoparsec.Text’.
182-
It is a member of the hidden package ‘attoparsec-0.14.4’.
183-
184-
This can be avoided by specifying the corresponding packages by package-id
185-
rather than package name.
186-
187-
The toolchain libraries catalog tracks a mapping from package name to
188-
package id. We apply it here to any toolchain library dependencies.
189-
"""
190-
result = []
191-
mapping = toolchain_packages["by-package-name"]
192-
193-
args_iter = iter(ghc_args)
194-
for arg in args_iter:
195-
if arg == "-package":
196-
package_name = next(args_iter)
197-
if package_name is None:
198-
raise RuntimeError("Missing package name argument for -package flag")
199-
200-
if (package_id := mapping.get(package_name, None)) is not None:
201-
result.extend(["-package-id", package_id])
202-
else:
203-
result.extend(["-package", package_name])
204-
else:
205-
result.append(arg)
206-
207-
return result
152+
return package_deps
208153

209154

210155
def run_ghc_depends(ghc, ghc_args, sources, aux_paths):

0 commit comments

Comments
 (0)