Skip to content
This repository has been archived by the owner on Jun 18, 2019. It is now read-only.

Commit

Permalink
Stop manually generating Cabal macros.
Browse files Browse the repository at this point in the history
It turns out they're generated automatically by GHC since version 8.0,
as long as we pass the right package name and version.  That's now possible
as of tweag/rules_haskell#246.

I'll hold off merging this PR until that one goes in, then I'll rebase to
`rules_haskell` master.
  • Loading branch information
judah committed May 15, 2018
1 parent c816cde commit baaedf6
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 152 deletions.
5 changes: 3 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ jobs:
command: bazel test //...
- run:
name: Test some package repositories
command: bazel build --jobs=2 \
@haskell_{aeson,language-c,lens,network}//...
command: |
bazel build --jobs=2 \
@haskell_{aeson,language-c,lens,network}//...
2 changes: 1 addition & 1 deletion WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ nixpkgs_git_repository(
revision = "c33c5239f62b4855b14dc5b01dfa3e2a885cf9ca",
)

RULES_HASKELL_SHA = "2f176d0b7e81371259f39993d7b96bb4711abb3b"
RULES_HASKELL_SHA = "fb6b7c4383d8de7092adab3a6e9ba0d4bcc2c190"
http_archive(
name = "io_tweag_rules_haskell",
urls = ["https://github.com/tweag/rules_haskell/archive/"
Expand Down
2 changes: 1 addition & 1 deletion hazel.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,4 @@ def hazel_repositories(prebuilt_dependencies, packages):

def hazel_library(name):
"""Returns the label of the haskell_library rule for the given package."""
return "@haskell_{}//:{}-lib".format(name,name)
return "@haskell_{}//:{}".format(name,name)
19 changes: 5 additions & 14 deletions hazel_base_repository/hazel_base_repository.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ def _hazel_base_repository_impl(ctx):
"@ai_formation_hazel//third_party/cabal2bazel:src/Google/Google3/Tools/Cabal2Build/Description.hs",
]

generate_cabal_macros_srcs = [
"@ai_formation_hazel//third_party/cabal2bazel:bzl/cabal/GenerateCabalMacros.hs",
]

for f in cabal2bazel_srcs + generate_cabal_macros_srcs:
for f in cabal2bazel_srcs:
l = Label(f)
ctx.symlink(Label(f), l.name)

Expand All @@ -21,11 +17,6 @@ def _hazel_base_repository_impl(ctx):
if res.return_code != 0:
fail("Couldn't build cabal2bazel:\n{}\n{}".format(res.stdout,res.stderr))

res = ctx.execute(["./ghc", "-Wall", "-Werror", "--make", "-o", "generate-cabal-macros"]
+ [Label(f).name for f in generate_cabal_macros_srcs])
if res.return_code != 0:
fail("Couldn't build generate-cabal-macros:\n{}\n{}".format(res.stdout,res.stderr))

res = ctx.execute(["./ghc", "--numeric-version"])
if res.return_code != 0:
fail("Couldn't get GHC version:\n{}\n{}".format(res.stdout,res.stderr))
Expand All @@ -42,7 +33,7 @@ packages = {}

ctx.file(
"BUILD",
content="""exports_files(["cabal2bazel", "generate-cabal-macros", "ghc-version"])""",
content="""exports_files(["cabal2bazel", "ghc-version"])""",
executable=False)

hazel_base_repository = repository_rule(
Expand All @@ -55,7 +46,7 @@ hazel_base_repository = repository_rule(

# TODO: don't reload all package names into every repository.
def symlink_and_invoke_hazel(ctx, hazel_base_repo_name, cabal_path, output):
for f in ["cabal2bazel", "ghc-version", "generate-cabal-macros"]:
for f in ["cabal2bazel", "ghc-version"]:
ctx.symlink(Label("@" + hazel_base_repo_name + "//:" + f), f)

ghc_version = ctx.execute(["cat", "ghc-version"]).stdout
Expand All @@ -70,13 +61,13 @@ def symlink_and_invoke_hazel(ctx, hazel_base_repo_name, cabal_path, output):
load("@ai_formation_hazel//third_party/cabal2bazel:bzl/cabal_package.bzl",
"cabal_haskell_package",
"hazel_symlink")
load("@hazel_base_repository//:packages.bzl", "prebuilt_dependencies", "packages")
load("@hazel_base_repository//:packages.bzl", "prebuilt_dependencies")
load("//:package.bzl", "package")
# Make a buildable target for easier debugging of the package.bzl file
hazel_symlink(
name = "bzl",
src = "package.bzl",
out = "package-bzl",
)
cabal_haskell_package(package, prebuilt_dependencies, packages)
cabal_haskell_package(package, prebuilt_dependencies)
""")
62 changes: 0 additions & 62 deletions third_party/cabal2bazel/bzl/cabal/GenerateCabalMacros.hs

This file was deleted.

83 changes: 11 additions & 72 deletions third_party/cabal2bazel/bzl/cabal_package.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -28,48 +28,6 @@ load("//templates:templates.bzl", "templates")

_conditions_default = "//conditions:default"

# Cabal macro generation target name ends with this.
_macros_suffix = "-macros"

# The _cabal_haskell_macros rule generates a file containing Cabal
# MIN_VERSION_* macros of all of the specified dependencies, as well as some
# other Cabal macros.
# For more details, see //bzl/cabal/GenerateCabalMacros.hs.
# Args:
# deps: A list of cabal_haskell_library rules.
# default_packages: A list of names of default packages that
# this package depends on; e.g., "base".
def _impl_cabal_haskell_macros(ctx):
if not ctx.label.name.endswith(_macros_suffix):
fail("Macros target ends with unexpected suffix.")
ctx.action(
outputs=[ctx.outputs.out],
inputs=[ctx.executable._generate_cabal_macros],
progress_message="Generating Haskell Cabal macros for %s" % str(ctx.label),
mnemonic="HaskellGenerateCabalMacros",
command=(
" ".join(
[ctx.executable._generate_cabal_macros.path]
+ ["{}-{}".format(p, ctx.attr.packages[p])
for p in ctx.attr.packages])
+ " > " + ctx.outputs.out.path),
)

_cabal_haskell_macros = rule(
implementation=_impl_cabal_haskell_macros,
attrs={
"packages": attr.string_dict(mandatory=True),
"_generate_cabal_macros": attr.label(
executable=True,
cfg="host",
allow_files=True,
single_file=True,
default=Label("@hazel_base_repository//:generate-cabal-macros")
),
},
outputs={"out": "%{name}.h"},
)

def _paths_module(desc):
return "Paths_" + desc.package.pkgName.replace("-","_")

Expand Down Expand Up @@ -118,7 +76,7 @@ def _fix_source_dirs(dirs):
return [""]

def _get_build_attrs(name, build_info, desc, generated_srcs_dir, extra_modules,
prebuilt_dependencies, packages,
prebuilt_dependencies,
cc_deps=[], version_overrides=None, ghcopts=[]):
"""Get the attributes for a particular library or binary rule.
Expand Down Expand Up @@ -227,32 +185,17 @@ def _get_build_attrs(name, build_info, desc, generated_srcs_dir, extra_modules,

# Collect the dependencies.
prebuilt_deps = []
dep_versions = {}
for condition, ps in _conditions_dict(depset(build_info.targetBuildDepends).to_list()).items():
if condition not in deps:
deps[condition] = []
for p in ps:
if p.name in prebuilt_dependencies:
dep_versions[p.name] = prebuilt_dependencies[p.name]
prebuilt_deps += [p.name]
elif p.name == desc.package.pkgName:
# Allow executables to depend on the library in the same package.
deps[condition] += [":" + p.name + "-lib"]
else:
deps[condition] += ["@haskell_{}//:{}-lib".format(p.name, p.name)]
dep_versions[p.name] = packages[p.name]


# Generate the macros for these dependencies.
# TODO: Maybe remove the MIN_VERSION_<package> macro generation,
# since GHC 8 itself (not Cabal) generates these. But not the
# CURRENT_PACKAGE_KEY macro?
# See https://ghc.haskell.org/trac/ghc/ticket/10970.
_cabal_haskell_macros(
name = name + _macros_suffix,
packages = dep_versions,
)
ghcopts += ["-optP-include", "-optP%s.h" % (name + _macros_suffix)]
deps[condition] += ["@haskell_{}//:{}".format(p.name, p.name)]

ghcopts += ["-optP" + o for o in build_info.cppOptions]

Expand All @@ -265,8 +208,7 @@ def _get_build_attrs(name, build_info, desc, generated_srcs_dir, extra_modules,
for f in build_info.installIncludes])
headers = depset(
native.glob(desc.extraSrcFiles)
+ install_includes
+ [":{}.h".format(name + _macros_suffix)])
+ install_includes)
ghcopts += ["-I" + native.package_name() + "/" + d for d in build_info.includeDirs]
lib_name = name + "-cbits"
for xs in deps.values():
Expand Down Expand Up @@ -305,14 +247,13 @@ def _collect_data_files(description):
else:
return native.glob([paths.join(description.dataDir, d) for d in description.dataFiles])

def cabal_haskell_package(description, prebuilt_dependencies, packages):
def cabal_haskell_package(description, prebuilt_dependencies):
"""Create rules for building a Cabal package.
Args: +def cabal_haskell_package(description, prebuilt_dependencies, packages):
Args:
description: A Skylark struct generated by cabal2build representing a
.cabal file's contents.
prebuilt_dependencies: A dict of the builtin GHC packages.
packages: A dict of the non-builtin packages.
"""
name = description.package.pkgName

Expand All @@ -326,23 +267,22 @@ def cabal_haskell_package(description, prebuilt_dependencies, packages):

lib = description.library
if lib and lib.libBuildInfo.buildable:
lib_name = name + "-lib"
if not lib.exposedModules:
native.cc_library(
name = lib_name,
name = name,
visibility = ["//visibility:public"],
)
else:
lib_attrs = _get_build_attrs(name + "-lib", lib.libBuildInfo, description,
lib_attrs = _get_build_attrs(name, lib.libBuildInfo, description,
"dist/build",
lib.exposedModules,
prebuilt_dependencies,
packages)
prebuilt_dependencies)
srcs = lib_attrs.pop("srcs")
deps = lib_attrs.pop("deps")
haskell_library(
name = lib_name,
name = name,
srcs = select(srcs),
version = description.package.pkgVersion,
deps = select(deps),
visibility = ["//visibility:public"],
**lib_attrs
Expand All @@ -363,8 +303,7 @@ def cabal_haskell_package(description, prebuilt_dependencies, packages):
# Paths_ module explicitly.
[paths_mod] if paths_mod not in exe.buildInfo.otherModules
else [],
prebuilt_dependencies,
packages)
prebuilt_dependencies)
srcs = attrs.pop("srcs")
deps = attrs.pop("deps")

Expand Down

0 comments on commit baaedf6

Please sign in to comment.