source: rtems-libbsd/builder.py @ a779a3b

55-freebsd-126-freebsd-12
Last change on this file since a779a3b was 338f300, checked in by Christian Mauderer <christian.mauderer@…>, on 04/25/18 at 14:28:00

buildset: Add minimal and everything config.

This adds two new buildset configurations: One that leaves out as much
features as possible and one that enables all features. For the default
configuration WiFi? support is now disabled.

To disable IPv6 for the minimal configuration, all -DINET6 are
eliminated in libbsd.py. They are now replaced by a #ifdef that checks
for RTEMS_BSD_MODULE_NETINET6 instead.

Close #3351.

  • Property mode set to 100755
File size: 30.8 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):
500        self.testName = testName
501        self.fileFragments = fileFragments
502        self.runTest = runTest
503        self.netTest = netTest
504
505    def compose(self, path):
506        return ['tests', self.testName, ('default', None)], { 'files': self.fileFragments,
507                                                              'run': self.runTest,
508                                                              'net': self.netTest }
509
510class TestIfHeaderComposer(TestFragementComposer):
511
512    def __init__(self, testName, headers, fileFragments, runTest = True, netTest = False):
513        if headers is not list:
514            headers = [headers]
515        self.headers = headers
516        super(TestIfHeaderComposer, self).__init__(testName, fileFragments,
517                                                   runTest = runTest, netTest = netTest)
518
519    def compose(self, path):
520        r = TestFragementComposer.compose(self, path)
521        define_keys = ''
522        for h in self.headers:
523            h = h.upper()
524            for c in '\/-.':
525                h = h.replace(c, '_')
526            define_keys += ' ' + h
527        r[0][2] = (define_keys.strip(), self.headers)
528        return r
529
530class KVMSymbolsFragmentComposer(BuildSystemFragmentComposer):
531
532    def compose(self, path):
533        return ['KVMSymbols', 'files', ('default', None)], [path], self.includes
534
535class RPCGENFragmentComposer(BuildSystemFragmentComposer):
536
537    def compose(self, path):
538        return ['RPCGen', 'files', ('default', None)], [path]
539
540class RouteKeywordsFragmentComposer(BuildSystemFragmentComposer):
541
542    def compose(self, path):
543        return ['RouteKeywords', 'files', ('default', None)], [path]
544
545class LexFragmentComposer(BuildSystemFragmentComposer):
546
547    def __init__(self, sym, dep, cflags = None, includes = None):
548        self.sym = sym
549        self.dep = dep
550        self.cflags, self.includes = _cflagsIncludes(cflags, includes)
551
552    def compose(self, path):
553        d = { 'file': path,
554              'sym': self.sym,
555              'dep': self.dep }
556        if None not in self.cflags:
557            d['cflags'] = self.cflags
558        if None not in self.includes:
559            d['includes'] = self.includes
560        return ['lex', path, ('default', None)], d
561
562class YaccFragmentComposer(BuildSystemFragmentComposer):
563
564    def __init__(self, sym, header, cflags = None, includes = None):
565        self.sym = sym
566        self.header = header
567        self.cflags, self.includes = _cflagsIncludes(cflags, includes)
568
569    def compose(self, path):
570        d = { 'file': path,
571              'sym': self.sym,
572              'header': self.header }
573        if None not in self.cflags:
574            d['cflags'] = self.cflags
575        if None not in self.includes:
576            d['includes'] = self.includes
577        return ['yacc', path, ('default', None)], d
578
579#
580# File - a file in the source we move backwards and forwards.
581#
582class File(object):
583    def __init__(self, path, pathComposer,
584                 forwardConverter, reverseConverter, buildSystemComposer):
585        if verbose(verboseMoreDetail):
586            print("FILE: %-50s F:%-45s R:%-45s" % \
587                  (path,
588                   forwardConverter.__class__.__name__,
589                   reverseConverter.__class__.__name__))
590        self.path = path
591        self.pathComposer = pathComposer
592        self.originPath = self.pathComposer.composeOriginPath(self.path)
593        self.libbsdPath = self.pathComposer.composeLibBSDPath(self.path, LIBBSD_DIR)
594        self.forwardConverter = forwardConverter
595        self.reverseConverter = reverseConverter
596        self.buildSystemComposer = buildSystemComposer
597
598    def processSource(self, forward):
599        if forward:
600            if verbose(verboseDetail):
601                print("process source: %s => %s" % (self.originPath, self.libbsdPath))
602            self.forwardConverter.convert(self.originPath, self.libbsdPath)
603        else:
604            if verbose(verboseDetail):
605                print("process source: %s => %s converter:%s" % \
606                      (self.libbsdPath, self.originPath, self.reverseConverter.__class__.__name__))
607            self.reverseConverter.convert(self.libbsdPath, self.originPath)
608
609    def getFragment(self):
610        return self.buildSystemComposer.compose(self.pathComposer.composeLibBSDPath(self.path, ''))
611
612#
613# Module - logical group of related files we can perform actions on
614#
615class Module(object):
616    def __init__(self, manager, name, enabled = True):
617        self.manager = manager
618        self.name = name
619        self.conditionalOn = "none"
620        self.files = []
621        self.cpuDependentSourceFiles = {}
622        self.dependencies = []
623
624    def initCPUDependencies(self, cpu):
625        if cpu not in self.cpuDependentSourceFiles:
626            self.cpuDependentSourceFiles[cpu] = []
627
628    def processSource(self, direction):
629        if verbose(verboseDetail):
630            print("process module: %s" % (self.name))
631        for f in self.files:
632            f.processSource(direction)
633        for cpu, files in self.cpuDependentSourceFiles.items():
634            for f in files:
635                f.processSource(direction)
636
637    def addFiles(self, newFiles, buildSystemComposer = BuildSystemFragmentComposer()):
638        files = []
639        for newFile in newFiles:
640            assertFile(newFile)
641            files += [File(newFile, composers, buildSystemComposer)]
642        return files
643
644    def addFile(self, f):
645        self.files += [f]
646
647    def addFiles(self, newFiles,
648                 pathComposer, forwardConverter, reverseConverter,
649                 assertFile, buildSystemComposer = BuildSystemFragmentComposer()):
650        files = []
651        for newFile in newFiles:
652            assertFile(newFile)
653            files += [File(newFile, pathComposer, forwardConverter,
654                           reverseConverter, buildSystemComposer)]
655        return files
656
657    def addKernelSpaceHeaderFiles(self, files):
658        self.files += self.addFiles(files,
659                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSHeaderConverter(),
660                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
661
662    def addUserSpaceHeaderFiles(self, files):
663        self.files += self.addFiles(files,
664                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSUserSpaceHeaderConverter(),
665                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
666
667    def addRTEMSHeaderFiles(self, files):
668        self.files += self.addFiles(files, RTEMSPathComposer(),
669                                    NoConverter(), NoConverter(), assertHeaderFile)
670
671    def addLinuxHeaderFiles(self, files):
672        self.files += self.addFiles(files,
673                                    PathComposer(), NoConverter(),
674                                    NoConverter(), assertHeaderFile)
675
676    def addCPUDependentFreeBSDHeaderFiles(self, files):
677        self.files += self.addFiles(files,
678                                    CPUDependentFreeBSDPathComposer(), FromFreeBSDToRTEMSHeaderConverter(),
679                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
680
681    def addCPUDependentLinuxHeaderFiles(self, files):
682        self.files += self.addFiles(files,
683                                    CPUDependentLinuxPathComposer(), NoConverter(),
684                                    NoConverter(), assertHeaderFile)
685
686    def addTargetSourceCPUDependentHeaderFiles(self, targetCPUs, sourceCPU, files):
687        for cpu in targetCPUs:
688            self.files += self.addFiles(files,
689                                        TargetSourceCPUDependentPathComposer(cpu, sourceCPU),
690                                        FromFreeBSDToRTEMSHeaderConverter(),
691                                        NoConverter(), assertHeaderFile)
692
693    def addSourceFiles(self, files, sourceFileFragmentComposer):
694        self.files += self.addFiles(files,
695                                    PathComposer(), NoConverter(), NoConverter(), assertSourceFile,
696                                    sourceFileFragmentComposer)
697
698    def addKernelSpaceSourceFiles(self, files, sourceFileFragmentComposer):
699        self.files += self.addFiles(files,
700                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSSourceConverter(),
701                                    FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
702                                    sourceFileFragmentComposer)
703
704    def addUserSpaceSourceFiles(self, files, sourceFileFragmentComposer):
705        self.files += self.addFiles(files,
706                                    FreeBSDPathComposer(),
707                                    FromFreeBSDToRTEMSUserSpaceSourceConverter(),
708                                    FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
709                                    sourceFileFragmentComposer)
710
711    def addRTEMSSourceFiles(self, files, sourceFileFragmentComposer):
712        self.files += self.addFiles(files,
713                                    RTEMSPathComposer(), NoConverter(), NoConverter(),
714                                    assertSourceFile, sourceFileFragmentComposer)
715
716    def addLinuxSourceFiles(self, files, sourceFileFragmentComposer):
717        self.files += self.addFiles(files,
718                                    PathComposer(), NoConverter(),
719                                    NoConverter(), assertSourceFile,
720                                    sourceFileFragmentComposer)
721
722    def addCPUDependentFreeBSDSourceFiles(self, cpus, files, sourceFileFragmentComposer):
723        for cpu in cpus:
724            self.initCPUDependencies(cpu)
725            self.cpuDependentSourceFiles[cpu] += \
726                self.addFiles(files,
727                              CPUDependentFreeBSDPathComposer(), FromFreeBSDToRTEMSSourceConverter(),
728                              FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
729                              sourceFileFragmentComposer)
730
731    def addCPUDependentRTEMSSourceFiles(self, cpus, files, sourceFileFragmentComposer):
732        for cpu in cpus:
733            self.initCPUDependencies(cpu)
734            self.cpuDependentSourceFiles[cpu] += \
735                self.addFiles(files,
736                              CPUDependentRTEMSPathComposer(), NoConverter(),
737                              NoConverter(), assertSourceFile,
738                              sourceFileFragmentComposer)
739
740    def addCPUDependentLinuxSourceFiles(self, cpus, files, sourceFileFragmentComposer):
741        for cpu in cpus:
742            self.initCPUDependencies(cpu)
743            self.cpuDependentSourceFiles[cpu] += \
744                self.addFiles(files,
745                              CPUDependentLinuxPathComposer(), NoConverter(),
746                              NoConverter(), assertSourceFile,
747                              sourceFileFragmentComposer)
748
749    def addTest(self, testFragementComposer):
750        self.files += [File(testFragementComposer.testName,
751                            PathComposer(), NoConverter(), NoConverter(),
752                            testFragementComposer)]
753
754    def addDependency(self, dep):
755        self.dependencies += [dep]
756
757#
758# Manager - a collection of modules.
759#
760class ModuleManager(object):
761    def __init__(self):
762        self.modules = {}
763        self.generator = {}
764        self.configuration = {}
765        self.setGenerators()
766
767    def __getitem__(self, key):
768        if key not in self.modules:
769            raise KeyError('module %s not found' % (key))
770        return self.modules[key]
771
772    def getAllModules(self):
773        if 'modules' in self.configuration:
774            return self.configuration['modules']
775        return []
776
777    def getEnabledModules(self):
778        if 'modules-enabled' in self.configuration:
779            return self.configuration['modules-enabled']
780        return []
781
782    def addModule(self, module):
783        self.modules[module.name] = module
784
785    def processSource(self, direction):
786        if verbose(verboseDetail):
787            print("process modules:")
788        for m in sorted(self.modules):
789            self.modules[m].processSource(direction)
790
791    def setConfiguration(self, config):
792        self.configuration = copy.deepcopy(config)
793
794    def getConfiguration(self):
795        return self.configuration
796
797    def updateConfiguration(self, config):
798        self.configuration.update(config)
799
800    def setModuleConfigiuration(self):
801        mods = sorted(self.modules.keys())
802        self.configuration['modules'] = mods
803        # Enabled modules are overwritten by config file. Default to all.
804        self.configuration['modules-enabled'] = mods
805
806    def generateBuild(self, only_enabled=True):
807        modules_to_process = self.getEnabledModules()
808        # Used for copy between FreeBSD and RTEMS
809        if only_enabled == False:
810            modules_to_process = self.getAllModules()
811        for m in modules_to_process:
812            self.modules[m].generate()
813
814    def setGenerators(self):
815        self.generator['convert'] = Converter
816        self.generator['no-convert'] = NoConverter
817        self.generator['from-FreeBSD-to-RTEMS-UserSpaceSourceConverter'] = FromFreeBSDToRTEMSUserSpaceSourceConverter
818        self.generator['from-RTEMS-To-FreeBSD-SourceConverter'] = FromRTEMSToFreeBSDSourceConverter
819        self.generator['buildSystemFragmentComposer'] = BuildSystemFragmentComposer
820
821        self.generator['file'] = File
822
823        self.generator['path'] = PathComposer
824        self.generator['freebsd-path'] = FreeBSDPathComposer
825        self.generator['rtems-path'] = RTEMSPathComposer
826        self.generator['cpu-path'] = CPUDependentFreeBSDPathComposer
827        self.generator['target-src-cpu--path'] = TargetSourceCPUDependentPathComposer
828
829        self.generator['source'] = SourceFileFragmentComposer
830        self.generator['test'] = TestFragementComposer
831        self.generator['kvm-symbols'] = KVMSymbolsFragmentComposer
832        self.generator['rpc-gen'] = RPCGENFragmentComposer
833        self.generator['route-keywords'] = RouteKeywordsFragmentComposer
834        self.generator['lex'] = LexFragmentComposer
835        self.generator['yacc'] = YaccFragmentComposer
836
837        self.generator['source-if-header'] = SourceFileIfHeaderComposer
838        self.generator['test-if-header'] = TestIfHeaderComposer
Note: See TracBrowser for help on using the repository browser.