Add SConf hook to check result against expected value
This commit is contained in:
parent
946048c54b
commit
37838329a1
39
SConstruct
39
SConstruct
|
@ -188,6 +188,8 @@ class ConfigureTests:
|
||||||
sconf_force_success = 'force-success'
|
sconf_force_success = 'force-success'
|
||||||
# Force test to report success, do not modify flags
|
# Force test to report success, do not modify flags
|
||||||
sconf_assume_success = 'assume-success'
|
sconf_assume_success = 'assume-success'
|
||||||
|
expect_sconf_success = 'success'
|
||||||
|
expect_sconf_failure = 'failure'
|
||||||
_implicit_test = Collector()
|
_implicit_test = Collector()
|
||||||
_custom_test = Collector()
|
_custom_test = Collector()
|
||||||
implicit_tests = _implicit_test.tests
|
implicit_tests = _implicit_test.tests
|
||||||
|
@ -257,6 +259,7 @@ struct %(N)s_derived : %(N)s_base {
|
||||||
self.__automatic_compiler_tests = {
|
self.__automatic_compiler_tests = {
|
||||||
'.cpp': self.check_cxx_works,
|
'.cpp': self.check_cxx_works,
|
||||||
}
|
}
|
||||||
|
self._sconf_results = []
|
||||||
def message(self,msg):
|
def message(self,msg):
|
||||||
print "%s: %s" % (self.msgprefix, msg)
|
print "%s: %s" % (self.msgprefix, msg)
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -271,8 +274,9 @@ struct %(N)s_derived : %(N)s_base {
|
||||||
def _quote_macro_value(v):
|
def _quote_macro_value(v):
|
||||||
return v.strip().replace('\n', ' \\\n')
|
return v.strip().replace('\n', ' \\\n')
|
||||||
def _check_sconf_forced(self,calling_function):
|
def _check_sconf_forced(self,calling_function):
|
||||||
if calling_function is not None:
|
return self._check_forced(calling_function), self._check_expected(calling_function)
|
||||||
return self._check_forced(calling_function)
|
@staticmethod
|
||||||
|
def _find_calling_sconf_function():
|
||||||
try:
|
try:
|
||||||
1//0
|
1//0
|
||||||
except ZeroDivisionError:
|
except ZeroDivisionError:
|
||||||
|
@ -280,11 +284,19 @@ struct %(N)s_derived : %(N)s_base {
|
||||||
while frame is not None:
|
while frame is not None:
|
||||||
co_name = frame.f_code.co_name
|
co_name = frame.f_code.co_name
|
||||||
if co_name[:6] == 'check_':
|
if co_name[:6] == 'check_':
|
||||||
return self._check_forced(co_name[6:])
|
return co_name[6:]
|
||||||
frame = frame.f_back
|
frame = frame.f_back
|
||||||
assert False
|
assert False
|
||||||
def _check_forced(self,name):
|
def _check_forced(self,name):
|
||||||
return getattr(self.user_settings, 'sconf_%s' % name)
|
return getattr(self.user_settings, 'sconf_%s' % name)
|
||||||
|
def _check_expected(self,name):
|
||||||
|
r = getattr(self.user_settings, 'expect_sconf_%s' % name)
|
||||||
|
if r is not None:
|
||||||
|
if r == self.expect_sconf_success:
|
||||||
|
return 1
|
||||||
|
if r == self.expect_sconf_failure:
|
||||||
|
return 0
|
||||||
|
return r
|
||||||
def _check_macro(self,context,macro_name,macro_value,test,**kwargs):
|
def _check_macro(self,context,macro_name,macro_value,test,**kwargs):
|
||||||
macro_value = self._quote_macro_value(macro_value)
|
macro_value = self._quote_macro_value(macro_value)
|
||||||
r = self.Compile(context, text="""
|
r = self.Compile(context, text="""
|
||||||
|
@ -310,13 +322,17 @@ struct %(N)s_derived : %(N)s_base {
|
||||||
return self._Test(context,action=context.TryLink, **kwargs)
|
return self._Test(context,action=context.TryLink, **kwargs)
|
||||||
def _Test(self,context,text,msg,action,main='',ext='.cpp',testflags={},successflags={},skipped=None,successmsg=None,failuremsg=None,expect_failure=False,calling_function=None):
|
def _Test(self,context,text,msg,action,main='',ext='.cpp',testflags={},successflags={},skipped=None,successmsg=None,failuremsg=None,expect_failure=False,calling_function=None):
|
||||||
self._check_compiler_works(context,ext)
|
self._check_compiler_works(context,ext)
|
||||||
|
if calling_function is None:
|
||||||
|
calling_function = self._find_calling_sconf_function()
|
||||||
context.Message('%s: checking %s...' % (self.msgprefix, msg))
|
context.Message('%s: checking %s...' % (self.msgprefix, msg))
|
||||||
if skipped is not None:
|
if skipped is not None:
|
||||||
context.Result('(skipped){skipped}'.format(skipped=skipped))
|
context.Result('(skipped){skipped}'.format(skipped=skipped))
|
||||||
|
if self.user_settings.record_sconf_results:
|
||||||
|
self._sconf_results.append((calling_function, 'skipped'))
|
||||||
return
|
return
|
||||||
env_flags = self.PreservedEnvironment(context.env, successflags.keys() + testflags.keys() + self.__flags_Werror.keys() + ['CPPDEFINES'])
|
env_flags = self.PreservedEnvironment(context.env, successflags.keys() + testflags.keys() + self.__flags_Werror.keys() + ['CPPDEFINES'])
|
||||||
context.env.MergeFlags(successflags)
|
context.env.MergeFlags(successflags)
|
||||||
forced = self._check_sconf_forced(calling_function)
|
forced, expected = self._check_sconf_forced(calling_function)
|
||||||
caller_modified_env_flags = self.PreservedEnvironment(context.env, self.__flags_Werror.keys() + testflags.keys())
|
caller_modified_env_flags = self.PreservedEnvironment(context.env, self.__flags_Werror.keys() + testflags.keys())
|
||||||
# Always pass -Werror
|
# Always pass -Werror
|
||||||
context.env.Append(**self.__flags_Werror)
|
context.env.Append(**self.__flags_Werror)
|
||||||
|
@ -329,6 +345,8 @@ struct %(N)s_derived : %(N)s_base {
|
||||||
r = not r
|
r = not r
|
||||||
cc_env_strings.restore(context.env)
|
cc_env_strings.restore(context.env)
|
||||||
context.Result((successmsg if r else failuremsg) or r)
|
context.Result((successmsg if r else failuremsg) or r)
|
||||||
|
if expected is not None and r != expected:
|
||||||
|
raise SCons.Errors.StopError('Expected and actual results differ. Test should ' + ('succeed' if expected else 'fail') + ', but it did not.')
|
||||||
else:
|
else:
|
||||||
choices = (self.sconf_force_failure, self.sconf_force_success, self.sconf_assume_success)
|
choices = (self.sconf_force_failure, self.sconf_force_success, self.sconf_assume_success)
|
||||||
if forced not in choices:
|
if forced not in choices:
|
||||||
|
@ -368,6 +386,7 @@ struct %(N)s_derived : %(N)s_base {
|
||||||
self._extend_successflags(k, v)
|
self._extend_successflags(k, v)
|
||||||
else:
|
else:
|
||||||
env_flags.restore(context.env)
|
env_flags.restore(context.env)
|
||||||
|
self._sconf_results.append((calling_function, r))
|
||||||
return r
|
return r
|
||||||
def _soft_check_system_library(self,context,header,main,lib,successflags={}):
|
def _soft_check_system_library(self,context,header,main,lib,successflags={}):
|
||||||
include = '\n'.join(['#include <%s>' % h for h in header])
|
include = '\n'.join(['#include <%s>' % h for h in header])
|
||||||
|
@ -1368,16 +1387,24 @@ class DXXCommon(LazyObjectConstructor):
|
||||||
def _enum_variable(key,help,default,allowed_values):
|
def _enum_variable(key,help,default,allowed_values):
|
||||||
return EnumVariable(key, help, default, allowed_values)
|
return EnumVariable(key, help, default, allowed_values)
|
||||||
def _options(self):
|
def _options(self):
|
||||||
|
tests = ConfigureTests.implicit_tests + ConfigureTests.custom_tests
|
||||||
return (
|
return (
|
||||||
{
|
{
|
||||||
'variable': self._enum_variable,
|
'variable': self._enum_variable,
|
||||||
'arguments': [
|
'arguments': [
|
||||||
('sconf_%s' % name[6:], None, ConfigureTests.describe(name) or ('assume result of %s' % name), {'allowed_values' : ['0', '1', '2', ConfigureTests.sconf_force_failure, ConfigureTests.sconf_force_success, ConfigureTests.sconf_assume_success]}) for name in ConfigureTests.implicit_tests + ConfigureTests.custom_tests if name[0] != '_'
|
('expect_sconf_%s' % name[6:], None, None, {'allowed_values' : ['0', '1', ConfigureTests.expect_sconf_success, ConfigureTests.expect_sconf_failure]}) for name in tests
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'variable': self._enum_variable,
|
||||||
|
'arguments': [
|
||||||
|
('sconf_%s' % name[6:], None, ConfigureTests.describe(name) or ('assume result of %s' % name), {'allowed_values' : ['0', '1', '2', ConfigureTests.sconf_force_failure, ConfigureTests.sconf_force_success, ConfigureTests.sconf_assume_success]}) for name in tests if name[0] != '_'
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'variable': BoolVariable,
|
'variable': BoolVariable,
|
||||||
'arguments': (
|
'arguments': (
|
||||||
|
('record_sconf_results', False, 'write sconf results to dxxsconf.h'),
|
||||||
('raspberrypi', False, 'build for Raspberry Pi (automatically sets opengles and opengles_lib)'),
|
('raspberrypi', False, 'build for Raspberry Pi (automatically sets opengles and opengles_lib)'),
|
||||||
('git_describe_version', os.path.exists(os.environ.get('GIT_DIR', '.git')), 'include git --describe in extra_version'),
|
('git_describe_version', os.path.exists(os.environ.get('GIT_DIR', '.git')), 'include git --describe in extra_version'),
|
||||||
('git_status', True, 'include git status'),
|
('git_status', True, 'include git status'),
|
||||||
|
@ -2010,6 +2037,8 @@ class DXXArchive(DXXCommon):
|
||||||
getattr(conf, k)()
|
getattr(conf, k)()
|
||||||
except SCons.Errors.StopError as e:
|
except SCons.Errors.StopError as e:
|
||||||
raise SCons.Errors.StopError(e.args[0] + ' See {log_file} for details.'.format(log_file=log_file), *e.args[1:])
|
raise SCons.Errors.StopError(e.args[0] + ' See {log_file} for details.'.format(log_file=log_file), *e.args[1:])
|
||||||
|
if self.user_settings.record_sconf_results:
|
||||||
|
conf.config_h_text += '/*\n' + '\n'.join(['check_%s=%s' % (n,v) for (n,v) in tests._sconf_results]) + '\n*/\n'
|
||||||
self.env = conf.Finish()
|
self.env = conf.Finish()
|
||||||
self.configure_pch_flags = tests.pch_flags
|
self.configure_pch_flags = tests.pch_flags
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue