Skip to content

Commit

Permalink
Solution for Issue SCons#4275 (Compilation db get's tmp file command …
Browse files Browse the repository at this point in the history
…line), also extending serveral APIs to allow specifying an overrides dictionary which would override (at the last minute) any envvar or potentially env TARGET/SOURCE when subst is being called a subst() or subst_list(). Tests created. Docs still need to be updated.
  • Loading branch information
bdbaddog committed Dec 11, 2022
1 parent 64353b2 commit d04f2b3
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 17 deletions.
14 changes: 7 additions & 7 deletions SCons/Action.py
Original file line number Diff line number Diff line change
Expand Up @@ -875,11 +875,11 @@ def __str__(self):
return ' '.join(map(str, self.cmd_list))
return str(self.cmd_list)

def process(self, target, source, env, executor=None):
def process(self, target, source, env, executor=None, overrides=False):
if executor:
result = env.subst_list(self.cmd_list, 0, executor=executor)
result = env.subst_list(self.cmd_list, 0, executor=executor, overrides=overrides)
else:
result = env.subst_list(self.cmd_list, 0, target, source)
result = env.subst_list(self.cmd_list, 0, target, source, overrides=overrides)
silent = None
ignore = None
while True:
Expand All @@ -896,18 +896,18 @@ def process(self, target, source, env, executor=None):
pass
return result, ignore, silent

def strfunction(self, target, source, env, executor=None):
def strfunction(self, target, source, env, executor=None, overrides=False):
if self.cmdstr is None:
return None
if self.cmdstr is not _null:
from SCons.Subst import SUBST_RAW
if executor:
c = env.subst(self.cmdstr, SUBST_RAW, executor=executor)
c = env.subst(self.cmdstr, SUBST_RAW, executor=executor, overrides=overrides)
else:
c = env.subst(self.cmdstr, SUBST_RAW, target, source)
c = env.subst(self.cmdstr, SUBST_RAW, target, source, overrides=overrides)
if c:
return c
cmd_list, ignore, silent = self.process(target, source, env, executor)
cmd_list, ignore, silent = self.process(target, source, env, executor, overrides=overrides)
if silent:
return ''
return _string_from_cmd_list(cmd_list[0])
Expand Down
8 changes: 4 additions & 4 deletions SCons/ActionTests.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,15 @@ def __init__(self, **kw):
self.d[k] = v

# Just use the underlying scons_subst*() utility methods.
def subst(self, strSubst, raw=0, target=[], source=[], conv=None):
def subst(self, strSubst, raw=0, target=[], source=[], conv=None, overrides=False):
return SCons.Subst.scons_subst(strSubst, self, raw,
target, source, self.d, conv=conv)
target, source, self.d, conv=conv, overrides=overrides)

subst_target_source = subst

def subst_list(self, strSubst, raw=0, target=[], source=[], conv=None):
def subst_list(self, strSubst, raw=0, target=[], source=[], conv=None, overrides=False):
return SCons.Subst.scons_subst_list(strSubst, self, raw,
target, source, self.d, conv=conv)
target, source, self.d, conv=conv, overrides=overrides)

def __getitem__(self, item):
return self.d[item]
Expand Down
8 changes: 4 additions & 4 deletions SCons/Environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ def gvars(self):
def lvars(self):
return {}

def subst(self, string, raw=0, target=None, source=None, conv=None, executor=None):
def subst(self, string, raw=0, target=None, source=None, conv=None, executor=None, overrides=False):
"""Recursively interpolates construction variables from the
Environment into the specified string, returning the expanded
result. Construction variables are specified by a $ prefix
Expand All @@ -496,7 +496,7 @@ def subst(self, string, raw=0, target=None, source=None, conv=None, executor=Non
lvars['__env__'] = self
if executor:
lvars.update(executor.get_lvars())
return SCons.Subst.scons_subst(string, self, raw, target, source, gvars, lvars, conv)
return SCons.Subst.scons_subst(string, self, raw, target, source, gvars, lvars, conv, overrides=overrides)

def subst_kw(self, kw, raw=0, target=None, source=None):
nkw = {}
Expand All @@ -507,15 +507,15 @@ def subst_kw(self, kw, raw=0, target=None, source=None):
nkw[k] = v
return nkw

def subst_list(self, string, raw=0, target=None, source=None, conv=None, executor=None):
def subst_list(self, string, raw=0, target=None, source=None, conv=None, executor=None, overrides=False):
"""Calls through to SCons.Subst.scons_subst_list(). See
the documentation for that function."""
gvars = self.gvars()
lvars = self.lvars()
lvars['__env__'] = self
if executor:
lvars.update(executor.get_lvars())
return SCons.Subst.scons_subst_list(string, self, raw, target, source, gvars, lvars, conv)
return SCons.Subst.scons_subst_list(string, self, raw, target, source, gvars, lvars, conv, overrides=overrides)

def subst_path(self, path, target=None, source=None):
"""Substitute a path list, turning EntryProxies into Nodes
Expand Down
13 changes: 11 additions & 2 deletions SCons/Subst.py
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,8 @@ def _remove_list(list):
# space characters in the string result from the scons_subst() function.
_space_sep = re.compile(r'[\t ]+(?![^{]*})')

def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None):

def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None, overrides=False):
"""Expand a string or list containing construction variable
substitutions.
Expand Down Expand Up @@ -834,6 +835,10 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
lvars = lvars.copy()
lvars.update(d)

# Allow last ditch chance to override lvars
if overrides:
lvars.update(overrides)

# We're (most likely) going to eval() things. If Python doesn't
# find a __builtins__ value in the global dictionary used for eval(),
# it copies the current global values for you. Avoid this by
Expand Down Expand Up @@ -882,7 +887,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={

return result

def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None):
def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None,overrides=False):
"""Substitute construction variables in a string (or list or other
object) and separate the arguments into a command list.
Expand All @@ -908,6 +913,10 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
lvars = lvars.copy()
lvars.update(d)

# Allow caller to specify last ditch override of lvars
if overrides:
lvars.update(overrides)

# We're (most likely) going to eval() things. If Python doesn't
# find a __builtins__ value in the global dictionary used for eval(),
# it copies the current global values for you. Avoid this by
Expand Down
15 changes: 15 additions & 0 deletions SCons/SubstTests.py
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,14 @@ def test_CLVar(self):
assert cmd_list[0][3] == "call", cmd_list[0][3]
assert cmd_list[0][4] == "test", cmd_list[0][4]


def test_subst_overriding_lvars_overrides(self):
"""Test that optional passed arg overrides overrides gvars, and existing lvars."""
env=DummyEnv({'XXX' : 'xxx'})
result = scons_subst('$XXX', env, gvars=env.Dictionary(), overrides={'XXX': 'yyz'})
assert result == 'yyz', result


class scons_subst_list_TestCase(SubstTestCase):

basic_cases = [
Expand Down Expand Up @@ -1102,6 +1110,13 @@ def test_subst_list_overriding_gvars2(self):
result = scons_subst_list('$XXX', env, gvars={'XXX' : 'yyy'})
assert result == [['yyy']], result

def test_subst_list_overriding_lvars_overrides(self):
"""Test that optional passed arg overrides overrides gvars, and existing lvars."""
env = DummyEnv({'XXX':'xxx'})
result = scons_subst_list('$XXX', env, gvars=env.Dictionary(), overrides={'XXX': 'yyy'})
assert result == [['yyy']], result


class scons_subst_once_TestCase(unittest.TestCase):

loc = {
Expand Down
9 changes: 9 additions & 0 deletions SCons/Tool/compilation_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import fnmatch
import SCons

from SCons.Platform import TempFileMunge

from .cxx import CXXSuffixes
from .cc import CSuffixes
from .asm import ASSuffixes, ASPPSuffixes
Expand All @@ -53,6 +55,7 @@ def __init__(self, value):
SCons.Node.Python.Value.__init__(self, value)
self.Decider(changed_since_last_build_node)


def changed_since_last_build_node(child, target, prev_ni, node):
""" Dummy decider to force always building"""
return True
Expand Down Expand Up @@ -103,6 +106,11 @@ def emit_compilation_db_entry(target, source, env):
return emit_compilation_db_entry


class CompDBTEMPFILE(TempFileMunge):
def __call__(self, target, source, env, for_signature):
return self.cmd


def compilation_db_entry_action(target, source, env, **kw):
"""
Create a dictionary with evaluated command line, target, source
Expand All @@ -119,6 +127,7 @@ def compilation_db_entry_action(target, source, env, **kw):
target=env["__COMPILATIONDB_UOUTPUT"],
source=env["__COMPILATIONDB_USOURCE"],
env=env["__COMPILATIONDB_ENV"],
overrides={'TEMPFILE': CompDBTEMPFILE}
)

entry = {
Expand Down

0 comments on commit d04f2b3

Please sign in to comment.