source: rtems-libbsd/waf_generator.py @ 1383c80

4.115-freebsd-12freebsd-9.3
Last change on this file since 1383c80 was 1383c80, checked in by Chris Johns <chrisj@…>, on May 27, 2015 at 12:42:28 AM

Add conditional support for RTEMS PCI to the waf build.

Check for the "rtems/pci.h" header and provide conditional build support
with waf to build for BSPs that do not have PCI support. The Makefile build
always defines HAVE_RTEMS_PCI_H which is the same state with this change.

The PCI calls still exist however they do nothing and return a constant.
Any PCI based driver that makes these calls on a BSP that does not have
PCI support will not work which is understandable. Either change the
driver or add PCI support the BSP.

  • Property mode set to 100755
File size: 22.1 KB
Line 
1#
2#  Copyright (c) 2015 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
35import os
36import tempfile
37
38import builder
39
40trace = False
41
42data = { }
43
44def _add_files(name, files):
45    if type(files) is not list:
46        files = [files]
47    if name not in data:
48        data[name] = []
49    data[name] += files
50
51class SourceFileFragmentComposer(builder.BuildSystemFragmentComposer):
52
53    def __init__(self, cflags = "default"):
54        self.cflags = cflags
55
56    def compose(self, path):
57        return ['sources', self.cflags], [path]
58
59class TestFragementComposer(builder.BuildSystemFragmentComposer):
60
61    def __init__(self, testName, fileFragments, runTest = True, netTest = False):
62        self.testName = testName
63        self.fileFragments = fileFragments
64        self.runTest = runTest
65        self.netTest = netTest
66
67    def compose(self, path):
68        return ['tests', self.testName], { 'files': self.fileFragments,
69                                           'run': self.runTest,
70                                           'net': self.netTest }
71
72class KVMSymbolsFragmentComposer(builder.BuildSystemFragmentComposer):
73
74    def compose(self, path):
75        return ['KVMSymbols', 'files'], [path]
76
77class RPCGENFragmentComposer(builder.BuildSystemFragmentComposer):
78
79    def compose(self, path):
80        return ['RPCGen', 'files'], [path]
81
82class RouteKeywordsFragmentComposer(builder.BuildSystemFragmentComposer):
83
84    def compose(self, path):
85        return ['RouteKeywords', 'files'], [path]
86
87class LexFragmentComposer(builder.BuildSystemFragmentComposer):
88
89    def __init__(self, sym, dep):
90        self.sym = sym
91        self.dep = dep
92
93    def compose(self, path):
94        return ['lex', path], { 'file': path,
95                                'sym': self.sym,
96                                'dep': self.dep }
97
98class YaccFragmentComposer(builder.BuildSystemFragmentComposer):
99
100    def __init__(self, sym, header):
101        self.sym = sym
102        self.header = header
103
104    def compose(self, path):
105        return ['yacc', path], { 'file': path,
106                                 'sym': self.sym,
107                                 'header': self.header }
108
109# Module Manager - Collection of Modules
110class ModuleManager(builder.ModuleManager):
111
112    def restart(self):
113        self.script = ''
114
115    def add(self, line = ''):
116        self.script += line + os.linesep
117
118    def write(self):
119        try:
120            out = tempfile.NamedTemporaryFile(delete = False)
121            out.write(self.script)
122            out.close()
123            wscript = builder.RTEMS_DIR + '/wscript'
124            builder.processIfDifferent(out.name, wscript, "wscript")
125        finally:
126            try:
127                os.remove(out.name)
128            except:
129                pass
130
131    def setGenerators(self):
132        self.generator['convert'] = builder.Converter
133        self.generator['no-convert'] = builder.NoConverter
134
135        self.generator['file'] = builder.File
136
137        self.generator['path'] = builder.PathComposer
138        self.generator['freebsd-path'] = builder.FreeBSDPathComposer
139        self.generator['rtems-path'] = builder.RTEMSPathComposer
140        self.generator['cpu-path'] = builder.CPUDependentPathComposer
141        self.generator['target-src-cpu--path'] = builder.TargetSourceCPUDependentPathComposer
142
143        self.generator['source'] = SourceFileFragmentComposer
144        self.generator['test'] = TestFragementComposer
145        self.generator['kvm-symbols'] = KVMSymbolsFragmentComposer
146        self.generator['rpc-gen'] = RPCGENFragmentComposer
147        self.generator['route-keywords'] = RouteKeywordsFragmentComposer
148        self.generator['lex'] = LexFragmentComposer
149        self.generator['yacc'] = YaccFragmentComposer
150
151    def generate(self):
152
153        def _source_list(lhs, files, append = False):
154            if append:
155                adder = '+'
156                adder_space = ' '
157            else:
158                adder = ''
159                adder_space = ''
160            ll = len(lhs)
161            if len(files) == 1:
162                self.add('%s %s= [%r]' % (lhs, adder, files[0]))
163            elif len(files) == 2:
164                self.add('%s %s= [%r,' % (lhs, adder, files[0]))
165                self.add('%s %s   %r]' % (' ' * ll, adder_space, files[-1]))
166            elif len(files) > 0:
167                self.add('%s %s= [%r,' % (lhs, adder, files[0]))
168                for f in files[1:-1]:
169                    self.add('%s %s   %r,' % (' ' * ll, adder_space, f))
170                self.add('%s %s   %r]' % (' ' * ll, adder_space, files[-1]))
171
172        def _data_insert(data, cpu, frag):
173            #
174            # The default handler returns an empty string. Skip it.
175            #
176            if type(frag) is not str:
177                d = data
178                for p in frag[0]:
179                    if p not in d:
180                        d[p] = {}
181                    d = d[p]
182                if type(frag[1]) is list:
183                    if cpu not in d:
184                        d[cpu] = []
185                    d[cpu] += frag[1]
186                else:
187                    d[cpu] = frag[1]
188
189        data = { }
190
191        for mn in self.getModules():
192            m = self[mn]
193            if m.conditionalOn == "none":
194                for f in m.files:
195                    _data_insert(data, 'all', f.getFragment())
196            for cpu, files in sorted(m.cpuDependentSourceFiles.items()):
197                for f in files:
198                    _data_insert(data, cpu, f.getFragment())
199
200        if trace:
201            import pprint
202            pprint.pprint(data)
203
204        self.restart()
205
206        self.add('#')
207        self.add('# RTEMS Project (https://www.rtems.org)')
208        self.add('#')
209        self.add('# Generated waf script. Do not edit, run ./freebsd-to-rtems.py -m')
210        self.add('#')
211        self.add('# To use see README.waf shipped with this file.')
212        self.add('#')
213        self.add('')
214        self.add('import os.path')
215        self.add('')
216        self.add('try:')
217        self.add('    import rtems_waf.rtems as rtems')
218        self.add('except:')
219        self.add('    print "error: no rtems_waf git submodule; see README.waf"')
220        self.add('    import sys')
221        self.add('    sys.exit(1)')
222        self.add('')
223        self.add('def init(ctx):')
224        self.add('    rtems.init(ctx)')
225        self.add('')
226        self.add('def options(opt):')
227        self.add('    rtems.options(opt)')
228        self.add('    opt.add_option("--enable-auto-regen",')
229        self.add('                   action = "store_true",')
230        self.add('                   default = False,')
231        self.add('                   dest = "auto_regen",')
232        self.add('                   help = "Enable auto-regeneration of LEX, RPC and YACC files.")')
233        self.add('    opt.add_option("--enable-warnings",')
234        self.add('                   action = "store_true",')
235        self.add('                   default = False,')
236        self.add('                   dest = "warnings",')
237        self.add('                   help = "Enable all warnings. The default is quiet builds.")')
238        self.add('    opt.add_option("--net-test-config",')
239        self.add('                   default = "config.inc",')
240        self.add('                   dest = "net_config",')
241        self.add('                   help = "Network test configuration.")')
242        self.add('')
243        self.add('def bsp_configure(conf, arch_bsp):')
244        self.add('    conf.check(header_name = "dlfcn.h", features = "c")')
245        self.add('    conf.check(header_name = "rtems/pci.h", features = "c", mandatory = False)')
246        self.add('')
247        self.add('def configure(conf):')
248        self.add('    if conf.options.auto_regen:')
249        self.add('        conf.find_program("lex", mandatory = True)')
250        self.add('        conf.find_program("rpcgen", mandatory = True)')
251        self.add('        conf.find_program("yacc", mandatory = True)')
252        self.add('    conf.env.AUTO_REGEN = conf.options.auto_regen')
253        self.add('    conf.env.WARNINGS = conf.options.warnings')
254        self.add('    conf.env.NET_CONFIG = conf.options.net_config')
255        self.add('    rtems.configure(conf, bsp_configure)')
256        self.add('    if rtems.check_networking(conf):')
257        self.add('        conf.fatal("RTEMS kernel contains the old network support; configure RTEMS with --disable-networking")')
258        self.add('')
259        self.add('def build(bld):')
260        self.add('    rtems.build(bld)')
261        self.add('')
262        self.add('    # C/C++ flags')
263        self.add('    common_flags = []')
264        for f in builder.common_flags():
265            self.add('    common_flags += ["%s"]' % (f))
266        self.add('    if bld.env.WARNINGS:')
267        for f in builder.common_warnings():
268            self.add('        common_flags += ["%s"]' % (f))
269        self.add('    else:')
270        for f in builder.common_no_warnings():
271            self.add('        common_flags += ["%s"]' % (f))
272        self.add('    cflags = %r + common_flags' % (builder.cflags()))
273        self.add('    cxxflags = %r + common_flags' % (builder.cxxflags()))
274        self.add('')
275        self.add('    # Include paths')
276        self.add('    includes = []')
277        for i in builder.includes():
278            self.add('    includes += ["%s"]' % (i[2:]))
279        self.add('    for i in %r:' % (builder.cpu_includes()))
280        self.add('        includes += ["%s" % (i[2:].replace("@CPU@", bld.get_env()["RTEMS_ARCH"]))]')
281        self.add('')
282        self.add('    # Support dummy PIC IRQ includes')
283        self.add('    if bld.get_env()["RTEMS_ARCH"] not in ("arm", "i386", "lm32", "mips", "powerpc", "sparc", "m68k"):')
284        self.add('        includes += ["rtems-dummy-pic-irq/include"]')
285        self.add('')
286
287        self.add('    # Collect the libbsd uses')
288        self.add('    libbsd_use = []')
289        self.add('')
290
291        #
292        # Support the existing Makefile based network configuration file.
293        #
294        self.add('    # Network test configuration')
295        self.add('    if not os.path.exists(bld.env.NET_CONFIG):')
296        self.add('        bld.fatal("network configuraiton \'%s\' not found" % (bld.env.NET_CONFIG))')
297        self.add('    net_cfg_self_ip = None')
298        self.add('    net_cfg_netmask = None')
299        self.add('    net_cfg_peer_ip = None')
300        self.add('    net_cfg_gateway_ip = None')
301        self.add('    net_tap_interface = None')
302        self.add('    try:')
303        self.add('        net_cfg_lines = open(bld.env.NET_CONFIG).readlines()')
304        self.add('    except:')
305        self.add('        bld.fatal("network configuraiton \'%s\' read failed" % (bld.env.NET_CONFIG))')
306        self.add('    lc = 0')
307        self.add('    for l in net_cfg_lines:')
308        self.add('        lc += 1')
309        self.add('        if l.strip().startswith("NET_CFG_"):')
310        self.add('            ls = l.split("=")')
311        self.add('            if len(ls) != 2:')
312        self.add('                bld.fatal("network configuraiton \'%s\' parse error: %d: %s" % ' + \
313                 '(bld.env.NET_CONFIG, lc, l))')
314        self.add('            lhs = ls[0].strip()')
315        self.add('            rhs = ls[1].strip()')
316        self.add('            if lhs == "NET_CFG_SELF_IP":')
317        self.add('                net_cfg_self_ip = rhs')
318        self.add('            if lhs == "NET_CFG_NETMASK":')
319        self.add('                net_cfg_netmask = rhs')
320        self.add('            if lhs == "NET_CFG_PEER_IP":')
321        self.add('                net_cfg_peer_ip = rhs')
322        self.add('            if lhs == "NET_CFG_GATEWAY_IP_IP":')
323        self.add('                net_cfg_gateway_ip = rhs')
324        self.add('            if lhs == "NET_TAP_INTERFACE_IP_IP":')
325        self.add('                net_tap_interface = rhs')
326        self.add('    bld(target = "testsuite/include/rtems/bsd/test/network-config.h",')
327        self.add('        source = "testsuite/include/rtems/bsd/test/network-config.h.in",')
328        self.add('        rule = "sed -e \'s/@NET_CFG_SELF_IP@/%s/\' ' + \
329                 '-e \'s/@NET_CFG_NETMASK@/%s/\' ' + \
330                 '-e \'s/@NET_CFG_PEER_IP@/%s/\' ' + \
331                 '-e \'s/@NET_CFG_GATEWAY_IP@/%s/\' < ${SRC} > ${TGT}" % ' + \
332                 '(net_cfg_self_ip, net_cfg_netmask, net_cfg_peer_ip, net_cfg_netmask),')
333        self.add('        update_outputs = True)')
334        self.add('')
335
336        #
337        # Add the specific rule based builders for generating files.
338        #
339        if 'KVMSymbols' in data:
340            kvmsymbols = data['KVMSymbols']
341            self.add('    # KVM Symbols')
342            self.add('    bld(target = "%s",' % (kvmsymbols['files']['all'][0]))
343            self.add('        source = "rtemsbsd/rtems/generate_kvm_symbols",')
344            self.add('        rule = "./${SRC} > ${TGT}",')
345            self.add('        update_outputs = True)')
346            self.add('    bld.objects(target = "kvmsymbols",')
347            self.add('                features = "c",')
348            self.add('                cflags = cflags,')
349            self.add('                includes = includes + ["rtemsbsd/rtems"],')
350            self.add('                source = "%s")' % (kvmsymbols['files']['all'][0]))
351            self.add('    libbsd_use += ["kvmsymbols"]')
352            self.add('')
353
354        self.add('    bld.add_group()')
355
356        if 'RPCGen' in data:
357            rpcgen = data['RPCGen']
358            rpcname = rpcgen['files']['all'][0][:-2]
359            self.add('    # RPC Generation')
360            self.add('    if bld.env.AUTO_REGEN:')
361            self.add('        bld(target = "%s.h",' % (rpcname))
362            self.add('            source = "%s.x",' % (rpcname))
363            self.add('            rule = "${RPCGEN} -h -o ${TGT} ${SRC}")')
364            self.add('')
365
366        if 'RouteKeywords' in data:
367            routekw = data['RouteKeywords']
368            rkwname = routekw['files']['all'][0]
369            self.add('    # Route keywords')
370            self.add('    if bld.env.AUTO_REGEN:')
371            self.add('        rkw_rule = "cat ${SRC} | ' + \
372                     'awk \'BEGIN { r = 0 } { if (NF == 1) ' + \
373                     'printf \\"#define\\\\tK_%%s\\\\t%%d\\\\n\\\\t{\\\\\\"%%s\\\\\\", K_%%s},\\\\n\\", ' + \
374                     'toupper($1), ++r, $1, toupper($1)}\' > ${TGT}"')
375            self.add('        bld(target = "%s.h",' % (rkwname))
376            self.add('            source = "%s",' % (rkwname))
377            self.add('            rule = rkw_rule)')
378            self.add('')
379
380        if 'lex' in data:
381            lexes = data['lex']
382            self.add('    # Lex')
383            for l in lexes:
384                lex = lexes[l]['all']
385                self.add('    if bld.env.AUTO_REGEN:')
386                self.add('        bld(target = "%s.c",' % (lex['file'][:-2]))
387                self.add('            source = "%s",' % (lex['file']))
388                self.add('            rule = "${LEX} -P %s -t ${SRC} | ' % (lex['sym']) + \
389                         'sed -e \'/YY_BUF_SIZE/s/16384/1024/\' > ${TGT}")')
390                self.add('    bld.objects(target = "lex_%s",' % (lex['sym']))
391                self.add('                features = "c",')
392                self.add('                cflags = cflags,')
393                self.add('                includes = includes,')
394                self.add('                source = "%s.c")' % (lex['file'][:-2]))
395                self.add('    libbsd_use += ["lex_%s"]' % (lex['sym']))
396                self.add('')
397
398        if 'yacc' in data:
399            yaccs = data['yacc']
400            self.add('    # Yacc')
401            for y in yaccs:
402                yacc = yaccs[y]['all']
403                yacc_file = yacc['file']
404                yacc_sym = yacc['sym']
405                yacc_header = '%s/%s' % (os.path.dirname(yacc_file), yacc['header'])
406                self.add('    if bld.env.AUTO_REGEN:')
407                self.add('        bld(target = "%s.c",' % (yacc_file[:-2]))
408                self.add('            source = "%s",' % (yacc_file))
409                self.add('            rule = "${YACC} -b %s -d -p %s ${SRC} && ' % (yacc_sym, yacc_sym) + \
410                         'sed -e \'/YY_BUF_SIZE/s/16384/1024/\' < %s.tab.c > ${TGT} && ' % (yacc_sym) + \
411                         'rm -f %s.tab.c && mv %s.tab.h %s")' % (yacc_sym, yacc_sym, yacc_header))
412                self.add('    bld.objects(target = "yacc_%s",' % (yacc_sym))
413                self.add('                features = "c",')
414                self.add('                cflags = cflags,')
415                self.add('                includes = includes,')
416                self.add('                source = "%s.c")' % (yacc_file[:-2]))
417                self.add('    libbsd_use += ["yacc_%s"]' % (yacc_sym))
418            self.add('')
419
420        #
421        # We have 'm' different sets of flags and there can be 'n' cpus
422        # specific files for those flags.
423        #
424        objs = 0
425        self.add('    # Objects built with different CFLAGS')
426        for cflags in sorted(data['sources']):
427            if cflags is not 'default':
428                objs += 1
429                _source_list('    objs%02d_source' % objs, sorted(data['sources'][cflags]['all']))
430                archs = sorted(data['sources'][cflags])
431                for arch in archs:
432                    if arch is not 'all':
433                        self.add('    if bld.get_env()["RTEMS_ARCH"] == "%s":' % arch)
434                        _source_list('        objs%02d_source' % objs,
435                                     sorted(data['sources'][cflags][arch]),
436                                     append = True)
437                defines = [d[2:] for d in cflags.split(' ')]
438                self.add('    bld.objects(target = "objs%02d",' % (objs))
439                self.add('                features = "c",')
440                self.add('                cflags = cflags,')
441                self.add('                includes = includes,')
442                self.add('                defines = %r,' % (defines))
443                self.add('                source = objs%02d_source)' % objs)
444                self.add('    libbsd_use += ["objs%02d"]' % (objs))
445                self.add('')
446
447        #
448        # We hold the 'default' cflags set of files to the end to create the
449        # static library with.
450        #
451        _source_list('    source', sorted(data['sources']['default']['all']))
452        archs = sorted(data['sources']['default'])
453        for arch in archs:
454            if arch is not 'all':
455                self.add('    if bld.get_env()["RTEMS_ARCH"] == "%s":' % arch)
456                _source_list('        source',
457                             sorted(data['sources']['default'][arch]),
458                             append = True)
459        self.add('    bld.stlib(target = "bsd",')
460        self.add('              features = "c cxx",')
461        self.add('              cflags = cflags,')
462        self.add('              cxxflags = cxxflags,')
463        self.add('              includes = includes,')
464        self.add('              source = source,')
465        self.add('              use = libbsd_use)')
466        self.add('')
467
468        #
469        # Head file collector.
470        #
471        self.add('    # Installs.    ')
472        self.add('    bld.install_files("${PREFIX}/" + rtems.arch_bsp_lib_path(bld.env.RTEMS_ARCH_BSP), ["libbsd.a"])')
473        header_paths = builder.header_paths()
474        self.add('    header_paths = [%s,' % (str(header_paths[0])))
475        for hp in header_paths[1:-1]:
476            self.add('                     %s,' % (str(hp)))
477        self.add('                     %s]' % (str(header_paths[-1])))
478        self.add('    for headers in header_paths:')
479        self.add('        ipath = os.path.join(rtems.arch_bsp_include_path(bld.env.RTEMS_ARCH_BSP), headers[2])')
480        self.add('        start_dir = bld.path.find_dir(headers[0])')
481        self.add('        bld.install_files("${PREFIX}/" + ipath,')
482        self.add('                          start_dir.ant_glob("**/" + headers[1]),')
483        self.add('                          cwd = start_dir,')
484        self.add('                          relative_trick = True)')
485        self.add('')
486
487        self.add('    # Tests')
488        tests = data['tests']
489        for test_name in tests:
490            files = ['testsuite/%s/%s.c' % (test_name, f) for f in  data['tests'][test_name]['all']['files']]
491            _source_list('    test_%s' % (test_name), sorted(files))
492            self.add('    bld.program(target = "%s",' % (test_name))
493            self.add('                features = "cprogram",')
494            self.add('                cflags = cflags,')
495            self.add('                includes = includes,')
496            self.add('                source = test_%s,' % (test_name))
497            self.add('                use = ["bsd"],')
498            self.add('                lib = ["m", "z"],')
499            self.add('                install_path = None)')
500            self.add('')
501
502        self.write()
Note: See TracBrowser for help on using the repository browser.