source: rtems-libbsd/builder.py @ 1378632

5-freebsd-12
Last change on this file since 1378632 was 1f7037d, checked in by Sichen Zhao <1473996754@…>, on Aug 1, 2017 at 12:32:08 PM

Port openssl to RTEMS.

  • Property mode set to 100755
File size: 29.5 KB
Line 
1#
2#  Copyright (c) 2015-2016 Chris Johns <chrisj@rtems.org>. All rights reserved.
3#
4#  Copyright (c) 2009-2015 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
47
48#
49# Global controls.
50#
51RTEMS_DIR = "."
52FreeBSD_DIR = "freebsd-org"
53verboseLevel = 0
54isDryRun = False
55isDiffMode = False
56filesProcessedCount = 0
57filesProcessed = []
58filesTotal = 0
59filesTotalLines = 0
60filesTotalInserts = 0
61filesTotalDeletes = 0
62diffDetails = { }
63
64verboseInfo = 1
65verboseDetail = 2
66verboseMoreDetail = 3
67verboseDebug = 4
68
69def verbose(level = verboseInfo):
70    return verboseLevel >= level
71
72def changedFileSummary(statsReport = False):
73
74    global filesTotal, filesTotalLines, filesTotalInserts, filesTotalDeletes
75
76    if isDiffMode == False:
77        if verbose():
78            print('%d file(s) were changed:' % (filesProcessedCount))
79            for f in sorted(filesProcessed):
80                print(' %s' % (f))
81        else:
82            print('%d file(s) were changed.' % (filesProcessedCount))
83    if statsReport:
84        print('Stats Report:')
85        transparent = filesTotal - len(diffDetails)
86        changes = filesTotalInserts + filesTotalDeletes
87        opacity = (float(changes) / (filesTotalLines + changes)) * 100.0
88        print(' Total File(s):%d  Unchanged:%d (%.1f%%)  Changed:%d' \
89              '   Opacity:%5.1f%% Lines:%d Edits:%d (+):%d (-):%d'  % \
90              (filesTotal, transparent, (float(transparent) / filesTotal) * 100.0, len(diffDetails), \
91               opacity, filesTotalLines, changes, filesTotalInserts, filesTotalDeletes))
92        #
93        # Sort by opacity.
94        #
95        ordered_diffs = sorted(diffDetails.items(), key = lambda diff: diff[1].opacity, reverse = True)
96        for f in ordered_diffs:
97            print(%s' % (diffDetails[f[0]].status()))
98
99def readFile(name):
100    try:
101        contents = codecs.open(name, mode = 'r', encoding = 'utf-8', errors = 'ignore').read()
102    except UnicodeDecodeError as ude:
103        print('error: reading: %s: %s' % (name, ude))
104        sys.exit(1)
105    return contents
106
107def writeFile(name, contents):
108    path = os.path.dirname(name)
109    if not os.path.exists(path):
110        try:
111            os.makedirs(path)
112        except OSError as oe:
113            print('error: cannot create directory: %s: %s' % (path, oe))
114            sys.exit(1)
115    try:
116        codecs.open(name, mode = 'w',  encoding = 'utf-8', errors = 'ignore').write(contents)
117    except UnicodeDecodeError as ude:
118        print('error: write: %s: %s' % (name, ude))
119        sys.exit(1)
120
121#
122# A builder error.
123#
124class error(Exception):
125    """Base class for exceptions."""
126    def __init__(self, msg):
127        self.msg = 'error: %s' % (msg)
128    def set_output(self, msg):
129        self.msg = msg
130    def __str__(self):
131        return self.msg
132
133#
134# Diff Record
135#
136class diffRecord:
137    def __init__(self, src, dst, orig, diff, inserts, deletes):
138        self.src = src
139        self.dst = dst
140        self.orig = orig
141        self.diff = diff
142        self.lines = len(orig)
143        self.inserts = inserts
144        self.deletes = deletes
145        self.changes = inserts + deletes
146        self.opacity = (float(self.changes) / (self.lines + self.changes)) * 100.0
147
148    def __repr__(self):
149        return self.src
150
151    def status(self):
152        return 'opacity:%5.1f%% edits:%4d (+):%-4d (-):%-4d %s' % \
153            (self.opacity, self.changes, self.inserts, self.deletes, self.src)
154
155#
156# This stuff needs to move to libbsd.py.
157#
158def commonFlags():
159    return ['-O2',
160            '-g',
161            '-fno-strict-aliasing',
162            '-ffreestanding',
163            '-fno-common']
164
165def commonWarnings():
166    return ['-Wall',
167            '-Wno-format',
168            '-Wno-pointer-sign']
169
170def commonNoWarnings():
171    return ['-w']
172
173def includes():
174    return ['-Irtemsbsd/include',
175            '-Ifreebsd/sys',
176            '-Ifreebsd/sys/contrib/pf',
177            '-Ifreebsd/sys/net',
178            '-Ifreebsd/include',
179            '-Ifreebsd/lib',
180            '-Ifreebsd/lib/libbsdstat',
181            '-Ifreebsd/lib/libc/include',
182            '-Ifreebsd/lib/libc/isc/include',
183            '-Ifreebsd/lib/libc/resolv',
184            '-Ifreebsd/lib/libutil',
185            '-Ifreebsd/lib/libkvm',
186            '-Ifreebsd/lib/libmemstat',
187            '-Ifreebsd/lib/libipsec',
188            '-Ifreebsd/contrib/expat/lib',
189            '-Ifreebsd/contrib/libpcap',
190            '-Ifreebsd/contrib/libxo',
191            '-Irtemsbsd/sys',
192            '-ImDNSResponder/mDNSCore',
193            '-ImDNSResponder/mDNSShared',
194            '-ImDNSResponder/mDNSPosix',
195            '-Itestsuite/include']
196
197def buildInclude():
198    """ Returns the path where headers will be copied during build. """
199    return 'build-include'
200
201def cpuIncludes():
202    return ['-Irtemsbsd/@CPU@/include',
203            '-Ifreebsd/sys/@CPU@/include']
204
205def cflags():
206    return []
207
208def cxxflags():
209    return []
210
211def headerPaths():
212    """ Returns a list of information about what header files should be
213    installed.
214
215    The list is also used to find headers with a local path that doesn't match
216    it's dest path. Due to the difference in the path name such files are
217    problematic during the build if they are included using their later
218    installation path (dest path) name. Therefore they are copied into a
219    sub-directory of the build path so that they can be included with their
220    normal installation path. """
221
222    #         local path                      wildcard             dest path
223    return [('rtemsbsd/include',              '**/*.h',            ''),
224            ('rtemsbsd/mghttpd',              'mongoose.h',        'mghttpd'),
225            ('freebsd/include',               '**/*.h',            ''),
226            ('freebsd/sys/bsm',               '**/*.h',            'bsm'),
227            ('freebsd/sys/cam',               '**/*.h',            'cam'),
228            ('freebsd/sys/net',               '**/*.h',            'net'),
229            ('freebsd/sys/net80211',          '**/*.h',            'net80211'),
230            ('freebsd/sys/netinet',           '**/*.h',            'netinet'),
231            ('freebsd/sys/netinet6',          '**/*.h',            'netinet6'),
232            ('freebsd/sys/netipsec',          '**/*.h',            'netipsec'),
233            ('freebsd/crypto/openssl',        '*.h',               'openssl'),
234            ('freebsd/crypto/openssl/crypto', '*.h',               'openssl'),
235            ('freebsd/crypto/openssl/ssl',    '(ssl|kssl|ssl2).h', 'openssl'),
236            ('freebsd/crypto/openssl/crypto/aes', 'aes.h',         'openssl'),
237            ('freebsd/crypto/openssl/crypto/err', 'err.h',         'openssl'),
238            ('freebsd/crypto/openssl/crypto/bio', '*.h',           'openssl'),
239            ('freebsd/crypto/openssl/crypto/dsa', '*.h',           'openssl'),
240            ('freebsd/crypto/openssl/ssl',        '*.h',           'openssl'),
241            ('freebsd/crypto/openssl/crypto/bn',  'bn.h',          'openssl'),
242            ('freebsd/crypto/openssl/crypto/x509',  'x509.h',      'openssl'),
243            ('freebsd/crypto/openssl/crypto/cast',  'cast.h',      'openssl'),
244            ('freebsd/crypto/openssl/crypto/lhash', 'lhash.h',     'openssl'),
245            ('freebsd/crypto/openssl/crypto/ecdh',  'ecdh.h',      'openssl'),
246            ('freebsd/crypto/openssl/crypto/ecdsa', 'ecdsa.h',     'openssl'),
247            ('freebsd/crypto/openssl/crypto/idea',  'idea.h',      'openssl'),
248            ('freebsd/crypto/openssl/crypto/mdc2',  'mdc2.h',      'openssl'),
249            ('freebsd/crypto/openssl/crypto/md4',   'md4.h',       'openssl'),
250            ('freebsd/crypto/openssl/crypto/md5',   'md5.h',       'openssl'),
251            ('freebsd/crypto/openssl/crypto/rc2',   'rc2.h',       'openssl'),
252            ('freebsd/crypto/openssl/crypto/rc4',   'rc4.h',       'openssl'),
253            ('freebsd/crypto/openssl/crypto/ripemd','ripemd.h',    'openssl'),
254            ('freebsd/crypto/openssl/crypto/seed',  'seed.h',      'openssl'),
255            ('freebsd/crypto/openssl/crypto/sha',   'sha.h',       'openssl'),
256            ('freebsd/crypto/openssl/crypto/x509v3','x509v3.h',    'openssl'),
257            ('freebsd/crypto/openssl/crypto/x509',  'x509_vfy.h',  'openssl'),
258            ('freebsd/crypto/openssl/crypto/buffer','buffer.h',    'openssl'),
259            ('freebsd/crypto/openssl/crypto/comp',  'comp.h',      'openssl'),
260            ('freebsd/crypto/openssl/crypto/asn1',  'asn1_mac.h',  'openssl'),
261            ('freebsd/crypto/openssl/crypto/pem',  '(pem|pem2).h', 'openssl'),
262            ('freebsd/crypto/openssl/crypto/rsa',   'rsa.h',       'openssl'),
263            ('freebsd/crypto/openssl/crypto/evp',   'evp.h',       'openssl'),
264            ('freebsd/crypto/openssl/crypto/ec',    'ec.h',        'openssl'),
265            ('freebsd/crypto/openssl/crypto/engine', 'engine.h',   'openssl'),
266            ('freebsd/crypto/openssl/crypto/pkcs7', 'pkcs7.h',     'openssl'),
267            ('freebsd/crypto/openssl/crypto/hmac',  'hmac.h',      'openssl'),
268            ('freebsd/crypto/openssl/crypto/pqueue', 'pqueue.h',   'openssl'),
269            ('freebsd/crypto/openssl/crypto/ocsp',  'ocsp.h',      'openssl'),
270            ('freebsd/crypto/openssl/crypto/rand',  'rand.h',      'openssl'),
271            ('freebsd/crypto/openssl/crypto/srp',   'srp.h',       'openssl'),
272            ('freebsd/crypto/openssl/crypto/dh',    'dh.h',        'openssl'),
273            ('freebsd/crypto/openssl/crypto/dso',   'dso.h',       'openssl'),
274            ('freebsd/crypto/openssl/crypto/krb5',  'krb5_asn.h',  'openssl'),
275            ('freebsd/crypto/openssl/crypto/cms',   'cms.h',       'openssl'),
276            ('freebsd/crypto/openssl/crypto/txt_db', 'txt_db.h',   'openssl'),
277            ('freebsd/crypto/openssl/crypto/ts',    'ts.h',        'openssl'),
278            ('freebsd/crypto/openssl/crypto/modes', 'modes.h',     'openssl'),
279            ('freebsd/crypto/openssl/crypto/pkcs12', 'pkcs12.h',   'openssl'),
280            ('freebsd/crypto/openssl/crypto/bf',    'blowfish.h',  'openssl'),
281            ('freebsd/crypto/openssl/crypto/cmac',  'cmac.h',      'openssl'),
282            ('freebsd/crypto/openssl/crypto/asn1',  '(asn1|asn1t).h',            'openssl'),
283            ('freebsd/crypto/openssl/crypto/camellia', 'camellia.h',             'openssl'),
284            ('freebsd/crypto/openssl/crypto/objects',  '(objects|obj_mac).h',    'openssl'),
285            ('freebsd/crypto/openssl/crypto/conf',     '(conf|conf_api).h',      'openssl'),
286            ('freebsd/crypto/openssl/crypto/des',      '(des|des_old).h',        'openssl'),
287            ('freebsd/crypto/openssl/crypto/ui',       '(ui_compat|ui).h',       'openssl'),
288            ('freebsd/crypto/openssl/crypto/whrlpool', 'whrlpool.h',             'openssl'),
289            ('freebsd/crypto/openssl/crypto/stack',    '(stack|safestack).h',    'openssl'),
290            ('freebsd/crypto/openssl/crypto', '(opensslconf|opensslv|crypto).h', 'openssl'),
291            ('freebsd/sys/rpc',               '**/*.h',            'rpc'),
292            ('freebsd/sys/sys',               '**/*.h',            'sys'),
293            ('freebsd/sys/vm',                '**/*.h',            'vm'),
294            ('freebsd/sys/dev/mii',           '**/*.h',            'dev/mii'),
295            ('mDNSResponder/mDNSCore',        'mDNSDebug.h',       ''),
296            ('mDNSResponder/mDNSCore',        'mDNSEmbeddedAPI.h', ''),
297            ('mDNSResponder/mDNSShared',      'dns_sd.h',          ''),
298            ('mDNSResponder/mDNSPosix',       'mDNSPosix.h',       '')]
299
300# Move target dependent files under a machine directory
301def mapCPUDependentPath(path):
302  return path.replace("include/", "include/machine/")
303
304def fixIncludes(data):
305    data = re.sub('#include <sys/resource.h>', '#include <rtems/bsd/sys/resource.h>', data)
306    data = re.sub('#include <sys/unistd.h>',   '#include <rtems/bsd/sys/unistd.h>', data)
307    return data
308
309# revert fixing the include paths inside a C or .h file
310def revertFixIncludes(data):
311    data = re.sub('#include <rtems/bsd/',  '#include <', data)
312    data = re.sub('#include <util.h>',     '#include <rtems/bsd/util.h>', data)
313    data = re.sub('#include <bsd.h>',      '#include <rtems/bsd/bsd.h>', data)
314    data = re.sub('#include <zerocopy.h>', '#include <rtems/bsd/zerocopy.h>', data)
315    return data
316
317# fix include paths inside a C or .h file
318def fixLocalIncludes(data):
319    data = re.sub('#include "opt_([^"]*)"',    '#include <rtems/bsd/local/opt_\\1>', data)
320    data = re.sub('#include "([^"]*)_if.h"',   '#include <rtems/bsd/local/\\1_if.h>', data)
321    data = re.sub('#include "miidevs([^"]*)"', '#include <rtems/bsd/local/miidevs\\1>', data)
322    data = re.sub('#include "usbdevs([^"]*)"', '#include <rtems/bsd/local/usbdevs\\1>', data)
323    return data
324
325# revert fixing the include paths inside a C or .h file
326def revertFixLocalIncludes(data):
327    data = re.sub('#include <rtems/bsd/local/([^>]*)>', '#include "\\1"', data)
328    return data
329
330def assertHeaderFile(path):
331    if path[-2] != '.' or path[-1] != 'h':
332        print("*** " + path + " does not end in .h")
333        print("*** Move it to a C source file list")
334        sys.exit(2)
335
336def assertSourceFile(path):
337    if path[-2] != '.' or (path[-1] != 'c' and path[-1] != 'S'):
338        print("*** " + path + " does not end in .c")
339        print("*** Move it to a header file list")
340        sys.exit(2)
341
342def diffSource(dstLines, srcLines, src, dst):
343    global filesTotal, filesTotalLines, filesTotalInserts, filesTotalDeletes
344    #
345    # Diff, note there is no line termination on each string.  Expand the
346    # generator to list because the generator is not reusable.
347    #
348    diff = list(difflib.unified_diff(dstLines,
349                                     srcLines,
350                                     fromfile = src,
351                                     tofile = dst,
352                                     n = 5,
353                                     lineterm = ''))
354    inserts = 0
355    deletes = 0
356    if len(diff) > 0:
357        if src in diffDetails and \
358           diffDetails[src].dst != dst and diffDetails[src].diff != diff:
359            raise error('repeated diff of file different: src:%s dst:%s' % (src, dst))
360        for l in diff:
361            if l[0] == '-':
362                deletes += 1
363            elif l[0] == '+':
364                inserts += 1
365        diffDetails[src] = diffRecord(src, dst, srcLines, diff, inserts, deletes)
366
367    #
368    # Count the total files, lines and the level of changes.
369    #
370    filesTotal += 1
371    filesTotalLines += len(srcLines)
372    filesTotalInserts += inserts
373    filesTotalDeletes += deletes
374
375    return diff
376
377#
378# Converters provide a way to alter the various types of code. The conversion
379# process filters a file as it is copies from the source path to the
380# destination path. Specialised versions are provided for different types of
381# source.
382#
383class Converter(object):
384
385    def convert(self, src, dst, hasSource = True, sourceFilter = None, srcContents = None):
386
387        global filesProcessed, filesProcessedCount
388
389        if verbose(verboseDebug):
390            print("convert: filter:%s: %s -> %s" % \
391                  (['yes', 'no'][sourceFilter is None], src, dst))
392
393        #
394        # If there is no source raise an error if we expect source else print a
395        # warning and do not try and convert.
396        #
397        if srcContents is None:
398            if not os.path.exists(src):
399                if hasSource:
400                    raise error('source not found: %s' % (src))
401                else:
402                    print('warning: no source: %s' % (src))
403                    return
404
405            #
406            # Files read as a single string if not passed in.
407            #
408            srcContents = readFile(src)
409
410        if os.path.exists(dst):
411            dstContents = readFile(dst)
412        else:
413            print('warning: no destination: %s' % (dst))
414            dstContents = ''
415
416        #
417        # Filter the source.
418        #
419        if sourceFilter is not None:
420            srcContents = sourceFilter(srcContents)
421
422        #
423        # Split into a list of lines.
424        #
425        srcLines = srcContents.split(os.linesep)
426        dstLines = dstContents.split(os.linesep)
427
428        if verbose(verboseDebug):
429            print('Unified diff: %s (lines:%d)' % (src, len(srcLines)))
430
431        #
432        # Diff, note there is no line termination on each string.
433        #
434        diff = diffSource(dstLines, srcLines, src, dst)
435
436        #
437        # The diff list is empty if the files are the same.
438        #
439        if len(diff) > 0:
440
441            if verbose(verboseDebug):
442                print('Unified diff length: %d' % len(diff))
443
444            filesProcessed += [dst]
445            filesProcessedCount += 1
446            if isDiffMode == False:
447                if verbose(verboseDetail):
448                    print("UPDATE: %s -> %s" % (src, dst))
449                if isDryRun == False:
450                    writeFile(dst, srcContents)
451            else:
452                print("diff -u %s %s" % (src, dst))
453                for l in diff:
454                    print(l)
455
456class NoConverter(Converter):
457    def convert(self, src, dst, hasSource = True, sourceFilter = None):
458        return '/* EMPTY */\n'
459
460class FromFreeBSDToRTEMSHeaderConverter(Converter):
461    def sourceFilter(self, data):
462        data = fixLocalIncludes(data)
463        data = fixIncludes(data)
464        return data
465
466    def convert(self, src, dst):
467        sconverter = super(FromFreeBSDToRTEMSHeaderConverter, self)
468        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
469
470class FromFreeBSDToRTEMSUserSpaceHeaderConverter(Converter):
471    def sourceFilter(self, data):
472        data = fixIncludes(data)
473        return data
474
475    def convert(self, src, dst):
476        sconverter = super(FromFreeBSDToRTEMSUserSpaceHeaderConverter, self)
477        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
478
479class FromFreeBSDToRTEMSSourceConverter(Converter):
480    def sourceFilter(self, data):
481        data = fixLocalIncludes(data)
482        data = fixIncludes(data)
483        data = '#include <machine/rtems-bsd-kernel-space.h>\n\n' + data
484        return data
485
486    def convert(self, src, dst):
487        sconverter = super(FromFreeBSDToRTEMSSourceConverter, self)
488        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
489
490class FromFreeBSDToRTEMSUserSpaceSourceConverter(Converter):
491    def sourceFilter(self, data):
492        data = fixIncludes(data)
493        data = '#include <machine/rtems-bsd-user-space.h>\n\n' + data
494        return data
495
496    def convert(self, src, dst):
497        sconverter = super(FromFreeBSDToRTEMSUserSpaceSourceConverter, self)
498        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
499
500class FromRTEMSToFreeBSDHeaderConverter(Converter):
501    def sourceFilter(self, data):
502        data = revertFixLocalIncludes(data)
503        data = revertFixIncludes(data)
504        return data
505
506    def convert(self, src, dst):
507        sconverter = super(FromRTEMSToFreeBSDHeaderConverter, self)
508        sconverter.convert(src, dst, hasSource = False,  sourceFilter = self.sourceFilter)
509
510class FromRTEMSToFreeBSDSourceConverter(Converter):
511    def sourceFilter(self, data):
512        data = re.sub('#include <machine/rtems-bsd-kernel-space.h>\n\n', '', data)
513        data = re.sub('#include <machine/rtems-bsd-user-space.h>\n\n', '', data)
514        data = revertFixLocalIncludes(data)
515        data = revertFixIncludes(data)
516        return data
517
518    def convert(self, src, dst):
519        sconverter = super(FromRTEMSToFreeBSDSourceConverter, self)
520        sconverter.convert(src, dst, hasSource = False, sourceFilter = self.sourceFilter)
521
522#
523# Compose a path based for the various parts of the source tree.
524#
525class PathComposer(object):
526    def composeFreeBSDPath(self, path):
527        return path
528
529    def composeRTEMSPath(self, path, prefix):
530        return os.path.join(prefix, path)
531
532class FreeBSDPathComposer(PathComposer):
533    def composeFreeBSDPath(self, path):
534        return os.path.join(FreeBSD_DIR, path)
535
536    def composeRTEMSPath(self, path, prefix):
537        return os.path.join(prefix, 'freebsd', path)
538
539class RTEMSPathComposer(PathComposer):
540    def composeFreeBSDPath(self, path):
541        return path
542
543    def composeRTEMSPath(self, path, prefix):
544        return os.path.join(prefix, 'rtemsbsd', path)
545
546class CPUDependentPathComposer(FreeBSDPathComposer):
547    def composeRTEMSPath(self, path, prefix):
548        path = super(CPUDependentPathComposer, self).composeRTEMSPath(path, prefix)
549        path = mapCPUDependentPath(path)
550        return path
551
552class TargetSourceCPUDependentPathComposer(CPUDependentPathComposer):
553    def __init__(self, targetCPU, sourceCPU):
554        self.targetCPU = targetCPU
555        self.sourceCPU = sourceCPU
556
557    def composeRTEMSPath(self, path, prefix):
558        path = super(TargetSourceCPUDependentPathComposer, self).composeRTEMSPath(path, prefix)
559        path = path.replace(self.sourceCPU, self.targetCPU)
560        return path
561
562class BuildSystemFragmentComposer(object):
563    def __init__(self, includes = None):
564        if type(includes) is not list:
565            self.includes = [includes]
566        else:
567            self.includes = includes
568
569    def compose(self, path):
570        return ''
571
572#
573# File - a file in the source we move backwards and forwards.
574#
575class File(object):
576    def __init__(self, path, pathComposer,
577                 forwardConverter, reverseConverter, buildSystemComposer):
578        if verbose(verboseMoreDetail):
579            print("FILE: %-50s F:%-45s R:%-45s" % \
580                  (path,
581                   forwardConverter.__class__.__name__,
582                   reverseConverter.__class__.__name__))
583        self.path = path
584        self.pathComposer = pathComposer
585        self.freebsdPath = self.pathComposer.composeFreeBSDPath(self.path)
586        self.rtemsPath = self.pathComposer.composeRTEMSPath(self.path, RTEMS_DIR)
587        self.forwardConverter = forwardConverter
588        self.reverseConverter = reverseConverter
589        self.buildSystemComposer = buildSystemComposer
590
591    def processSource(self, forward):
592        if forward:
593            if verbose(verboseDetail):
594                print("process source: %s => %s" % (self.freebsdPath, self.rtemsPath))
595            self.forwardConverter.convert(self.freebsdPath, self.rtemsPath)
596        else:
597            if verbose(verboseDetail):
598                print("process source: %s => %s converter:%s" % \
599                      (self.rtemsPath, self.freebsdPath, self.reverseConverter.__class__.__name__))
600            self.reverseConverter.convert(self.rtemsPath, self.freebsdPath)
601
602    def getFragment(self):
603        return self.buildSystemComposer.compose(self.pathComposer.composeRTEMSPath(self.path, ''))
604
605#
606# Module - logical group of related files we can perform actions on
607#
608class Module:
609    def __init__(self, name):
610        self.name = name
611        self.conditionalOn = "none"
612        self.files = []
613        self.cpuDependentSourceFiles = {}
614        self.dependencies = []
615
616    def initCPUDependencies(self, cpu):
617        if cpu not in self.cpuDependentSourceFiles:
618            self.cpuDependentSourceFiles[cpu] = []
619
620    def processSource(self, direction):
621        if verbose(verboseDetail):
622            print("process module: %s" % (self.name))
623        for f in self.files:
624            f.processSource(direction)
625        for cpu, files in self.cpuDependentSourceFiles.items():
626            for f in files:
627                f.processSource(direction)
628
629    def addFiles(self, newFiles, buildSystemComposer = BuildSystemFragmentComposer()):
630        files = []
631        for newFile in newFiles:
632            assertFile(newFile)
633            files += [File(newFile, composers, buildSystemComposer)]
634        return files
635
636    def addFile(self, f):
637        self.files += [f]
638
639    def addFiles(self, newFiles,
640                 pathComposer, fromFreeBSDToRTEMSConverter, fromRTEMSToFreeBSDConverter,
641                 assertFile, buildSystemComposer = BuildSystemFragmentComposer()):
642        files = []
643        for newFile in newFiles:
644            assertFile(newFile)
645            files += [File(newFile, pathComposer, fromFreeBSDToRTEMSConverter,
646                           fromRTEMSToFreeBSDConverter, buildSystemComposer)]
647        return files
648
649    def addKernelSpaceHeaderFiles(self, files):
650        self.files += self.addFiles(files,
651                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSHeaderConverter(),
652                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
653
654    def addUserSpaceHeaderFiles(self, files):
655        self.files += self.addFiles(files,
656                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSUserSpaceHeaderConverter(),
657                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
658
659    def addRTEMSHeaderFiles(self, files):
660        self.files += self.addFiles(files, RTEMSPathComposer(),
661                                    NoConverter(), NoConverter(), assertHeaderFile)
662
663    def addCPUDependentHeaderFiles(self, files):
664        self.files += self.addFiles(files,
665                                    CPUDependentPathComposer(), FromFreeBSDToRTEMSHeaderConverter(),
666                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
667
668    def addTargetSourceCPUDependentHeaderFiles(self, targetCPUs, sourceCPU, files):
669        for cpu in targetCPUs:
670            self.files += self.addFiles(files,
671                                        TargetSourceCPUDependentPathComposer(cpu, sourceCPU),
672                                        FromFreeBSDToRTEMSHeaderConverter(),
673                                        NoConverter(), assertHeaderFile)
674
675    def addSourceFiles(self, files, sourceFileFragmentComposer):
676        self.files += self.addFiles(files,
677                                    PathComposer(), NoConverter(), NoConverter(), assertSourceFile,
678                                    sourceFileFragmentComposer)
679
680    def addKernelSpaceSourceFiles(self, files, sourceFileFragmentComposer):
681        self.files += self.addFiles(files,
682                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSSourceConverter(),
683                                    FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
684                                    sourceFileFragmentComposer)
685
686    def addUserSpaceSourceFiles(self, files, sourceFileFragmentComposer):
687        self.files += self.addFiles(files,
688                                    FreeBSDPathComposer(),
689                                    FromFreeBSDToRTEMSUserSpaceSourceConverter(),
690                                    FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
691                                    sourceFileFragmentComposer)
692
693    def addRTEMSSourceFiles(self, files, sourceFileFragmentComposer):
694        self.files += self.addFiles(files,
695                                    RTEMSPathComposer(), NoConverter(), NoConverter(),
696                                    assertSourceFile, sourceFileFragmentComposer)
697
698    def addCPUDependentSourceFiles(self, cpus, files, sourceFileFragmentComposer):
699        for cpu in cpus:
700            self.initCPUDependencies(cpu)
701            self.cpuDependentSourceFiles[cpu] += \
702                self.addFiles(files,
703                              CPUDependentPathComposer(), FromFreeBSDToRTEMSSourceConverter(),
704                              FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
705                              sourceFileFragmentComposer)
706
707    def addTest(self, testFragementComposer):
708        self.files += [File(testFragementComposer.testName,
709                            PathComposer(), NoConverter(), NoConverter(),
710                            testFragementComposer)]
711
712    def addDependency(self, dep):
713        self.dependencies += [dep]
714
715#
716# Manager - a collection of modules.
717#
718class ModuleManager:
719    def __init__(self):
720        self.modules = {}
721        self.generator = {}
722        self.setGenerators()
723
724    def __getitem__(self, key):
725        if key not in self.modules:
726            raise KeyError('module %s not found' % (key))
727        return self.modules[key]
728
729    def getModules(self):
730        return sorted(self.modules.keys())
731
732    def addModule(self, module):
733        self.modules[module.name] = module
734
735    def processSource(self, direction):
736        if verbose(verboseDetail):
737            print("process modules:")
738        for m in sorted(self.modules):
739            self.modules[m].processSource(direction)
Note: See TracBrowser for help on using the repository browser.