Skip to content
This repository was archived by the owner on Feb 4, 2020. It is now read-only.

Commit c876277

Browse files
committed
Support CLCACHE_BASEDIR in nodirect mode
Do a simple case-insensitive find-and-replace to transform absolute paths into relative paths within the preprocessor output that is used to compute the hash. This makes CLCACHE_NODIRECT mode usable in the presence of the __FILE__ macro. Fixes a bug in _normalizedCommandLine that caused the source filename to be included in the hash computation.
1 parent dd7bf50 commit c876277

File tree

4 files changed

+45
-6
lines changed

4 files changed

+45
-6
lines changed

README.asciidoc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,11 @@ CLCACHE_NODIRECT::
8686
key. Use this if you experience problems with direct mode or if you need
8787
built-in macroses like \__TIME__ to work correctly.
8888
CLCACHE_BASEDIR::
89-
Has effect only when direct mode is on. Set this to path to root directory
90-
of your project. This allows clcache to cache relative paths, so if you
91-
move your project to different directory, clcache will produce cache hits as
92-
before.
89+
Set this to path to root directory of your project. In direct mode, this allows
90+
clcache to cache relative paths, so if you move your project to different directory,
91+
clcache will produce cache hits as before. When direct mode is disabled, clcache will
92+
translate any absolute paths in the preprocessor output into relative paths before
93+
computing the hash.
9394
CLCACHE_OBJECT_CACHE_TIMEOUT_MS::
9495
Overrides the default ObjectCacheLock timeout (Default is 10 * 1000 ms).
9596
The ObjectCacheLock is used to give exclusive access to the cache, which is

clcache/__main__.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,19 @@ def normalizeBaseDir(baseDir):
118118
return None
119119

120120

121+
def caseInsensitiveReplace(data, old, new):
122+
dataLower = data.lower()
123+
oldLower = old.lower()
124+
output = b''
125+
index = 0
126+
while True:
127+
nextIndex = dataLower.find(oldLower, index)
128+
if nextIndex < 0:
129+
return output + data[index:]
130+
output += data[index:nextIndex] + new
131+
index = nextIndex + len(old)
132+
133+
121134
def getCachedCompilerConsoleOutput(path):
122135
try:
123136
with open(path, 'rb') as f:
@@ -469,6 +482,11 @@ def computeKeyNodirect(compilerBinary, commandLine, environment):
469482
compilerHash = getCompilerHash(compilerBinary)
470483
normalizedCmdLine = CompilerArtifactsRepository._normalizedCommandLine(commandLine)
471484

485+
if "CLCACHE_BASEDIR" in os.environ:
486+
baseDir = normalizeBaseDir(os.environ["CLCACHE_BASEDIR"]).replace("\\", "\\\\").encode("UTF-8")
487+
newBaseDir = BASEDIR_REPLACEMENT.encode("UTF-8")
488+
preprocessedSourceCode = re.sub(re.escape(baseDir), newBaseDir, preprocessedSourceCode, flags=re.IGNORECASE)
489+
472490
h = HashAlgorithm()
473491
h.update(compilerHash.encode("UTF-8"))
474492
h.update(' '.join(normalizedCmdLine).encode("UTF-8"))
@@ -495,7 +513,7 @@ def _normalizedCommandLine(cmdline):
495513
argsToStrip += ("MP",)
496514

497515
return [arg for arg in cmdline
498-
if not (arg[0] in "/-" and arg[1:].startswith(argsToStrip))]
516+
if arg[0] in "/-" and not arg[1:].startswith(argsToStrip)]
499517

500518
class CacheFileStrategy:
501519
def __init__(self, cacheDirectory=None):
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <iostream>
2+
3+
int main()
4+
{
5+
std::cout << __FILE__ << '\n';
6+
}
7+
8+

tests/test_integration.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1069,12 +1069,14 @@ def tearDown(self):
10691069
os.chdir(self.savedCwd)
10701070
self.tempDir.cleanup()
10711071

1072-
def _runCompiler(self, cppFile, extraArgs=None):
1072+
def _runCompiler(self, cppFile, extraArgs=None, direct=True):
10731073
cmd = CLCACHE_CMD + ["/nologo", "/EHsc", "/c"]
10741074
if extraArgs:
10751075
cmd.extend(extraArgs)
10761076
cmd.append(cppFile)
10771077
env = dict(os.environ, CLCACHE_DIR=self.clcacheDir, CLCACHE_BASEDIR=os.getcwd())
1078+
if not direct:
1079+
env["CLCACHE_NODIRECT"] = "1"
10781080
self.assertEqual(subprocess.call(cmd, env=env), 0)
10791081

10801082
def expectHit(self, runCompiler):
@@ -1140,6 +1142,16 @@ def runCompiler():
11401142
self._runCompiler("main.cpp", ["/DRESOURCES_DIR={}".format(os.getcwd())])
11411143
self.expectMiss([runCompiler, runCompiler])
11421144

1145+
def testBasedirNoDirectAbsolutePath(self):
1146+
def runCompiler():
1147+
self._runCompiler(os.path.join(os.getcwd(), "main.cpp"), direct=False)
1148+
self.expectHit([runCompiler, runCompiler])
1149+
1150+
def testBasedirNoDirectFileMacro(self):
1151+
def runCompiler():
1152+
self._runCompiler(os.path.join(os.getcwd(), "filemacro.cpp"), direct=False)
1153+
self.expectHit([runCompiler, runCompiler])
1154+
11431155
def testBasedirRelativeIncludeArg(self):
11441156
basedir = os.getcwd()
11451157

0 commit comments

Comments
 (0)