diff options
Diffstat (limited to 'third_party/bazel/rules_haskell/haskell/private/actions/package.bzl')
-rw-r--r-- | third_party/bazel/rules_haskell/haskell/private/actions/package.bzl | 210 |
1 files changed, 0 insertions, 210 deletions
diff --git a/third_party/bazel/rules_haskell/haskell/private/actions/package.bzl b/third_party/bazel/rules_haskell/haskell/private/actions/package.bzl deleted file mode 100644 index 1c438e8445a5..000000000000 --- a/third_party/bazel/rules_haskell/haskell/private/actions/package.bzl +++ /dev/null @@ -1,210 +0,0 @@ -"""Action for creating packages and registering them with ghc-pkg""" - -load("@bazel_skylib//lib:paths.bzl", "paths") -load(":private/path_utils.bzl", "target_unique_name") -load(":private/pkg_id.bzl", "pkg_id") -load(":private/set.bzl", "set") -load(":private/path_utils.bzl", "get_lib_name") - -def _get_extra_libraries(dep_info): - """Get directories and library names for extra library dependencies. - - Args: - dep_info: HaskellInfo provider of the package. - - Returns: - (dirs, libs): - dirs: list: Library search directories for extra library dependencies. - libs: list: Extra library dependencies. - """ - cc_libs = dep_info.cc_dependencies.dynamic_linking.libraries_to_link.to_list() - - # The order in which library dependencies are listed is relevant when - # linking static archives. To maintain the order defined by the input - # depset we collect the library dependencies in a list, and use a separate - # set to deduplicate entries. - seen_libs = set.empty() - extra_libs = [] - extra_lib_dirs = set.empty() - for lib in cc_libs: - lib_name = get_lib_name(lib) - if not set.is_member(seen_libs, lib_name): - set.mutable_insert(seen_libs, lib_name) - extra_libs.append(lib_name) - set.mutable_insert(extra_lib_dirs, lib.dirname) - return (set.to_list(extra_lib_dirs), extra_libs) - -def package( - hs, - dep_info, - interfaces_dir, - interfaces_dir_prof, - static_library, - dynamic_library, - exposed_modules_file, - other_modules, - my_pkg_id, - static_library_prof): - """Create GHC package using ghc-pkg. - - Args: - hs: Haskell context. - interfaces_dir: Directory containing interface files. - static_library: Static library of the package. - dynamic_library: Dynamic library of the package. - static_library_prof: Static library compiled with profiling or None. - - Returns: - (File, File): GHC package conf file, GHC package cache file - """ - pkg_db_dir = pkg_id.to_string(my_pkg_id) - conf_file = hs.actions.declare_file( - paths.join(pkg_db_dir, "{0}.conf".format(pkg_db_dir)), - ) - cache_file = hs.actions.declare_file("package.cache", sibling = conf_file) - - import_dir = paths.join( - "${pkgroot}", - paths.join(pkg_db_dir, "_iface"), - ) - interfaces_dirs = [interfaces_dir] - - if interfaces_dir_prof != None: - import_dir_prof = paths.join( - "${pkgroot}", - paths.join(pkg_db_dir, "_iface_prof"), - ) - interfaces_dirs.append(interfaces_dir_prof) - else: - import_dir_prof = "" - - (extra_lib_dirs, extra_libs) = _get_extra_libraries(dep_info) - - metadata_entries = { - "name": my_pkg_id.name, - "version": my_pkg_id.version, - "id": pkg_id.to_string(my_pkg_id), - "key": pkg_id.to_string(my_pkg_id), - "exposed": "True", - "hidden-modules": " ".join(other_modules), - "import-dirs": " ".join([import_dir, import_dir_prof]), - "library-dirs": " ".join(["${pkgroot}"] + extra_lib_dirs), - "dynamic-library-dirs": " ".join(["${pkgroot}"] + extra_lib_dirs), - "hs-libraries": pkg_id.library_name(hs, my_pkg_id), - "extra-libraries": " ".join(extra_libs), - "depends": ", ".join( - # Prebuilt dependencies are added further down, since their - # package-ids are not available as strings but in build outputs. - set.to_list(dep_info.package_ids), - ), - } - - # Create a file from which ghc-pkg will create the actual package - # from. List of exposed modules generated below. - metadata_file = hs.actions.declare_file(target_unique_name(hs, "metadata")) - hs.actions.write( - output = metadata_file, - content = "\n".join([ - "{0}: {1}".format(k, v) - for k, v in metadata_entries.items() - if v - ]) + "\n", - ) - - # Collect the package id files of all prebuilt dependencies. - prebuilt_deps_id_files = [ - dep.id_file - for dep in set.to_list(dep_info.prebuilt_dependencies) - ] - - # Combine exposed modules and other metadata to form the package - # configuration file. - - prebuilt_deps_args = hs.actions.args() - prebuilt_deps_args.add_all([f.path for f in prebuilt_deps_id_files]) - prebuilt_deps_args.use_param_file("%s", use_always = True) - prebuilt_deps_args.set_param_file_format("multiline") - - hs.actions.run_shell( - inputs = [metadata_file, exposed_modules_file] + prebuilt_deps_id_files, - outputs = [conf_file], - command = """ - cat $1 > $4 - echo "exposed-modules: `cat $2`" >> $4 - - # this is equivalent to 'readarray'. We do use 'readarray' in order to - # support older bash versions. - while IFS= read -r line; do deps_id_files+=("$line"); done < $3 - - if [ ${#deps_id_files[@]} -eq 0 ]; then - deps="" - else - deps=$(cat "${deps_id_files[@]}" | tr '\n' " ") - fi - echo "depends: $deps" >> $4 -""", - arguments = [ - metadata_file.path, - exposed_modules_file.path, - prebuilt_deps_args, - conf_file.path, - ], - use_default_shell_env = True, - ) - - # Make the call to ghc-pkg and use the package configuration file - package_path = ":".join([c.dirname for c in set.to_list(dep_info.package_databases)]) + ":" - hs.actions.run( - inputs = depset(transitive = [ - set.to_depset(dep_info.package_databases), - depset(interfaces_dirs), - depset([ - input - for input in [ - static_library, - conf_file, - dynamic_library, - static_library_prof, - ] - if input - ]), - ]), - outputs = [cache_file], - env = { - "GHC_PACKAGE_PATH": package_path, - }, - mnemonic = "HaskellRegisterPackage", - progress_message = "HaskellRegisterPackage {}".format(hs.label), - executable = hs.tools.ghc_pkg, - # Registration of a new package consists in, - # - # 1. copying the registration file into the package db, - # 2. performing some validation on the registration file content, - # 3. recaching, i.e. regenerating the package db cache file. - # - # Normally, this is all done by `ghc-pkg register`. But in our - # case, `ghc-pkg register` is painful, because the validation - # it performs is slow, somewhat redundant but especially, too - # strict (see e.g. - # https://ghc.haskell.org/trac/ghc/ticket/15478). So we do (1) - # and (3) manually, by copying then calling `ghc-pkg recache` - # directly. - # - # The downside is that we do lose the few validations that - # `ghc-pkg register` was doing that was useful. e.g. when - # reexporting modules, validation checks that the source - # module does exist. - # - # TODO Go back to using `ghc-pkg register`. Blocked by - # https://ghc.haskell.org/trac/ghc/ticket/15478 - arguments = [ - "recache", - "--package-db={0}".format(conf_file.dirname), - "-v0", - "--no-expand-pkgroot", - ], - # XXX: Seems required for this to work on Windows - use_default_shell_env = True, - ) - - return conf_file, cache_file |