hook-pyproj.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. # ------------------------------------------------------------------
  2. # Copyright (c) 2020 PyInstaller Development Team.
  3. #
  4. # This file is distributed under the terms of the GNU General Public
  5. # License (version 2.0 or later).
  6. #
  7. # The full license is available in LICENSE, distributed with
  8. # this software.
  9. #
  10. # SPDX-License-Identifier: GPL-2.0-or-later
  11. # ------------------------------------------------------------------
  12. import os
  13. import sys
  14. from PyInstaller.utils.hooks import collect_data_files, is_module_satisfies, copy_metadata
  15. from PyInstaller.compat import is_win
  16. hiddenimports = [
  17. "pyproj.datadir"
  18. ]
  19. binaries = []
  20. # Versions prior to 2.3.0 also require pyproj._datadir
  21. if not is_module_satisfies("pyproj >= 2.3.0"):
  22. hiddenimports += ["pyproj._datadir"]
  23. # Starting with version 3.0.0, pyproj._compat is needed
  24. if is_module_satisfies("pyproj >= 3.0.0"):
  25. hiddenimports += ["pyproj._compat"]
  26. # Linux and macOS also require distutils.
  27. if not is_win:
  28. hiddenimports += ["distutils.util"]
  29. # Data collection
  30. datas = collect_data_files('pyproj')
  31. # Repackagers may de-vendor the proj data directory (Conda, Debian)
  32. if not any(dest.startswith("pyproj/proj_dir") for (_, dest) in datas):
  33. if hasattr(sys, 'real_prefix'): # check if in a virtual environment
  34. root_path = sys.real_prefix
  35. else:
  36. root_path = sys.prefix
  37. if is_win:
  38. tgt_proj_data = os.path.join('Library', 'share', 'proj')
  39. src_proj_data = os.path.join(root_path, 'Library', 'share', 'proj')
  40. else: # both linux and darwin
  41. tgt_proj_data = os.path.join('share', 'proj')
  42. src_proj_data = os.path.join(root_path, 'share', 'proj')
  43. if os.path.exists(src_proj_data):
  44. datas.append((src_proj_data, tgt_proj_data))
  45. # A runtime hook defines the path for `PROJ_LIB`
  46. else:
  47. from PyInstaller.utils.hooks import logger
  48. logger.warning("Datas for pyproj not found at:\n{}".format(src_proj_data))
  49. # With pyproj 3.4.0, we need to collect package's metadata due to `importlib.metadata.version(__package__)` call in
  50. # `__init__.py`. This change was reverted in subsequent releases of pyproj, so we collect metadata only for 3.4.0.
  51. if is_module_satisfies("pyproj == 3.4.0"):
  52. datas += copy_metadata("pyproj")
  53. # pyproj 3.4.0 was also the first release that used `delvewheel` for its Windows PyPI wheels. While contemporary
  54. # PyInstaller versions automatically pick up DLLs from external `pyproj.libs` directory, this does not work on Anaconda
  55. # python 3.8 and 3.9 due to defunct `os.add_dll_directory`, which forces `delvewheel` to use the old load-order file
  56. # approach. So we need to explicitly ensure that load-order file as well as DLLs are collected.
  57. if is_win and is_module_satisfies("pyproj >= 3.4.0"):
  58. if is_module_satisfies("PyInstaller >= 5.6"):
  59. from PyInstaller.utils.hooks import collect_delvewheel_libs_directory
  60. datas, binaries = collect_delvewheel_libs_directory("pyproj", datas=datas, binaries=binaries)