~ubuntu-branches/ubuntu/natty/scons/natty

« back to all changes in this revision

Viewing changes to engine/SCons/SConf.py

  • Committer: Bazaar Package Importer
  • Author(s): Michael Bienia
  • Date: 2007-12-08 20:01:12 UTC
  • mfrom: (0.2.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20071208200112-vqk3vh6hm31pqlxu
Tags: 0.97.0d20071203-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Don't use os.system()+env to spawn tools, working around underquoting of
    the environment until a real fix is done upstream.
  - debian/control: Modify Maintainer value to match
    DebianMaintainerField spec.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
27
#
28
28
 
29
 
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/SConf.py 0.97.D001 2007/05/17 11:35:19 knight"
 
29
__revision__ = "src/engine/SCons/SConf.py 2509 2007/12/03 20:20:38 broonie"
 
30
 
 
31
import SCons.compat
30
32
 
31
33
import os
32
34
import re
46
48
import SCons.Warnings
47
49
import SCons.Conftest
48
50
 
 
51
from SCons.Debug import Trace
 
52
 
49
53
# Turn off the Conftest error logging
50
54
SCons.Conftest.LogInputFiles = 0
51
55
SCons.Conftest.LogErrorMessages = 0
52
56
 
 
57
# Set
 
58
build_type = None
 
59
build_types = ['clean', 'help']
 
60
 
 
61
def SetBuildType(type):
 
62
    global build_type
 
63
    build_type = type
 
64
 
53
65
# to be set, if we are in dry-run mode
54
66
dryrun = 0
55
67
 
158
170
    """
159
171
    result = None # -> 0/None -> no error, != 0 error
160
172
    string = None # the stdout / stderr output when building the target
161
 
    
162
 
    def __init__(self, node, result, string, sig):
163
 
        SCons.Node.FS.FileBuildInfo.__init__(self, node)
 
173
 
 
174
    def set_build_result(self, result, string):
164
175
        self.result = result
165
176
        self.string = string
166
 
        self.ninfo.bsig = sig
167
177
 
168
178
 
169
179
class Streamer:
211
221
        """
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__)
215
225
        else:
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
248
 
        is_up_to_date = 1
249
 
        cached_error = 0
250
 
        cachable = 1
 
258
        T = 0
 
259
        changed = False
 
260
        cached_error = False
 
261
        cachable = True
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)')
256
270
                else:
257
 
                    new_bsig = t.calc_signature(sconf_global.calc)
258
 
                    if t.env.use_build_signature():
259
 
                        old_bsig = bi.ninfo.bsig
260
 
                    else:
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()):
 
274
                        changed = True
 
275
                    if T: Trace(': changed %s' % changed)
263
276
                cached_error = cached_error or bi.result
264
277
            else:
 
278
                if T: Trace(': else')
265
279
                # the node hasn't been built in a SConf context or doesn't
266
280
                # exist
267
 
                cachable = 0
268
 
                is_up_to_date = 0
269
 
        return (is_up_to_date, cached_error, cachable)
 
281
                cachable = False
 
282
                changed = ( t.get_state() != SCons.Node.up_to_date )
 
283
                if T: Trace(': changed %s' % changed)
 
284
        if T: Trace('\n')
 
285
        return (not changed, cached_error, cachable)
270
286
 
271
287
    def execute(self):
 
288
        if not self.targets[0].has_builder():
 
289
            return
 
290
 
272
291
        sconf = sconf_global
273
292
 
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)
289
310
        elif dryrun:
290
311
            raise ConfigureDryRunError(self.targets[0])
291
312
        else:
305
326
            except SystemExit:
306
327
                exc_value = sys.exc_info()[1]
307
328
                raise SCons.Errors.ExplicitExit(self.targets[0],exc_value.code)
308
 
            except:
 
329
            except Exception, e:
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)
314
 
                raise
 
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
 
342
                    # regular File.
 
343
                    sconsign = t.dir.sconsign()
 
344
                    sconsign.set_entry(t.name, sconsign_entry)
 
345
                    sconsign.merge()
 
346
                raise e
315
347
            else:
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
 
360
                    # regular File.
 
361
                    sconsign = t.dir.sconsign()
 
362
                    sconsign.set_entry(t.name, sconsign_entry)
 
363
                    sconsign.merge()
321
364
 
322
 
class SConf:
 
365
class SConfBase:
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,
369
413
        self.AddTests(default_tests)
370
414
        self.AddTests(custom_tests)
371
415
        self.confdir = SConfFS.Dir(env.subst(conf_dir))
372
 
        self.calc = None
373
416
        if not config_h is None:
374
417
            config_h = SConfFS.File(config_h)
375
418
        self.config_h = config_h
377
420
 
378
421
    def Finish(self):
379
422
        """Call this method after finished with your tests:
380
 
        env = sconf.Finish()"""
 
423
                env = sconf.Finish()
 
424
        """
381
425
        self._shutdown()
382
426
        return self.env
383
427
 
398
442
        old_os_dir = os.getcwd()
399
443
        SConfFS.chdir(SConfFS.Top, change_os_dir=1)
400
444
 
 
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.
 
449
        for n in nodes:
 
450
            n.store_info = n.do_not_store_info
 
451
 
401
452
        ret = 1
402
453
 
403
454
        try:
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))
565
616
 
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.
774
825
 
775
826
 
 
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:
 
831
            try:
 
832
                del kw[bt]
 
833
            except KeyError:
 
834
                pass
 
835
        return apply(SConfBase, args, kw)
 
836
    else:
 
837
        return SCons.Util.Null()
 
838
 
 
839
 
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
785
849
    return not res
786
850
 
 
851
def CheckTypeSize(context, type_name, includes = "", language = None, expect = None):
 
852
    res = SCons.Conftest.CheckTypeSize(context, type_name,
 
853
                                       header = includes, language = language, 
 
854
                                       expect = expect)
 
855
    context.did_show_result = 1
 
856
    return res
 
857
 
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)