[PATCH 6-freebsd-12 3/4] build: Separate the kernel and user land include paths

chrisj at rtems.org chrisj at rtems.org
Tue Sep 15 02:33:08 UTC 2020


From: Chris Johns <chrisj at rtems.org>

- 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
  appeanding 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
---
 builder.py           | 339 +++++++++++++++------------
 buildset/default.ini |   2 +
 freebsd-to-rtems.py  |  12 +
 libbsd.py            | 530 ++++++++++++++++++++++++-------------------
 waf_libbsd.py        | 165 ++++++++------
 wscript              |   4 +-
 6 files changed, 614 insertions(+), 438 deletions(-)

diff --git a/builder.py b/builder.py
index 9dfe373f..46e19b6a 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 at 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
 
@@ -527,7 +509,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]
@@ -537,7 +519,7 @@ class BuildSystemFragmentComposer(object):
     def __str__(self):
         return ''
 
-    def get_includes(self):
+    def getIncludes(self):
         if None in self.includes:
             incs = []
         else:
@@ -545,52 +527,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,
@@ -638,13 +638,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
 
 
@@ -668,37 +662,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):
@@ -715,11 +705,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):
@@ -738,14 +728,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)
@@ -756,12 +746,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):
@@ -771,17 +771,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
@@ -791,23 +797,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))
@@ -818,52 +843,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('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)
 
@@ -871,73 +908,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):
@@ -946,7 +990,6 @@ class Module(object):
 
 class ModuleManager(object):
     '''A manager for a collection of modules.'''
-
     def __init__(self):
         self.modules = {}
         self.generator = {}
@@ -987,7 +1030,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)
@@ -1004,17 +1047,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
 
@@ -1025,13 +1084,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
diff --git a/buildset/default.ini b/buildset/default.ini
index b17f2b59..9c0d1bf8 100644
--- a/buildset/default.ini
+++ b/buildset/default.ini
@@ -50,11 +50,13 @@ net80211 = off
 netinet = on
 netinet6 = on
 netipsec = off
+nfsv2 = on
 nvme = on
 opencrypto = on
 pci = on
 pf = on
 regulator = on
+rpc_user = on
 rtems = on
 tests = on
 tty = on
diff --git a/freebsd-to-rtems.py b/freebsd-to-rtems.py
index 5710b902..8f66e589 100755
--- a/freebsd-to-rtems.py
+++ b/freebsd-to-rtems.py
@@ -152,6 +152,18 @@ try:
     libbsd.load(build)
     build.generateBuild(only_enabled=False)
 
+    dups = build.duplicateCheck()
+    if len(dups) > 0:
+        print()
+        print('Duplicates: %d' % (len(dups)))
+        mods = list(set([dup[0] for dup in dups]))
+        max_mod_len = max(len(dup[1]) for dup in dups)
+        for mod in mods:
+            print(' %s:' % (mod))
+            for dup in [dup for dup in dups if dup[0] == mod]:
+                print('  %-*s %s %s' % (max_mod_len, dup[1], dup[3][0].upper(), dup[2]))
+        print()
+
     if isConfig:
         print()
         print(build)
diff --git a/libbsd.py b/libbsd.py
index c251fba4..5b7e8a88 100644
--- a/libbsd.py
+++ b/libbsd.py
@@ -1,5 +1,5 @@
 #
-#  Copyright (c) 2015-2016, 2018 Chris Johns <chrisj at rtems.org>.
+#  Copyright (c) 2015, 2020 Chris Johns <chrisj at rtems.org>.
 #  All rights reserved.
 #
 #  Copyright (c) 2009, 2018 embedded brains GmbH.  All rights reserved.
@@ -56,51 +56,56 @@ _defaults = {
     #
     # Includes
     #
-    'include-paths': ['rtemsbsd/include',
-                      'freebsd/sys',
-                      'freebsd/sys/contrib/ck/include',
-                      'freebsd/sys/contrib/libsodium/src/libsodium/include',
-                      'freebsd/sys/contrib/libsodium/src/libsodium/include/sodium',
-                      'freebsd/sys/contrib/pf',
-                      'freebsd/crypto',
-                      'freebsd/crypto/openssl/include',
-                      'freebsd/sys/net',
-                      'freebsd/include',
-                      'freebsd/lib',
-                      'freebsd/lib/libbsdstat',
-                      'freebsd/lib/libcapsicum',
-                      'freebsd/lib/libcasper',
-                      'freebsd/lib/libc/include',
-                      'freebsd/lib/libc/isc/include',
-                      'freebsd/lib/libc/resolv',
-                      'freebsd/lib/libutil',
-                      'freebsd/lib/libkvm',
-                      'freebsd/lib/libmemstat',
-                      'freebsd/contrib/expat/lib',
-                      'freebsd/contrib/libpcap',
-                      'freebsd/contrib/libxo',
-                      'ipsec-tools/src/libipsec',
-                      'linux/include',
-                      'linux/drivers/net/ethernet/freescale/fman',
-                      'rtemsbsd/sys',
-                      'mDNSResponder/mDNSCore',
-                      'mDNSResponder/mDNSShared',
-                      'mDNSResponder/mDNSPosix',
-                      'testsuite/include'],
-    'cpu-include-paths': ['rtemsbsd/@CPU@/include',
-                          'freebsd/sys/@CPU@/include'],
+    'include-paths': {
+        # The path where headers will be copied during the build.
+        'build': ['build-include'],
+        # Kernel header paths
+        'kernel': ['rtemsbsd/include',
+                   'freebsd/sys',
+                   'freebsd/sys/contrib/ck/include',
+                   'freebsd/sys/contrib/libsodium/src/libsodium/include',
+                   'freebsd/sys/contrib/libsodium/src/libsodium/include/sodium',
+                   'freebsd/sys/contrib/pf',
+                   'freebsd/sys/net',
+                   'ipsec-tools/src/libipsec',
+                   'linux/include',
+                   'linux/drivers/net/ethernet/freescale/fman',
+                   'rtemsbsd/sys'],
+        # User header paths
+        'user': ['freebsd/crypto',
+                 'freebsd/crypto/openssl/include',
+                 'freebsd/include',
+                 'freebsd/lib',
+                 'freebsd/lib/libbsdstat',
+                 'freebsd/lib/libcapsicum',
+                 'freebsd/lib/libcasper',
+                 'freebsd/lib/libc/include',
+                 'freebsd/lib/libc/isc/include',
+                 'freebsd/lib/libc/resolv',
+                 'freebsd/lib/libutil',
+                 'freebsd/lib/libkvm',
+                 'freebsd/lib/libmemstat',
+                 'freebsd/contrib/expat/lib',
+                 'freebsd/contrib/libpcap',
+                 'freebsd/contrib/libxo',
+                 'mDNSResponder/mDNSCore',
+                 'mDNSResponder/mDNSShared',
+                 'mDNSResponder/mDNSPosix',
+                 'testsuite/include'],
+        # CPU specific path, assumed to be in the kernel context
+        'cpu': ['rtemsbsd/@CPU@/include',
+                'freebsd/sys/@CPU@/include'],
+    },
 
     #
     # Map paths based on RTEMS naming to FreeBSD naming.
     #
-    'path-mappings': [     # (source, targets)
-    # i386
-    ('freebsd/sys/i386/include', ['freebsd/sys/x86/include', 'freebsd/sys/i386/include']),
+    'path-mappings': [
+        # (source, [targets..])
+        # i386
+        ('freebsd/sys/i386/include', ['freebsd/sys/x86/include', 'freebsd/sys/i386/include']),
     ],
 
-    # The path where headers will be copied during build.
-    'build-include-path': ['build-include'],
-
     #
     # Install headers
     #
@@ -152,7 +157,7 @@ class rtems(builder.Module):
 
     def generate(self):
         mm = self.manager
-        self.addRTEMSSourceFiles(
+        self.addRTEMSKernelSourceFiles(
             [
                 'local/bus_if.c',
                 'local/cryptodev_if.c',
@@ -168,35 +173,11 @@ class rtems(builder.Module):
                 'local/mmcbr_if.c',
                 'local/if_dwc_if.c',
                 'local/gpio_if.c',
-                'rtems/ipsec_get_policylen.c',
-                'rtems/rtems-bsd-arp-processor.c',
                 'rtems/rtems-bsd-allocator-domain-size.c',
-                'rtems/rtems-bsd-cxx.cc',
                 'rtems/rtems-bsd-get-allocator-domain-size.c',
-                'rtems/rtems-bsd-get-ethernet-addr.c',
                 'rtems/rtems-bsd-get-mac-address.c',
                 'rtems/rtems-bsd-get-task-priority.c',
                 'rtems/rtems-bsd-get-task-stack-size.c',
-                'rtems/rtems-bsd-ifconfig.c',
-                'rtems/rtems-bsd-ifconfig-lo0.c',
-                'rtems/rtems-bsd-init-dhcp.c',
-                'rtems/rtems-bsd-rc-conf-net.c',
-                'rtems/rtems-bsd-rc-conf-pf.c',
-                'rtems/rtems-bsd-rc-conf.c',
-                'rtems/rtems-bsd-set-if-input.c',
-                'rtems/rtems-bsd-shell-arp.c',
-                'rtems/rtems-bsd-shell-ifconfig.c',
-                'rtems/rtems-bsd-shell-ifmcstat.c',
-                'rtems/rtems-bsd-shell-netstat.c',
-                'rtems/rtems-bsd-shell-nvmecontrol.c',
-                'rtems/rtems-bsd-shell-pfctl.c',
-                'rtems/rtems-bsd-shell-ping.c',
-                'rtems/rtems-bsd-shell-route.c',
-                'rtems/rtems-bsd-shell-stty.c',
-                'rtems/rtems-bsd-shell-sysctl.c',
-                'rtems/rtems-bsd-shell-tcpdump.c',
-                'rtems/rtems-bsd-shell-vmstat.c',
-                'rtems/rtems-bsd-shell-wlanstats.c',
                 'rtems/rtems-bsd-syscall-api.c',
                 'rtems/rtems-kernel-assert.c',
                 'rtems/rtems-kernel-autoconf.c',
@@ -235,16 +216,59 @@ class rtems(builder.Module):
                 'rtems/rtems-legacy-rtrequest.c',
                 'rtems/rtems-legacy-newproc.c',
                 'rtems/rtems-legacy-mii.c',
+                'sys/arm/lpc/if_lpe.c',
+                'sys/arm/lpc/lpc_pwr.c',
+                'sys/dev/atsam/if_atsam.c',
+                'sys/dev/atsam/if_atsam_media.c',
+                'sys/dev/dw_mmc/dw_mmc.c',
+                'sys/dev/ffec/if_ffec_mcf548x.c',
+                'sys/dev/ffec/if_ffec_mpc8xx.c',
+                'sys/dev/input/touchscreen/tsc_lpc32xx.c',
+                'sys/dev/smc/if_smc_nexus.c',
+                'sys/dev/tsec/if_tsec_nexus.c',
+                'sys/dev/usb/controller/ehci_mpc83xx.c',
+                'sys/dev/usb/controller/ohci_lpc32xx.c',
+                'sys/dev/usb/controller/ohci_lpc.c',
+                'sys/dev/usb/controller/usb_otg_transceiver.c',
+                'sys/dev/usb/controller/usb_otg_transceiver_dump.c',
+                'sys/fs/devfs/devfs_devs.c',
+                'sys/net/if_ppp.c',
+                'sys/net/ppp_tty.c',
+            ],
+            mm.generator['source']()
+        )
+        self.addRTEMSUserSourceFiles(
+            [
+                'rtems/ipsec_get_policylen.c',
+                'rtems/rtems-bsd-arp-processor.c',
+                'rtems/rtems-bsd-cxx.cc',
+                'rtems/rtems-bsd-get-ethernet-addr.c',
+                'rtems/rtems-bsd-ifconfig.c',
+                'rtems/rtems-bsd-ifconfig-lo0.c',
+                'rtems/rtems-bsd-init-dhcp.c',
+                'rtems/rtems-bsd-rc-conf-net.c',
+                'rtems/rtems-bsd-rc-conf-pf.c',
+                'rtems/rtems-bsd-rc-conf.c',
+                'rtems/rtems-bsd-set-if-input.c',
+                'rtems/rtems-bsd-shell-arp.c',
+                'rtems/rtems-bsd-shell-ifconfig.c',
+                'rtems/rtems-bsd-shell-ifmcstat.c',
+                'rtems/rtems-bsd-shell-netstat.c',
+                'rtems/rtems-bsd-shell-nvmecontrol.c',
+                'rtems/rtems-bsd-shell-pfctl.c',
+                'rtems/rtems-bsd-shell-ping.c',
+                'rtems/rtems-bsd-shell-route.c',
+                'rtems/rtems-bsd-shell-stty.c',
+                'rtems/rtems-bsd-shell-sysctl.c',
+                'rtems/rtems-bsd-shell-tcpdump.c',
+                'rtems/rtems-bsd-shell-vmstat.c',
+                'rtems/rtems-bsd-shell-wlanstats.c',
                 'rtems/rtems-kvm.c',
                 'rtems/rtems-program.c',
                 'rtems/rtems-program-socket.c',
                 'rtems/rtems-routes.c',
                 'rtems/syslog.c',
                 'ftpd/ftpd-service.c',
-                'nfsclient/mount_prot_xdr.c',
-                'nfsclient/nfs.c',
-                'nfsclient/nfs_prot_xdr.c',
-                'nfsclient/rpcio.c',
                 'pppd/auth.c',
                 'pppd/ccp.c',
                 'pppd/chap.c',
@@ -261,39 +285,24 @@ class rtems(builder.Module):
                 'pppd/sys-rtems.c',
                 'pppd/upap.c',
                 'pppd/utils.c',
-                'sys/arm/lpc/if_lpe.c',
-                'sys/arm/lpc/lpc_pwr.c',
-                'sys/dev/atsam/if_atsam.c',
-                'sys/dev/atsam/if_atsam_media.c',
-                'sys/dev/dw_mmc/dw_mmc.c',
-                'sys/dev/ffec/if_ffec_mcf548x.c',
-                'sys/dev/ffec/if_ffec_mpc8xx.c',
-                'sys/dev/input/touchscreen/tsc_lpc32xx.c',
-                'sys/dev/smc/if_smc_nexus.c',
-                'sys/dev/tsec/if_tsec_nexus.c',
-                'sys/dev/usb/controller/ehci_mpc83xx.c',
-                'sys/dev/usb/controller/ohci_lpc32xx.c',
-                'sys/dev/usb/controller/ohci_lpc.c',
-                'sys/dev/usb/controller/usb_otg_transceiver.c',
-                'sys/dev/usb/controller/usb_otg_transceiver_dump.c',
-                'sys/fs/devfs/devfs_devs.c',
-                'sys/net/if_ppp.c',
-                'sys/net/ppp_tty.c',
                 'telnetd/telnetd-service.c',
             ],
             mm.generator['source']()
         )
-        self.addFile(mm.generator['file']('rtems/rtems-kernel-kvm-symbols.c',
+        self.addFile(mm.generator['file']('kernel',
+                                          'rtems/rtems-kernel-kvm-symbols.c',
                                           mm.generator['rtems-path'](),
                                           mm.generator['no-convert'](),
                                           mm.generator['no-convert'](),
                                           mm.generator['kvm-symbols'](includes = 'rtemsbsd/rtems')))
-        self.addFile(mm.generator['file']('lib/libc/net/nslexer.l',
+        self.addFile(mm.generator['file']('user',
+                                          'lib/libc/net/nslexer.l',
                                           mm.generator['freebsd-path'](),
                                           mm.generator['convert'](),
                                           mm.generator['convert'](),
                                           mm.generator['lex']('_nsyy', 'nsparser.c')))
-        self.addFile(mm.generator['file']('lib/libc/net/nsparser.y',
+        self.addFile(mm.generator['file']('user',
+                                          'lib/libc/net/nsparser.y',
                                           mm.generator['freebsd-path'](),
                                           mm.generator['convert'](),
                                           mm.generator['convert'](),
@@ -344,8 +353,6 @@ class base(builder.Module):
                 'sys/contrib/ck/include/gcc/x86/ck_f_pr.h',
                 'sys/contrib/ck/include/gcc/x86/ck_pr.h',
                 'sys/fs/devfs/devfs_int.h',
-                'sys/rpc/netconfig.h',
-                'sys/rpc/types.h',
                 'sys/security/audit/audit.h',
                 'sys/security/mac/mac_framework.h',
                 'sys/sys/acl.h',
@@ -569,7 +576,7 @@ class fdt(builder.Module):
             ],
             mm.generator['source']()
         )
-        self.addRTEMSSourceFiles(
+        self.addRTEMSKernelSourceFiles(
             [
                 'rtems/ofw_machdep.c',
             ],
@@ -606,7 +613,7 @@ class tty(builder.Module):
             ],
             mm.generator['source']()
         )
-#        self.addRTEMSSourceFiles(
+#        self.addRTEMSKernelSourceFiles(
 #            [
 #                'rtems/ofw_machdep.c',
 #            ],
@@ -643,7 +650,7 @@ class mmc(builder.Module):
             ],
             mm.generator['source']()
         )
-        self.addRTEMSSourceFiles(
+        self.addRTEMSKernelSourceFiles(
             [
                 'sys/arm/at91/at91_mci.c',
             ],
@@ -682,7 +689,7 @@ class mmc_ti(builder.Module):
             ],
             mm.generator['source']()
         )
-        self.addRTEMSSourceFiles(
+        self.addRTEMSKernelSourceFiles(
             [
                 'local/sdhci_if.c',
                 'local/gpiobus_if.c',
@@ -1082,7 +1089,7 @@ class dev_usb_wlan(builder.Module):
                 'sys/dev/usb/wlan/if_zydreg.h',
             ]
         )
-        self.addRTEMSSourceFiles(
+        self.addRTEMSKernelSourceFiles(
             [
                 'local/runfw.c',
             ],
@@ -1194,7 +1201,7 @@ class dev_wlan_rtwn(builder.Module):
                 'sys/dev/rtwn/usb/rtwn_usb_var.h',
             ]
         )
-        self.addRTEMSSourceFiles(
+        self.addRTEMSKernelSourceFiles(
             [
                 'local/rtwn-rtl8192cfwT.c',
                 'local/rtwn-rtl8188eufw.c',
@@ -1403,7 +1410,7 @@ class dev_net(builder.Module):
             ],
             mm.generator['source']()
         )
-        self.addRTEMSSourceFiles(
+        self.addRTEMSKernelSourceFiles(
             [
                 'sys/dev/mii/ksz8091rnb_50MHz.c',
             ],
@@ -1697,7 +1704,7 @@ class nvme(builder.Module):
             ],
             mm.generator['source']()
         )
-        self.addRTEMSSourceFiles(
+        self.addRTEMSKernelSourceFiles(
             [
                 'sys/dev/nvd/nvd.c',
             ],
@@ -2105,14 +2112,16 @@ class netipsec(builder.Module):
             ],
             mm.generator['source'](libipsec_cflags)
         )
-        self.addFile(mm.generator['file']('ipsec-tools/src/libipsec/policy_token.l',
+        self.addFile(mm.generator['file']('user',
+                                          'ipsec-tools/src/libipsec/policy_token.l',
                                           mm.generator['path'](),
                                           mm.generator['convert'](),
                                           mm.generator['convert'](),
                                           mm.generator['lex']('__libipsec',
                                                               'policy_parse.c',
                                                               libipsec_cflags)))
-        self.addFile(mm.generator['file']('ipsec-tools/src/libipsec/policy_parse.y',
+        self.addFile(mm.generator['file']('user',
+                                          'ipsec-tools/src/libipsec/policy_parse.y',
                                           mm.generator['path'](),
                                           mm.generator['convert'](),
                                           mm.generator['convert'](),
@@ -2174,7 +2183,8 @@ class netipsec(builder.Module):
             mm.generator['source'](racoon_cflags,
                                    ['freebsd/crypto/openssl'])
         )
-        self.addFile(mm.generator['file']('ipsec-tools/src/racoon/cftoken.l',
+        self.addFile(mm.generator['file']('user',
+                                          'ipsec-tools/src/racoon/cftoken.l',
                                           mm.generator['path'](),
                                           mm.generator['convert'](),
                                           mm.generator['convert'](),
@@ -2182,7 +2192,8 @@ class netipsec(builder.Module):
                                                               'cftoken.c',
                                                               racoon_cflags,
                                                               build=False)))
-        self.addFile(mm.generator['file']('ipsec-tools/src/racoon/cfparse.y',
+        self.addFile(mm.generator['file']('user',
+                                          'ipsec-tools/src/racoon/cfparse.y',
                                           mm.generator['path'](),
                                           mm.generator['convert'](),
                                           mm.generator['convert'](),
@@ -2190,7 +2201,8 @@ class netipsec(builder.Module):
                                                                'cfparse.h',
                                                                racoon_cflags,
                                                                build=False)))
-        self.addFile(mm.generator['file']('ipsec-tools/src/racoon/prsa_tok.l',
+        self.addFile(mm.generator['file']('user',
+                                          'ipsec-tools/src/racoon/prsa_tok.l',
                                           mm.generator['path'](),
                                           mm.generator['convert'](),
                                           mm.generator['convert'](),
@@ -2198,7 +2210,8 @@ class netipsec(builder.Module):
                                                               'prsa_tok.c',
                                                               racoon_cflags,
                                                               build=False)))
-        self.addFile(mm.generator['file']('ipsec-tools/src/racoon/prsa_par.y',
+        self.addFile(mm.generator['file']('user',
+                                          'ipsec-tools/src/racoon/prsa_par.y',
                                           mm.generator['path'](),
                                           mm.generator['convert'](),
                                           mm.generator['convert'](),
@@ -2211,7 +2224,7 @@ class netipsec(builder.Module):
                 'rtems/ipsec.h',
             ]
         )
-        self.addRTEMSSourceFiles(
+        self.addRTEMSUserSourceFiles(
             [
                 'rtems/rtems-bsd-racoon.c',
                 'rtems/rtems-bsd-rc-conf-ipsec.c',
@@ -2231,7 +2244,8 @@ class netipsec(builder.Module):
             ],
             mm.generator['source'](setkey_cflags)
         )
-        self.addFile(mm.generator['file']('ipsec-tools/src/setkey/token.l',
+        self.addFile(mm.generator['file']('user',
+                                          'ipsec-tools/src/setkey/token.l',
                                           mm.generator['path'](),
                                           mm.generator['convert'](),
                                           mm.generator['convert'](),
@@ -2239,7 +2253,8 @@ class netipsec(builder.Module):
                                                               'token.c',
                                                               setkey_cflags,
                                                               build=False)))
-        self.addFile(mm.generator['file']('ipsec-tools/src/setkey/parse.y',
+        self.addFile(mm.generator['file']('user',
+                                          'ipsec-tools/src/setkey/parse.y',
                                           mm.generator['path'](),
                                           mm.generator['convert'](),
                                           mm.generator['convert'](),
@@ -2247,7 +2262,7 @@ class netipsec(builder.Module):
                                                                'parse.h',
                                                                setkey_cflags,
                                                                build=False)))
-        self.addRTEMSSourceFiles(
+        self.addRTEMSUserSourceFiles(
             [
                 'rtems/rtems-bsd-shell-setkey.c',
             ],
@@ -2585,6 +2600,156 @@ class pf(builder.Module):
             mm.generator['source']()
         )
 
+#
+# RPC for user space, remove when NFSv2 is removed
+#
+class rpc_user(builder.Module):
+
+    def __init__(self, manager):
+        super(rpc_user, self).__init__(manager, type(self).__name__)
+
+    def generate(self):
+        mm = self.manager
+        # User space support for legacy nfsv2 client, remove when nfsv2 is removed
+        self.addUserSpaceHeaderFiles(
+            [
+                'include/rpc/clnt.h',
+                'include/rpc/pmap_rmt.h',
+                'include/rpc/svc_soc.h',
+                'include/rpc/nettype.h',
+                'include/rpc/xdr.h',
+                'include/rpc/svc.h',
+                'include/rpc/rpc_msg.h',
+                'include/rpc/rpcsec_gss.h',
+                'include/rpc/raw.h',
+                'include/rpc/clnt_stat.h',
+                'include/rpc/auth.h',
+                'include/rpc/svc_dg.h',
+                'include/rpc/auth_kerb.h',
+                'include/rpc/auth_des.h',
+                'include/rpc/rpcb_clnt.h',
+                'include/rpc/rpc.h',
+                'include/rpc/des.h',
+                'include/rpc/des_crypt.h',
+                'include/rpc/svc_auth.h',
+                'include/rpc/pmap_clnt.h',
+                'include/rpc/clnt_soc.h',
+                'include/rpc/pmap_prot.h',
+                'include/rpc/auth_unix.h',
+                'include/rpc/rpc_com.h',
+                'include/rpc/rpcent.h',
+                'include/rpcsvc/nis_db.h',
+                'include/rpcsvc/nislib.h',
+                'include/rpcsvc/nis_tags.h',
+                'include/rpcsvc/ypclnt.h',
+                'include/rpcsvc/yp_prot.h',
+                'lib/libc/rpc/mt_misc.h',
+                'lib/libc/rpc/rpc_com.h',
+            ]
+        )
+        self.addFile(mm.generator['file']('user',
+                                          'include/rpc/rpcb_prot.x',
+                                          mm.generator['freebsd-path'](),
+                                          mm.generator['convert'](),
+                                          mm.generator['convert'](),
+                                          mm.generator['rpc-gen']()))
+        self.addFile(mm.generator['file']('user',
+                                          'include/rpcsvc/nis.x',
+                                          mm.generator['freebsd-path'](),
+                                          mm.generator['convert'](),
+                                          mm.generator['convert'](),
+                                          mm.generator['rpc-gen']()))
+        self.addUserSpaceSourceFiles(
+            [
+                'lib/libc/rpc/auth_des.c',
+                'lib/libc/rpc/authdes_prot.c',
+                'lib/libc/rpc/auth_none.c',
+                'lib/libc/rpc/auth_time.c',
+                'lib/libc/rpc/auth_unix.c',
+                'lib/libc/rpc/authunix_prot.c',
+                'lib/libc/rpc/bindresvport.c',
+                'lib/libc/rpc/clnt_bcast.c',
+                'lib/libc/rpc/clnt_dg.c',
+                'lib/libc/rpc/clnt_generic.c',
+                'lib/libc/rpc/clnt_perror.c',
+                'lib/libc/rpc/clnt_raw.c',
+                'lib/libc/rpc/clnt_simple.c',
+                'lib/libc/rpc/clnt_vc.c',
+                'lib/libc/rpc/crypt_client.c',
+                'lib/libc/rpc/des_crypt.c',
+                'lib/libc/rpc/des_soft.c',
+                'lib/libc/rpc/getnetconfig.c',
+                'lib/libc/rpc/getnetpath.c',
+                'lib/libc/rpc/getpublickey.c',
+                'lib/libc/rpc/getrpcent.c',
+                'lib/libc/rpc/getrpcport.c',
+                'lib/libc/rpc/key_call.c',
+                'lib/libc/rpc/key_prot_xdr.c',
+                'lib/libc/rpc/mt_misc.c',
+                'lib/libc/rpc/netname.c',
+                'lib/libc/rpc/netnamer.c',
+                'lib/libc/rpc/pmap_clnt.c',
+                'lib/libc/rpc/pmap_getmaps.c',
+                'lib/libc/rpc/pmap_getport.c',
+                'lib/libc/rpc/pmap_prot2.c',
+                'lib/libc/rpc/pmap_prot.c',
+                'lib/libc/rpc/pmap_rmt.c',
+                'lib/libc/rpc/rpcb_clnt.c',
+                'lib/libc/rpc/rpcb_prot.c',
+                'lib/libc/rpc/rpcb_st_xdr.c',
+                'lib/libc/rpc/rpc_callmsg.c',
+                'lib/libc/rpc/rpc_commondata.c',
+                'lib/libc/rpc/rpcdname.c',
+                'lib/libc/rpc/rpc_dtablesize.c',
+                'lib/libc/rpc/rpc_generic.c',
+                'lib/libc/rpc/rpc_prot.c',
+                'lib/libc/rpc/rpcsec_gss_stub.c',
+                'lib/libc/rpc/rpc_soc.c',
+                'lib/libc/rpc/rtime.c',
+                'lib/libc/rpc/svc_auth.c',
+                'lib/libc/rpc/svc_auth_des.c',
+                'lib/libc/rpc/svc_auth_unix.c',
+                'lib/libc/rpc/svc.c',
+                'lib/libc/rpc/svc_dg.c',
+                'lib/libc/rpc/svc_generic.c',
+                'lib/libc/rpc/svc_raw.c',
+                'lib/libc/rpc/svc_run.c',
+                'lib/libc/rpc/svc_simple.c',
+                'lib/libc/rpc/svc_vc.c',
+                'lib/libc/xdr/xdr_array.c',
+                'lib/libc/xdr/xdr.c',
+                'lib/libc/xdr/xdr_float.c',
+                'lib/libc/xdr/xdr_mem.c',
+                'lib/libc/xdr/xdr_rec.c',
+                'lib/libc/xdr/xdr_reference.c',
+                'lib/libc/xdr/xdr_sizeof.c',
+                'lib/libc/xdr/xdr_stdio.c',
+            ],
+            mm.generator['source'](['-DINET'])
+        )
+
+#
+# NFSv2 Client
+#
+class nfsv2(builder.Module):
+
+    def __init__(self, manager):
+        super(nfsv2, self).__init__(manager, type(self).__name__)
+
+    def generate(self):
+        mm = self.manager
+        self.addDependency(mm['rpc_user'])
+        self.addRTEMSUserSourceFiles(
+            [
+                'nfsclient/mount_prot_xdr.c',
+                'nfsclient/nfs.c',
+                'nfsclient/nfs_prot_xdr.c',
+                'nfsclient/rpcio.c',
+            ],
+            mm.generator['source']()
+        )
+
+
 #
 # PCI
 #
@@ -2630,6 +2795,7 @@ class pci(builder.Module):
             mm.generator['source']()
         )
 
+
 #
 # User space
 #
@@ -2665,36 +2831,6 @@ class user_space(builder.Module):
                 'include/nsswitch.h',
                 'include/resolv.h',
                 'include/res_update.h',
-                'include/rpc/clnt.h',
-                'include/rpc/pmap_rmt.h',
-                'include/rpc/svc_soc.h',
-                'include/rpc/nettype.h',
-                'include/rpc/xdr.h',
-                'include/rpc/svc.h',
-                'include/rpc/rpc_msg.h',
-                'include/rpc/rpcsec_gss.h',
-                'include/rpc/raw.h',
-                'include/rpc/clnt_stat.h',
-                'include/rpc/auth.h',
-                'include/rpc/svc_dg.h',
-                'include/rpc/auth_kerb.h',
-                'include/rpc/auth_des.h',
-                'include/rpc/rpcb_clnt.h',
-                'include/rpc/rpc.h',
-                'include/rpc/des.h',
-                'include/rpc/des_crypt.h',
-                'include/rpc/svc_auth.h',
-                'include/rpc/pmap_clnt.h',
-                'include/rpc/clnt_soc.h',
-                'include/rpc/pmap_prot.h',
-                'include/rpc/auth_unix.h',
-                'include/rpc/rpc_com.h',
-                'include/rpc/rpcent.h',
-                'include/rpcsvc/nis_db.h',
-                'include/rpcsvc/nislib.h',
-                'include/rpcsvc/nis_tags.h',
-                'include/rpcsvc/ypclnt.h',
-                'include/rpcsvc/yp_prot.h',
                 'include/sysexits.h',
                 'lib/lib80211/lib80211_ioctl.h',
                 'lib/lib80211/lib80211_regdomain.h',
@@ -2724,8 +2860,6 @@ class user_space(builder.Module):
                 'lib/libc/net/res_config.h',
                 'lib/libc/resolv/res_debug.h',
                 'lib/libc/resolv/res_private.h',
-                'lib/libc/rpc/mt_misc.h',
-                'lib/libc/rpc/rpc_com.h',
                 'lib/libc/stdio/local.h',
                 'lib/libkvm/kvm.h',
                 'lib/libmemstat/memstat.h',
@@ -2741,22 +2875,14 @@ class user_space(builder.Module):
                 'usr.bin/netstat/netstat.h'
             ]
         )
-        self.addFile(mm.generator['file']('include/rpc/rpcb_prot.x',
-                                          mm.generator['freebsd-path'](),
-                                          mm.generator['convert'](),
-                                          mm.generator['convert'](),
-                                          mm.generator['rpc-gen']()))
-        self.addFile(mm.generator['file']('include/rpcsvc/nis.x',
-                                          mm.generator['freebsd-path'](),
-                                          mm.generator['convert'](),
-                                          mm.generator['convert'](),
-                                          mm.generator['rpc-gen']()))
-        self.addFile(mm.generator['file']('sbin/route/keywords',
+        self.addFile(mm.generator['file']('user',
+                                          'sbin/route/keywords',
                                           mm.generator['freebsd-path'](),
                                           mm.generator['convert'](),
                                           mm.generator['convert'](),
                                           mm.generator['route-keywords']()))
-        self.addFile(mm.generator['file']('sbin/pfctl/parse.y',
+        self.addFile(mm.generator['file']('user',
+                                          'sbin/pfctl/parse.y',
                                           mm.generator['freebsd-path'](),
                                           mm.generator['convert'](),
                                           mm.generator['convert'](),
@@ -2796,7 +2922,7 @@ class user_space(builder.Module):
                 'include/machine/rtems-bsd-regdomain.h',
             ]
         )
-        self.addRTEMSSourceFiles(
+        self.addRTEMSUserSourceFiles(
             [
                 'rtems/rtems-bsd-regdomain.c',
             ],
@@ -2891,72 +3017,9 @@ class user_space(builder.Module):
                 'lib/libc/resolv/res_send.c',
                 'lib/libc/resolv/res_state.c',
                 'lib/libc/resolv/res_update.c',
-                'lib/libc/rpc/auth_des.c',
-                'lib/libc/rpc/authdes_prot.c',
-                'lib/libc/rpc/auth_none.c',
-                'lib/libc/rpc/auth_time.c',
-                'lib/libc/rpc/auth_unix.c',
-                'lib/libc/rpc/authunix_prot.c',
-                'lib/libc/rpc/bindresvport.c',
-                'lib/libc/rpc/clnt_bcast.c',
-                'lib/libc/rpc/clnt_dg.c',
-                'lib/libc/rpc/clnt_generic.c',
-                'lib/libc/rpc/clnt_perror.c',
-                'lib/libc/rpc/clnt_raw.c',
-                'lib/libc/rpc/clnt_simple.c',
-                'lib/libc/rpc/clnt_vc.c',
-                'lib/libc/rpc/crypt_client.c',
-                'lib/libc/rpc/des_crypt.c',
-                'lib/libc/rpc/des_soft.c',
-                'lib/libc/rpc/getnetconfig.c',
-                'lib/libc/rpc/getnetpath.c',
-                'lib/libc/rpc/getpublickey.c',
-                'lib/libc/rpc/getrpcent.c',
-                'lib/libc/rpc/getrpcport.c',
-                'lib/libc/rpc/key_call.c',
-                'lib/libc/rpc/key_prot_xdr.c',
-                'lib/libc/rpc/mt_misc.c',
-                'lib/libc/rpc/netname.c',
-                'lib/libc/rpc/netnamer.c',
-                'lib/libc/rpc/pmap_clnt.c',
-                'lib/libc/rpc/pmap_getmaps.c',
-                'lib/libc/rpc/pmap_getport.c',
-                'lib/libc/rpc/pmap_prot2.c',
-                'lib/libc/rpc/pmap_prot.c',
-                'lib/libc/rpc/pmap_rmt.c',
-                'lib/libc/rpc/rpcb_clnt.c',
-                'lib/libc/rpc/rpcb_prot.c',
-                'lib/libc/rpc/rpcb_st_xdr.c',
-                'lib/libc/rpc/rpc_callmsg.c',
-                'lib/libc/rpc/rpc_commondata.c',
-                'lib/libc/rpc/rpcdname.c',
-                'lib/libc/rpc/rpc_dtablesize.c',
-                'lib/libc/rpc/rpc_generic.c',
-                'lib/libc/rpc/rpc_prot.c',
-                'lib/libc/rpc/rpcsec_gss_stub.c',
-                'lib/libc/rpc/rpc_soc.c',
-                'lib/libc/rpc/rtime.c',
-                'lib/libc/rpc/svc_auth.c',
-                'lib/libc/rpc/svc_auth_des.c',
-                'lib/libc/rpc/svc_auth_unix.c',
-                'lib/libc/rpc/svc.c',
-                'lib/libc/rpc/svc_dg.c',
-                'lib/libc/rpc/svc_generic.c',
-                'lib/libc/rpc/svc_raw.c',
-                'lib/libc/rpc/svc_run.c',
-                'lib/libc/rpc/svc_simple.c',
-                'lib/libc/rpc/svc_vc.c',
                 'lib/libc/stdio/fgetln.c',
                 'lib/libc/stdlib/strtonum.c',
                 'lib/libc/string/strsep.c',
-                'lib/libc/xdr/xdr_array.c',
-                'lib/libc/xdr/xdr.c',
-                'lib/libc/xdr/xdr_float.c',
-                'lib/libc/xdr/xdr_mem.c',
-                'lib/libc/xdr/xdr_rec.c',
-                'lib/libc/xdr/xdr_reference.c',
-                'lib/libc/xdr/xdr_sizeof.c',
-                'lib/libc/xdr/xdr_stdio.c',
                 'lib/libmemstat/memstat_all.c',
                 'lib/libmemstat/memstat.c',
                 'lib/libmemstat/memstat_malloc.c',
@@ -3068,6 +3131,7 @@ class crypto_openssl(builder.Module):
 
     def generate(self):
         mm = self.manager
+        self.addDependency(mm['user_space'])
         self.addUserSpaceHeaderFiles(
             [
                 'crypto/openssl/crypto/aes/aes_locl.h',
@@ -4021,21 +4085,22 @@ class crypto_openssl(builder.Module):
                                     'freebsd/crypto/openssl/crypto/ec/curve448',
                                     'freebsd/crypto/openssl/crypto/ec/curve448/arch_32'])
         )
-        self.addFile(mm.generator['file']('crypto/openssl/crypto/LPdir_unix.c',
+        self.addFile(mm.generator['file']('user',
+                                          'crypto/openssl/crypto/LPdir_unix.c',
                                           mm.generator['freebsd-path'](),
                                           mm.generator['from-FreeBSD-to-RTEMS-UserSpaceSourceConverter'](),
                                           mm.generator['from-RTEMS-To-FreeBSD-SourceConverter'](),
-                                          mm.generator['buildSystemFragmentComposer']()))
-        self.addFile(mm.generator['file']('crypto/openssl/crypto/ec/ecp_nistz256_table.c',
+                                          mm.generator['buildSystemComposer']()))
+        self.addFile(mm.generator['file']('user',
+                                          'crypto/openssl/crypto/ec/ecp_nistz256_table.c',
                                           mm.generator['freebsd-path'](),
                                           mm.generator['from-FreeBSD-to-RTEMS-UserSpaceSourceConverter'](),
                                           mm.generator['from-RTEMS-To-FreeBSD-SourceConverter'](),
-                                          mm.generator['buildSystemFragmentComposer']()))
+                                          mm.generator['buildSystemComposer']()))
 
 #
 # /usr/bin/openssl
 #
-# depends on crypto_openssl, user_space
 class usr_bin_openssl(builder.Module):
 
     def __init__(self, manager):
@@ -4043,6 +4108,7 @@ class usr_bin_openssl(builder.Module):
 
     def generate(self):
         mm = self.manager
+        self.addDependency(mm['crypto_openssl'])
         self.addUserSpaceHeaderFiles(
             [
                 'crypto/openssl/apps/apps.h',
@@ -4115,7 +4181,7 @@ class usr_bin_openssl(builder.Module):
                                    ['freebsd/crypto/openssl']
             )
         )
-        self.addRTEMSSourceFiles(
+        self.addRTEMSUserSourceFiles(
             [
                 'rtems/rtems-bsd-shell-openssl.c',
             ],
@@ -4233,14 +4299,16 @@ class contrib_libpcap(builder.Module):
         )
         gen_cflags = cflags + ['-DNEED_YYPARSE_WRAPPER=1',
                                '-Dyylval=pcap_lval']
-        self.addFile(mm.generator['file']('contrib/libpcap/scanner.l',
+        self.addFile(mm.generator['file']('user',
+                                          'contrib/libpcap/scanner.l',
                                           mm.generator['freebsd-path'](),
                                           mm.generator['convert'](),
                                           mm.generator['convert'](),
                                           mm.generator['lex']('pcap',
                                                               'scanner.c',
                                                               gen_cflags)))
-        self.addFile(mm.generator['file']('contrib/libpcap/grammar.y',
+        self.addFile(mm.generator['file']('user',
+                                          'contrib/libpcap/grammar.y',
                                           mm.generator['freebsd-path'](),
                                           mm.generator['convert'](),
                                           mm.generator['convert'](),
@@ -4811,7 +4879,7 @@ class usr_sbin_wpa_supplicant(builder.Module):
                                     'freebsd/usr.sbin/wpa/wpa_supplicant',
                                     'freebsd/crypto/openssl/crypto'])
         )
-        self.addRTEMSSourceFiles(
+        self.addRTEMSUserSourceFiles(
             [
                 'rtems/rtems-bsd-shell-wpa_supplicant.c',
                 'rtems/rtems-wpa_supplicant_mutex.c',
@@ -4920,7 +4988,7 @@ class dhcpcd(builder.Module):
             ],
             mm.generator['source']('-D__FreeBSD__ -DTHERE_IS_NO_FORK -DMASTER_ONLY -DINET')
         )
-        self.addRTEMSSourceFiles(
+        self.addRTEMSUserSourceFiles(
             [
                 'rtems/rtems-bsd-shell-dhcpcd.c',
             ],
@@ -4958,6 +5026,7 @@ class mdnsresponder(builder.Module):
             mm.generator['source']()
         )
 
+
 class dpaa(builder.Module):
 
     def __init__(self, manager):
@@ -5057,7 +5126,7 @@ class regulator(builder.Module):
 
     def generate(self):
         mm = self.manager
-        self.addRTEMSSourceFiles(
+        self.addRTEMSKernelSourceFiles(
             [
                 'local/regdev_if.c',
                 'local/regnode_if.c',
@@ -5223,6 +5292,9 @@ def load(mm):
     mm.addModule(pf(mm))
     mm.addModule(dev_net(mm))
 
+    mm.addModule(rpc_user(mm))
+    mm.addModule(nfsv2(mm))
+
     # Add PCI
     mm.addModule(pci(mm))
 
diff --git a/waf_libbsd.py b/waf_libbsd.py
index bdd1cf4a..d7a0c224 100644
--- a/waf_libbsd.py
+++ b/waf_libbsd.py
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: BSD-2-Clause
-'''LibBSD build configuration to waf integration module.
-'''
+"""LibBSD build configuration to waf integration module.
+"""
 
 # Copyright (c) 2015, 2020 Chris Johns <chrisj at rtems.org>. All rights reserved.
 #
@@ -37,12 +37,6 @@
 
 from __future__ import print_function
 
-# Python 3 does no longer know the basestring class. Catch that.
-try:
-    basestring
-except NameError:
-    basestring = (str, bytes)
-
 import os
 import sys
 import tempfile
@@ -86,11 +80,11 @@ class Builder(builder.ModuleManager):
         return sources
 
     def generate(self, rtems_version):
-        def _dataInsert(data, cpu, frag):
+        def _dataInsert(data, cpu, space, frag):
             #
-            # The default handler returns an empty string. Skip it.
+            # The default handler returns None. Skip it.
             #
-            if type(frag) is not str:
+            if frag is not None:
                 # Start at the top of the tree
                 d = data
                 path = frag[0]
@@ -99,6 +93,10 @@ class Builder(builder.ModuleManager):
                 # Select the sub-part of the tree as the compile options
                 # specialise how files are built.
                 d = d[path[0]]
+                # Group based on the space, ie kernel or user
+                if space not in d:
+                    d[space] = {}
+                d = d[space]
                 if type(path[1]) is list:
                     p = ' '.join(path[1])
                 else:
@@ -144,11 +142,14 @@ class Builder(builder.ModuleManager):
             m = self[mn]
             if m.conditionalOn == "none":
                 for f in m.files:
-                    _dataInsert(self.data, 'all', f.getFragment())
+                    _dataInsert(self.data, 'all', f.getSpace(),
+                                f.getFragment())
             for cpu, files in sorted(m.cpuDependentSourceFiles.items()):
                 for f in files:
-                    _dataInsert(self.data, cpu, f.getFragment())
+                    _dataInsert(self.data, cpu, f.getSpace(),
+                                f.getFragment())
 
+        # Start here if you need to understand self.data. Add 'True or'
         if self.trace:
             import pprint
             pprint.pprint(self.data)
@@ -206,21 +207,45 @@ class Builder(builder.ModuleManager):
                 defines += ['%s=1' % (o.strip().upper())]
 
         #
-        # Include paths
-        #
-        includes = []
-        buildinclude = 'build-include'
-        if 'cpu-include-paths' in config:
+        # Include paths, maintain paths for each build space.
+        #
+        include_paths = config['include-paths']
+        if 'build' not in include_paths:
+            bld.fatal('no build include path found in include-path defaults')
+        buildinclude = include_paths['build']
+        if isinstance(buildinclude, list):
+            buildinclude = buildinclude[0]
+        inc_paths = sorted(include_paths)
+        inc_paths.remove('build')
+        inc_paths.remove('cpu')
+        includes = {}
+        for inc in inc_paths:
+            includes[inc] = include_paths[inc]
+        # cpu include paths must be the first searched
+        if 'cpu' in include_paths:
             cpu = bld.get_env()['RTEMS_ARCH']
-            for i in config['cpu-include-paths']:
-                includes += [i.replace('@CPU@', cpu)]
-        if 'include-paths' in config:
-            includes += config['include-paths']
-        if 'build-include-path' in config:
-            buildinclude = config['build-include-path']
-            if not isinstance(buildinclude, basestring):
-                buildinclude = buildinclude[0]
-        includes += [buildinclude]
+            for i in include_paths['cpu']:
+                includes['kernel'].insert(0, i.replace('@CPU@', cpu))
+        includes['kernel'] += [buildinclude]
+
+        #
+        # Path mappings
+        #
+        if 'path-mappings' in config:
+            for source, target in config['path-mappings']:
+                for space in includes:
+                    incs = includes[space]
+                    if source in incs:
+                        target = [target] if isinstance(target,
+                                                        str) else target
+                        i = incs.index(source)
+                        incs.remove(source)
+                        incs[i:i] = target
+
+        #
+        # Place the kernel include paths after the user paths
+        #
+        includes['user'] += includes['kernel']
 
         #
         # Path mappings
@@ -325,7 +350,7 @@ class Builder(builder.ModuleManager):
         # KVM Symbols
         #
         if 'KVMSymbols' in self.data:
-            kvmsymbols = self.data['KVMSymbols']
+            kvmsymbols = self.data['KVMSymbols']['kernel']
             if 'includes' in kvmsymbols['files']:
                 kvmsymbols_includes = kvmsymbols['files']['includes']
             else:
@@ -337,7 +362,7 @@ class Builder(builder.ModuleManager):
             bld.objects(target='kvmsymbols',
                         features='c',
                         cflags=cflags,
-                        includes=kvmsymbols_includes + includes,
+                        includes=kvmsymbols_includes + includes['kernel'],
                         source=kvmsymbols['files']['all']['default'][0])
             libbsd_use += ["kvmsymbols"]
 
@@ -348,7 +373,7 @@ class Builder(builder.ModuleManager):
         #
         if 'RPCGen' in self.data:
             if bld.env.AUTO_REGEN:
-                rpcgen = self.data['RPCGen']
+                rpcgen = self.data['RPCGen']['user']
                 rpcname = rpcgen['files']['all']['default'][0][:-2]
                 bld(target=rpcname + '.h',
                     source=rpcname + '.x',
@@ -359,7 +384,7 @@ class Builder(builder.ModuleManager):
         #
         if 'RouteKeywords' in self.data:
             if bld.env.AUTO_REGEN:
-                routekw = self.data['RouteKeywords']
+                routekw = self.data['RouteKeywords']['user']
                 rkwname = routekw['files']['all']['default'][0]
                 rkw_rule = host_shell + "cat ${SRC} | " + \
                            "awk 'BEGIN { r = 0 } { if (NF == 1) " + \
@@ -371,7 +396,7 @@ class Builder(builder.ModuleManager):
         # Lex
         #
         if 'lex' in self.data:
-            lexes = self.data['lex']
+            lexes = self.data['lex']['user']
             for l in sorted(lexes.keys()):
                 lex = lexes[l]['all']['default']
                 if 'cflags' in lex:
@@ -392,7 +417,7 @@ class Builder(builder.ModuleManager):
                     bld.objects(target='lex_%s' % (lex['sym']),
                                 features='c',
                                 cflags=cflags,
-                                includes=lexIncludes + includes,
+                                includes=lexIncludes + includes['user'],
                                 defines=defines + lexDefines,
                                 source=lex['file'][:-2] + '.c')
                 libbsd_use += ['lex_%s' % (lex['sym'])]
@@ -401,7 +426,7 @@ class Builder(builder.ModuleManager):
         # Yacc
         #
         if 'yacc' in self.data:
-            yaccs = self.data['yacc']
+            yaccs = self.data['yacc']['user']
             for y in sorted(yaccs.keys()):
                 yacc = yaccs[y]['all']['default']
                 yaccFile = yacc['file']
@@ -432,7 +457,7 @@ class Builder(builder.ModuleManager):
                     bld.objects(target='yacc_%s' % (yaccSym),
                                 features='c',
                                 cflags=cflags,
-                                includes=yaccIncludes + includes,
+                                includes=yaccIncludes + includes['user'],
                                 defines=defines + yaccDefines,
                                 source=yaccFile[:-2] + '.c')
                 libbsd_use += ['yacc_%s' % (yaccSym)]
@@ -442,34 +467,40 @@ class Builder(builder.ModuleManager):
         # specific files for those flags.
         #
         objs = 0
-        sources = sorted(self.data['sources'])
-        if 'default' in sources:
-            sources.remove('default')
-        for flags in sources:
-            objs += 1
-            build = self.data['sources'][flags]
-            target = 'objs%02d' % (objs)
-            bld_sources = Builder._sourceList(bld, build['all'])
-            archs = sorted(build)
-            for i in ['all', 'cflags', 'includes']:
-                if i in archs:
-                    archs.remove(i)
-            for arch in archs:
-                if bld.get_env()['RTEMS_ARCH'] == arch:
-                    bld_sources += Builder._sourceList(bld, build[arch])
-            bld.objects(target=target,
-                        features='c',
-                        cflags=cflags + sorted(build.get('cflags', [])),
-                        includes=sorted(build.get('includes', [])) + includes,
-                        defines=defines,
-                        source=bld_sources)
-            libbsd_use += [target]
-
-        #
-        # We hold the 'default' cflags set of files to the end to create the
-        # static library with.
-        #
-        build = self.data['sources']['default']
+        for space in sorted(self.data['sources']):
+            sources = sorted(self.data['sources'][space])
+            if space == 'kernel' and 'default' in sources:
+                sources.remove('default')
+            for flags in sources:
+                objs += 1
+                build = self.data['sources'][space][flags]
+                target = 'objs%02d' % (objs)
+                bld_sources = Builder._sourceList(bld, build['all'])
+                archs = sorted(build)
+                for i in ['all', 'cflags', 'includes']:
+                    if i in archs:
+                        archs.remove(i)
+                for arch in archs:
+                    if bld.get_env()['RTEMS_ARCH'] == arch:
+                        bld_sources += Builder._sourceList(bld, build[arch])
+                bld_cflags = sorted(build.get('cflags', []))
+                if 'default' in bld_cflags:
+                    bld_cflags.remove('default')
+                bld.objects(target=target,
+                            features='c cxx',
+                            cflags=cflags + bld_cflags,
+                            cxxflags=cxxflags,
+                            includes=sorted(build.get('includes', [])) +
+                            includes[space],
+                            defines=defines,
+                            source=bld_sources)
+                libbsd_use += [target]
+
+        #
+        # We hold the kernel 'default' cflags set of files to the end to
+        # create the static library with.
+        #
+        build = self.data['sources']['kernel']['default']
         bld_sources = Builder._sourceList(bld, build['all'])
         archs = sorted(build)
         archs.remove('all')
@@ -480,7 +511,7 @@ class Builder(builder.ModuleManager):
                   features='c cxx',
                   cflags=cflags,
                   cxxflags=cxxflags,
-                  includes=includes,
+                  includes=includes['kernel'],
                   defines=defines,
                   source=bld_sources,
                   use=libbsd_use)
@@ -522,9 +553,9 @@ class Builder(builder.ModuleManager):
         #
         tests = []
         if 'tests' in self.data:
-            tests = self.data['tests']
+            tests = self.data['tests']['user']
         for testName in sorted(tests):
-            test = self.data['tests'][testName]['all']
+            test = tests[testName]['all']
             test_source = []
             libs = ['bsd', 'm', 'z', 'rtemstest']
             for cfg in test:
@@ -542,7 +573,7 @@ class Builder(builder.ModuleManager):
                 bld.program(target='%s.exe' % (testName),
                             features='cprogram',
                             cflags=cflags,
-                            includes=includes,
+                            includes=includes['user'],
                             source=test_sources,
                             use=['bsd'],
                             lib=libs,
diff --git a/wscript b/wscript
index e9541327..466b50be 100644
--- a/wscript
+++ b/wscript
@@ -1,9 +1,9 @@
 # SPDX-License-Identifier: BSD-2-Clause
-'''RTEMS LibBSD is a transparent source build of the FreeBSD kernel
+"""RTEMS LibBSD is a transparent source build of the FreeBSD kernel
 source for RTEMS.
 
 To use see README.waf shipped with this file.
-'''
+"""
 
 # Copyright (c) 2015-2016 Chris Johns <chrisj at rtems.org>. All rights reserved.
 #
-- 
2.24.1



More information about the devel mailing list