mirror of https://gitlab.com/ita1024/waf.git
msvcdeps: use ant_glob() to get correct case of include paths
When using msvcdeps, header dependencies are not detected reliably for generated source files. The root cause is a bug in versions of MSVC prior to VS2019 16.0 in which it emits lower-case path prefixes when resolving include paths relative to the containing file. Absolute paths and paths relative to include directories passed in the MSVC command line are, in contrast, case-correct. Such a file-relative include directive with an incorrect lower-case prefix derails waf's node hash signature handling and fails silently. This change uses ant_glob() with the ignorecase keyword argument to find the file on the filesystem with the correct case. The prior case-correction code has been superseded and was removed. See the following Visual Studio bug report for details on the issue: https://developercommunity.visualstudio.com/content/problem/233871/showincludes-lowercases-some-path-segments.html
This commit is contained in:
parent
7c362340af
commit
9caad8c3ba
|
@ -50,17 +50,19 @@ 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)
|
||||||
|
|
||||||
# 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):
|
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
|
||||||
|
# parent path components (..)
|
||||||
|
path = os.path.normpath(path)
|
||||||
|
|
||||||
|
# normalize the path case to increase likelihood of a cache hit
|
||||||
|
path = os.path.normcase(path)
|
||||||
|
|
||||||
node_lookup_key = (base_node, path)
|
node_lookup_key = (base_node, path)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -71,7 +73,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 = cached_nodes[node_lookup_key] = base_node.find_resource(path)
|
node_list = base_node.ant_glob([path], ignorecase=True, remove=False, quiet=True)
|
||||||
|
node = cached_nodes[node_lookup_key] = node_list[0] if node_list else None
|
||||||
|
|
||||||
return node
|
return node
|
||||||
|
|
||||||
|
@ -87,11 +90,6 @@ def post_run(self):
|
||||||
unresolved_names = []
|
unresolved_names = []
|
||||||
resolved_nodes = []
|
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
|
# Dynamically bind to the cache
|
||||||
try:
|
try:
|
||||||
cached_nodes = bld.cached_nodes
|
cached_nodes = bld.cached_nodes
|
||||||
|
@ -101,18 +99,6 @@ def post_run(self):
|
||||||
for path in self.msvcdeps_paths:
|
for path in self.msvcdeps_paths:
|
||||||
node = None
|
node = None
|
||||||
if os.path.isabs(path):
|
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)
|
node = path_to_node(bld.root, path, cached_nodes)
|
||||||
else:
|
else:
|
||||||
# when calling find_resource, make sure the path does not begin with '..'
|
# when calling find_resource, make sure the path does not begin with '..'
|
||||||
|
|
Loading…
Reference in New Issue