Skip to content

Commit 9a38604

Browse files
avdvylecornec
authored andcommitted
Create symlinks for absolute paths in path_to_label
Also expand files directly instead of generating glob calls, which is needed for ncurses from nixpkgs since it includes self-referencing symlinks which Bazel does not support (see [33]). [33]: bazelbuild/bazel#133
1 parent 7e947bb commit 9a38604

File tree

1 file changed

+40
-23
lines changed

1 file changed

+40
-23
lines changed

haskell/private/pkgdb_to_bzl.py

Lines changed: 40 additions & 23 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([str(p.relative_to(root_dir)) 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
@@ -57,10 +63,22 @@ def path_to_label(path, pkgroot):
5763

5864
return None if relative_path.startswith('..') else relative_path.replace('\\', '/')
5965

60-
topdir_relative_path = path.replace(pkgroot, "$topdir")
61-
if topdir_relative_path.find("$topdir") != -1:
66+
topdir_relative_path = path.replace(os.path.realpath(pkgroot), "$topdir")
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
@@ -115,7 +133,7 @@ def hs_library_pattern(name, mode = "static", profiling = False):
115133
# pkgroot is not part of .conf files. It's a computed value. It is
116134
# defined to be the directory enclosing the package database
117135
# directory.
118-
pkgroot = os.path.dirname(os.path.dirname(os.path.realpath(conf)))
136+
pkgroot = os.path.dirname(os.path.dirname(conf))
119137

120138
pkg_id_map.append((pkg.name, pkg.id))
121139

@@ -200,37 +218,36 @@ def hs_library_pattern(name, mode = "static", profiling = False):
200218
name = pkg.name,
201219
id = pkg.id,
202220
version = pkg.version,
203-
hdrs = "glob({}, allow_empty = True)".format([
204-
path_to_label("{}/**/*.h".format(include_dir), pkgroot)
221+
hdrs = [
222+
"/".join([path_to_label(include_dir, pkgroot, output), header])
205223
for include_dir in pkg.include_dirs
206-
if path_to_label(include_dir, pkgroot)
207-
]),
224+
for header in match_glob(resolve(include_dir, pkgroot), "**/*.h")
225+
],
208226
includes = [
209-
"/".join([repo_dir, path_to_label(include_dir, pkgroot)])
227+
"/".join([repo_dir, path_to_label(include_dir, pkgroot, output)])
210228
for include_dir in pkg.include_dirs
211-
if path_to_label(include_dir, pkgroot)
212229
],
213-
static_libraries = "glob({}, allow_empty = True)".format([
214-
path_to_label("{}/{}".format(library_dir, pattern), pkgroot)
230+
static_libraries = [
231+
"/".join([path_to_label(library_dir, pkgroot, output), library])
215232
for hs_library in pkg.hs_libraries
216233
for pattern in hs_library_pattern(hs_library, mode = "static", profiling = False)
217234
for library_dir in pkg.library_dirs
218-
if path_to_label(library_dir, pkgroot)
219-
]),
220-
static_profiling_libraries = "glob({}, allow_empty = True)".format([
221-
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])
222239
for hs_library in pkg.hs_libraries
223240
for pattern in hs_library_pattern(hs_library, mode = "static", profiling = True)
224241
for library_dir in pkg.library_dirs
225-
if path_to_label(library_dir, pkgroot)
226-
]),
227-
shared_libraries = "glob({}, allow_empty = True)".format([
228-
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])
229246
for hs_library in pkg.hs_libraries
230247
for pattern in hs_library_pattern(hs_library, mode = "dynamic", profiling = False)
231-
for dynamic_library_dir in pkg.dynamic_library_dirs + pkg.library_dirs
232-
if path_to_label(dynamic_library_dir, pkgroot)
233-
]),
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+
],
234251
haddock_html = repr(haddock_html),
235252
haddock_interfaces = repr(haddock_interfaces),
236253
deps = pkg.depends,

0 commit comments

Comments
 (0)