Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Merge branch 'public/build/multiarchsimple' of git://trac.sagemath.or…
Browse files Browse the repository at this point in the history
…g/sage into public/refactoring/pytest-numerical-backends
  • Loading branch information
tobiasdiez committed Dec 26, 2020
2 parents 99c4ffd + fa4556a commit 4cdf94d
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 49 deletions.
80 changes: 39 additions & 41 deletions src/sage/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@
# https://www.gnu.org/licenses/
# ****************************************************************************

from typing import List, Optional

import sage
import glob
import os
import socket
import sys
import sysconfig
from . import version
from pathlib import Path


# All variables set by var() appear in this SAGE_ENV dict and also
Expand Down Expand Up @@ -208,7 +209,7 @@ def var(key, *fallbacks, **kwds):
var('SAGE_IMPORTALL', 'yes')


def _get_shared_lib_filename(libname, *additional_libnames):
def _get_shared_lib_path(*libnames: str) -> Optional[str]:
"""
Return the full path to a shared library file installed in
``$SAGE_LOCAL/lib`` or the directories associated with the
Expand All @@ -226,78 +227,75 @@ def _get_shared_lib_filename(libname, *additional_libnames):
For distributions like Debian that use a multiarch layout, we also try the
multiarch lib paths (i.e. ``/usr/lib/<arch>/``).
This returns ``None`` if the file does not exist.
This returns ``None`` if no matching library file could be found.
EXAMPLES::
sage: import sys
sage: from fnmatch import fnmatch
sage: from sage.env import _get_shared_lib_filename
sage: lib_filename = _get_shared_lib_filename("Singular",
....: "singular-Singular")
sage: from sage.env import _get_shared_lib_path
sage: lib_filename = _get_shared_lib_path("Singular", "singular-Singular")
sage: if sys.platform == 'cygwin':
....: pattern = "*/cygSingular-*.dll"
....: elif sys.platform == 'darwin':
....: pattern = "*/libSingular.dylib"
....: pattern = "*/libSingular-*.dylib"
....: else:
....: pattern = "*/lib*Singular.so"
sage: fnmatch(lib_filename, pattern)
....: pattern = "*/lib*Singular-*.so"
sage: fnmatch(str(lib_filename), pattern)
True
sage: _get_shared_lib_filename("an_absurd_lib") is None
sage: _get_shared_lib_path("an_absurd_lib") is None
True
"""

for libname in (libname,) + additional_libnames:
for libname in libnames:
search_directories: List[Path] = []
patterns: List[str] = []
if sys.platform == 'cygwin':
# Later down we take the last matching DLL found, so search
# SAGE_LOCAL second so that it takes precedence
bindirs = [
sysconfig.get_config_var('BINDIR'),
os.path.join(SAGE_LOCAL, 'bin')
# Later down we take the first matching DLL found, so search
# SAGE_LOCAL first so that it takes precedence
search_directories = [
Path(SAGE_LOCAL) / 'bin',
Path(sysconfig.get_config_var('BINDIR')),
]
pats = ['cyg{}.dll'.format(libname), 'cyg{}-*.dll'.format(libname)]
filenames = []
for bindir in bindirs:
for pat in pats:
filenames += glob.glob(os.path.join(bindir, pat))

# Note: This is not very robust, since if there are multi DLL
# Note: The following is not very robust, since if there are multible
# versions for the same library this just selects one more or less
# at arbitrary. However, practically speaking, on Cygwin, there
# at arbitrary. However, practically speaking, on Cygwin, there
# will only ever be one version
if filenames:
return filenames[-1]
patterns = [f'cyg{libname}.dll', f'cyg{libname}-*.dll']
else:
if sys.platform == 'darwin':
ext = 'dylib'
else:
ext = 'so'

libdirs = [
os.path.join(SAGE_LOCAL, 'lib'),
sysconfig.get_config_var('LIBDIR')
]
multilib = sysconfig.get_config_var('MULTILIB')
if multilib:
libdirs.insert(1, os.path.join(libdirs[0], multilib))
search_directories = [Path(SAGE_LOCAL) / 'lib']
libdir = sysconfig.get_config_var('LIBDIR')
if libdir is not None:
libdir = Path(libdir)
search_directories.append(libdir)

multiarchlib = sysconfig.get_config_var('MULTIARCH')
if multiarchlib is not None:
search_directories.append(libdir / multiarchlib),

for libdir in libdirs:
basename = 'lib{}.{}'.format(libname, ext)
filename = os.path.join(libdir, basename)
if os.path.exists(filename):
return filename
patterns = [f'lib{libname}.{ext}']

for directory in search_directories:
for pattern in patterns:
path = next(directory.glob(pattern), None)
if path is not None:
return str(path.resolve())

# Just return None if no files were found
return None


# locate singular shared object
# On Debian it's libsingular-Singular so try that as well
SINGULAR_SO = _get_shared_lib_filename('Singular', 'singular-Singular')
SINGULAR_SO = _get_shared_lib_path('Singular', 'singular-Singular')
var('SINGULAR_SO', SINGULAR_SO)

# locate libgap shared object
GAP_SO= _get_shared_lib_filename('gap','')
GAP_SO = _get_shared_lib_path('gap')
var('GAP_SO', GAP_SO)

# post process
Expand Down
1 change: 1 addition & 0 deletions src/sage/libs/gap/util.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ cdef initialize():
# global symbol table
# Note: we could use RTLD_NOLOAD and avoid the subsequent dlclose() but
# this isn't portable

cdef void* handle
libgapname = str_to_bytes(sage.env.GAP_SO)
handle = dlopen(libgapname, RTLD_NOW | RTLD_GLOBAL)
Expand Down
11 changes: 3 additions & 8 deletions src/sage/libs/singular/singular.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -771,20 +771,15 @@ cdef init_libsingular():
from sage.env import SINGULAR_SO
if not SINGULAR_SO or not os.path.exists(SINGULAR_SO):
raise RuntimeError(
"libSingular not found--a working Singular install in $SAGE_LOCAL "
"libSingular not found--a working Singular install "
"is required for Sage to work")

lib = SINGULAR_SO

if not os.path.exists(lib):
raise ImportError("cannot locate Singular library ({})".format(lib))

lib = str_to_bytes(lib, FS_ENCODING, "surrogateescape")
lib = str_to_bytes(SINGULAR_SO, FS_ENCODING, "surrogateescape")

handle = dlopen(lib, RTLD_GLOBAL|RTLD_LAZY)
if not handle:
err = dlerror()
raise ImportError("cannot load Singular library ({})".format(err))
raise ImportError(f"cannot load Singular library from {SINGULAR_SO} ({err})")

# load SINGULAR
siInit(lib)
Expand Down

0 comments on commit 4cdf94d

Please sign in to comment.