1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
#
# (C) Copyright 2017- ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
#
# In applying this licence, ECMWF does not waive the privileges and immunities
# granted to it by virtue of its status as an intergovernmental organisation nor
# does it submit to any jurisdiction.
#
# Authors:
# Alessandro Amici - B-Open - https://bopen.eu
# Shahram Najm - ECMWF - https://www.ecmwf.int
#
from __future__ import absolute_import, division, print_function, unicode_literals
import logging
import os
import pkgutil
import sys
import cffi
__version__ = "2.43.0"
LOG = logging.getLogger(__name__)
_MAP = {
"grib_api": "eccodes",
"gribapi": "eccodes",
}
EXTENSIONS = {
"darwin": ".dylib",
"win32": ".dll",
}
# convenient way to trace the search for the library
if int(os.environ.get("ECCODES_PYTHON_TRACE_LIB_SEARCH", "0")):
LOG.setLevel(logging.DEBUG)
LOG.addHandler(logging.StreamHandler())
def _lookup(name):
return _MAP.get(name, name)
def find_binary_libs(name):
name = _lookup(name)
env_var = "ECCODES_PYTHON_USE_FINDLIBS"
if int(os.environ.get(env_var, "0")):
LOG.debug(f"{name} lib search: {env_var} set, so using findlibs")
elif os.name == "nt":
LOG.debug(f"{name} lib search: trying to find binary wheel")
here = os.path.dirname(__file__)
# eccodes libs are actually in eccodes dir, not gribapi dir
here = os.path.abspath(os.path.join(here, os.path.pardir, "eccodes"))
extension = EXTENSIONS.get(sys.platform, ".so")
for libdir in [here + ".libs", os.path.join(here, ".dylibs"), here]:
LOG.debug(f"{name} lib search: looking in {libdir}")
if not name.startswith("lib"):
libnames = ["lib" + name, name]
else:
libnames = [name, name[3:]]
if os.path.exists(libdir):
for file in os.listdir(libdir):
if file.endswith(extension):
for libname in libnames:
if libname == file.split("-")[0].split(".")[0]:
foundlib = os.path.join(libdir, file)
LOG.debug(
f"{name} lib search: returning wheel library from {foundlib}"
)
# force linking with the C++ 'glue' library
try:
from eccodes._eccodes import versions as _versions
except ImportError as e:
LOG.warn(str(e))
raise
LOG.debug(
f"{name} lib search: versions: %s", _versions()
)
return foundlib
LOG.debug(
f"{name} lib search: did not find library from wheel; try to find as separate lib"
)
# if did not find the binary wheel, or the env var is set, fall back to findlibs
import findlibs
foundlib = findlibs.find(name)
LOG.debug(f"{name} lib search: findlibs returned {foundlib}")
return foundlib
library_path = find_binary_libs("eccodes")
if library_path is None:
raise RuntimeError("Cannot find the ecCodes library")
# default encoding for ecCodes strings
ENC = "ascii"
ffi = cffi.FFI()
CDEF = pkgutil.get_data(__name__, "grib_api.h")
CDEF += pkgutil.get_data(__name__, "eccodes.h")
ffi.cdef(CDEF.decode("utf-8").replace("\r", "\n"))
lib = ffi.dlopen(library_path)
|