From a05d56c9094a68313e51556899b46334a7f47499 Mon Sep 17 00:00:00 2001 From: Rok Mandeljc Date: Sat, 18 May 2024 13:03:46 +0200 Subject: [PATCH] hook: add hook for gribapi package from eccodes dist Add hook for `gribapi` package from `eccodes` dist, in order to collect bundled headers and ensure that the eccodes shared library is collected from the build environment. --- .github/workflows/pr-test.yml | 4 ++ news/744.new.rst | 3 ++ requirements-test-libraries.txt | 3 ++ .../hooks/stdhooks/hook-gribapi.py | 42 +++++++++++++++++++ .../tests/test_libraries.py | 21 ++++++++++ 5 files changed, 73 insertions(+) create mode 100644 news/744.new.rst create mode 100644 src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-gribapi.py diff --git a/.github/workflows/pr-test.yml b/.github/workflows/pr-test.yml index 73ed2333..bafb985f 100644 --- a/.github/workflows/pr-test.yml +++ b/.github/workflows/pr-test.yml @@ -100,6 +100,8 @@ jobs: # These are dependencies of gmsh sudo apt-get install -y libglu1 libgl1 libxrender1 libxcursor1 libxft2 \ libxinerama1 libgomp1 + # This one is required by eccodes + sudo apt-get install -y libeccodes0 - name: Install brew dependencies if: startsWith(matrix.os, 'macos') @@ -112,6 +114,8 @@ jobs: brew install libdiscid # Install lsl library for pylsl brew install labstreaminglayer/tap/lsl + # This one is required by eccodes + brew install eccodes - name: Install dependencies shell: bash diff --git a/news/744.new.rst b/news/744.new.rst new file mode 100644 index 00000000..557336f3 --- /dev/null +++ b/news/744.new.rst @@ -0,0 +1,3 @@ +Add hook for ``gribapi`` package from ``eccodes`` dist, in order to +collect bundled headers and ensure that the eccodes shared library is +collected from the build environment. diff --git a/requirements-test-libraries.txt b/requirements-test-libraries.txt index a64a5261..629c6673 100644 --- a/requirements-test-libraries.txt +++ b/requirements-test-libraries.txt @@ -181,6 +181,9 @@ schwifty==2024.5.3 # ------------------- Platform (OS) specifics +# eccodes package requires the eccodes shared library provided by the environment (linux distribution, homebrew, or Anaconda). +eccodes==1.7.0; sys_platform == 'darwin' or sys_platform == 'linux' + # PyEnchant only pre-builds macOS and Windows pyenchant==3.2.2; sys_platform == 'darwin' or sys_platform == 'win32' diff --git a/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-gribapi.py b/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-gribapi.py new file mode 100644 index 00000000..c1c21a5c --- /dev/null +++ b/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-gribapi.py @@ -0,0 +1,42 @@ +# ------------------------------------------------------------------ +# Copyright (c) 2024 PyInstaller Development Team. +# +# This file is distributed under the terms of the GNU General Public +# License (version 2.0 or later). +# +# The full license is available in LICENSE.GPL.txt, distributed with +# this software. +# +# SPDX-License-Identifier: GPL-2.0-or-later +# ------------------------------------------------------------------ + +import os + +from PyInstaller.utils.hooks import collect_data_files, get_module_attribute, logger + +# Collect the headers (eccodes.h, gribapi.h) that are bundled with the package. +datas = collect_data_files('gribapi') + +# Collect the eccodes shared library +binaries = [] +try: + library_path = get_module_attribute('gribapi.bindings', 'library_path') +except Exception: + logger.warning("hook-gribapi: failed to query gribapi.bindings.library_path!", exc_info=True) + library_path = None + +if library_path: + if not os.path.isabs(library_path): + from PyInstaller.depend.utils import _resolveCtypesImports + resolved_binary = _resolveCtypesImports([os.path.basename(library_path)]) + if resolved_binary: + library_path = resolved_binary[0][1] + else: + logger.warning("hook-gribapi: failed to resolve shared library name %r!", library_path) + library_path = None +else: + logger.warning("hook-gribapi: could not determine path to eccodes shared library!") + +if library_path: + logger.debug("hook-gribapi: collecting eccodes shared library: %r", library_path) + binaries.append((library_path, '.')) diff --git a/src/_pyinstaller_hooks_contrib/tests/test_libraries.py b/src/_pyinstaller_hooks_contrib/tests/test_libraries.py index 424ba8e5..d44eaa42 100644 --- a/src/_pyinstaller_hooks_contrib/tests/test_libraries.py +++ b/src/_pyinstaller_hooks_contrib/tests/test_libraries.py @@ -2036,3 +2036,24 @@ def test_schwifty(pyi_builder): print(iban.bank_code) print(iban.account_code) """) + + +@importorskip('gribapi') +def test_eccodes_gribapi(pyi_builder): + pyi_builder.test_source(""" + import sys + import os + + # Basic import test + import gribapi + + # Ensure that the eccodes shared library is bundled with the frozen application. + import gribapi.bindings + + lib_filename = os.path.join( + sys._MEIPASS, + os.path.basename(gribapi.bindings.library_path), + ) + + assert os.path.isfile(lib_filename), f"Shared library {lib_filename!s} not found!" + """)