ninja tool sometimes obscures getting file contents for scanning
This information is collected from the discord thread at https://discord.com/channels/571796279483564041/1262451038435414027 Filing this to make sure it's captured, I did not discover it.
It is reported that sometimes dependencies are not found when generating the build.ninja file. This appears to happen because the tool monkey-patches several core SCons routines as not needed, so the ninja work can go faster. One of those has a side effect that may not be what we want:
SCons.Node.FS.File.get_contents = ninja_contents(SCons.Node.FS.File.get_contents)
Means for a File node, we get a decorated form of get_contents. The decorator is:
def ninja_contents(original):
"""Return a dummy content without doing IO"""
def wrapper(self):
if isinstance(self, SCons.Node.Node) and (self.is_sconscript() or self.is_conftest()):
return original(self)
return bytes("dummy_ninja_contents", encoding="utf-8")
return wrapper
So only if the node is an SConscript file, or we're a conftest node will the file's contents be returned, else it's skipped. That's fine - we don't need the binary file contents in ninja mode, but we do need the text contents, for use by the scanner, if the file type has a scanner. There is no consistency about how this is done across all the Node types, but in the case of File nodes, get_text_contents is implemented in terms of get_contents:
def get_text_contents(self) -> str:
"""Return the contents of the file as text."""
return SCons.Util.to_Text(self.get_contents())
Since the matching get_contents is stubbed out in this case, we don't get any file contents. Most scanners use get_text_contents, so perhaps some rethinking is needed here.
Some code permalinks:
- https://github.com/SCons/scons/blob/731337725b2ccf668c7187072328faa57ff8c144/SCons/Tool/ninja/init.py#L391C1-L391C86
- https://github.com/SCons/scons/blob/731337725b2ccf668c7187072328faa57ff8c144/SCons/Tool/ninja/Utils.py#L388
- https://github.com/SCons/scons/blob/731337725b2ccf668c7187072328faa57ff8c144/SCons/Node/FS.py#L2739