source: rtems-libbsd/builder.py @ 01855a5

5-freebsd-12
Last change on this file since 01855a5 was 01855a5, checked in by Christian Mauderer <christian.mauderer@…>, on May 7, 2018 at 8:19:28 AM

waf: Allow to only generate lex and yacc.

In some applications, it's usefull if the files generated by lex or yacc
are not build automatically. With that it is for example possible to
create a wrapper source file that sets some defines before the generated
code is parsed.

  • Property mode set to 100755
File size: 31.2 KB
Line 
1#
2#  Copyright (c) 2015-2016 Chris Johns <chrisj@rtems.org>. All rights reserved.
3#
4#  Copyright (c) 2009, 2017 embedded brains GmbH.  All rights reserved.
5#
6#   embedded brains GmbH
7#   Dornierstr. 4
8#   82178 Puchheim
9#   Germany
10#   <info@embedded-brains.de>
11#
12#  Copyright (c) 2012 OAR Corporation. All rights reserved.
13#
14#  Redistribution and use in source and binary forms, with or without
15#  modification, are permitted provided that the following conditions
16#  are met:
17#  1. Redistributions of source code must retain the above copyright
18#     notice, this list of conditions and the following disclaimer.
19#  2. Redistributions in binary form must reproduce the above copyright
20#     notice, this list of conditions and the following disclaimer in the
21#     documentation and/or other materials provided with the distribution.
22#
23#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27#  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29#  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30#  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31#  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32#  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33#  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35# FreeBSD: http://svn.freebsd.org/base/releng/8.2/sys (revision 222485)
36
37from __future__ import print_function
38
39import shutil
40import os
41import re
42import sys
43import getopt
44import filecmp
45import difflib
46import codecs
47import copy
48
49#
50# Global controls.
51#
52LIBBSD_DIR = "."
53FreeBSD_DIR = "freebsd-org"
54verboseLevel = 0
55isDryRun = False
56isDiffMode = False
57filesProcessedCount = 0
58filesProcessed = []
59filesTotal = 0
60filesTotalLines = 0
61filesTotalInserts = 0
62filesTotalDeletes = 0
63diffDetails = { }
64
65verboseInfo = 1
66verboseDetail = 2
67verboseMoreDetail = 3
68verboseDebug = 4
69
70def _cflagsIncludes(cflags, includes):
71    if type(cflags) is not list:
72        if cflags is not None:
73            _cflags = cflags.split(' ')
74        else:
75            _cflags = [None]
76    else:
77        _cflags = cflags
78    if type(includes) is not list:
79        _includes = [includes]
80    else:
81        _includes = includes
82    return _cflags, _includes
83
84def verbose(level = verboseInfo):
85    return verboseLevel >= level
86
87def changedFileSummary(statsReport = False):
88
89    global filesTotal, filesTotalLines, filesTotalInserts, filesTotalDeletes
90
91    if isDiffMode == False:
92        if verbose():
93            print('%d file(s) were changed:' % (filesProcessedCount))
94            for f in sorted(filesProcessed):
95                print(' %s' % (f))
96        else:
97            print('%d file(s) were changed.' % (filesProcessedCount))
98    if statsReport:
99        print('Stats Report:')
100        transparent = filesTotal - len(diffDetails)
101        changes = filesTotalInserts + filesTotalDeletes
102        opacity = (float(changes) / (filesTotalLines + changes)) * 100.0
103        print(' Total File(s):%d  Unchanged:%d (%.1f%%)  Changed:%d' \
104              '   Opacity:%5.1f%% Lines:%d Edits:%d (+):%d (-):%d'  % \
105              (filesTotal, transparent, (float(transparent) / filesTotal) * 100.0, len(diffDetails), \
106               opacity, filesTotalLines, changes, filesTotalInserts, filesTotalDeletes))
107        #
108        # Sort by opacity.
109        #
110        ordered_diffs = sorted(diffDetails.items(), key = lambda diff: diff[1].opacity, reverse = True)
111        for f in ordered_diffs:
112            print(%s' % (diffDetails[f[0]].status()))
113
114def readFile(name):
115    try:
116        contents = codecs.open(name, mode = 'r', encoding = 'utf-8', errors = 'ignore').read()
117    except UnicodeDecodeError as ude:
118        print('error: reading: %s: %s' % (name, ude))
119        sys.exit(1)
120    return contents
121
122def writeFile(name, contents):
123    path = os.path.dirname(name)
124    if not os.path.exists(path):
125        try:
126            os.makedirs(path)
127        except OSError as oe:
128            print('error: cannot create directory: %s: %s' % (path, oe))
129            sys.exit(1)
130    try:
131        codecs.open(name, mode = 'w',  encoding = 'utf-8', errors = 'ignore').write(contents)
132    except UnicodeDecodeError as ude:
133        print('error: write: %s: %s' % (name, ude))
134        sys.exit(1)
135
136#
137# A builder error.
138#
139class error(Exception):
140    """Base class for exceptions."""
141    def __init__(self, msg):
142        self.msg = 'error: %s' % (msg)
143    def set_output(self, msg):
144        self.msg = msg
145    def __str__(self):
146        return self.msg
147
148#
149# Diff Record
150#
151class diffRecord:
152    def __init__(self, src, dst, orig, diff, inserts, deletes):
153        self.src = src
154        self.dst = dst
155        self.orig = orig
156        self.diff = diff
157        self.lines = len(orig)
158        self.inserts = inserts
159        self.deletes = deletes
160        self.changes = inserts + deletes
161        self.opacity = (float(self.changes) / (self.lines + self.changes)) * 100.0
162
163    def __repr__(self):
164        return self.src
165
166    def status(self):
167        return 'opacity:%5.1f%% edits:%4d (+):%-4d (-):%-4d %s' % \
168            (self.opacity, self.changes, self.inserts, self.deletes, self.src)
169
170#
171# This stuff needs to move to libbsd.py.
172#
173
174# Move target dependent files under a machine directory
175def mapCPUDependentPath(path):
176  return path.replace("include/", "include/machine/")
177
178def fixIncludes(data):
179    data = re.sub('#include <sys/resource.h>', '#include <rtems/bsd/sys/resource.h>', data)
180    data = re.sub('#include <sys/unistd.h>',   '#include <rtems/bsd/sys/unistd.h>', data)
181    return data
182
183# revert fixing the include paths inside a C or .h file
184def revertFixIncludes(data):
185    data = re.sub('#include <rtems/bsd/',  '#include <', data)
186    data = re.sub('#include <util.h>',     '#include <rtems/bsd/util.h>', data)
187    data = re.sub('#include <bsd.h>',      '#include <rtems/bsd/bsd.h>', data)
188    data = re.sub('#include <zerocopy.h>', '#include <rtems/bsd/zerocopy.h>', data)
189    data = re.sub('#include <modules.h>',  '#include <rtems/bsd/modules.h>', data)
190    return data
191
192# fix include paths inside a C or .h file
193def fixLocalIncludes(data):
194    data = re.sub('#include "opt_([^"]*)"',    '#include <rtems/bsd/local/opt_\\1>', data)
195    data = re.sub('#include "([^"]*)_if.h"',   '#include <rtems/bsd/local/\\1_if.h>', data)
196    data = re.sub('#include "miidevs([^"]*)"', '#include <rtems/bsd/local/miidevs\\1>', data)
197    data = re.sub('#include "usbdevs([^"]*)"', '#include <rtems/bsd/local/usbdevs\\1>', data)
198    return data
199
200# revert fixing the include paths inside a C or .h file
201def revertFixLocalIncludes(data):
202    data = re.sub('#include <rtems/bsd/local/([^>]*)>', '#include "\\1"', data)
203    return data
204
205def assertHeaderFile(path):
206    if path[-2] != '.' or path[-1] != 'h':
207        print("*** " + path + " does not end in .h")
208        print("*** Move it to a C source file list")
209        sys.exit(2)
210
211def assertSourceFile(path):
212    if path[-2] != '.' or (path[-1] != 'c' and path[-1] != 'S'):
213        print("*** " + path + " does not end in .c")
214        print("*** Move it to a header file list")
215        sys.exit(2)
216
217def diffSource(dstLines, srcLines, src, dst):
218    global filesTotal, filesTotalLines, filesTotalInserts, filesTotalDeletes
219    #
220    # Diff, note there is no line termination on each string.  Expand the
221    # generator to list because the generator is not reusable.
222    #
223    diff = list(difflib.unified_diff(dstLines,
224                                     srcLines,
225                                     fromfile = src,
226                                     tofile = dst,
227                                     n = 5,
228                                     lineterm = ''))
229    inserts = 0
230    deletes = 0
231    if len(diff) > 0:
232        if src in diffDetails and \
233           diffDetails[src].dst != dst and diffDetails[src].diff != diff:
234            raise error('repeated diff of file different: src:%s dst:%s' % (src, dst))
235        for l in diff:
236            if l[0] == '-':
237                deletes += 1
238            elif l[0] == '+':
239                inserts += 1
240        diffDetails[src] = diffRecord(src, dst, srcLines, diff, inserts, deletes)
241
242    #
243    # Count the total files, lines and the level of changes.
244    #
245    filesTotal += 1
246    filesTotalLines += len(srcLines)
247    filesTotalInserts += inserts
248    filesTotalDeletes += deletes
249
250    return diff
251
252#
253# Converters provide a way to alter the various types of code. The conversion
254# process filters a file as it is copies from the source path to the
255# destination path. Specialised versions are provided for different types of
256# source.
257#
258class Converter(object):
259
260    def convert(self, src, dst, hasSource = True, sourceFilter = None, srcContents = None):
261
262        global filesProcessed, filesProcessedCount
263
264        if verbose(verboseDebug):
265            print("convert: filter:%s: %s -> %s" % \
266                  (['yes', 'no'][sourceFilter is None], src, dst))
267
268        #
269        # If there is no source raise an error if we expect source else print a
270        # warning and do not try and convert.
271        #
272        if srcContents is None:
273            if not os.path.exists(src):
274                if hasSource:
275                    raise error('source not found: %s' % (src))
276                else:
277                    print('warning: no source: %s' % (src))
278                    return
279
280            #
281            # Files read as a single string if not passed in.
282            #
283            srcContents = readFile(src)
284
285        if os.path.exists(dst):
286            dstContents = readFile(dst)
287        else:
288            print('warning: no destination: %s' % (dst))
289            dstContents = ''
290
291        #
292        # Filter the source.
293        #
294        if sourceFilter is not None:
295            srcContents = sourceFilter(srcContents)
296
297        #
298        # Split into a list of lines.
299        #
300        srcLines = srcContents.split(os.linesep)
301        dstLines = dstContents.split(os.linesep)
302
303        if verbose(verboseDebug):
304            print('Unified diff: %s (lines:%d)' % (src, len(srcLines)))
305
306        #
307        # Diff, note there is no line termination on each string.
308        #
309        diff = diffSource(dstLines, srcLines, src, dst)
310
311        #
312        # The diff list is empty if the files are the same.
313        #
314        if len(diff) > 0:
315
316            if verbose(verboseDebug):
317                print('Unified diff length: %d' % len(diff))
318
319            filesProcessed += [dst]
320            filesProcessedCount += 1
321            if isDiffMode == False:
322                if verbose(verboseDetail):
323                    print("UPDATE: %s -> %s" % (src, dst))
324                if isDryRun == False:
325                    writeFile(dst, srcContents)
326            else:
327                print("diff -u %s %s" % (src, dst))
328                for l in diff:
329                    print(l)
330
331class NoConverter(Converter):
332    def convert(self, src, dst, hasSource = True, sourceFilter = None):
333        return '/* EMPTY */\n'
334
335class FromFreeBSDToRTEMSHeaderConverter(Converter):
336    def sourceFilter(self, data):
337        data = fixLocalIncludes(data)
338        data = fixIncludes(data)
339        return data
340
341    def convert(self, src, dst):
342        sconverter = super(FromFreeBSDToRTEMSHeaderConverter, self)
343        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
344
345class FromFreeBSDToRTEMSUserSpaceHeaderConverter(Converter):
346    def sourceFilter(self, data):
347        data = fixIncludes(data)
348        return data
349
350    def convert(self, src, dst):
351        sconverter = super(FromFreeBSDToRTEMSUserSpaceHeaderConverter, self)
352        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
353
354class FromFreeBSDToRTEMSSourceConverter(Converter):
355    def sourceFilter(self, data):
356        data = fixLocalIncludes(data)
357        data = fixIncludes(data)
358        data = '#include <machine/rtems-bsd-kernel-space.h>\n\n' + data
359        return data
360
361    def convert(self, src, dst):
362        sconverter = super(FromFreeBSDToRTEMSSourceConverter, self)
363        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
364
365class FromFreeBSDToRTEMSUserSpaceSourceConverter(Converter):
366    def sourceFilter(self, data):
367        data = fixIncludes(data)
368        data = '#include <machine/rtems-bsd-user-space.h>\n\n' + data
369        return data
370
371    def convert(self, src, dst):
372        sconverter = super(FromFreeBSDToRTEMSUserSpaceSourceConverter, self)
373        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
374
375class FromRTEMSToFreeBSDHeaderConverter(Converter):
376    def sourceFilter(self, data):
377        data = revertFixLocalIncludes(data)
378        data = revertFixIncludes(data)
379        return data
380
381    def convert(self, src, dst):
382        sconverter = super(FromRTEMSToFreeBSDHeaderConverter, self)
383        sconverter.convert(src, dst, hasSource = False,  sourceFilter = self.sourceFilter)
384
385class FromRTEMSToFreeBSDSourceConverter(Converter):
386    def sourceFilter(self, data):
387        data = re.sub('#include <machine/rtems-bsd-kernel-space.h>\n\n', '', data)
388        data = re.sub('#include <machine/rtems-bsd-user-space.h>\n\n', '', data)
389        data = revertFixLocalIncludes(data)
390        data = revertFixIncludes(data)
391        return data
392
393    def convert(self, src, dst):
394        sconverter = super(FromRTEMSToFreeBSDSourceConverter, self)
395        sconverter.convert(src, dst, hasSource = False, sourceFilter = self.sourceFilter)
396
397#
398# Compose a path based for the various parts of the source tree.
399#
400class PathComposer(object):
401    def composeOriginPath(self, path):
402        return path
403
404    def composeLibBSDPath(self, path, prefix):
405        return os.path.join(prefix, path)
406
407class FreeBSDPathComposer(PathComposer):
408    def composeOriginPath(self, path):
409        return os.path.join(FreeBSD_DIR, path)
410
411    def composeLibBSDPath(self, path, prefix):
412        return os.path.join(prefix, 'freebsd', path)
413
414class RTEMSPathComposer(PathComposer):
415    def composeOriginPath(self, path):
416        return path
417
418    def composeLibBSDPath(self, path, prefix):
419        return os.path.join(prefix, 'rtemsbsd', path)
420
421class LinuxPathComposer(PathComposer):
422    def composeOriginPath(self, path):
423        return path
424
425    def composeLibBSDPath(self, path, prefix):
426        return os.path.join(prefix, 'linux', path)
427
428class CPUDependentFreeBSDPathComposer(FreeBSDPathComposer):
429    def composeLibBSDPath(self, path, prefix):
430        path = super(CPUDependentFreeBSDPathComposer, self).composeLibBSDPath(path, prefix)
431        path = mapCPUDependentPath(path)
432        return path
433
434class CPUDependentRTEMSPathComposer(RTEMSPathComposer):
435    def composeLibBSDPath(self, path, prefix):
436        path = super(CPUDependentRTEMSPathComposer, self).composeLibBSDPath(path, prefix)
437        path = mapCPUDependentPath(path)
438        return path
439
440class CPUDependentLinuxPathComposer(LinuxPathComposer):
441    def composeLibBSDPath(self, path, prefix):
442        path = super(CPUDependentLinuxPathComposer, self).composeLibBSDPath(path, prefix)
443        path = mapCPUDependentPath(path)
444        return path
445
446class TargetSourceCPUDependentPathComposer(CPUDependentFreeBSDPathComposer):
447    def __init__(self, targetCPU, sourceCPU):
448        self.targetCPU = targetCPU
449        self.sourceCPU = sourceCPU
450
451    def composeLibBSDPath(self, path, prefix):
452        path = super(TargetSourceCPUDependentPathComposer, self).composeLibBSDPath(path, prefix)
453        path = path.replace(self.sourceCPU, self.targetCPU)
454        return path
455
456class BuildSystemFragmentComposer(object):
457    def __init__(self, includes = None):
458        if type(includes) is not list:
459            self.includes = [includes]
460        else:
461            self.includes = includes
462
463    def compose(self, path):
464        return ''
465
466class SourceFileFragmentComposer(BuildSystemFragmentComposer):
467
468    def __init__(self, cflags = "default", includes = None):
469        self.cflags, self.includes = _cflagsIncludes(cflags, includes)
470
471    def compose(self, path):
472        if None in self.includes:
473            flags = self.cflags
474        else:
475            flags = self.cflags + self.includes
476        return ['sources', flags, ('default', None)], [path], self.cflags, self.includes
477
478class SourceFileIfHeaderComposer(SourceFileFragmentComposer):
479
480    def __init__(self, headers, cflags = "default", includes = None):
481        if headers is not list:
482            headers = [headers]
483        self.headers = headers
484        super(SourceFileIfHeaderComposer, self).__init__(cflags = cflags, includes = includes)
485
486    def compose(self, path):
487        r = SourceFileFragmentComposer.compose(self, path)
488        define_keys = ''
489        for h in self.headers:
490            h = h.upper()
491            for c in '\/-.':
492                h = h.replace(c, '_')
493            define_keys += ' ' + h
494        r[0][2] = (define_keys.strip(), self.headers)
495        return r
496
497class TestFragementComposer(BuildSystemFragmentComposer):
498
499    def __init__(self, testName, fileFragments, runTest = True, netTest = False, extraLibs = []):
500        self.testName = testName
501        self.fileFragments = fileFragments
502        self.runTest = runTest
503        self.netTest = netTest
504        self.extraLibs = extraLibs
505
506    def compose(self, path):
507        return ['tests', self.testName, ('default', None)], { 'files': self.fileFragments,
508                                                              'run': self.runTest,
509                                                              'net': self.netTest,
510                                                              'libs': self.extraLibs}
511
512class TestIfHeaderComposer(TestFragementComposer):
513
514    def __init__(self, testName, headers, fileFragments, runTest = True, netTest = False, extraLibs = []):
515        if headers is not list:
516            headers = [headers]
517        self.headers = headers
518        super(TestIfHeaderComposer, self).__init__(testName, fileFragments,
519                                                   runTest = runTest, netTest = netTest,
520                                                   extraLibs = extraLibs)
521
522    def compose(self, path):
523        r = TestFragementComposer.compose(self, path)
524        define_keys = ''
525        for h in self.headers:
526            h = h.upper()
527            for c in '\/-.':
528                h = h.replace(c, '_')
529            define_keys += ' ' + h
530        r[0][2] = (define_keys.strip(), self.headers)
531        return r
532
533class KVMSymbolsFragmentComposer(BuildSystemFragmentComposer):
534
535    def compose(self, path):
536        return ['KVMSymbols', 'files', ('default', None)], [path], self.includes
537
538class RPCGENFragmentComposer(BuildSystemFragmentComposer):
539
540    def compose(self, path):
541        return ['RPCGen', 'files', ('default', None)], [path]
542
543class RouteKeywordsFragmentComposer(BuildSystemFragmentComposer):
544
545    def compose(self, path):
546        return ['RouteKeywords', 'files', ('default', None)], [path]
547
548class LexFragmentComposer(BuildSystemFragmentComposer):
549
550    def __init__(self, sym, dep, cflags = None, includes = None, build = True):
551        self.sym = sym
552        self.dep = dep
553        self.cflags, self.includes = _cflagsIncludes(cflags, includes)
554        self.build = build
555
556    def compose(self, path):
557        d = { 'file': path,
558              'sym': self.sym,
559              'dep': self.dep,
560              'build': self.build }
561        if None not in self.cflags:
562            d['cflags'] = self.cflags
563        if None not in self.includes:
564            d['includes'] = self.includes
565        return ['lex', path, ('default', None)], d
566
567class YaccFragmentComposer(BuildSystemFragmentComposer):
568
569    def __init__(self, sym, header, cflags = None, includes = None, build = True):
570        self.sym = sym
571        self.header = header
572        self.cflags, self.includes = _cflagsIncludes(cflags, includes)
573        self.build = build
574
575    def compose(self, path):
576        d = { 'file': path,
577              'sym': self.sym,
578              'header': self.header,
579              'build': self.build }
580        if None not in self.cflags:
581            d['cflags'] = self.cflags
582        if None not in self.includes:
583            d['includes'] = self.includes
584        return ['yacc', path, ('default', None)], d
585
586#
587# File - a file in the source we move backwards and forwards.
588#
589class File(object):
590    def __init__(self, path, pathComposer,
591                 forwardConverter, reverseConverter, buildSystemComposer):
592        if verbose(verboseMoreDetail):
593            print("FILE: %-50s F:%-45s R:%-45s" % \
594                  (path,
595                   forwardConverter.__class__.__name__,
596                   reverseConverter.__class__.__name__))
597        self.path = path
598        self.pathComposer = pathComposer
599        self.originPath = self.pathComposer.composeOriginPath(self.path)
600        self.libbsdPath = self.pathComposer.composeLibBSDPath(self.path, LIBBSD_DIR)
601        self.forwardConverter = forwardConverter
602        self.reverseConverter = reverseConverter
603        self.buildSystemComposer = buildSystemComposer
604
605    def processSource(self, forward):
606        if forward:
607            if verbose(verboseDetail):
608                print("process source: %s => %s" % (self.originPath, self.libbsdPath))
609            self.forwardConverter.convert(self.originPath, self.libbsdPath)
610        else:
611            if verbose(verboseDetail):
612                print("process source: %s => %s converter:%s" % \
613                      (self.libbsdPath, self.originPath, self.reverseConverter.__class__.__name__))
614            self.reverseConverter.convert(self.libbsdPath, self.originPath)
615
616    def getFragment(self):
617        return self.buildSystemComposer.compose(self.pathComposer.composeLibBSDPath(self.path, ''))
618
619#
620# Module - logical group of related files we can perform actions on
621#
622class Module(object):
623    def __init__(self, manager, name, enabled = True):
624        self.manager = manager
625        self.name = name
626        self.conditionalOn = "none"
627        self.files = []
628        self.cpuDependentSourceFiles = {}
629        self.dependencies = []
630
631    def initCPUDependencies(self, cpu):
632        if cpu not in self.cpuDependentSourceFiles:
633            self.cpuDependentSourceFiles[cpu] = []
634
635    def processSource(self, direction):
636        if verbose(verboseDetail):
637            print("process module: %s" % (self.name))
638        for f in self.files:
639            f.processSource(direction)
640        for cpu, files in self.cpuDependentSourceFiles.items():
641            for f in files:
642                f.processSource(direction)
643
644    def addFiles(self, newFiles, buildSystemComposer = BuildSystemFragmentComposer()):
645        files = []
646        for newFile in newFiles:
647            assertFile(newFile)
648            files += [File(newFile, composers, buildSystemComposer)]
649        return files
650
651    def addFile(self, f):
652        self.files += [f]
653
654    def addFiles(self, newFiles,
655                 pathComposer, forwardConverter, reverseConverter,
656                 assertFile, buildSystemComposer = BuildSystemFragmentComposer()):
657        files = []
658        for newFile in newFiles:
659            assertFile(newFile)
660            files += [File(newFile, pathComposer, forwardConverter,
661                           reverseConverter, buildSystemComposer)]
662        return files
663
664    def addKernelSpaceHeaderFiles(self, files):
665        self.files += self.addFiles(files,
666                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSHeaderConverter(),
667                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
668
669    def addUserSpaceHeaderFiles(self, files):
670        self.files += self.addFiles(files,
671                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSUserSpaceHeaderConverter(),
672                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
673
674    def addRTEMSHeaderFiles(self, files):
675        self.files += self.addFiles(files, RTEMSPathComposer(),
676                                    NoConverter(), NoConverter(), assertHeaderFile)
677
678    def addLinuxHeaderFiles(self, files):
679        self.files += self.addFiles(files,
680                                    PathComposer(), NoConverter(),
681                                    NoConverter(), assertHeaderFile)
682
683    def addCPUDependentFreeBSDHeaderFiles(self, files):
684        self.files += self.addFiles(files,
685                                    CPUDependentFreeBSDPathComposer(), FromFreeBSDToRTEMSHeaderConverter(),
686                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
687
688    def addCPUDependentLinuxHeaderFiles(self, files):
689        self.files += self.addFiles(files,
690                                    CPUDependentLinuxPathComposer(), NoConverter(),
691                                    NoConverter(), assertHeaderFile)
692
693    def addTargetSourceCPUDependentHeaderFiles(self, targetCPUs, sourceCPU, files):
694        for cpu in targetCPUs:
695            self.files += self.addFiles(files,
696                                        TargetSourceCPUDependentPathComposer(cpu, sourceCPU),
697                                        FromFreeBSDToRTEMSHeaderConverter(),
698                                        NoConverter(), assertHeaderFile)
699
700    def addSourceFiles(self, files, sourceFileFragmentComposer):
701        self.files += self.addFiles(files,
702                                    PathComposer(), NoConverter(), NoConverter(), assertSourceFile,
703                                    sourceFileFragmentComposer)
704
705    def addKernelSpaceSourceFiles(self, files, sourceFileFragmentComposer):
706        self.files += self.addFiles(files,
707                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSSourceConverter(),
708                                    FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
709                                    sourceFileFragmentComposer)
710
711    def addUserSpaceSourceFiles(self, files, sourceFileFragmentComposer):
712        self.files += self.addFiles(files,
713                                    FreeBSDPathComposer(),
714                                    FromFreeBSDToRTEMSUserSpaceSourceConverter(),
715                                    FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
716                                    sourceFileFragmentComposer)
717
718    def addRTEMSSourceFiles(self, files, sourceFileFragmentComposer):
719        self.files += self.addFiles(files,
720                                    RTEMSPathComposer(), NoConverter(), NoConverter(),
721                                    assertSourceFile, sourceFileFragmentComposer)
722
723    def addLinuxSourceFiles(self, files, sourceFileFragmentComposer):
724        self.files += self.addFiles(files,
725                                    PathComposer(), NoConverter(),
726                                    NoConverter(), assertSourceFile,
727                                    sourceFileFragmentComposer)
728
729    def addCPUDependentFreeBSDSourceFiles(self, cpus, files, sourceFileFragmentComposer):
730        for cpu in cpus:
731            self.initCPUDependencies(cpu)
732            self.cpuDependentSourceFiles[cpu] += \
733                self.addFiles(files,
734                              CPUDependentFreeBSDPathComposer(), FromFreeBSDToRTEMSSourceConverter(),
735                              FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
736                              sourceFileFragmentComposer)
737
738    def addCPUDependentRTEMSSourceFiles(self, cpus, files, sourceFileFragmentComposer):
739        for cpu in cpus:
740            self.initCPUDependencies(cpu)
741            self.cpuDependentSourceFiles[cpu] += \
742                self.addFiles(files,
743                              CPUDependentRTEMSPathComposer(), NoConverter(),
744                              NoConverter(), assertSourceFile,
745                              sourceFileFragmentComposer)
746
747    def addCPUDependentLinuxSourceFiles(self, cpus, files, sourceFileFragmentComposer):
748        for cpu in cpus:
749            self.initCPUDependencies(cpu)
750            self.cpuDependentSourceFiles[cpu] += \
751                self.addFiles(files,
752                              CPUDependentLinuxPathComposer(), NoConverter(),
753                              NoConverter(), assertSourceFile,
754                              sourceFileFragmentComposer)
755
756    def addTest(self, testFragementComposer):
757        self.files += [File(testFragementComposer.testName,
758                            PathComposer(), NoConverter(), NoConverter(),
759                            testFragementComposer)]
760
761    def addDependency(self, dep):
762        self.dependencies += [dep]
763
764#
765# Manager - a collection of modules.
766#
767class ModuleManager(object):
768    def __init__(self):
769        self.modules = {}
770        self.generator = {}
771        self.configuration = {}
772        self.setGenerators()
773
774    def __getitem__(self, key):
775        if key not in self.modules:
776            raise KeyError('module %s not found' % (key))
777        return self.modules[key]
778
779    def getAllModules(self):
780        if 'modules' in self.configuration:
781            return self.configuration['modules']
782        return []
783
784    def getEnabledModules(self):
785        if 'modules-enabled' in self.configuration:
786            return self.configuration['modules-enabled']
787        return []
788
789    def addModule(self, module):
790        self.modules[module.name] = module
791
792    def processSource(self, direction):
793        if verbose(verboseDetail):
794            print("process modules:")
795        for m in sorted(self.modules):
796            self.modules[m].processSource(direction)
797
798    def setConfiguration(self, config):
799        self.configuration = copy.deepcopy(config)
800
801    def getConfiguration(self):
802        return self.configuration
803
804    def updateConfiguration(self, config):
805        self.configuration.update(config)
806
807    def setModuleConfigiuration(self):
808        mods = sorted(self.modules.keys())
809        self.configuration['modules'] = mods
810        # Enabled modules are overwritten by config file. Default to all.
811        self.configuration['modules-enabled'] = mods
812
813    def generateBuild(self, only_enabled=True):
814        modules_to_process = self.getEnabledModules()
815        # Used for copy between FreeBSD and RTEMS
816        if only_enabled == False:
817            modules_to_process = self.getAllModules()
818        for m in modules_to_process:
819            self.modules[m].generate()
820
821    def setGenerators(self):
822        self.generator['convert'] = Converter
823        self.generator['no-convert'] = NoConverter
824        self.generator['from-FreeBSD-to-RTEMS-UserSpaceSourceConverter'] = FromFreeBSDToRTEMSUserSpaceSourceConverter
825        self.generator['from-RTEMS-To-FreeBSD-SourceConverter'] = FromRTEMSToFreeBSDSourceConverter
826        self.generator['buildSystemFragmentComposer'] = BuildSystemFragmentComposer
827
828        self.generator['file'] = File
829
830        self.generator['path'] = PathComposer
831        self.generator['freebsd-path'] = FreeBSDPathComposer
832        self.generator['rtems-path'] = RTEMSPathComposer
833        self.generator['cpu-path'] = CPUDependentFreeBSDPathComposer
834        self.generator['target-src-cpu--path'] = TargetSourceCPUDependentPathComposer
835
836        self.generator['source'] = SourceFileFragmentComposer
837        self.generator['test'] = TestFragementComposer
838        self.generator['kvm-symbols'] = KVMSymbolsFragmentComposer
839        self.generator['rpc-gen'] = RPCGENFragmentComposer
840        self.generator['route-keywords'] = RouteKeywordsFragmentComposer
841        self.generator['lex'] = LexFragmentComposer
842        self.generator['yacc'] = YaccFragmentComposer
843
844        self.generator['source-if-header'] = SourceFileIfHeaderComposer
845        self.generator['test-if-header'] = TestIfHeaderComposer
Note: See TracBrowser for help on using the repository browser.