Skip to content

Commit 1efc991

Browse files
authored
Merge branch 'master' into cg/use_join_jobs
2 parents d14584e + 7c484ed commit 1efc991

File tree

9 files changed

+121
-20
lines changed

9 files changed

+121
-20
lines changed

.github/workflows/workflow.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ jobs:
4848
ghc:
4949
- 9.2.8
5050
- 9.4.6
51+
- 9.6.2
5152
exclude:
5253
- module: rules_haskell_nix
5354

@@ -56,6 +57,8 @@ jobs:
5657
# and stack config per GHC version
5758
- ghc: 9.4.6
5859
bzlmod: true
60+
- ghc: 9.6.2
61+
bzlmod: true
5962
runs-on: ${{ matrix.os }}
6063
steps:
6164
- uses: actions/checkout@v4

haskell/cabal.bzl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,15 @@ def _prepare_cabal_inputs(
289289
]
290290
extra_args = ["--flags=" + " ".join(flags)]
291291

292+
if hs.toolchain.is_darwin:
293+
# assume `otool` and `install_name_tool` are available at the same location as `ar`
294+
ar_bindir = paths.dirname(cc.tools.ar)
295+
296+
extra_args.append("--ghc-option=-pgmotool=" + paths.join(ar_bindir, "otool"))
297+
extra_args.append("--ghc-option=-pgminstall_name_tool=" + paths.join(ar_bindir, "install_name_tool"))
298+
extra_args.append("--haddock-option=--optghc=-pgmotool=" + paths.join(ar_bindir, "otool"))
299+
extra_args.append("--haddock-option=--optghc=-pgminstall_name_tool=" + paths.join(ar_bindir, "install_name_tool"))
300+
292301
ghc_version = [int(x) for x in hs.toolchain.version.split(".")]
293302
if dynamic_file:
294303
# See Note [No PIE when linking] in haskell/private/actions/link.bzl

haskell/experimental/private/module.bzl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,13 @@ def _build_haskell_module(
302302
args.add_all(hs.toolchain.ghcopts)
303303
args.add_all(user_ghcopts)
304304

305+
if hs.toolchain.is_darwin:
306+
# assume `otool` and `install_name_tool` are available at the same location as `ar`
307+
ar_bindir = paths.dirname(cc.tools.ar)
308+
309+
args.add(paths.join(ar_bindir, "otool"), format = "-pgmotool=%s")
310+
args.add(paths.join(ar_bindir, "install_name_tool"), format = "-pgminstall_name_tool=%s")
311+
305312
if plugins and not enable_th:
306313
# For #1681. These suppresses bogus warnings about missing libraries which
307314
# aren't really needed.

haskell/private/actions/compile.bzl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,15 @@ def _compilation_defaults(
124124
compile_flags += hs.toolchain.ghcopts
125125
compile_flags += user_compile_flags
126126

127+
if hs.toolchain.is_darwin:
128+
# assume `otool` and `install_name_tool` are available at the same location as `ar`
129+
ar_bindir = paths.dirname(cc.tools.ar)
130+
131+
compile_flags += [
132+
"-pgmotool=" + paths.join(ar_bindir, "otool"),
133+
"-pgminstall_name_tool=" + paths.join(ar_bindir, "install_name_tool"),
134+
]
135+
127136
package_ids = []
128137
all_plugins = plugins + non_default_plugins
129138
for plugin in all_plugins:

haskell/private/actions/link.bzl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,14 @@ def link_binary(
133133
args.add_all(cc.linker_flags, format_each = "-optl%s")
134134
if with_profiling:
135135
args.add("-prof")
136+
137+
if hs.toolchain.is_darwin:
138+
# assume `otool` and `install_name_tool` are available at the same location as `ar`
139+
ar_bindir = paths.dirname(cc.tools.ar)
140+
141+
args.add(paths.join(ar_bindir, "otool"), format = "-pgmotool=%s")
142+
args.add(paths.join(ar_bindir, "install_name_tool"), format = "-pgminstall_name_tool=%s")
143+
136144
args.add_all(hs.toolchain.ghcopts)
137145
args.add_all(compiler_flags)
138146

@@ -366,6 +374,14 @@ def link_library_dynamic(hs, cc, posix, dep_info, extra_srcs, object_files, my_p
366374
args = hs.actions.args()
367375
args.add_all(cc.linker_flags, format_each = "-optl%s")
368376
args.add_all(["-shared", "-dynamic"])
377+
378+
if hs.toolchain.is_darwin:
379+
# assume `otool` and `install_name_tool` are available at the same location as `ar`
380+
ar_bindir = paths.dirname(cc.tools.ar)
381+
382+
args.add(paths.join(ar_bindir, "otool"), format = "-pgmotool=%s")
383+
args.add(paths.join(ar_bindir, "install_name_tool"), format = "-pgminstall_name_tool=%s")
384+
369385
args.add_all(hs.toolchain.ghcopts)
370386
args.add_all(compiler_flags)
371387

haskell/private/pkgdb_to_bzl.py

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,43 @@
2121
if len(sys.argv) == 3:
2222
repo_dir = "external/" + sys.argv[1]
2323
topdir = sys.argv[2]
24+
25+
if os.path.exists(os.path.join(topdir, 'package.conf.d')):
26+
package_conf_dir = os.path.join(topdir, 'package.conf.d')
27+
elif os.path.exists(os.path.join(topdir, 'lib', 'package.conf.d')):
28+
topdir = os.path.join(topdir, 'lib')
29+
package_conf_dir = os.path.join(topdir, 'package.conf.d')
30+
else:
31+
sys.exit("could not find package.conf.d directory at {}".format(topdir))
32+
repo_root = os.getcwd()
2433
else:
2534
sys.exit("Usage: pkgdb_to_bzl.py <REPO_NAME> <TOPDIR>")
2635

36+
def resolve(path, pkgroot):
37+
"""Resolve references to ${pkgroot} with the given value, resolve $topdir with `topdir`"""
38+
if path.find("${pkgroot}") != -1:
39+
norm_path = os.path.normpath(path.strip("\"").replace("${pkgroot}", pkgroot))
40+
if not os.path.isabs(norm_path) and norm_path.startswith('..'):
41+
return resolve(path, os.path.realpath(pkgroot))
42+
else:
43+
return norm_path
44+
elif path.startswith("$topdir"):
45+
return os.path.normpath(path.replace("$topdir", topdir)).replace('\\', '/')
46+
else:
47+
return path
48+
2749
def path_to_label(path, pkgroot):
2850
"""Substitute one pkgroot for another relative one to obtain a label."""
2951
if path.find("${pkgroot}") != -1:
30-
return os.path.normpath(path.strip("\"").replace("${pkgroot}", topdir)).replace('\\', '/')
52+
# determine if the given path is inside the repository root
53+
# if it is not, return None to signal it needs to be symlinked into the
54+
# repository
55+
norm_path = os.path.normpath(resolve(path, pkgroot))
56+
relative_path = os.path.relpath(norm_path, start=repo_root)
57+
58+
return None if relative_path.startswith('..') else relative_path.replace('\\', '/')
3159

32-
topdir_relative_path = path.replace(pkgroot, "$topdir")
60+
topdir_relative_path = path.replace(os.path.realpath(pkgroot), "$topdir")
3361
if topdir_relative_path.find("$topdir") != -1:
3462
return os.path.normpath(topdir_relative_path.replace("$topdir", topdir)).replace('\\', '/')
3563

@@ -79,15 +107,17 @@ def hs_library_pattern(name, mode = "static", profiling = False):
79107

80108
# Accumulate package id to package name mappings.
81109
pkg_id_map = []
82-
for conf in glob.glob(os.path.join(topdir, "package.conf.d", "*.conf")):
110+
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+
117+
for conf in glob.glob(os.path.join(package_conf_dir, '*.conf')):
83118
with open(conf, 'r') as f:
84119
pkg = package_configuration.parse_package_configuration(f)
85120

86-
# pkgroot is not part of .conf files. It's a computed value. It is
87-
# defined to be the directory enclosing the package database
88-
# directory.
89-
pkgroot = os.path.dirname(os.path.dirname(os.path.realpath(conf)))
90-
91121
pkg_id_map.append((pkg.name, pkg.id))
92122

93123
# Haddock handling
@@ -105,31 +135,45 @@ def hs_library_pattern(name, mode = "static", profiling = False):
105135
haddock_html = None
106136

107137
if pkg.haddock_html:
108-
haddock_html = path_to_label(pkg.haddock_html, pkgroot)
109138
# We check if the file exists because cabal will unconditionally
110139
# generate the database entry even if no haddock was generated.
111-
if not haddock_html and os.path.exists(pkg.haddock_html):
112-
haddock_html = os.path.join("haddock", "html", pkg.name)
113-
output.append("#SYMLINK: {} {}".format(pkg.haddock_html, haddock_html))
140+
resolved_haddock_html = resolve(pkg.haddock_html, pkgroot)
141+
142+
if not os.path.exists(resolved_haddock_html):
143+
# try to resolve relative to the package.conf.d dir
144+
# see https://gitlab.haskell.org/ghc/ghc/-/issues/23476
145+
resolved_haddock_html = resolve(pkg.haddock_html, package_conf_dir)
146+
147+
if os.path.exists(resolved_haddock_html):
148+
haddock_html = path_to_label(pkg.haddock_html, pkgroot)
149+
if not haddock_html:
150+
haddock_html = os.path.join("haddock", "html", pkg.name)
151+
output.append("#SYMLINK: {} {}".format(resolved_haddock_html.replace('\\', '/'), haddock_html))
114152

115153
# If there is many interfaces, we give them a number
116154
interface_id = 0
117155
haddock_interfaces = []
118156
for interface_path in pkg.haddock_interfaces:
119-
interface = path_to_label(interface_path, pkgroot)
157+
resolved_path = resolve(interface_path, pkgroot).replace('\\', '/')
158+
159+
if not os.path.exists(resolved_path):
160+
# try to resolve relative to the package.conf.d dir
161+
# see https://gitlab.haskell.org/ghc/ghc/-/issues/23476
162+
resolved_path = resolve(interface_path, package_conf_dir)
120163

121164
# We check if the file exists because cabal will unconditionally
122165
# generate the database entry even if no haddock was generated.
123-
if not os.path.exists(interface or interface_path):
124-
continue
166+
if not os.path.exists(resolved_path): continue
167+
168+
interface = path_to_label(interface_path, pkgroot)
125169

126170
if not interface:
127171
interface = os.path.join(
128172
"haddock",
129173
"interfaces",
130174
pkg.name + "_" + str(interface_id) + ".haddock",
131175
)
132-
output.append("#SYMLINK: {} {}".format(interface_path, interface))
176+
output.append("#SYMLINK: {} {}".format(resolved_path, interface))
133177
interface_id += 1
134178
haddock_interfaces.append(interface)
135179

rules_haskell_tests/tests/BUILD.bazel

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,7 @@ rule_test(
248248
"haddock/testsZShaddockZShaddock-lib-b",
249249
"haddock/testsZShaddockZShaddock-lib-deep",
250250
],
251-
}[TEST_GHC_VERSION] + ([
252-
"haddock/rts-1.0.2",
253-
] if is_windows else []),
251+
}[TEST_GHC_VERSION],
254252
rule = "//tests/haddock",
255253
)
256254

rules_haskell_tests/tests/RunTests.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import System.Directory (copyFile)
1010
import System.FilePath ((</>))
1111
import System.Info (os)
1212
import System.IO.Temp (withSystemTempDirectory)
13+
import System.Environment (lookupEnv)
1314

1415
import qualified System.Process as Process
1516
import Test.Hspec.Core.Spec (SpecM)
@@ -26,11 +27,15 @@ main = hspec $ do
2627
assertSuccess (bazel ["test", "//..."])
2728

2829
it "bazel test prof" $ do
30+
ghcVersion <- lookupEnv "GHC_VERSION"
31+
2932
-- In .github/workflows/workflow.yaml we specify --test_tag_filters
3033
-- -dont_test_on_darwin. However, specifiying --test_tag_filters
3134
-- -requires_dynamic here alone would override that filter. So,
3235
-- we have to duplicate that filter here.
33-
let tagFilter | os == "darwin" = "-dont_test_on_darwin,-requires_dynamic,-skip_profiling"
36+
let tagFilter | os == "darwin" = "-dont_test_on_darwin,-requires_dynamic,-skip_profiling" ++ (
37+
-- skip tests for specific GHC version, see https://github.com/tweag/rules_haskell/issues/2073
38+
maybe "" (",-dont_build_on_macos_with_ghc_" ++) ghcVersion)
3439
| otherwise = "-requires_dynamic,-skip_profiling"
3540
assertSuccess (bazel ["test", "-c", "dbg", "//...", "--build_tag_filters", tagFilter, "--test_tag_filters", tagFilter])
3641

rules_haskell_tests/tests/haskell_module/dep-narrowing-th/BUILD.bazel

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ haskell_library(
9494
narrowed_deps = [
9595
":TestLib2",
9696
],
97+
tags = [
98+
# skip building this target on macos with GHC 9.6.2 since it crashes ghc-iserv
99+
# see https://github.com/tweag/rules_haskell/issues/2073
100+
"dont_build_on_macos_with_ghc_9.6.2",
101+
],
97102
deps = [
98103
":NonModulesTestLib",
99104
":TestLib",
@@ -113,6 +118,11 @@ haskell_test(
113118
name = "Test",
114119
modules = [":TestBinModule"],
115120
narrowed_deps = [":lib"],
121+
tags = [
122+
# skip testing this target on macos with GHC 9.6.2 since it crashes ghc-iserv
123+
# see https://github.com/tweag/rules_haskell/issues/2073
124+
"dont_build_on_macos_with_ghc_9.6.2",
125+
],
116126
visibility = ["//visibility:public"],
117127
deps = [
118128
"//tests/hackage:base",

0 commit comments

Comments
 (0)