Ticket #9210: trac-9210-rewrite-sage-location.patch

File trac-9210-rewrite-sage-location.patch, 10.1 KB (added by jason, 11 years ago)

apply to sage-scripts repository

  • sage-location

    # HG changeset patch
    # User Jason Grout <jason-sage@creativetrax.com>
    # Date 1276288715 18000
    # Node ID 88d7882d759d6b7b222447f75054eebe50f37cfd
    # Parent  30e166e656caba02894172a14a83c47d489597d5
    #9210: Rewrite of sage-location, which fixes things after moving SAGE_ROOT.
    
    In addition to numerous style/python improvements, the sage-location script now
    sets a SAGE_ROOT variable inside of the pkg-config files
    (SAGE_LOCAL/lib/pkgconfig/*.pc), updates the other
    paths to rely on it, and updates SAGE_ROOT when needed.
    
    diff -r 30e166e656ca -r 88d7882d759d sage-location
    a b  
    22
    33import os, sys
    44
    5 SAGE_ROOT     = os.environ['SAGE_ROOT']
     5OLD_SAGE_ROOT = None
     6SAGE_ROOT     = os.path.realpath(os.environ['SAGE_ROOT'])
    67
    7 location_file = '%s/local/lib/sage-current-location.txt'%SAGE_ROOT
    8 flags_file    = '%s/local/lib/sage-flags.txt'%SAGE_ROOT
    9 
    10 def install_moved():
    11     """
    12     Check whether or not this install of Sage moved.  If it hasn't
    13     moved make sure the location and processor flags files are
    14     written.
    15     """
    16     # Write the flags file if it isn't there.
    17     if not os.path.exists(flags_file):
    18         write_flags_file()
    19 
    20     if not os.path.exists(location_file):
    21         # Write the location file since it isn't there.
    22         O = open(location_file,'w')
    23         O.write(SAGE_ROOT)
    24         O.close()
    25         return False, ''   # first time -- so no need to update; this was during the build.
    26 
    27     # The install moved and we had written the flags and location files.
    28     O = open(location_file)
    29     R = O.read().strip()
    30     O.close()
    31     if os.path.realpath(R) != os.path.realpath(SAGE_ROOT):  # really different
    32         return True, R  # it moved
    33     return False, ''
    34 
     8location_file = os.path.join(SAGE_ROOT, 'local', 'lib', 'sage-current-location.txt')
     9flags_file    = os.path.join(SAGE_ROOT, 'local', 'lib', 'sage-flags.txt')
    3510
    3611# The flags we care about recording in the local/lib/sage-flags.txt file
    3712# In SAGE_FAT_BINARY mode we only require that ['sse', 'sse2', '3d',
     
    4823else:
    4924    FLAGS = ['sse', 'sse2', 'ssse3', '3d', 'mmx', 'pni', 'cmov']
    5025
     26
     27def write_location_file():
     28    """
     29    Write the location file with the current SAGE_ROOT
     30    """
     31    # Write new location file.
     32    O = open(location_file,'w')
     33    O.write(SAGE_ROOT)
     34    O.close()
     35
     36def read_location_file():
     37    """
     38    If the location file exists, return the real path contained in it.  Otherwise, return None.
     39    """
     40    if os.path.exists(location_file):
     41        # The install moved and we had written the flags and location files.
     42        O = open(location_file)
     43        R = O.read().strip()
     44        O.close()
     45        return os.path.realpath(R)
     46    else:
     47        return None
     48
     49def install_moved():
     50    """
     51    Check whether or not this install of Sage moved.  If it hasn't
     52    moved make sure the location and processor flags files are
     53    written.
     54
     55    Returns True if location possibly moved, and sets the global
     56    OLD_SAGE_ROOT variable to the old SAGE_ROOT path.
     57
     58    Returns False if location has not moved.
     59    """
     60    # Write the flags file if it isn't there.
     61    if not os.path.exists(flags_file):
     62        f=open(flags_file,'w')
     63        f.write(get_flags_info())
     64        f.close()
     65
     66    path=read_location_file()
     67    if path is None:
     68        # first time checked (during the build)
     69        write_location_file()
     70        initialize_pkgconfig_files()
     71        return False
     72    elif path != SAGE_ROOT:
     73        # location moved
     74        global OLD_SAGE_ROOT
     75        OLD_SAGE_ROOT=path
     76        write_location_file()
     77        return True
     78    else:
     79        # path didn't change
     80        return False
     81
    5182def get_flags_info():
    5283    """
    5384    Return a space-separated string that lists the flags supported by
     
    6798        return ' '.join(set(x for x in r.split() if x in FLAGS))
    6899
    69100    except IOError:
    70         # On a system without /proc/cpuinfo, so don't bother In
     101        # On a system without /proc/cpuinfo, so don't bother. In
    71102        # particular, for non Linux systems I have no clue how to get
    72103        # the processor flags, and we so far have never ever had any
    73104        # problem with processor flags on such machines.  So we don't
    74105        # bother.
    75106        return ''
    76    
    77 def write_flags_file():
    78     """
    79     Write the flags file to disk.
    80     """
    81     # Just record the flags
    82     open(flags_file,'w').write(get_flags_info())
    83107
    84108def check_processor_flags():
    85109    """
     
    109133        print "*"*70
    110134        sys.exit(1)
    111135
    112 def update_library_files(R):
    113     LIB = '%s/local/lib/'%os.path.abspath(SAGE_ROOT)
     136def update_library_files():
     137    """
     138    Run ranlib on the library directory and manually change the path
     139    in .la library files.
     140    """
     141    LIB = os.path.join(os.path.abspath(SAGE_ROOT), 'local', 'lib')
    114142    # The .a files should be re-ranlib'd
    115143    os.system('cd "%s"; ranlib *.a 1>/dev/null 2>/dev/null'%LIB)
    116144
    117     # The .la files hardcode path info.  Fix this.
     145    # The .la files hardcode path info, so we manually fix the path
     146    # info
    118147    for F in os.listdir(LIB):
    119        if F[-3:] == ".la":
    120            G = open(LIB + F).read()
     148       if os.path.splitext(F)[1]==".la":
     149           G = open(os.path.join(LIB,F)).read()
    121150           i = G.find('libdir=')
    122151           j = i+8 + G[i+8:].find("'")
    123152           z = G[i+8:j].strip().strip("'")
     
    125154           if i != -1:
    126155               z = z[:i]
    127156               H = G.replace(z, os.path.abspath(SAGE_ROOT) + '/')
    128                open(LIB + F,'w').write(H)
     157               open(os.path.join(LIB, F),'w').write(H)
    129158
    130 def update_hardcoded_files(path):
    131     # The only known files with hard coded paths.
    132     if os.path.isdir(path):
    133         for X in os.listdir(path):
    134             update_hardcoded_files('%s/%s'%(path,X))
    135     else:
    136         P = path[-4:]
    137         if P == '.pyo' or P == '.pyc':
    138             try:
    139                 os.unlink(path)
    140             except OSError, msg:
    141                 print msg
    142159
    143     # Write new location file.
    144     if os.path.exists(location_file):
    145         O = open(location_file,'w')
    146         O.write(SAGE_ROOT)
    147         O.close()       
     160def initialize_pkgconfig_files():
     161    """
     162    Insert a sage_local variable in each pkg_config file and replace
     163    them to make the paths portable.
     164    """
     165    LIB = os.path.join(os.path.abspath(SAGE_ROOT), 'local', 'lib')
     166    PKG = os.path.join(LIB,'pkgconfig')
     167    for name in os.listdir(PKG):
     168        filename=os.path.join(PKG,name)
     169        if os.path.splitext(filename)[1]==".pc":
     170            with open(filename) as file:
     171                config = file.read()
     172               
     173            new_config = config.replace(os.path.abspath(SAGE_ROOT), "${SAGE_ROOT}")
    148174
    149 # Note that due to updating setuptools to 0.6c9 in Sage 3.3 we no longer need to rewrite
    150 # site-packages in easy-install.pth
    151 def update_easy_install():
     175            new_config = 'SAGE_ROOT=%s\n'%os.path.abspath(SAGE_ROOT)+new_config
     176
     177            with open(filename, 'w') as file:
     178                file.write(new_config)
     179
     180   
     181
     182def update_pkgconfig_files():
    152183    """
    153     Find the easy-install.pth file in the current tree, and replace the line
    154     with site-packages in it with a new line that has the correct path to
    155     our new site-packages.
     184    Change paths in package configuration files.
    156185    """
    157     base = '%s/local/lib/python2.5/site-packages'%SAGE_ROOT
    158     file = '%s/easy-install.pth'%base
    159     r = open(file).readlines()
    160     for i in range(len(r)):
    161         if 'site-packages' in r[i]:   # found it
    162             r[i] = base + '\n'
    163             open(file,'w').write(''.join(r))
    164             return
    165     print "Warning: something went wrong updating the easy-install.pth file."  # non fatal
     186    LIB = os.path.join(os.path.abspath(SAGE_ROOT), 'local', 'lib')
     187    PKG = os.path.join(LIB,'pkgconfig')
     188    for name in os.listdir(PKG):
     189        filename=os.path.join(PKG,name)
     190        if os.path.splitext(filename)[1]==".pc":
     191            with open(filename) as file:
     192                config = file.read()
     193               
     194            prefix_start=config.find('SAGE_ROOT=')
     195            prefix_end=config.find('\n', prefix_start)
     196            new_prefix='SAGE_ROOT=%s'%os.path.abspath(SAGE_ROOT)
     197            new_config=config[:prefix_start]+new_prefix+config[prefix_end:]
    166198
     199            with open(filename, 'w') as file:
     200                file.write(new_config)
     201   
     202
     203def remove_files(path, remove_extensions):
     204    """
     205    Walk the tree starting at path and remove all files with
     206    extensions in remove_ext.  The extensions in remove_extensions
     207    should start with a period, i.e., remove_files(path, ('.pyc',
     208    '.pyo')).
     209    """
     210    for root, dirs, files in os.walk(path):
     211        for file in files:
     212            filename=os.path.join(root,file)
     213            if os.path.splitext(filename)[1] in remove_extensions:
     214                try:
     215                    os.unlink(filename)
     216                except OSError, msg:
     217                    print msg
     218           
    167219def __mysig(a,b):
    168220    raise KeyboardInterrupt, "computation timed out because alarm was set for %s seconds"%__alarm_time
    169221
    170222if __name__ ==  '__main__':
    171     # Check if SAGE has moved, and if so delete all .pyo and .pyc files
    172     # in the python libs directory, so they are rebuilt.
     223   
    173224    check_processor_flags()
    174     t, R = install_moved()
    175     if t:
    176         print "The Sage install tree may have moved."
    177         print "Regenerating Python.pyo and .pyc files that hardcode the install PATH"
     225    if install_moved():
     226        print "The Sage install tree may have moved"
     227        print "(from %s to %s)"%(OLD_SAGE_ROOT, SAGE_ROOT)
     228        print "Changing various hardcoded paths"
    178229        print "(please wait at most a few minutes)..."
    179230        print "Do not interrupt this."
    180         update_library_files(R)
    181         update_hardcoded_files(SAGE_ROOT + '/local/lib/python/')
    182         #update_easy_install()
    183 
    184 
     231        update_library_files()
     232        update_pkgconfig_files()
     233        # Compiled python files need to be regenerated, so we remove them
     234        remove_files(os.path.join(SAGE_ROOT, 'local', 'lib', 'python'),
     235                     remove_extensions=('.pyc', '.pyo'))
     236        print "Done resetting paths"