Skip to content

Commit 9ebc5dd

Browse files
authored
Merge pull request #2098 from tweag/cb/fix-2097
Fix toolchain libraries creation when using `ghcWithPackages`
2 parents 68ee316 + ffc8177 commit 9ebc5dd

File tree

8 files changed

+158
-29
lines changed

8 files changed

+158
-29
lines changed

.bazelrc.common

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ coverage --build_tag_filters "coverage-compatible" --test_tag_filters "coverage-
143143

144144
# To update these lines, execute
145145
# `bazel run @contrib_rules_bazel_integration_test//tools:update_deleted_packages`
146-
build --deleted_packages=examples,examples/arm,examples/basic_modules,examples/cat_hs,examples/cat_hs/exec/cat_hs,examples/cat_hs/lib/args,examples/cat_hs/lib/cat,examples/primitive,examples/rts,examples/transformers,examples/vector,tests/c2hs/repo,tests/haskell_module/repl/haskell_module_repl_cross_library_deps_test/package-a,tests/haskell_module/repl/haskell_module_repl_cross_library_deps_test/package-b,tests/haskell_module/repl/haskell_module_repl_test,tests/library-external-workspace/repo,tests/recompilation/recompilation_workspace,tests/repl-targets/hs_bin_repl_test,tests/repl-targets/hs_lib_repl_test,tests/stack-snapshot-deps/hs_override_stack_test,tutorial,tutorial/lib,tutorial/main,tutorial/tools/build_rules
147-
query --deleted_packages=examples,examples/arm,examples/basic_modules,examples/cat_hs,examples/cat_hs/exec/cat_hs,examples/cat_hs/lib/args,examples/cat_hs/lib/cat,examples/primitive,examples/rts,examples/transformers,examples/vector,tests/c2hs/repo,tests/haskell_module/repl/haskell_module_repl_cross_library_deps_test/package-a,tests/haskell_module/repl/haskell_module_repl_cross_library_deps_test/package-b,tests/haskell_module/repl/haskell_module_repl_test,tests/library-external-workspace/repo,tests/recompilation/recompilation_workspace,tests/repl-targets/hs_bin_repl_test,tests/repl-targets/hs_lib_repl_test,tests/stack-snapshot-deps/hs_override_stack_test,tutorial,tutorial/lib,tutorial/main,tutorial/tools/build_rules
146+
build --deleted_packages=examples,examples/arm,examples/basic_modules,examples/cat_hs,examples/cat_hs/exec/cat_hs,examples/cat_hs/lib/args,examples/cat_hs/lib/cat,examples/primitive,examples/rts,examples/transformers,examples/vector,tests/c2hs/repo,tests/haskell_module/repl/haskell_module_repl_cross_library_deps_test/package-a,tests/haskell_module/repl/haskell_module_repl_cross_library_deps_test/package-b,tests/haskell_module/repl/haskell_module_repl_test,tests/library-external-workspace/repo,tests/recompilation/recompilation_workspace,tests/repl-targets/hs_bin_repl_test,tests/repl-targets/hs_lib_repl_test,tests/stack-snapshot-deps/hs_override_stack_test,tutorial,tutorial/lib,tutorial/main,tutorial/tools/build_rules,tests/ghcWithPackages_2097/test
147+
query --deleted_packages=examples,examples/arm,examples/basic_modules,examples/cat_hs,examples/cat_hs/exec/cat_hs,examples/cat_hs/lib/args,examples/cat_hs/lib/cat,examples/primitive,examples/rts,examples/transformers,examples/vector,tests/c2hs/repo,tests/haskell_module/repl/haskell_module_repl_cross_library_deps_test/package-a,tests/haskell_module/repl/haskell_module_repl_cross_library_deps_test/package-b,tests/haskell_module/repl/haskell_module_repl_test,tests/library-external-workspace/repo,tests/recompilation/recompilation_workspace,tests/repl-targets/hs_bin_repl_test,tests/repl-targets/hs_lib_repl_test,tests/stack-snapshot-deps/hs_override_stack_test,tutorial,tutorial/lib,tutorial/main,tutorial/tools/build_rules,tests/ghcWithPackages_2097/test
148148

149149
# Needed to build @rules_jvm_external//private/tools/java/com/github/bazelbuild/rules_jvm_external/zip (used by //tests/java_classpath)
150150
build:macos-nixpkgs --tool_java_language_version=11

haskell/private/pkgdb_to_bzl.py

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,13 @@
1515
import textwrap
1616
import types
1717
import json
18+
from pathlib import Path
1819

1920
import package_configuration
2021

22+
def match_glob(root_dir, pattern):
23+
return sorted([p.relative_to(root_dir).as_posix() for p in Path(root_dir).glob(pattern)])
24+
2125
if len(sys.argv) == 3:
2226
repo_dir = "external/" + sys.argv[1]
2327
topdir = sys.argv[2]
@@ -46,7 +50,9 @@ def resolve(path, pkgroot):
4650
else:
4751
return path
4852

49-
def path_to_label(path, pkgroot):
53+
symlinks = {}
54+
55+
def path_to_label(path, pkgroot, output=None):
5056
"""Substitute one pkgroot for another relative one to obtain a label."""
5157
if path.find("${pkgroot}") != -1:
5258
# determine if the given path is inside the repository root
@@ -58,9 +64,21 @@ def path_to_label(path, pkgroot):
5864
return None if relative_path.startswith('..') else relative_path.replace('\\', '/')
5965

6066
topdir_relative_path = path.replace(os.path.realpath(pkgroot), "$topdir")
61-
if topdir_relative_path.find("$topdir") != -1:
67+
if topdir_relative_path.startswith("$topdir"):
6268
return os.path.normpath(topdir_relative_path.replace("$topdir", topdir)).replace('\\', '/')
6369

70+
if not output is None:
71+
if os.path.isabs(path) and os.path.exists(path):
72+
global symlinks
73+
lnk = symlinks.get(path)
74+
if not lnk:
75+
lnk = "lnk_{}".format(len(symlinks))
76+
symlinks[path] = lnk
77+
output.append("#SYMLINK: {} {}".format(path.replace('\\', '/'), lnk))
78+
return lnk
79+
else:
80+
print("WARN: could not handle", path, file=sys.stderr)
81+
6482
def hs_library_pattern(name, mode = "static", profiling = False):
6583
"""Convert hs-libraries entry to glob patterns.
6684
@@ -108,16 +126,15 @@ def hs_library_pattern(name, mode = "static", profiling = False):
108126
# Accumulate package id to package name mappings.
109127
pkg_id_map = []
110128

111-
# pkgroot is not part of .conf files. It's a computed value. It is
112-
# defined to be the directory enclosing the package database
113-
# directory.
114-
pkgroot = os.path.dirname(package_conf_dir)
115-
116-
117129
for conf in glob.glob(os.path.join(package_conf_dir, '*.conf')):
118130
with open(conf, 'r') as f:
119131
pkg = package_configuration.parse_package_configuration(f)
120132

133+
# pkgroot is not part of .conf files. It's a computed value. It is
134+
# defined to be the directory enclosing the package database
135+
# directory.
136+
pkgroot = os.path.dirname(os.path.dirname(conf))
137+
121138
pkg_id_map.append((pkg.name, pkg.id))
122139

123140
# Haddock handling
@@ -201,37 +218,36 @@ def hs_library_pattern(name, mode = "static", profiling = False):
201218
name = pkg.name,
202219
id = pkg.id,
203220
version = pkg.version,
204-
hdrs = "glob({}, allow_empty = True)".format([
205-
path_to_label("{}/**/*.h".format(include_dir), pkgroot)
221+
hdrs = [
222+
"/".join([path_to_label(include_dir, pkgroot, output), header])
206223
for include_dir in pkg.include_dirs
207-
if path_to_label(include_dir, pkgroot)
208-
]),
224+
for header in match_glob(resolve(include_dir, pkgroot), "**/*.h")
225+
],
209226
includes = [
210-
"/".join([repo_dir, path_to_label(include_dir, pkgroot)])
227+
"/".join([repo_dir, path_to_label(include_dir, pkgroot, output)])
211228
for include_dir in pkg.include_dirs
212-
if path_to_label(include_dir, pkgroot)
213229
],
214-
static_libraries = "glob({}, allow_empty = True)".format([
215-
path_to_label("{}/{}".format(library_dir, pattern), pkgroot)
230+
static_libraries = [
231+
"/".join([path_to_label(library_dir, pkgroot, output), library])
216232
for hs_library in pkg.hs_libraries
217233
for pattern in hs_library_pattern(hs_library, mode = "static", profiling = False)
218234
for library_dir in pkg.library_dirs
219-
if path_to_label(library_dir, pkgroot)
220-
]),
221-
static_profiling_libraries = "glob({}, allow_empty = True)".format([
222-
path_to_label("{}/{}".format(library_dir, pattern), pkgroot)
235+
for library in match_glob(resolve(library_dir, pkgroot), pattern)
236+
],
237+
static_profiling_libraries = [
238+
"/".join([path_to_label(library_dir, pkgroot, output), library])
223239
for hs_library in pkg.hs_libraries
224240
for pattern in hs_library_pattern(hs_library, mode = "static", profiling = True)
225241
for library_dir in pkg.library_dirs
226-
if path_to_label(library_dir, pkgroot)
227-
]),
228-
shared_libraries = "glob({}, allow_empty = True)".format([
229-
path_to_label("{}/{}".format(dynamic_library_dir, pattern), pkgroot)
242+
for library in match_glob(resolve(library_dir, pkgroot), pattern)
243+
],
244+
shared_libraries = [
245+
"/".join([path_to_label(dynamic_library_dir, pkgroot, output), library])
230246
for hs_library in pkg.hs_libraries
231247
for pattern in hs_library_pattern(hs_library, mode = "dynamic", profiling = False)
232-
for dynamic_library_dir in pkg.dynamic_library_dirs + pkg.library_dirs
233-
if path_to_label(dynamic_library_dir, pkgroot)
234-
]),
248+
for dynamic_library_dir in set(pkg.dynamic_library_dirs + pkg.library_dirs)
249+
for library in match_glob(resolve(dynamic_library_dir, pkgroot), pattern)
250+
],
235251
haddock_html = repr(haddock_html),
236252
haddock_interfaces = repr(haddock_interfaces),
237253
deps = pkg.depends,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
load("//tests/integration_testing:rules_haskell_integration_test.bzl", "rules_haskell_integration_test")
2+
3+
rules_haskell_integration_test(
4+
name = "ghc_with_packages_test",
5+
srcs = ["Test.hs"],
6+
workspace_path = "test",
7+
)
8+
9+
filegroup(
10+
name = "all_files",
11+
testonly = True,
12+
srcs = glob(["**"]),
13+
visibility = ["//visibility:public"],
14+
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{-# OPTIONS -Wall #-}
2+
3+
import Test.Hspec (hspec, it)
4+
import IntegrationTesting
5+
6+
main :: IO ()
7+
main = hspec $ do
8+
it "bazel run ghcWithPackages" $ do
9+
bazel <- setupTestBazel
10+
assertSuccess (bazel ["run", "//:add-one"])
11+
-- assertSuccess (bazel ["cquery", "--output", "build", "@rules_haskell_ghc_nixpkgs_haskell_toolchain//:rts"])
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
load("@rules_cc//cc:defs.bzl", "cc_test")
2+
load(
3+
"@rules_haskell//haskell:defs.bzl",
4+
"haskell_library",
5+
"haskell_toolchain_library",
6+
)
7+
8+
haskell_toolchain_library(name = "base")
9+
10+
haskell_toolchain_library(name = "rts")
11+
12+
haskell_library(
13+
name = "add-one-hs",
14+
srcs = ["One.hs"],
15+
deps = [":base"],
16+
)
17+
18+
cc_test(
19+
name = "add-one",
20+
srcs = [
21+
"main.c",
22+
],
23+
visibility = ["//visibility:public"],
24+
deps = [
25+
":add-one-hs",
26+
":rts",
27+
],
28+
)
29+
30+
filegroup(
31+
name = "all_files",
32+
testonly = True,
33+
srcs = glob(["**"]),
34+
visibility = ["//visibility:public"],
35+
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module One () where
2+
3+
add_one_hs :: Int -> Int
4+
add_one_hs x = x + 1
5+
6+
foreign export ccall add_one_hs :: Int -> Int
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
local_repository(
2+
name = "rules_haskell",
3+
path = "%RULES_HASKELL_PATH%",
4+
)
5+
6+
load("@rules_haskell//haskell:repositories.bzl", "rules_haskell_dependencies")
7+
8+
rules_haskell_dependencies()
9+
10+
load("@rules_haskell//haskell:nixpkgs.bzl", "haskell_register_ghc_nixpkgs")
11+
12+
haskell_register_ghc_nixpkgs(
13+
attribute_path = "",
14+
nix_file_content = "with import <nixpkgs> {}; haskell.packages.ghc948.ghcWithPackages (p:[p.async])",
15+
repository = "@rules_haskell//nixpkgs:default.nix",
16+
version = "9.4.8",
17+
)
18+
19+
load("@rules_haskell//haskell:toolchain.bzl", "rules_haskell_toolchains")
20+
21+
rules_haskell_toolchains(version = "9.4.8")
22+
23+
load(
24+
"@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl",
25+
"nixpkgs_cc_configure",
26+
"nixpkgs_python_configure",
27+
)
28+
29+
nixpkgs_cc_configure(
30+
name = "nixpkgs_config_cc",
31+
repository = "@rules_haskell//nixpkgs:default.nix",
32+
)
33+
34+
nixpkgs_python_configure(
35+
repository = "@rules_haskell//nixpkgs:default.nix",
36+
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <stdio.h>
2+
#include "HsFFI.h"
3+
4+
extern HsInt add_one_hs(HsInt a0);
5+
6+
int main(int argc, char *argv[]) {
7+
hs_init(&argc, &argv);
8+
printf("Adding one to 5 through Haskell is %lld\n", add_one_hs(5));
9+
hs_exit();
10+
return 0;
11+
}

0 commit comments

Comments
 (0)