mirror of https://gitlab.com/ita1024/waf.git
msvcdeps: Faster case correction
Visual Studio returns paths to dependencies with incorrect case. ant_glob() is very slow for this use case (40~50% impact to overall build time). This patch uses os.listdir() to find the correct case of each path component.
This commit is contained in:
parent
80ffb62e4d
commit
2d14817f1f
|
@ -50,23 +50,42 @@ def apply_msvcdeps_flags(taskgen):
|
||||||
if taskgen.env.get_flat(flag).find(PREPROCESSOR_FLAG) < 0:
|
if taskgen.env.get_flat(flag).find(PREPROCESSOR_FLAG) < 0:
|
||||||
taskgen.env.append_value(flag, PREPROCESSOR_FLAG)
|
taskgen.env.append_value(flag, PREPROCESSOR_FLAG)
|
||||||
|
|
||||||
|
|
||||||
|
def get_correct_path_case(base_path, path):
|
||||||
|
'''
|
||||||
|
Return a case-corrected version of ``path`` by searching the filesystem for
|
||||||
|
``path``, relative to ``base_path``, using the case returned by the filesystem.
|
||||||
|
'''
|
||||||
|
components = Utils.split_path(path)
|
||||||
|
|
||||||
|
corrected_path = ''
|
||||||
|
if os.path.isabs(path):
|
||||||
|
corrected_path = components.pop(0).upper() + os.sep
|
||||||
|
|
||||||
|
for part in components:
|
||||||
|
part = part.lower()
|
||||||
|
search_path = os.path.join(base_path, corrected_path)
|
||||||
|
for item in os.listdir(search_path):
|
||||||
|
if item.lower() == part:
|
||||||
|
corrected_path = os.path.join(corrected_path, item)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise ValueError("Can't find %r in %r" % (part, search_path))
|
||||||
|
|
||||||
|
return corrected_path
|
||||||
|
|
||||||
|
|
||||||
def path_to_node(base_node, path, cached_nodes):
|
def path_to_node(base_node, path, cached_nodes):
|
||||||
'''
|
'''
|
||||||
Take the base node and the path and return a node
|
Take the base node and the path and return a node
|
||||||
Results are cached because searching the node tree is expensive
|
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...
|
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
|
# normalize the path to remove parent path components (..)
|
||||||
# parent path components (..)
|
|
||||||
path = os.path.normpath(path)
|
path = os.path.normpath(path)
|
||||||
|
|
||||||
# normalize the path case to increase likelihood of a cache hit
|
# normalize the path case to increase likelihood of a cache hit
|
||||||
path = os.path.normcase(path)
|
node_lookup_key = (base_node, 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:
|
try:
|
||||||
node = cached_nodes[node_lookup_key]
|
node = cached_nodes[node_lookup_key]
|
||||||
|
@ -76,8 +95,8 @@ def path_to_node(base_node, path, cached_nodes):
|
||||||
try:
|
try:
|
||||||
node = cached_nodes[node_lookup_key]
|
node = cached_nodes[node_lookup_key]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
node_list = base_node.ant_glob([path], ignorecase=True, remove=False, quiet=True, regex=False)
|
path = get_correct_path_case(base_node.abspath(), path)
|
||||||
node = cached_nodes[node_lookup_key] = node_list[0] if node_list else None
|
node = cached_nodes[node_lookup_key] = base_node.find_node(path)
|
||||||
|
|
||||||
return node
|
return node
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue