summaryrefslogtreecommitdiffstats
path: root/builder.py
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2020-09-03 09:54:27 +1000
committerChris Johns <chrisj@rtems.org>2020-09-16 15:49:37 +1000
commitc38f93b0c6da8c1da59e611502899cac3d169426 (patch)
tree438e5ecc0c0b04bd6aad863387fe9513da2e0a2b /builder.py
parentwaf: Add a config report (diff)
downloadrtems-libbsd-c38f93b0c6da8c1da59e611502899cac3d169426.tar.bz2
build: Separate the kernel and user land include paths
- Provide support for separate user and kernel include paths in libbsd.py. - Update all added files with a suitable context to build them with. Supported contexts are `kernel` and `user`. - Kernel source use the kernel, CPU, and build header paths in this order. - User source use the user, kernel, CPU and build header paths in this order. The FreeBSD /usr/include tree has some kernel header files installed as well as user land header files. This complicates the separation as some kernel header files are not visible to user land code while other are. This is handled by appending the kernel header paths to the user header paths so user land code will include a user header with the same name as a kernel header over the kernel header but will find a kernel header if there is no matching user header file. Closes #4067
Diffstat (limited to 'builder.py')
-rwxr-xr-xbuilder.py336
1 files changed, 195 insertions, 141 deletions
diff --git a/builder.py b/builder.py
index 79cb6c17..fe2158a9 100755
--- a/builder.py
+++ b/builder.py
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: BSD-2-Clause
-'''Manage the libbsd build configuration data.
-'''
+"""Manage the libbsd build configuration data.
+"""
# Copyright (c) 2015, 2020 Chris Johns <chrisj@rtems.org>. All rights reserved.
#
@@ -35,15 +35,12 @@
from __future__ import print_function
-import shutil
+import codecs
+import copy
+import difflib
import os
import re
import sys
-import getopt
-import filecmp
-import difflib
-import codecs
-import copy
#
# Global controls.
@@ -67,21 +64,6 @@ verboseMoreDetail = 3
verboseDebug = 4
-def _cflagsIncludes(cflags, includes):
- if type(cflags) is not list:
- if cflags is not None:
- _cflags = cflags.split(' ')
- else:
- _cflags = [None]
- else:
- _cflags = cflags
- if type(includes) is not list:
- _includes = [includes]
- else:
- _includes = includes
- return _cflags, _includes
-
-
def verbose(level=verboseInfo):
return verboseLevel >= level
@@ -530,7 +512,7 @@ class TargetSourceCPUDependentPathComposer(CPUDependentFreeBSDPathComposer):
return path
-class BuildSystemFragmentComposer(object):
+class BuildSystemComposer(object):
def __init__(self, includes=None):
if type(includes) is not list:
self.includes = [includes]
@@ -540,7 +522,7 @@ class BuildSystemFragmentComposer(object):
def __str__(self):
return ''
- def get_includes(self):
+ def getIncludes(self):
if None in self.includes:
incs = []
else:
@@ -548,52 +530,70 @@ class BuildSystemFragmentComposer(object):
return incs
def compose(self, path):
- return ''
+ """A None result means there is nothing to build."""
+ return None
+
+ @staticmethod
+ def filesAsDefines(files):
+ define_keys = ''
+ for f in files:
+ f = f.upper()
+ for c in '\/-.':
+ f = f.replace(c, '_')
+ define_keys += ' ' + f
+ return define_keys.strip()
+
+ @staticmethod
+ def cflagsIncludes(cflags, includes):
+ if type(cflags) is not list:
+ if cflags is not None:
+ _cflags = cflags.split(' ')
+ else:
+ _cflags = [None]
+ else:
+ _cflags = cflags
+ if type(includes) is not list:
+ _includes = [includes]
+ else:
+ _includes = includes
+ return _cflags, _includes
-class SourceFileFragmentComposer(BuildSystemFragmentComposer):
+class SourceFileBuildComposer(BuildSystemComposer):
def __init__(self, cflags="default", includes=None):
- self.cflags, self.includes = _cflagsIncludes(cflags, includes)
-
- def _get_flags(self):
- return self.cflags + self.get_includes()
+ self.cflags, self.includes = self.cflagsIncludes(cflags, includes)
def __str__(self):
- return 'SF: ' + ' '.join(self._get_flags())
+ return 'SF: ' + ' '.join(self.getFlags())
def compose(self, path):
- flags = self._get_flags()
- return ['sources', flags,
- ('default', None)], [path], self.cflags, self.includes
+ flags = self.getFlags()
+ return ['sources', flags, ('default', None)], \
+ [path], self.cflags, self.includes
+ def getFlags(self):
+ return self.cflags + self.getIncludes()
-class SourceFileIfHeaderComposer(SourceFileFragmentComposer):
+
+class SourceFileIfHeaderComposer(SourceFileBuildComposer):
def __init__(self, headers, cflags="default", includes=None):
if headers is not list:
headers = [headers]
self.headers = headers
super(SourceFileIfHeaderComposer, self).__init__(cflags=cflags,
includes=includes)
+
def __str__(self):
- incs = self.headers + self.get_includes
- if len(incs) > 0:
- return 'SFIH:' + ' '.join(incs)
- else:
- return ''
+ return 'SFIH:' + ' '.join(self.getFlags()) + \
+ ' ' + self.filesAsDefines(self.headers)
def compose(self, path):
- r = SourceFileFragmentComposer.compose(self, path)
- define_keys = ''
- for h in self.headers:
- h = h.upper()
- for c in '\/-.':
- h = h.replace(c, '_')
- define_keys += ' ' + h
- r[0][2] = (define_keys.strip(), self.headers)
+ r = SourceFileBuildComposer.compose(self, path)
+ r[0][2] = (self.filesAsDefines(self.headers), self.headers)
return r
-class TestFragementComposer(BuildSystemFragmentComposer):
+class TestFragementComposer(BuildSystemComposer):
def __init__(self,
testName,
fileFragments,
@@ -641,13 +641,7 @@ class TestIfHeaderComposer(TestFragementComposer):
def compose(self, path):
r = TestFragementComposer.compose(self, path)
- define_keys = ''
- for h in self.headers:
- h = h.upper()
- for c in '\/-.':
- h = h.replace(c, '_')
- define_keys += ' ' + h
- r[0][2] = (define_keys.strip(), self.headers)
+ r[0][2] = (self.filesAsDefines(self.headers), self.headers)
return r
@@ -671,37 +665,33 @@ class TestIfLibraryComposer(TestFragementComposer):
def compose(self, path):
r = TestFragementComposer.compose(self, path)
- define_keys = ''
- for l in self.libraries:
- l = l.upper()
- for c in '\/-.':
- l = l.replace(c, '_')
- define_keys += ' ' + l
- r[0][2] = (define_keys.strip(), self.libraries)
+ r[0][2] = (self.filesAsDefines(self.libraries), self.libraries)
return r
-class KVMSymbolsFragmentComposer(BuildSystemFragmentComposer):
+class KVMSymbolsBuildComposer(BuildSystemComposer):
def compose(self, path):
- return ['KVMSymbols', 'files',
- ('default', None)], [path], self.includes
+ return ['KVMSymbols', 'files', ('default', None)], \
+ [path], self.includes
-class RPCGENFragmentComposer(BuildSystemFragmentComposer):
+class RPCGENBuildComposer(BuildSystemComposer):
def compose(self, path):
- return ['RPCGen', 'files', ('default', None)], [path]
+ return ['RPCGen', 'files', ('default', None)], \
+ [path]
-class RouteKeywordsFragmentComposer(BuildSystemFragmentComposer):
+class RouteKeywordsBuildComposer(BuildSystemComposer):
def compose(self, path):
- return ['RouteKeywords', 'files', ('default', None)], [path]
+ return ['RouteKeywords', 'files', ('default', None)], \
+ [path]
-class LexFragmentComposer(BuildSystemFragmentComposer):
+class LexBuildComposer(BuildSystemComposer):
def __init__(self, sym, dep, cflags=None, includes=None, build=True):
self.sym = sym
self.dep = dep
- self.cflags, self.includes = _cflagsIncludes(cflags, includes)
+ self.cflags, self.includes = self.cflagsIncludes(cflags, includes)
self.build = build
def compose(self, path):
@@ -718,11 +708,11 @@ class LexFragmentComposer(BuildSystemFragmentComposer):
return ['lex', path, ('default', None)], d
-class YaccFragmentComposer(BuildSystemFragmentComposer):
+class YaccBuildComposer(BuildSystemComposer):
def __init__(self, sym, header, cflags=None, includes=None, build=True):
self.sym = sym
self.header = header
- self.cflags, self.includes = _cflagsIncludes(cflags, includes)
+ self.cflags, self.includes = self.cflagsIncludes(cflags, includes)
self.build = build
def compose(self, path):
@@ -741,14 +731,14 @@ class YaccFragmentComposer(BuildSystemFragmentComposer):
class File(object):
'''A file of source we move backwards and forwards and build.'''
-
- def __init__(self, path, pathComposer, forwardConverter, reverseConverter,
- buildSystemComposer):
+ def __init__(self, space, path, pathComposer, forwardConverter,
+ reverseConverter, buildSystemComposer):
if verbose(verboseMoreDetail):
- print("FILE: %-50s F:%-45s R:%-45s" % \
- (path,
+ print("FILE: %-6s %-50s F:%-45s R:%-45s" % \
+ (space, path,
forwardConverter.__class__.__name__,
reverseConverter.__class__.__name__))
+ self.space = space
self.path = path
self.pathComposer = pathComposer
self.originPath = self.pathComposer.composeOriginPath(self.path)
@@ -759,12 +749,22 @@ class File(object):
self.buildSystemComposer = buildSystemComposer
def __str__(self):
- out = self.path
+ out = self.space[0].upper() + ' ' + self.path
bsc = str(self.buildSystemComposer)
if len(bsc) > 0:
out += ' (' + bsc + ')'
return out
+ def __eq__(self, other):
+ state = self.space == other.space
+ state = state and (self.path == self.path)
+ state = state and (self.pathComposer == self.pathComposer)
+ state = state and (self.originPath == self.originPath)
+ state = state and (self.forwardConverter == self.forwardConverter)
+ state = state and (self.self.reverseConverter == self.self.reverseConverter)
+ state = state and (self.buildSystemComposer == self.buildSystemComposer)
+ return state
+
def processSource(self, forward):
if forward:
if verbose(verboseDetail):
@@ -774,17 +774,23 @@ class File(object):
else:
if verbose(verboseDetail):
print("process source: %s => %s converter:%s" % \
- (self.libbsdPath, self.originPath, self.reverseConverter.__class__.__name__))
+ (self.libbsdPath, self.originPath,
+ self.reverseConverter.__class__.__name__))
self.reverseConverter.convert(self.libbsdPath, self.originPath)
def getFragment(self):
return self.buildSystemComposer.compose(
self.pathComposer.composeLibBSDPath(self.path, ''))
+ def getPath(self):
+ return self.path
+
+ def getSpace(self):
+ return self.space
+
class Module(object):
'''Logical group of related files we can perform actions on'''
-
def __init__(self, manager, name, enabled=True):
self.manager = manager
self.name = name
@@ -794,23 +800,42 @@ class Module(object):
self.dependencies = []
def __str__(self):
- out = [self.name + ': ' + self.conditionalOn]
+ out = [self.name + ': conditional-on=' + self.conditionalOn]
if len(self.dependencies) > 0:
out += [' Deps: ' + str(len(self.dependencies))]
out += [' ' + type(d).__name__ for d in self.dependencies]
if len(self.files) > 0:
- out += [' Files: ' + str(len(self.files))]
+ counts = {}
+ for f in self.files:
+ space = f.getSpace()
+ if space not in counts:
+ counts[space] = 0
+ counts[space] += 1
+ count_str = ''
+ for space in sorted(counts.keys()):
+ count_str += '%s:%d ' % (space[0].upper(), counts[space])
+ count_str = count_str[:-1]
+ out += [' Files: %d (%s)' % (len(self.files), count_str)]
out += [' ' + str(f) for f in self.files]
if len(self.cpuDependentSourceFiles) > 0:
out += [' CPU Dep: ' + str(len(self.cpuDependentSourceFiles))]
for cpu in self.cpuDependentSourceFiles:
- out += [' ' + cpu + ':' + str(f) for f in self.cpuDependentSourceFiles[cpu]]
+ out += [' ' + cpu + ':']
+ out += [
+ ' ' + str(f) for f in self.cpuDependentSourceFiles[cpu]
+ ]
return os.linesep.join(out)
def initCPUDependencies(self, cpu):
if cpu not in self.cpuDependentSourceFiles:
self.cpuDependentSourceFiles[cpu] = []
+ def getName(self):
+ return self.name
+
+ def getFiles(self):
+ return (f for f in self.files)
+
def processSource(self, direction):
if verbose(verboseDetail):
print("process module: %s" % (self.name))
@@ -821,57 +846,64 @@ class Module(object):
f.processSource(direction)
def addFile(self, f):
+ if not isinstance(f, File):
+ raise TypeError('invalid type for addFiles: %s' % (type(f)))
self.files += [f]
def addFiles(self,
+ space,
newFiles,
pathComposer,
forwardConverter,
reverseConverter,
assertFile,
- buildSystemComposer=BuildSystemFragmentComposer()):
+ buildSystemComposer=BuildSystemComposer()):
files = []
for newFile in newFiles:
assertFile(newFile)
files += [
- File(newFile, pathComposer, forwardConverter, reverseConverter,
- buildSystemComposer)
+ File(space, newFile, pathComposer, forwardConverter,
+ reverseConverter, buildSystemComposer)
]
return files
def addPlainTextFile(self, files):
- self.files += self.addFiles(files,
+ self.files += self.addFiles('user', files,
FreeBSDPathComposer(), Converter(),
Converter(), assertNothing)
def addKernelSpaceHeaderFiles(self, files):
- self.files += self.addFiles(files, FreeBSDPathComposer(),
+ self.files += self.addFiles('kernel', files, FreeBSDPathComposer(),
FromFreeBSDToRTEMSHeaderConverter(),
FromRTEMSToFreeBSDHeaderConverter(),
assertHeaderOrSourceFile)
def addUserSpaceHeaderFiles(self, files):
self.files += self.addFiles(
- files, FreeBSDPathComposer(),
+ 'user', files, FreeBSDPathComposer(),
FromFreeBSDToRTEMSUserSpaceHeaderConverter(),
FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
def addRTEMSHeaderFiles(self, files):
- self.files += self.addFiles(files, RTEMSPathComposer(), NoConverter(),
- NoConverter(), assertHeaderFile)
+ self.files += self.addFiles('user', files, RTEMSPathComposer(),
+ NoConverter(), NoConverter(),
+ assertHeaderFile)
def addLinuxHeaderFiles(self, files):
- self.files += self.addFiles(files, PathComposer(), NoConverter(),
- NoConverter(), assertHeaderFile)
+ self.files += self.addFiles('kernel', files, PathComposer(),
+ NoConverter(), NoConverter(),
+ assertHeaderFile)
def addCPUDependentFreeBSDHeaderFiles(self, files):
- self.files += self.addFiles(files, CPUDependentFreeBSDPathComposer(),
+ self.files += self.addFiles('kernel', files,
+ CPUDependentFreeBSDPathComposer(),
FromFreeBSDToRTEMSHeaderConverter(),
FromRTEMSToFreeBSDHeaderConverter(),
assertHeaderFile)
def addCPUDependentLinuxHeaderFiles(self, files):
- self.files += self.addFiles(files, CPUDependentLinuxPathComposer(),
+ self.files += self.addFiles('kernel', files,
+ CPUDependentLinuxPathComposer(),
NoConverter(), NoConverter(),
assertHeaderFile)
@@ -879,73 +911,80 @@ class Module(object):
files):
for cpu in targetCPUs:
self.files += self.addFiles(
- files, TargetSourceCPUDependentPathComposer(cpu, sourceCPU),
+ 'kernel', files,
+ TargetSourceCPUDependentPathComposer(cpu, sourceCPU),
FromFreeBSDToRTEMSHeaderConverter(), NoConverter(),
assertHeaderFile)
- def addSourceFiles(self, files, sourceFileFragmentComposer):
- self.files += self.addFiles(files, PathComposer(), NoConverter(),
+ def addSourceFiles(self, files, sourceFileBuildComposer):
+ self.files += self.addFiles('user',
+ files, PathComposer(), NoConverter(),
NoConverter(), assertSourceFile,
- sourceFileFragmentComposer)
+ sourceFileBuildComposer)
- def addKernelSpaceSourceFiles(self, files, sourceFileFragmentComposer):
- self.files += self.addFiles(files, FreeBSDPathComposer(),
+ def addKernelSpaceSourceFiles(self, files, sourceFileBuildComposer):
+ self.files += self.addFiles('kernel', files, FreeBSDPathComposer(),
FromFreeBSDToRTEMSSourceConverter(),
FromRTEMSToFreeBSDSourceConverter(),
- assertSourceFile,
- sourceFileFragmentComposer)
+ assertSourceFile, sourceFileBuildComposer)
- def addUserSpaceSourceFiles(self, files, sourceFileFragmentComposer):
+ def addUserSpaceSourceFiles(self, files, sourceFileBuildComposer):
self.files += self.addFiles(
- files, FreeBSDPathComposer(),
+ 'user', files, FreeBSDPathComposer(),
FromFreeBSDToRTEMSUserSpaceSourceConverter(),
FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
- sourceFileFragmentComposer)
+ sourceFileBuildComposer)
- def addRTEMSSourceFiles(self, files, sourceFileFragmentComposer):
- self.files += self.addFiles(files, RTEMSPathComposer(), NoConverter(),
- NoConverter(), assertSourceFile,
- sourceFileFragmentComposer)
+ def addRTEMSKernelSourceFiles(self, files, sourceFileBuildComposer):
+ self.files += self.addFiles('kernel', files, RTEMSPathComposer(),
+ NoConverter(), NoConverter(),
+ assertSourceFile, sourceFileBuildComposer)
- def addLinuxSourceFiles(self, files, sourceFileFragmentComposer):
- self.files += self.addFiles(files, PathComposer(), NoConverter(),
- NoConverter(), assertSourceFile,
- sourceFileFragmentComposer)
+ def addRTEMSUserSourceFiles(self, files, sourceFileBuildComposer):
+ self.files += self.addFiles('user', files, RTEMSPathComposer(),
+ NoConverter(), NoConverter(),
+ assertSourceFile, sourceFileBuildComposer)
+
+ def addLinuxSourceFiles(self, files, sourceFileBuildComposer):
+ self.files += self.addFiles('kernel', files, PathComposer(),
+ NoConverter(), NoConverter(),
+ assertSourceFile, sourceFileBuildComposer)
def addCPUDependentFreeBSDSourceFiles(self, cpus, files,
- sourceFileFragmentComposer):
+ sourceFileBuildComposer):
for cpu in cpus:
self.initCPUDependencies(cpu)
self.cpuDependentSourceFiles[cpu] += \
- self.addFiles(files,
- CPUDependentFreeBSDPathComposer(), FromFreeBSDToRTEMSSourceConverter(),
- FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
- sourceFileFragmentComposer)
+ self.addFiles(
+ 'kernel', files,
+ CPUDependentFreeBSDPathComposer(), FromFreeBSDToRTEMSSourceConverter(),
+ FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
+ sourceFileBuildComposer)
def addCPUDependentRTEMSSourceFiles(self, cpus, files,
- sourceFileFragmentComposer):
+ sourceFileBuildComposer):
for cpu in cpus:
self.initCPUDependencies(cpu)
self.cpuDependentSourceFiles[cpu] += \
- self.addFiles(files,
+ self.addFiles('kernel', files,
CPUDependentRTEMSPathComposer(), NoConverter(),
NoConverter(), assertSourceFile,
- sourceFileFragmentComposer)
+ sourceFileBuildComposer)
def addCPUDependentLinuxSourceFiles(self, cpus, files,
- sourceFileFragmentComposer):
+ sourceFileBuildComposer):
for cpu in cpus:
self.initCPUDependencies(cpu)
self.cpuDependentSourceFiles[cpu] += \
- self.addFiles(files,
+ self.addFiles('kernel', files,
CPUDependentLinuxPathComposer(), NoConverter(),
NoConverter(), assertSourceFile,
- sourceFileFragmentComposer)
+ sourceFileBuildComposer)
def addTest(self, testFragementComposer):
self.files += [
- File(testFragementComposer.testName, PathComposer(), NoConverter(),
- NoConverter(), testFragementComposer)
+ File('user', testFragementComposer.testName, PathComposer(),
+ NoConverter(), NoConverter(), testFragementComposer)
]
def addDependency(self, dep):
@@ -954,7 +993,6 @@ class Module(object):
class ModuleManager(object):
'''A manager for a collection of modules.'''
-
def __init__(self):
self.modules = {}
self.generator = {}
@@ -995,7 +1033,7 @@ class ModuleManager(object):
self.configuration = copy.deepcopy(config)
def getConfiguration(self):
- return self.configuration
+ return copy.deepcopy(self.configuration)
def updateConfiguration(self, config):
self.configuration.update(config)
@@ -1012,17 +1050,33 @@ class ModuleManager(object):
if only_enabled == False:
modules_to_process = self.getAllModules()
for m in modules_to_process:
+ if m not in self.modules:
+ raise KeyError('enabled module not registered: %s' % (m))
self.modules[m].generate()
+ def duplicateCheck(self):
+ dups = []
+ modules_to_check = sorted(self.getAllModules(), reverse=True)
+ while len(modules_to_check) > 1:
+ mod = modules_to_check.pop()
+ for m in modules_to_check:
+ if m not in self.modules:
+ raise KeyError('enabled module not registered: %s' % (m))
+ for fmod in self.modules[mod].getFiles():
+ for fm in self.modules[m].getFiles():
+ if fmod.getPath() == fm.getPath():
+ dups += [(m, mod, fm.getPath(), fm.getSpace())]
+ return dups
+
def setGenerators(self):
self.generator['convert'] = Converter
self.generator['no-convert'] = NoConverter
self.generator[
- 'from-FreeBSD-to-RTEMS-UserSpaceSourceConverter'] = FromFreeBSDToRTEMSUserSpaceSourceConverter
+ 'from-FreeBSD-to-RTEMS-UserSpaceSourceConverter'] = \
+ FromFreeBSDToRTEMSUserSpaceSourceConverter
self.generator[
'from-RTEMS-To-FreeBSD-SourceConverter'] = FromRTEMSToFreeBSDSourceConverter
- self.generator[
- 'buildSystemFragmentComposer'] = BuildSystemFragmentComposer
+ self.generator['buildSystemComposer'] = BuildSystemComposer
self.generator['file'] = File
@@ -1033,13 +1087,13 @@ class ModuleManager(object):
self.generator[
'target-src-cpu--path'] = TargetSourceCPUDependentPathComposer
- self.generator['source'] = SourceFileFragmentComposer
+ self.generator['source'] = SourceFileBuildComposer
self.generator['test'] = TestFragementComposer
- self.generator['kvm-symbols'] = KVMSymbolsFragmentComposer
- self.generator['rpc-gen'] = RPCGENFragmentComposer
- self.generator['route-keywords'] = RouteKeywordsFragmentComposer
- self.generator['lex'] = LexFragmentComposer
- self.generator['yacc'] = YaccFragmentComposer
+ self.generator['kvm-symbols'] = KVMSymbolsBuildComposer
+ self.generator['rpc-gen'] = RPCGENBuildComposer
+ self.generator['route-keywords'] = RouteKeywordsBuildComposer
+ self.generator['lex'] = LexBuildComposer
+ self.generator['yacc'] = YaccBuildComposer
self.generator['source-if-header'] = SourceFileIfHeaderComposer
self.generator['test-if-header'] = TestIfHeaderComposer