46
48
import SCons.Warnings
47
49
import SCons.Conftest
51
from SCons.Debug import Trace
49
53
# Turn off the Conftest error logging
50
54
SCons.Conftest.LogInputFiles = 0
51
55
SCons.Conftest.LogErrorMessages = 0
59
build_types = ['clean', 'help']
61
def SetBuildType(type):
53
65
# to be set, if we are in dry-run mode
159
171
result = None # -> 0/None -> no error, != 0 error
160
172
string = None # the stdout / stderr output when building the target
162
def __init__(self, node, result, string, sig):
163
SCons.Node.FS.FileBuildInfo.__init__(self, node)
174
def set_build_result(self, result, string):
164
175
self.result = result
165
176
self.string = string
166
self.ninfo.bsig = sig
212
222
if not isinstance(bi, SConfBuildInfo):
213
223
SCons.Warnings.warn(SConfWarning,
214
"The stored build information has an unexpected class.")
224
"The stored build information has an unexpected class: %s" % bi.__class__)
216
226
self.display("The original builder output was:\n" +
217
227
string.replace(" |" + str(bi.string),
245
255
# cached_error is 1, if the node(s) are up_to_date, but the
246
256
# build will fail
247
257
# cachable is 0, if some nodes are not in our cache
251
262
for t in self.targets:
252
bi = t.get_stored_info()
263
if T: Trace('%s' % (t))
264
bi = t.get_stored_info().binfo
253
265
if isinstance(bi, SConfBuildInfo):
266
if T: Trace(': SConfBuildInfo')
254
267
if cache_mode == CACHE:
255
268
t.set_state(SCons.Node.up_to_date)
269
if T: Trace(': set_state(up_to-date)')
257
new_bsig = t.calc_signature(sconf_global.calc)
258
if t.env.use_build_signature():
259
old_bsig = bi.ninfo.bsig
261
old_bsig = bi.ninfo.csig
262
is_up_to_date = (is_up_to_date and new_bsig == old_bsig)
271
if T: Trace(': get_state() %s' % t.get_state())
272
if T: Trace(': changed() %s' % t.changed())
273
if (t.get_state() != SCons.Node.up_to_date and t.changed()):
275
if T: Trace(': changed %s' % changed)
263
276
cached_error = cached_error or bi.result
278
if T: Trace(': else')
265
279
# the node hasn't been built in a SConf context or doesn't
269
return (is_up_to_date, cached_error, cachable)
282
changed = ( t.get_state() != SCons.Node.up_to_date )
283
if T: Trace(': changed %s' % changed)
285
return (not changed, cached_error, cachable)
271
287
def execute(self):
288
if not self.targets[0].has_builder():
272
291
sconf = sconf_global
274
293
is_up_to_date, cached_error, cachable = self.collect_node_states()
281
300
if cached_error and is_up_to_date:
282
301
self.display("Building \"%s\" failed in a previous run and all "
283
302
"its sources are up to date." % str(self.targets[0]))
284
self.display_cached_string(self.targets[0].get_stored_info())
303
binfo = self.targets[0].get_stored_info().binfo
304
self.display_cached_string(binfo)
285
305
raise SCons.Errors.BuildError # will be 'caught' in self.failed
286
306
elif is_up_to_date:
287
307
self.display("\"%s\" is up to date." % str(self.targets[0]))
288
self.display_cached_string(self.targets[0].get_stored_info())
308
binfo = self.targets[0].get_stored_info().binfo
309
self.display_cached_string(binfo)
290
311
raise ConfigureDryRunError(self.targets[0])
305
326
except SystemExit:
306
327
exc_value = sys.exc_info()[1]
307
328
raise SCons.Errors.ExplicitExit(self.targets[0],exc_value.code)
309
330
for t in self.targets:
310
sig = t.calc_signature(sconf.calc)
311
string = s.getvalue()
312
binfo = SConfBuildInfo(t,1,string,sig)
313
t.dir.sconsign().set_entry(t.name, binfo)
331
binfo = t.get_binfo()
332
binfo.__class__ = SConfBuildInfo
333
binfo.set_build_result(1, s.getvalue())
334
sconsign_entry = SCons.SConsign.SConsignEntry()
335
sconsign_entry.binfo = binfo
336
#sconsign_entry.ninfo = self.get_ninfo()
337
# We'd like to do this as follows:
338
# t.store_info(binfo)
339
# However, we need to store it as an SConfBuildInfo
340
# object, and store_info() will turn it into a
341
# regular FileNodeInfo if the target is itself a
343
sconsign = t.dir.sconsign()
344
sconsign.set_entry(t.name, sconsign_entry)
316
348
for t in self.targets:
317
sig = t.calc_signature(sconf.calc)
318
string = s.getvalue()
319
binfo = SConfBuildInfo(t,0,string,sig)
320
t.dir.sconsign().set_entry(t.name, binfo)
349
binfo = t.get_binfo()
350
binfo.__class__ = SConfBuildInfo
351
binfo.set_build_result(0, s.getvalue())
352
sconsign_entry = SCons.SConsign.SConsignEntry()
353
sconsign_entry.binfo = binfo
354
#sconsign_entry.ninfo = self.get_ninfo()
355
# We'd like to do this as follows:
356
# t.store_info(binfo)
357
# However, we need to store it as an SConfBuildInfo
358
# object, and store_info() will turn it into a
359
# regular FileNodeInfo if the target is itself a
361
sconsign = t.dir.sconsign()
362
sconsign.set_entry(t.name, sconsign_entry)
323
366
"""This is simply a class to represent a configure context. After
324
367
creating a SConf object, you can call any tests. After finished with your
325
368
tests, be sure to call the Finish() method, which returns the modified
360
403
default_tests = {
361
404
'CheckFunc' : CheckFunc,
362
405
'CheckType' : CheckType,
406
'CheckTypeSize' : CheckTypeSize,
363
407
'CheckHeader' : CheckHeader,
364
408
'CheckCHeader' : CheckCHeader,
365
409
'CheckCXXHeader' : CheckCXXHeader,
398
442
old_os_dir = os.getcwd()
399
443
SConfFS.chdir(SConfFS.Top, change_os_dir=1)
445
# Because we take responsibility here for writing out our
446
# own .sconsign info (see SConfBuildTask.execute(), above),
447
# we override the store_info() method with a null place-holder
448
# so we really control how it gets written.
450
n.store_info = n.do_not_store_info
561
612
def AddTest(self, test_name, test_instance):
562
613
"""Adds test_class to this SConf instance. It can be called with
563
614
self.test_name(...)"""
564
setattr(self, test_name, SConf.TestWrapper(test_instance, self))
615
setattr(self, test_name, SConfBase.TestWrapper(test_instance, self))
566
617
def AddTests(self, tests):
567
618
"""Adds all the tests given in the tests dictionary to this SConf
773
824
#### End of stuff used by Conftest.py.
827
def SConf(*args, **kw):
828
if kw.get(build_type, True):
829
kw['_depth'] = kw.get('_depth', 0) + 1
830
for bt in build_types:
835
return apply(SConfBase, args, kw)
837
return SCons.Util.Null()
776
840
def CheckFunc(context, function_name, header = None, language = None):
777
841
res = SCons.Conftest.CheckFunc(context, function_name, header = header, language = language)
778
842
context.did_show_result = 1
784
848
context.did_show_result = 1
851
def CheckTypeSize(context, type_name, includes = "", language = None, expect = None):
852
res = SCons.Conftest.CheckTypeSize(context, type_name,
853
header = includes, language = language,
855
context.did_show_result = 1
787
858
def createIncludesFromHeaders(headers, leaveLast, include_quotes = '""'):
788
859
# used by CheckHeader and CheckLibWithHeader to produce C - #include
789
860
# statements from the specified header (list)