scons signatures for Python actions

Finally, I traced out why time-to-time my functional tests stop passing.
* Some steps are associated with Python functions.
* Signatures of such steps depend on the code of the functions.
* If the code of a function is changed, the signature is changes, and the step is considered out-of-date.
Therefore, small changes in code lead to changes in the build process.

I’m tired of updating tests, so decided to trace out and fix the problem. With the following code, the signature doesn’t depend on the code, only on the function name.

import sys, os, re, string
import SCons.Action

#
# When a Python function is changed, SCons signals "the contents
# of the build action changed" and re-builds the target. It breaks
# all the functional tests, so let's use customized signature
# when in the test mode.
#
def change_function_signature():
  #
  # Do nothing when not in the test mode
  #
  check = os.getenv('cdoc_testtest_sconscript')
  if not check:
    return
  #
  # Customized signature calculation: if "f" is function, return
  # "str(f)" with masked pointers plus something I don't know.
  #
  re_drop_pointer = re.compile('0x[0123456789ABCDEFabcdef]{8}')
  def get_contents(self, target, source, env):
    s = str(self.execfunction)
    s = re.sub(re_drop_pointer, '0xXXXXXXXX', s)
    s = s + env.subst(string.join(map(lambda v: '${'+v+'}', self.varlist)))
    return s
  #
  # Setup the function
  #
  SCons.Action.FunctionAction.get_contents = get_contents

#
# Work correctly under different versions of SCons
#
def tune_scons():
  change_function_signature()

Leave a Reply