Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(292)

Side by Side Diff: scons-2.0.1/engine/SCons/CacheDir.py

Issue 6711079: Added an unmodified copy of SCons to third_party. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/third_party/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « scons-2.0.1/engine/SCons/Builder.py ('k') | scons-2.0.1/engine/SCons/Conftest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 #
2 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The S Cons Foundation
3 #
4 # Permission is hereby granted, free of charge, to any person obtaining
5 # a copy of this software and associated documentation files (the
6 # "Software"), to deal in the Software without restriction, including
7 # without limitation the rights to use, copy, modify, merge, publish,
8 # distribute, sublicense, and/or sell copies of the Software, and to
9 # permit persons to whom the Software is furnished to do so, subject to
10 # the following conditions:
11 #
12 # The above copyright notice and this permission notice shall be included
13 # in all copies or substantial portions of the Software.
14 #
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
16 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
17 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 #
23
24 __revision__ = "src/engine/SCons/CacheDir.py 5134 2010/08/16 23:02:40 bdeegan"
25
26 __doc__ = """
27 CacheDir support
28 """
29
30 import os.path
31 import stat
32 import sys
33
34 import SCons.Action
35
36 cache_enabled = True
37 cache_debug = False
38 cache_force = False
39 cache_show = False
40
41 def CacheRetrieveFunc(target, source, env):
42 t = target[0]
43 fs = t.fs
44 cd = env.get_CacheDir()
45 cachedir, cachefile = cd.cachepath(t)
46 if not fs.exists(cachefile):
47 cd.CacheDebug('CacheRetrieve(%s): %s not in cache\n', t, cachefile)
48 return 1
49 cd.CacheDebug('CacheRetrieve(%s): retrieving from %s\n', t, cachefile)
50 if SCons.Action.execute_actions:
51 if fs.islink(cachefile):
52 fs.symlink(fs.readlink(cachefile), t.path)
53 else:
54 env.copy_from_cache(cachefile, t.path)
55 st = fs.stat(cachefile)
56 fs.chmod(t.path, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
57 return 0
58
59 def CacheRetrieveString(target, source, env):
60 t = target[0]
61 fs = t.fs
62 cd = env.get_CacheDir()
63 cachedir, cachefile = cd.cachepath(t)
64 if t.fs.exists(cachefile):
65 return "Retrieved `%s' from cache" % t.path
66 return None
67
68 CacheRetrieve = SCons.Action.Action(CacheRetrieveFunc, CacheRetrieveString)
69
70 CacheRetrieveSilent = SCons.Action.Action(CacheRetrieveFunc, None)
71
72 def CachePushFunc(target, source, env):
73 t = target[0]
74 if t.nocache:
75 return
76 fs = t.fs
77 cd = env.get_CacheDir()
78 cachedir, cachefile = cd.cachepath(t)
79 if fs.exists(cachefile):
80 # Don't bother copying it if it's already there. Note that
81 # usually this "shouldn't happen" because if the file already
82 # existed in cache, we'd have retrieved the file from there,
83 # not built it. This can happen, though, in a race, if some
84 # other person running the same build pushes their copy to
85 # the cache after we decide we need to build it but before our
86 # build completes.
87 cd.CacheDebug('CachePush(%s): %s already exists in cache\n', t, cachefi le)
88 return
89
90 cd.CacheDebug('CachePush(%s): pushing to %s\n', t, cachefile)
91
92 tempfile = cachefile+'.tmp'+str(os.getpid())
93 errfmt = "Unable to copy %s to cache. Cache file is %s"
94
95 if not fs.isdir(cachedir):
96 try:
97 fs.makedirs(cachedir)
98 except EnvironmentError:
99 # We may have received an exception because another process
100 # has beaten us creating the directory.
101 if not fs.isdir(cachedir):
102 msg = errfmt % (str(target), cachefile)
103 raise SCons.Errors.EnvironmentError(msg)
104
105 try:
106 if fs.islink(t.path):
107 fs.symlink(fs.readlink(t.path), tempfile)
108 else:
109 fs.copy2(t.path, tempfile)
110 fs.rename(tempfile, cachefile)
111 st = fs.stat(t.path)
112 fs.chmod(cachefile, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
113 except EnvironmentError:
114 # It's possible someone else tried writing the file at the
115 # same time we did, or else that there was some problem like
116 # the CacheDir being on a separate file system that's full.
117 # In any case, inability to push a file to cache doesn't affect
118 # the correctness of the build, so just print a warning.
119 msg = errfmt % (str(target), cachefile)
120 SCons.Warnings.warn(SCons.Warnings.CacheWriteErrorWarning, msg)
121
122 CachePush = SCons.Action.Action(CachePushFunc, None)
123
124 class CacheDir(object):
125
126 def __init__(self, path):
127 try:
128 import hashlib
129 except ImportError:
130 msg = "No hashlib or MD5 module available, CacheDir() not supported"
131 SCons.Warnings.warn(SCons.Warnings.NoMD5ModuleWarning, msg)
132 self.path = None
133 else:
134 self.path = path
135 self.current_cache_debug = None
136 self.debugFP = None
137
138 def CacheDebug(self, fmt, target, cachefile):
139 if cache_debug != self.current_cache_debug:
140 if cache_debug == '-':
141 self.debugFP = sys.stdout
142 elif cache_debug:
143 self.debugFP = open(cache_debug, 'w')
144 else:
145 self.debugFP = None
146 self.current_cache_debug = cache_debug
147 if self.debugFP:
148 self.debugFP.write(fmt % (target, os.path.split(cachefile)[1]))
149
150 def is_enabled(self):
151 return (cache_enabled and not self.path is None)
152
153 def cachepath(self, node):
154 """
155 """
156 if not self.is_enabled():
157 return None, None
158
159 sig = node.get_cachedir_bsig()
160 subdir = sig[0].upper()
161 dir = os.path.join(self.path, subdir)
162 return dir, os.path.join(dir, sig)
163
164 def retrieve(self, node):
165 """
166 This method is called from multiple threads in a parallel build,
167 so only do thread safe stuff here. Do thread unsafe stuff in
168 built().
169
170 Note that there's a special trick here with the execute flag
171 (one that's not normally done for other actions). Basically
172 if the user requested a no_exec (-n) build, then
173 SCons.Action.execute_actions is set to 0 and when any action
174 is called, it does its showing but then just returns zero
175 instead of actually calling the action execution operation.
176 The problem for caching is that if the file does NOT exist in
177 cache then the CacheRetrieveString won't return anything to
178 show for the task, but the Action.__call__ won't call
179 CacheRetrieveFunc; instead it just returns zero, which makes
180 the code below think that the file *was* successfully
181 retrieved from the cache, therefore it doesn't do any
182 subsequent building. However, the CacheRetrieveString didn't
183 print anything because it didn't actually exist in the cache,
184 and no more build actions will be performed, so the user just
185 sees nothing. The fix is to tell Action.__call__ to always
186 execute the CacheRetrieveFunc and then have the latter
187 explicitly check SCons.Action.execute_actions itself.
188 """
189 if not self.is_enabled():
190 return False
191
192 env = node.get_build_env()
193 if cache_show:
194 if CacheRetrieveSilent(node, [], env, execute=1) == 0:
195 node.build(presub=0, execute=0)
196 return True
197 else:
198 if CacheRetrieve(node, [], env, execute=1) == 0:
199 return True
200
201 return False
202
203 def push(self, node):
204 if not self.is_enabled():
205 return
206 return CachePush(node, [], node.get_build_env())
207
208 def push_if_forced(self, node):
209 if cache_force:
210 return self.push(node)
211
212 # Local Variables:
213 # tab-width:4
214 # indent-tabs-mode:nil
215 # End:
216 # vim: set expandtab tabstop=4 shiftwidth=4:
OLDNEW
« no previous file with comments | « scons-2.0.1/engine/SCons/Builder.py ('k') | scons-2.0.1/engine/SCons/Conftest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698