Skip to content

Commit

Permalink
Refactor hs_libary_pattern in pkgdb_to_bzl.py
Browse files Browse the repository at this point in the history
According to the cabal docs, the `hs-libraries` entries of a package config
needs to comply to specific file naming conventions, see [1].

Only names starting with `HS` or `C` are allowed and dynamic libs prefixed with
`C` need to be handled specially as the "C" prefix should be stripped.

The "rts" hs-libraries also exist in all configured GHC ways, single/multi
threaded and debug/non-debug variants.

Before, only rts's Cffi was handled correctly but other C libs were not.

[1]: https://cabal.readthedocs.io/en/3.4/cabal-package.html#pkg-field-extra-bundled-libraries
  • Loading branch information
avdv committed Jun 17, 2024
1 parent a776c9b commit ea41a91
Showing 1 changed file with 30 additions and 18 deletions.
48 changes: 30 additions & 18 deletions haskell/private/pkgdb_to_bzl.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,11 @@ def path_to_label(path, pkgroot, output=None):
else:
print("WARN: could not handle", path, file=sys.stderr)

def hs_library_pattern(name, mode = "static", profiling = False):
def hs_library_pattern(package_name, name, mode = "static", profiling = False):
"""Convert hs-libraries entry to glob patterns.
Args:
package_name: The name of the package.
name: The library name. E.g. HSrts or Cffi.
mode: The linking mode. Either "static" or "dynamic".
profiling: Look for profiling mode libraries.
Expand All @@ -96,30 +97,41 @@ def hs_library_pattern(name, mode = "static", profiling = False):
List of globbing patterns for the library file.
"""
configs = ["_p"] if profiling else [""]

# Library names must either be prefixed with "HS" or "C" and corresponding
# library file names must match:
# - Libraries with name "HS<library-name>":
# - `libHS<library-name>.a`
# - `libHS<library-name>-ghc<ghc-flavour><ghc-version>.<dyn-library-extension>*`
# - Libraries with name "C<library-name>":
# - `libC<library-name>.a`
# - `lib<library-name>.<dyn-library-extension>*`
if name.startswith("C"):
libname = name[1:] if mode == "dynamic" else name
elif name.startswith("HS"):
libname = name
else:
sys.error("do not know how to handle hs-library `{}` in package {}".format(name, package_name))

# The RTS configuration suffix.
# See https://gitlab.haskell.org/ghc/ghc/wikis/commentary/rts/config#rts-configurations
configs = ["_p"] if profiling else [""]
# Special case HSrts or Cffi - include both libXYZ and libXYZ_thr.
if name == "HSrts" or name.startswith("HSrts-") or name == "Cffi":
# Special case for rts - include multi threaded and single threaded, and debug / non-debug variants
if package_name == "rts":
configs = [
prefix + config
for config in configs
for prefix in ["", "_thr"]
for prefix in ["", "_thr", "_debug", "_thr_debug"]
]
# Special case libCffi - dynamic lib has no configs and is called libffi.
if name == "Cffi" and mode == "dynamic":
libname = "ffi"
configs = [""]
else:
libname = name

libnames = [libname + config for config in configs]
# Special case libCffi - dynamic lib has no version suffix.
if mode == "dynamic" and name != "Cffi":
libnames = [libname + "-ghc*" for libname in libnames]

if mode == "dynamic":
exts = ["so", "so.*", "dylib", "dll"]
libnames = [libname + "-ghc*" for libname in libnames]
exts = ["so", "so.*", "dylib", "dll"] if mode == "dynamic" else ["a"]
else:
exts = ["a"]

return [
"lib{}.{}".format(libname, ext)
for libname in libnames
Expand Down Expand Up @@ -235,21 +247,21 @@ def hs_library_pattern(name, mode = "static", profiling = False):
static_libraries = join_paths([
[path_to_label(library_dir, pkgroot, output), library]
for hs_library in pkg.hs_libraries
for pattern in hs_library_pattern(hs_library, mode = "static", profiling = False)
for pattern in hs_library_pattern(pkg.name, hs_library, mode = "static", profiling = False)
for library_dir in pkg.library_dirs
for library in match_glob(resolve(library_dir, pkgroot), pattern)
]),
static_profiling_libraries = join_paths([
[path_to_label(library_dir, pkgroot, output), library]
for hs_library in pkg.hs_libraries
for pattern in hs_library_pattern(hs_library, mode = "static", profiling = True)
for pattern in hs_library_pattern(pkg.name, hs_library, mode = "static", profiling = True)
for library_dir in pkg.library_dirs
for library in match_glob(resolve(library_dir, pkgroot), pattern)
]),
shared_libraries = join_paths([
[path_to_label(dynamic_library_dir, pkgroot, output), library]
for hs_library in pkg.hs_libraries
for pattern in hs_library_pattern(hs_library, mode = "dynamic", profiling = False)
for pattern in hs_library_pattern(pkg.name, hs_library, mode = "dynamic", profiling = False)
for dynamic_library_dir in set(pkg.dynamic_library_dirs + pkg.library_dirs)
for library in match_glob(resolve(dynamic_library_dir, pkgroot), pattern)
]),
Expand Down

0 comments on commit ea41a91

Please sign in to comment.