summaryrefslogtreecommitdiffstats
path: root/extras/msvcdeps.py
diff options
context:
space:
mode:
Diffstat (limited to 'extras/msvcdeps.py')
-rw-r--r--extras/msvcdeps.py73
1 files changed, 34 insertions, 39 deletions
diff --git a/extras/msvcdeps.py b/extras/msvcdeps.py
index fc1ecd4..873a419 100644
--- a/extras/msvcdeps.py
+++ b/extras/msvcdeps.py
@@ -50,28 +50,35 @@ def apply_msvcdeps_flags(taskgen):
if taskgen.env.get_flat(flag).find(PREPROCESSOR_FLAG) < 0:
taskgen.env.append_value(flag, PREPROCESSOR_FLAG)
- # Figure out what casing conventions the user's shell used when
- # launching Waf
- (drive, _) = os.path.splitdrive(taskgen.bld.srcnode.abspath())
- taskgen.msvcdeps_drive_lowercase = drive == drive.lower()
-
def path_to_node(base_node, path, cached_nodes):
- # Take the base node and the path and return a node
- # Results are cached because searching the node tree is expensive
- # The following code is executed by threads, it is not safe, so a lock is needed...
- if getattr(path, '__hash__'):
- node_lookup_key = (base_node, path)
- else:
- # Not hashable, assume it is a list and join into a string
- node_lookup_key = (base_node, os.path.sep.join(path))
+ '''
+ Take the base node and the path and return a node
+ Results are cached because searching the node tree is expensive
+ The following code is executed by threads, it is not safe, so a lock is needed...
+ '''
+ # normalize the path because ant_glob() does not understand
+ # parent path components (..)
+ path = os.path.normpath(path)
+
+ # normalize the path case to increase likelihood of a cache hit
+ path = os.path.normcase(path)
+
+ # ant_glob interprets [] and () characters, so those must be replaced
+ path = path.replace('[', '?').replace(']', '?').replace('(', '[(]').replace(')', '[)]')
+
+ node_lookup_key = (base_node, path)
+
try:
- lock.acquire()
node = cached_nodes[node_lookup_key]
except KeyError:
- node = base_node.find_resource(path)
- cached_nodes[node_lookup_key] = node
- finally:
- lock.release()
+ # retry with lock on cache miss
+ with lock:
+ try:
+ node = cached_nodes[node_lookup_key]
+ except KeyError:
+ node_list = base_node.ant_glob([path], ignorecase=True, remove=False, quiet=True, regex=False)
+ node = cached_nodes[node_lookup_key] = node_list[0] if node_list else None
+
return node
def post_run(self):
@@ -86,11 +93,6 @@ def post_run(self):
unresolved_names = []
resolved_nodes = []
- lowercase = self.generator.msvcdeps_drive_lowercase
- correct_case_path = bld.path.abspath()
- correct_case_path_len = len(correct_case_path)
- correct_case_path_norm = os.path.normcase(correct_case_path)
-
# Dynamically bind to the cache
try:
cached_nodes = bld.cached_nodes
@@ -100,26 +102,15 @@ def post_run(self):
for path in self.msvcdeps_paths:
node = None
if os.path.isabs(path):
- # Force drive letter to match conventions of main source tree
- drive, tail = os.path.splitdrive(path)
-
- if os.path.normcase(path[:correct_case_path_len]) == correct_case_path_norm:
- # Path is in the sandbox, force it to be correct. MSVC sometimes returns a lowercase path.
- path = correct_case_path + path[correct_case_path_len:]
- else:
- # Check the drive letter
- if lowercase and (drive != drive.lower()):
- path = drive.lower() + tail
- elif (not lowercase) and (drive != drive.upper()):
- path = drive.upper() + tail
node = path_to_node(bld.root, path, cached_nodes)
else:
+ # when calling find_resource, make sure the path does not begin with '..'
base_node = bld.bldnode
- # when calling find_resource, make sure the path does not begin by '..'
path = [k for k in Utils.split_path(path) if k and k != '.']
while path[0] == '..':
- path = path[1:]
+ path.pop(0)
base_node = base_node.parent
+ path = os.sep.join(path)
node = path_to_node(base_node, path, cached_nodes)
@@ -213,8 +204,12 @@ def exec_command(self, cmd, **kw):
raw_out = self.generator.bld.cmd_and_log(cmd + ['@' + tmp], **kw)
ret = 0
except Errors.WafError as e:
- raw_out = e.stdout
- ret = e.returncode
+ # Use e.msg if e.stdout is not set
+ raw_out = getattr(e, 'stdout', e.msg)
+
+ # Return non-zero error code even if we didn't
+ # get one from the exception object
+ ret = getattr(e, 'returncode', 1)
for line in raw_out.splitlines():
if line.startswith(INCLUDE_PATTERN):