forked from ethanchewy/PythonBuddy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgcc_cache.py
More file actions
80 lines (76 loc) · 2.8 KB
/
gcc_cache.py
File metadata and controls
80 lines (76 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
from hashlib import md5
import py, os, sys
def cache_file_path(c_files, eci, cachename):
"Builds a filename to cache compilation data"
# Import 'platform' every time, the compiler may have been changed
from rpython.translator.platform import platform
from rpython.config.translationoption import CACHE_DIR
cache_root = py.path.local(CACHE_DIR).ensure(dir=1)
cache_dir = cache_root.join(cachename).ensure(dir=1)
filecontents = [c_file.read() for c_file in c_files]
key = repr((filecontents, eci, platform.key()))
hash = md5(key).hexdigest()
return cache_dir.join(hash)
def build_executable_cache(c_files, eci, ignore_errors=False):
"Builds and run a program; caches the result"
# Import 'platform' every time, the compiler may have been changed
from rpython.translator.platform import platform
path = cache_file_path(c_files, eci, 'build_executable_cache')
try:
return path.read()
except py.error.Error:
_previous = platform.log_errors
try:
if ignore_errors:
platform.log_errors = False
result = platform.execute(platform.compile(c_files, eci))
if result.err:
sys.stderr.write(result.err)
finally:
if ignore_errors:
del platform.log_errors
# ^^^remove from the instance --- needed so that it can
# compare equal to another instance without it
if platform.log_errors != _previous:
platform.log_errors = _previous
if not result.err:
try_atomic_write(path, result.out)
return result.out
def try_atomic_write(path, data):
path = str(path)
tmppath = '%s~%d' % (path, os.getpid())
f = open(tmppath, 'wb')
f.write(data)
f.close()
try:
os.rename(tmppath, path)
except OSError:
try:
os.unlink(tmppath)
except OSError:
pass
def try_compile_cache(c_files, eci):
"Try to compile a program. If it works, caches this fact."
# Import 'platform' every time, the compiler may have been changed
from rpython.translator.platform import platform
path = cache_file_path(c_files, eci, 'try_compile_cache')
try:
data = path.read()
if data == 'True':
return True
except py.error.Error:
pass
#
_previous = platform.log_errors
try:
platform.log_errors = False
platform.compile(c_files, eci)
# ^^^ may raise CompilationError. We don't cache such results.
finally:
del platform.log_errors
# ^^^remove from the instance --- needed so that it can
# compare equal to another instance without it
if platform.log_errors != _previous:
platform.log_errors = _previous
path.write('True')
return True