# 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
|
|
2 | 2 | |
3 | 3 | import os, sys |
4 | 4 | |
5 | | SAGE_ROOT = os.environ['SAGE_ROOT'] |
| 5 | OLD_SAGE_ROOT = None |
| 6 | SAGE_ROOT = os.path.realpath(os.environ['SAGE_ROOT']) |
6 | 7 | |
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 | | |
| 8 | location_file = os.path.join(SAGE_ROOT, 'local', 'lib', 'sage-current-location.txt') |
| 9 | flags_file = os.path.join(SAGE_ROOT, 'local', 'lib', 'sage-flags.txt') |
35 | 10 | |
36 | 11 | # The flags we care about recording in the local/lib/sage-flags.txt file |
37 | 12 | # In SAGE_FAT_BINARY mode we only require that ['sse', 'sse2', '3d', |
… |
… |
|
48 | 23 | else: |
49 | 24 | FLAGS = ['sse', 'sse2', 'ssse3', '3d', 'mmx', 'pni', 'cmov'] |
50 | 25 | |
| 26 | |
| 27 | def 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 | |
| 36 | def 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 | |
| 49 | def 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 | |
51 | 82 | def get_flags_info(): |
52 | 83 | """ |
53 | 84 | Return a space-separated string that lists the flags supported by |
… |
… |
|
67 | 98 | return ' '.join(set(x for x in r.split() if x in FLAGS)) |
68 | 99 | |
69 | 100 | 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 |
71 | 102 | # particular, for non Linux systems I have no clue how to get |
72 | 103 | # the processor flags, and we so far have never ever had any |
73 | 104 | # problem with processor flags on such machines. So we don't |
74 | 105 | # bother. |
75 | 106 | 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()) |
83 | 107 | |
84 | 108 | def check_processor_flags(): |
85 | 109 | """ |
… |
… |
|
109 | 133 | print "*"*70 |
110 | 134 | sys.exit(1) |
111 | 135 | |
112 | | def update_library_files(R): |
113 | | LIB = '%s/local/lib/'%os.path.abspath(SAGE_ROOT) |
| 136 | def 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') |
114 | 142 | # The .a files should be re-ranlib'd |
115 | 143 | os.system('cd "%s"; ranlib *.a 1>/dev/null 2>/dev/null'%LIB) |
116 | 144 | |
117 | | # The .la files hardcode path info. Fix this. |
| 145 | # The .la files hardcode path info, so we manually fix the path |
| 146 | # info |
118 | 147 | 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() |
121 | 150 | i = G.find('libdir=') |
122 | 151 | j = i+8 + G[i+8:].find("'") |
123 | 152 | z = G[i+8:j].strip().strip("'") |
… |
… |
|
125 | 154 | if i != -1: |
126 | 155 | z = z[:i] |
127 | 156 | 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) |
129 | 158 | |
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 |
142 | 159 | |
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() |
| 160 | def 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}") |
148 | 174 | |
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 | |
| 182 | def update_pkgconfig_files(): |
152 | 183 | """ |
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. |
156 | 185 | """ |
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:] |
166 | 198 | |
| 199 | with open(filename, 'w') as file: |
| 200 | file.write(new_config) |
| 201 | |
| 202 | |
| 203 | def 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 | |
167 | 219 | def __mysig(a,b): |
168 | 220 | raise KeyboardInterrupt, "computation timed out because alarm was set for %s seconds"%__alarm_time |
169 | 221 | |
170 | 222 | if __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 | |
173 | 224 | 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" |
178 | 229 | print "(please wait at most a few minutes)..." |
179 | 230 | 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" |