Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Sage Runtime Environment
AUTHORS:
- \R. Andrew Ohana (2012): Initial version.
""" ######################################################################## # Copyright (C) 2013 R. Andrew Ohana <andrew.ohana@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # http://www.gnu.org/licenses/ ######################################################################## from __future__ import absolute_import
import glob import os import socket import site from . import version
opj = os.path.join
# set default values for sage environment variables # every variable can be overwritten by os.environ SAGE_ENV = dict()
# Helper to build the SAGE_ENV dictionary def _add_variable_or_fallback(key, fallback, force=False): """ Set ``SAGE_ENV[key]``.
If ``key`` is an environment variable, this is the value. Otherwise, the ``fallback`` is used.
INPUT:
- ``key`` -- string.
- ``fallback`` -- anything.
- ``force`` -- boolean (optional, default is ``False``). Whether to always use the fallback, regardless of environment variables.
EXAMPLES::
sage: import os, sage.env sage: sage.env.SAGE_ENV = dict() sage: os.environ['SAGE_FOO'] = 'foo' sage: sage.env._add_variable_or_fallback('SAGE_FOO', '---$SAGE_URL---') sage: sage.env.SAGE_FOO 'foo' sage: sage.env.SAGE_ENV['SAGE_FOO'] 'foo'
If the environment variable does not exist, the fallback is used. Previously-declared variables are replaced if they are prefixed with a dollar sign::
sage: _ = os.environ.pop('SAGE_BAR', None) # ensure that SAGE_BAR does not exist sage: sage.env._add_variable_or_fallback('SAGE_BAR', '---$SAGE_FOO---') sage: sage.env.SAGE_BAR '---foo---' sage: sage.env.SAGE_ENV['SAGE_BAR'] '---foo---'
Test that :trac:`23758` has been resolved::
sage: sage.env._add_variable_or_fallback('SAGE_BA', '---hello---') sage: sage.env._add_variable_or_fallback('SAGE_QUX', '$SAGE_BAR') sage: sage.env.SAGE_ENV['SAGE_QUX'] '---foo---' """ global SAGE_ENV value = fallback # Now do the variable replacement. First treat 'value' as if # it were a path and do the substitution on each of the # components. This is to avoid the sloppiness in the second # round of substitutions: if VAR and VAR_NEW are both in # SAGE_ENV, then when doing substitution on the string # "$VAR_NEW/a/b", we want to match VAR_NEW, not VAR, if # possible. else: # Now deal with any remaining substitutions. The following is # sloppy, as mentioned above: if $VAR and $VAR_NEW are both in # SAGE_ENV, the substitution for "$VAR_NEw" depends on which # of the two appears first when iterating over # SAGE_ENV.items().
# system info _add_variable_or_fallback('UNAME', os.uname()[0]) _add_variable_or_fallback('HOSTNAME', socket.gethostname()) _add_variable_or_fallback('LOCAL_IDENTIFIER','$HOSTNAME.%s'%os.getpid())
# bunch of sage directories and files _add_variable_or_fallback('SAGE_ROOT', None) _add_variable_or_fallback('SAGE_LOCAL', None) _add_variable_or_fallback('SAGE_ETC', opj('$SAGE_LOCAL', 'etc')) _add_variable_or_fallback('SAGE_INC', opj('$SAGE_LOCAL', 'include')) _add_variable_or_fallback('SAGE_SHARE', opj('$SAGE_LOCAL', 'share'))
_add_variable_or_fallback('SAGE_SRC', opj('$SAGE_ROOT', 'src'))
try: sitepackages_dirs = site.getsitepackages() except AttributeError: # in case of use inside virtualenv sitepackages_dirs = [os.path.join(os.path.dirname(site.__file__), 'site-packages')] _add_variable_or_fallback('SITE_PACKAGES', sitepackages_dirs)
_add_variable_or_fallback('SAGE_LIB', SITE_PACKAGES[0])
# Used by sage/misc/package.py. Should be SAGE_SRC_ROOT in VPATH. _add_variable_or_fallback('SAGE_PKGS', opj('$SAGE_ROOT', 'build', 'pkgs'))
_add_variable_or_fallback('SAGE_EXTCODE', opj('$SAGE_SHARE', 'sage', 'ext')) _add_variable_or_fallback('SAGE_LOGS', opj('$SAGE_ROOT', 'logs', 'pkgs')) _add_variable_or_fallback('SAGE_SPKG_INST', opj('$SAGE_LOCAL', 'var', 'lib', 'sage', 'installed')) _add_variable_or_fallback('SAGE_DOC_SRC', opj('$SAGE_SRC', 'doc')) _add_variable_or_fallback('SAGE_DOC', opj('$SAGE_SHARE', 'doc', 'sage')) _add_variable_or_fallback('DOT_SAGE', opj(os.environ.get('HOME','$SAGE_ROOT'), '.sage')) _add_variable_or_fallback('SAGE_DOT_GIT', opj('$SAGE_ROOT', '.git')) _add_variable_or_fallback('SAGE_DISTFILES', opj('$SAGE_ROOT', 'upstream'))
# misc _add_variable_or_fallback('SAGE_URL', 'http://sage.math.washington.edu/sage/') _add_variable_or_fallback('REALM', 'sage.math.washington.edu') _add_variable_or_fallback('TRAC_SERVER_URI', 'https://trac.sagemath.org') _add_variable_or_fallback('SAGE_REPO_AUTHENTICATED', 'ssh://git@trac.sagemath.org:2222/sage.git') _add_variable_or_fallback('SAGE_REPO_ANONYMOUS', 'git://trac.sagemath.org/sage.git') _add_variable_or_fallback('SAGE_VERSION', version.version) _add_variable_or_fallback('SAGE_DATE', version.date) _add_variable_or_fallback('SAGE_BANNER', '') _add_variable_or_fallback('SAGE_IMPORTALL', 'yes')
# additional packages locations _add_variable_or_fallback('CONWAY_POLYNOMIALS_DATA_DIR', opj('$SAGE_SHARE','conway_polynomials')) _add_variable_or_fallback('GRAPHS_DATA_DIR', opj('$SAGE_SHARE','graphs')) _add_variable_or_fallback('ELLCURVE_DATA_DIR',opj('$SAGE_SHARE','ellcurves')) _add_variable_or_fallback('POLYTOPE_DATA_DIR',opj('$SAGE_SHARE','reflexive_polytopes')) _add_variable_or_fallback('GAP_ROOT_DIR', opj('$SAGE_LOCAL','gap','latest')) _add_variable_or_fallback('THEBE_DIR', opj('$SAGE_SHARE','thebe'))
# locate singular shared object if UNAME[:6] == "CYGWIN": SINGULAR_SO = ([None] + glob.glob(os.path.join( SAGE_LOCAL, "bin", "cygSingular-*.dll")))[-1] else: if UNAME == "Darwin": extension = "dylib" else: extension = "so" # library name changed from libsingular to libSingular btw 3.x and 4.x SINGULAR_SO = SAGE_LOCAL+"/lib/libSingular."+extension
_add_variable_or_fallback('SINGULAR_SO', 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 " "is required for Sage to work")
# post process if ' ' in DOT_SAGE: if UNAME[:6] == 'CYGWIN': # on windows/cygwin it is typical for the home directory # to have a space in it. Fortunately, users also have # write privileges to c:\cygwin\home, so we just put # .sage there. _add_variable_or_fallback('DOT_SAGE', "/home/.sage", force=True) else: print("Your home directory has a space in it. This") print("will probably break some functionality of Sage. E.g.,") print("the GAP interface will not work. A workaround") print("is to set the environment variable HOME to a") print("directory with no spaces that you have write") print("permissions to before you start sage.")
CYGWIN_VERSION = None if UNAME[:6] == 'CYGWIN': import re _uname = os.uname() if len(_uname) >= 2: m = re.match(r'(\d+\.\d+\.\d+)\(.+\)', _uname[2]) if m: CYGWIN_VERSION = tuple(map(int, m.group(1).split('.')))
del m del _uname, re
# things that need DOT_SAGE _add_variable_or_fallback('PYTHON_EGG_CACHE', opj('$DOT_SAGE', '.python-eggs')) _add_variable_or_fallback('SAGE_STARTUP_FILE', opj('$DOT_SAGE', 'init.sage'))
# delete temporary variables used for setting up sage.env del opj, os, socket, version, site
def sage_include_directories(use_sources=False): """ Return the list of include directories for compiling Sage extension modules.
INPUT:
- ``use_sources`` -- (default: False) a boolean
OUTPUT:
a list of include directories to be used to compile sage code 1. while building sage (use_sources='True') 2. while using sage (use_sources='False')
EXAMPLES:
Expected output while using sage
::
sage: import sage.env sage: sage.env.sage_include_directories() ['.../include', '.../include/python...', '.../python.../numpy/core/include', '.../python.../site-packages', '.../python.../site-packages/sage/ext'] """
distutils.sysconfig.get_python_inc(), numpy.get_include()]
include_directories.extend([SAGE_SRC, opj(SAGE_SRC, 'sage', 'ext')]) else: opj(SAGE_LIB, 'sage', 'ext')])
def cython_aliases(): """ Return the aliases for compiling Cython code. These aliases are macros which can occur in ``# distutils`` headers.
EXAMPLES::
sage: from sage.env import cython_aliases sage: cython_aliases() {...} sage: sorted(cython_aliases().keys()) ['FFLASFFPACK_CFLAGS', 'FFLASFFPACK_INCDIR', 'FFLASFFPACK_LIBDIR', 'FFLASFFPACK_LIBRARIES', 'GIVARO_CFLAGS', 'GIVARO_INCDIR', 'GIVARO_LIBDIR', 'GIVARO_LIBRARIES', 'GSL_CFLAGS', 'GSL_INCDIR', 'GSL_LIBDIR', 'GSL_LIBRARIES', 'LINBOX_CFLAGS', 'LINBOX_INCDIR', 'LINBOX_LIBDIR', 'LINBOX_LIBRARIES', 'SINGULAR_CFLAGS', 'SINGULAR_INCDIR', 'SINGULAR_LIBDIR', 'SINGULAR_LIBRARIES'] """
# INCDIR should be redundant because the -I options are also # passed in CFLAGS
# LinBox needs special care because it actually requires C++11 with # GNU extensions: -std=c++11 does not work, you need -std=gnu++11 # (this is true at least with GCC 7.2.0). # # Further, note that LinBox does not add any C++11 flag in its .pc # file (possibly because of confusion between CFLAGS and CXXFLAGS?). # This is not a problem in practice since LinBox depends on # fflas-ffpack and fflas-ffpack does add such a C++11 flag.
|