source: rtems-libbsd/builder.py @ 1043048

55-freebsd-126-freebsd-12
Last change on this file since 1043048 was d18c643, checked in by Christian Mauderer <Christian.Mauderer@…>, on 10/02/17 at 07:57:04

Allow to set optimization level during configure.

This allows to set the optimization level for libbsd via a configure
switch. Useful for building with for example no optimization during
debug or with size optimization for space restricted targets.

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