diff --git a/src/sage/config.py.in b/src/sage/config.py.in index d7ae0db56d4..c3a6cc3bdc3 100644 --- a/src/sage/config.py.in +++ b/src/sage/config.py.in @@ -12,11 +12,6 @@ VERSION = "@PACKAGE_VERSION@" SAGE_LOCAL = "@prefix@" SAGE_ROOT = "@SAGE_ROOT@" -# The semicolon-separated list of GAP root paths. This is the list of -# locations that are searched for GAP packages. This is passed directly -# to GAP via the -l flag. -GAP_ROOT_PATHS = "@GAP_ROOT_PATHS@".replace("${prefix}", SAGE_LOCAL) - # The path to the standalone maxima executable. MAXIMA = "@SAGE_MAXIMA@".replace("${prefix}", SAGE_LOCAL) @@ -147,3 +142,16 @@ def get_include_dirs() -> list[Path]: # because some headers are generated in the build directory. dirs.extend([root / "src" for root in editable_root]) return [dir for dir in dirs if dir.is_dir()] + + +def get_gap_root() -> Path: + """ + Return the GAP root path. + + EXAMPLES:: + + sage: from sage.config import get_gap_root + sage: get_gap_root() # random + '/path/to/local/lib/gap' + """ + return Path("@GAP_ROOT_PATH@") diff --git a/src/sage/env.py b/src/sage/env.py index 1ef76525a8f..534a8eb2b6f 100644 --- a/src/sage/env.py +++ b/src/sage/env.py @@ -244,12 +244,6 @@ def var(key: str, *fallbacks: Optional[str], force: bool = False) -> Optional[st SAGE_GAP_MEMORY = var('SAGE_GAP_MEMORY', None) SAGE_GAP_COMMAND = var('SAGE_GAP_COMMAND', None) -# The semicolon-separated search path for GAP packages. It is passed -# directly to GAP via the -l flag. -GAP_ROOT_PATHS = var("GAP_ROOT_PATHS", - ";".join([join(SAGE_LOCAL, "lib", "gap"), - join(SAGE_LOCAL, "share", "gap")])) - # post process if DOT_SAGE is not None and ' ' in DOT_SAGE: print("Your home directory has a space in it. This") diff --git a/src/sage/interfaces/gap.py b/src/sage/interfaces/gap.py index af29d7e5926..8bfcd675890 100644 --- a/src/sage/interfaces/gap.py +++ b/src/sage/interfaces/gap.py @@ -203,7 +203,7 @@ import sage.interfaces.abc from sage.cpython.string import bytes_to_str -from sage.env import GAP_ROOT_PATHS, SAGE_EXTCODE, SAGE_GAP_COMMAND, SAGE_GAP_MEMORY +from sage.env import SAGE_EXTCODE, SAGE_GAP_COMMAND, SAGE_GAP_MEMORY from sage.interfaces.expect import ( Expect, ExpectElement, @@ -225,7 +225,7 @@ # Passing -A allows us to use a minimal GAP installation without # producing errors at start-up. The files sage.g and sage.gaprc are # used to load any additional packages that may be available. - gap_cmd = f'gap -A -l "{GAP_ROOT_PATHS}"' + gap_cmd = 'gap -A' if SAGE_GAP_MEMORY is not None: gap_cmd += " -s " + SAGE_GAP_MEMORY + " -o " + SAGE_GAP_MEMORY else: diff --git a/src/sage/interfaces/gap_workspace.py b/src/sage/interfaces/gap_workspace.py index c7df7ffaed1..0f35a07f2e5 100644 --- a/src/sage/interfaces/gap_workspace.py +++ b/src/sage/interfaces/gap_workspace.py @@ -13,11 +13,13 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -import os -import time import hashlib +import os import subprocess -from sage.env import DOT_SAGE, HOSTNAME, GAP_ROOT_PATHS +import time + +from sage.config import get_gap_root +from sage.env import DOT_SAGE, HOSTNAME def gap_workspace_file(system='gap', name='workspace', dir=None): @@ -60,15 +62,10 @@ def gap_workspace_file(system='gap', name='workspace', dir=None): if dir is None: dir = os.path.join(DOT_SAGE, 'gap') - data = f'{GAP_ROOT_PATHS}' - for path in GAP_ROOT_PATHS.split(";"): - if not path: - # If GAP_ROOT_PATHS begins or ends with a semicolon, - # we'll get one empty path. - continue - sysinfo = os.path.join(path, "sysinfo.gap") - if os.path.exists(sysinfo): - data += subprocess.getoutput(f'. "{sysinfo}" && echo ":$GAP_VERSION:$GAParch"') + data = f'{get_gap_root()}' + sysinfo = get_gap_root() / "sysinfo.gap" + if os.path.exists(sysinfo): + data += subprocess.getoutput(f'. "{sysinfo}" && echo ":$GAP_VERSION:$GAParch"') h = hashlib.sha1(data.encode('utf-8')).hexdigest() return os.path.join(dir, f'{system}-{name}-{HOSTNAME}-{h}') diff --git a/src/sage/libs/gap/saved_workspace.py b/src/sage/libs/gap/saved_workspace.py index c26993ac638..ae7ec147021 100644 --- a/src/sage/libs/gap/saved_workspace.py +++ b/src/sage/libs/gap/saved_workspace.py @@ -6,9 +6,10 @@ workspaces. """ -import os import glob -from sage.env import GAP_ROOT_PATHS +import os + +from sage.config import get_gap_root from sage.interfaces.gap_workspace import gap_workspace_file @@ -30,18 +31,12 @@ def timestamp(): <... 'float'> """ libgap_dir = os.path.dirname(__file__) - libgap_files = glob.glob(os.path.join(libgap_dir, '*')) - gap_packages = [] - for d in GAP_ROOT_PATHS.split(";"): - if d: - # If GAP_ROOT_PATHS begins or ends with a semicolon, - # we'll get one empty d. - gap_packages += glob.glob(os.path.join(d, 'pkg', '*')) - + libgap_files = glob.glob(os.path.join(libgap_dir, "*")) + gap_packages = glob.glob(get_gap_root() / "pkg" / "*") files = libgap_files + gap_packages if len(files) == 0: - print('Unable to find LibGAP files.') - return float('inf') + print("Unable to find LibGAP files.") + return float("inf") return max(map(os.path.getmtime, files)) diff --git a/src/sage/libs/gap/util.pyx b/src/sage/libs/gap/util.pyx index 399c4827b7e..27cda6882ad 100644 --- a/src/sage/libs/gap/util.pyx +++ b/src/sage/libs/gap/util.pyx @@ -231,28 +231,25 @@ cdef initialize(): cdef char* argv[16] argv[0] = "sage" argv[1] = "-A" - argv[2] = "-l" - s = str_to_bytes(sage.env.GAP_ROOT_PATHS, FS_ENCODING, "surrogateescape") - argv[3] = s - - argv[4] = "-m" - argv[5] = "64m" - - argv[6] = "-q" # no prompt! - argv[7] = "-E" # don't use readline as this will interfere with Python - argv[8] = "--nointeract" # Implies -T - argv[9] = "-x" # set the "screen" width so that GAP is less likely to - argv[10] = "4096" # insert newlines when printing objects + + argv[2] = "-m" + argv[3] = "64m" + + argv[4] = "-q" # no prompt! + argv[5] = "-E" # don't use readline as this will interfere with Python + argv[6] = "--nointeract" # Implies -T + argv[7] = "-x" # set the "screen" width so that GAP is less likely to + argv[8] = "4096" # insert newlines when printing objects # 4096 unfortunately is the hard-coded max, but should # be long enough for most cases - cdef int argc = 11 # argv[argc] must be NULL + cdef int argc = 9 # argv[argc] must be NULL gap_mem = sage.env.SAGE_GAP_MEMORY if gap_mem is not None: argc += 2 - argv[11] = "-s" + argv[9] = "-s" s1 = str_to_bytes(gap_mem, FS_ENCODING, "surrogateescape") - argv[12] = s1 - argv[5] = s1 + argv[10] = s1 + argv[3] = s1 from sage.libs.gap.saved_workspace import workspace workspace, workspace_is_up_to_date = workspace() diff --git a/src/sage/meson.build b/src/sage/meson.build index d43e636a4e8..b327d5ae28e 100644 --- a/src/sage/meson.build +++ b/src/sage/meson.build @@ -35,19 +35,15 @@ if openmp.found() conf_data.set('OPENMP_CXXFLAGS', '-fopenmp') endif gap_exe = find_program('gap', required: not is_windows, disabler: true) + if gap_exe.found() gaprun = run_command( gap_exe, - '-r', - '-q', - '--bare', - '--nointeract', - '-c', - 'Display(JoinStringsWithSeparator(GAPInfo.RootPaths,";"));', + '--print-gaproot', check: true, ) - gap_root_paths = gaprun.stdout().strip() - conf_data.set('GAP_ROOT_PATHS', gap_root_paths) + gap_root_path = gaprun.stdout().strip() + conf_data.set('GAP_ROOT_PATH', gap_root_path) endif ecm_bin = find_program( ['ecm', 'gmp-ecm'],