summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons
diff options
context:
space:
mode:
authorRussel Winder <russel@winder.org.uk>2016-04-10 09:41:00 (GMT)
committerRussel Winder <russel@winder.org.uk>2016-04-10 09:41:00 (GMT)
commit6a37189174372c9c98c63ada58ab4352adf650e8 (patch)
tree521ddb1071569fa90100e11d7f03af13d5689aaf /src/engine/SCons
parent14924bcc1713c5bd7dcf4db5b420204407048889 (diff)
parent3e0a831c7fcd60384266e14641a3a15f2cba1ced (diff)
downloadSCons-6a37189174372c9c98c63ada58ab4352adf650e8.zip
SCons-6a37189174372c9c98c63ada58ab4352adf650e8.tar.gz
SCons-6a37189174372c9c98c63ada58ab4352adf650e8.tar.bz2
Commit resolved conflicted merge.
Diffstat (limited to 'src/engine/SCons')
-rw-r--r--src/engine/SCons/CacheDir.py72
-rw-r--r--src/engine/SCons/CacheDirTests.py13
-rw-r--r--src/engine/SCons/SConf.py8
-rw-r--r--src/engine/SCons/Warnings.py4
4 files changed, 82 insertions, 15 deletions
diff --git a/src/engine/SCons/CacheDir.py b/src/engine/SCons/CacheDir.py
index 3b7d06f..1690674 100644
--- a/src/engine/SCons/CacheDir.py
+++ b/src/engine/SCons/CacheDir.py
@@ -27,7 +27,8 @@ __doc__ = """
CacheDir support
"""
-import os.path
+import json
+import os
import stat
import sys
@@ -72,7 +73,8 @@ CacheRetrieve = SCons.Action.Action(CacheRetrieveFunc, CacheRetrieveString)
CacheRetrieveSilent = SCons.Action.Action(CacheRetrieveFunc, None)
def CachePushFunc(target, source, env):
- if cache_readonly: return
+ if cache_readonly:
+ return
t = target[0]
if t.nocache:
@@ -125,6 +127,10 @@ def CachePushFunc(target, source, env):
CachePush = SCons.Action.Action(CachePushFunc, None)
+# Nasty hack to cut down to one warning for each cachedir path that needs
+# upgrading.
+warned = dict()
+
class CacheDir(object):
def __init__(self, path):
@@ -133,11 +139,63 @@ class CacheDir(object):
except ImportError:
msg = "No hashlib or MD5 module available, CacheDir() not supported"
SCons.Warnings.warn(SCons.Warnings.NoMD5ModuleWarning, msg)
- self.path = None
- else:
- self.path = path
+ path = None
+ self.path = path
self.current_cache_debug = None
self.debugFP = None
+ self.config = dict()
+ if path is None:
+ return
+ # See if there's a config file in the cache directory. If there is,
+ # use it. If there isn't, and the directory exists and isn't empty,
+ # produce a warning. If the directory doesn't exist or is empty,
+ # write a config file.
+ config_file = os.path.join(path, 'config')
+ if not os.path.exists(config_file):
+ # A note: There is a race hazard here, if two processes start and
+ # attempt to create the cache directory at the same time. However,
+ # python doesn't really give you the option to do exclusive file
+ # creation (it doesn't even give you the option to error on opening
+ # an existing file for writing...). The ordering of events here
+ # as an attempt to alleviate this, on the basis that it's a pretty
+ # unlikely occurence (it'd require two builds with a brand new cache
+ # directory)
+ if os.path.isdir(path) and len(os.listdir(path)) != 0:
+ self.config['prefix_len'] = 1
+ # When building the project I was testing this on, the warning
+ # was output over 20 times. That seems excessive
+ global warned
+ if self.path not in warned:
+ msg = "Please upgrade your cache by running " +\
+ " scons-configure-cache.py " + self.path
+ SCons.Warnings.warn(SCons.Warnings.CacheVersionWarning, msg)
+ warned[self.path] = True
+ else:
+ if not os.path.isdir(path):
+ try:
+ os.makedirs(path)
+ except OSError:
+ # If someone else is trying to create the directory at
+ # the same time as me, bad things will happen
+ msg = "Failed to create cache directory " + path
+ raise SCons.Errors.EnvironmentError(msg)
+
+ self.config['prefix_len'] = 2
+ if not os.path.exists(config_file):
+ try:
+ with open(config_file, 'w') as config:
+ json.dump(self.config, config)
+ except:
+ msg = "Failed to write cache configuration for " + path
+ raise SCons.Errors.EnvironmentError(msg)
+ else:
+ try:
+ with open(config_file) as config:
+ self.config = json.load(config)
+ except ValueError:
+ msg = "Failed to read cache configuration for " + path
+ raise SCons.Errors.EnvironmentError(msg)
+
def CacheDebug(self, fmt, target, cachefile):
if cache_debug != self.current_cache_debug:
@@ -152,7 +210,7 @@ class CacheDir(object):
self.debugFP.write(fmt % (target, os.path.split(cachefile)[1]))
def is_enabled(self):
- return (cache_enabled and not self.path is None)
+ return cache_enabled and not self.path is None
def is_readonly(self):
return cache_readonly
@@ -164,7 +222,7 @@ class CacheDir(object):
return None, None
sig = node.get_cachedir_bsig()
- subdir = sig[0].upper()
+ subdir = sig[:self.config['prefix_len']].upper()
dir = os.path.join(self.path, subdir)
return dir, os.path.join(dir, sig)
diff --git a/src/engine/SCons/CacheDirTests.py b/src/engine/SCons/CacheDirTests.py
index 878a87a..8a52928 100644
--- a/src/engine/SCons/CacheDirTests.py
+++ b/src/engine/SCons/CacheDirTests.py
@@ -83,6 +83,11 @@ class BaseTestCase(unittest.TestCase):
#node.binfo.ninfo.bsig = bsig
return node
+ def tearDown(self):
+ os.remove(os.path.join(self._CacheDir.path, 'config'))
+ os.rmdir(self._CacheDir.path)
+ # Should that be shutil.rmtree?
+
class CacheDirTestCase(BaseTestCase):
"""
Test calling CacheDir code directly.
@@ -98,10 +103,12 @@ class CacheDirTestCase(BaseTestCase):
SCons.Util.MD5collect = my_collect
try:
- f5 = self.File("cd.f5", 'a_fake_bsig')
+ name = 'a_fake_bsig'
+ f5 = self.File("cd.f5", name)
result = self._CacheDir.cachepath(f5)
- dirname = os.path.join('cache', 'A')
- filename = os.path.join(dirname, 'a_fake_bsig')
+ len = self._CacheDir.config['prefix_len']
+ dirname = os.path.join('cache', name.upper()[:len])
+ filename = os.path.join(dirname, name)
assert result == (dirname, filename), result
finally:
SCons.Util.MD5collect = save_collect
diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py
index 935eef2..d56b333 100644
--- a/src/engine/SCons/SConf.py
+++ b/src/engine/SCons/SConf.py
@@ -756,10 +756,10 @@ class CheckContext(object):
A typical test is just a callable with an instance of CheckContext as
first argument:
- def CheckCustom(context, ...)
- context.Message('Checking my weird test ... ')
- ret = myWeirdTestFunction(...)
- context.Result(ret)
+ def CheckCustom(context, ...):
+ context.Message('Checking my weird test ... ')
+ ret = myWeirdTestFunction(...)
+ context.Result(ret)
Often, myWeirdTestFunction will be one of
context.TryCompile/context.TryLink/context.TryRun. The results of
diff --git a/src/engine/SCons/Warnings.py b/src/engine/SCons/Warnings.py
index 5c27825..2495b89 100644
--- a/src/engine/SCons/Warnings.py
+++ b/src/engine/SCons/Warnings.py
@@ -41,10 +41,12 @@ class WarningOnByDefault(Warning):
# NOTE: If you add a new warning class, add it to the man page, too!
-
class TargetNotBuiltWarning(Warning): # Should go to OnByDefault
pass
+class CacheVersionWarning(WarningOnByDefault):
+ pass
+
class CacheWriteErrorWarning(Warning):
pass